changeset 2578:96280a58fefb

* cdl/usbs_at91.cdl: * include/usbs_at91.h: * src/usbs_at91.c: * src/usbs_at91_data.c: Support for SAM7SE which has an internal pullup. Added extra endpoints for those chips that have them.
author asl
date Mon, 03 Nov 2008 08:48:19 +0000
parents de43e04cf3a5
children 23e894d966a8
files packages/devs/usb/at91/current/ChangeLog packages/devs/usb/at91/current/cdl/usbs_at91.cdl packages/devs/usb/at91/current/include/usbs_at91.h packages/devs/usb/at91/current/src/usbs_at91.c packages/devs/usb/at91/current/src/usbs_at91_data.cxx
diffstat 5 files changed, 294 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/packages/devs/usb/at91/current/ChangeLog
+++ b/packages/devs/usb/at91/current/ChangeLog
@@ -1,3 +1,11 @@
+2008-11-03  Gabor Toeroek <tgabor84@gmail.com>
+
+	* cdl/usbs_at91.cdl: 
+	* include/usbs_at91.h:
+	* src/usbs_at91.c:
+	* src/usbs_at91_data.c: Support for SAM7SE which has an internal
+	  pullup.  Added extra endpoints for those chips that have them.
+	
 2007-11-20  Andrew Lunn  <andrew.lunn@ascom.ch>
 
 	* cdl/usbs_at91.cdl: Fixed typos in
--- a/packages/devs/usb/at91/current/cdl/usbs_at91.cdl
+++ b/packages/devs/usb/at91/current/cdl/usbs_at91.cdl
@@ -93,6 +93,17 @@ cdl_package CYGPKG_DEVS_USB_AT91 {
             Enable support for endpoint 0. If this support is disabled
             then the entire USB port is unusable."
     
+        cdl_option CYGDAT_DEVS_USB_AT91_GPIO_SET_PULLUP_INTERNAL {
+            display       "The chip has internal pullup"
+            flavor        bool
+            calculated    { CYGHWR_HAL_ARM_AT91SAM7SE }
+            requires      { CYGDAT_DEVS_USB_AT91_GPIO_SET_PULLUP_PIN == "NONE" }
+            description "
+                   The chip has an internal pullup resistor;
+                   the use of this pullup is mandatory (?), so there
+                   should be no external pullup resistor."
+        }
+    
         cdl_option CYGDAT_DEVS_USB_AT91_GPIO_SET_PULLUP_PIN {
             display       "PIO-Pin who controls the pullup resistor"
             flavor        data
@@ -105,6 +116,7 @@ cdl_package CYGPKG_DEVS_USB_AT91 {
 
         cdl_option CYGNUM_DEVS_USB_AT91_GPIO_SET_PULLUP_INVERTED {
             display       "Has the signal to be inverted?"
+            active_if     {CYGDAT_DEVS_USB_AT91_GPIO_SET_PULLUP_PIN != "NONE"}
             flavor        bool
             default_value 1
             description "
--- a/packages/devs/usb/at91/current/include/usbs_at91.h
+++ b/packages/devs/usb/at91/current/include/usbs_at91.h
@@ -50,13 +50,31 @@
 
 #include <cyg/io/usb/usbs.h>
 #include <pkgconf/devs_usb_at91.h>
+#include <pkgconf/system.h>
+#ifdef CYGPKG_HAL_ARM_AT91SAM7
+#include <pkgconf/hal_arm_at91sam7.h>
+#endif
 
+#if defined(CYGHWR_HAL_ARM_AT91SAM7SE)
+#define AT91_USB_ENDPOINTS 8
+#elif defined(CYGHWR_HAL_ARM_AT91SAM7X)
+#define AT91_USB_ENDPOINTS 6
+#else
 #define AT91_USB_ENDPOINTS 4
+#endif
  
 extern usbs_control_endpoint    usbs_at91_ep0;
 extern usbs_rx_endpoint         usbs_at91_ep1;
 extern usbs_rx_endpoint         usbs_at91_ep2;
 extern usbs_rx_endpoint         usbs_at91_ep3;
+#if (AT91_USB_ENDPOINTS > 4)
+extern usbs_rx_endpoint         usbs_at91_ep4;
+extern usbs_rx_endpoint         usbs_at91_ep5;
+#if (AT91_USB_ENDPOINTS > 6)
+extern usbs_rx_endpoint         usbs_at91_ep6;
+extern usbs_rx_endpoint         usbs_at91_ep7;
+#endif
+#endif
 
 extern void usbs_at91_endpoint_init(usbs_rx_endpoint * pep, 
                                     cyg_uint8 endpoint_type, cyg_bool enable);
--- a/packages/devs/usb/at91/current/src/usbs_at91.c
+++ b/packages/devs/usb/at91/current/src/usbs_at91.c
@@ -49,11 +49,13 @@
 //####DESCRIPTIONEND####
 //==========================================================================
 
+#include <pkgconf/system.h>
 #include <pkgconf/devs_usb_at91.h>
 #include <cyg/io/usb/usb.h>
 #include <cyg/io/usb/usbs.h>
 #include <cyg/io/usb/usbs_at91.h>
 
+#include CYGBLD_HAL_PLATFORM_H
 #include <cyg/hal/hal_io.h>
 #include <cyg/hal/drv_api.h>
 #include <cyg/hal/hal_io.h>
@@ -82,39 +84,132 @@
 #define pCSRn(N) (pCSR0 + (N * 4))
 #define pFDRn(N) (pFDR0 + (N * 4))
 
+#if (AT91_USB_ENDPOINTS == 8)
+#define AT91_UDP_ALLOWED_IRQs \
+    (AT91_UDP_WAKEUP | AT91_UDP_ENDBUSRES | AT91_UDP_EXTRSM | \
+     AT91_UDP_RXRSM  | AT91_UDP_RXSUSP    | AT91_UDP_EPINT0 | \
+     AT91_UDP_EPINT1 | AT91_UDP_EPINT2    | AT91_UDP_EPINT3 | \
+     AT91_UDP_EPINT4 | AT91_UDP_EPINT5 | \
+     AT91_UDP_EPINT6 | AT91_UDP_EPINT7 )
+#elif (AT91_USB_ENDPOINTS == 6)
+#define AT91_UDP_ALLOWED_IRQs \
+    (AT91_UDP_WAKEUP | AT91_UDP_ENDBUSRES | AT91_UDP_EXTRSM | \
+     AT91_UDP_RXRSM  | AT91_UDP_RXSUSP    | AT91_UDP_EPINT0 | \
+     AT91_UDP_EPINT1 | AT91_UDP_EPINT2    | AT91_UDP_EPINT3 | \
+     AT91_UDP_EPINT4 | AT91_UDP_EPINT5 )
+#elif (AT91_USB_ENDPOINTS == 4)
 #define AT91_UDP_ALLOWED_IRQs \
     (AT91_UDP_WAKEUP | AT91_UDP_ENDBUSRES | AT91_UDP_EXTRSM | \
      AT91_UDP_RXRSM  | AT91_UDP_RXSUSP    | AT91_UDP_EPINT0 | \
      AT91_UDP_EPINT1 | AT91_UDP_EPINT2    | AT91_UDP_EPINT3)
+#endif
 
 #define THERE_IS_A_NEW_PACKET_IN_THE_UDP 0xffff
 
 // Fifo size for each end point.
+#if defined(CYGHWR_HAL_ARM_AT91SAM7SE)
+static const cyg_uint16 usbs_at91_endpoint_fifo_size[AT91_USB_ENDPOINTS] = {
+  8,
+  64,
+  64,
+  64,
+  512,
+  512,
+  64,
+  64
+};
+#elif defined(CYGHWR_HAL_ARM_AT91SAM7X)
+static const cyg_uint16 usbs_at91_endpoint_fifo_size[AT91_USB_ENDPOINTS] = {
+  8,
+  64,
+  64,
+  64,
+  256,
+  256
+};
+#else
 static const cyg_uint16 usbs_at91_endpoint_fifo_size[AT91_USB_ENDPOINTS] = {
   8,
   64,
   64,
   64,
 };
+#endif
 
 // Does an endpoint support ping pong buffering?
+#if defined(CYGHWR_HAL_ARM_AT91SAM7SE)
+static const bool usbs_at91_endpoint_pingpong[AT91_USB_ENDPOINTS] = {
+  false,
+  true,
+  true,
+  false,
+  true,
+  true,
+  true,
+  true
+};
+#elif defined(CYGHWR_HAL_ARM_AT91SAM7X)
+static const bool usbs_at91_endpoint_pingpong[AT91_USB_ENDPOINTS] = {
+  false,
+  true,
+  true,
+  false,
+  true,
+  true
+};
+#else
 static const bool usbs_at91_endpoint_pingpong[AT91_USB_ENDPOINTS] = {
   false,
   true,
   true,
   false
 };
+#endif
 
 static cyg_uint8 *usbs_at91_endpoint_pbegin[AT91_USB_ENDPOINTS] = 
+#if (AT91_USB_ENDPOINTS == 8)
+  { 0, 0, 0, 0, 0, 0, 0, 0 };
+#elif (AT91_USB_ENDPOINTS == 6)
+  { 0, 0, 0, 0, 0, 0 };
+#else
   { 0, 0, 0, 0 };
+#endif
+
 static cyg_uint8 *usbs_at91_endpoint_pend[AT91_USB_ENDPOINTS] = 
+#if (AT91_USB_ENDPOINTS == 8)
+  { 0, 0, 0, 0, 0, 0, 0, 0 };
+#elif (AT91_USB_ENDPOINTS == 6)
+  { 0, 0, 0, 0, 0, 0 };
+#else
   { 0, 0 ,0, 0 };
+#endif
+
 static bool usbs_at91_endpoint_bank1[AT91_USB_ENDPOINTS] = 
+#if (AT91_USB_ENDPOINTS == 8)
+  { false, false, false, false, false, false, false, false };
+#elif (AT91_USB_ENDPOINTS == 6)
+  { false, false, false, false, false, false };
+#else
   { false, false, false, false };
+#endif
+
 static cyg_uint16 usbs_at91_endpoint_bytes_in_fifo[AT91_USB_ENDPOINTS] =
+#if (AT91_USB_ENDPOINTS == 8)
+  { 0, 0, 0, 0, 0, 0, 0, 0 };
+#elif (AT91_USB_ENDPOINTS == 6)
+  { 0, 0, 0, 0, 0, 0 };
+#else
   { 0, 0, 0, 0 };
+#endif
+
 static cyg_uint16 usbs_at91_endpoint_bytes_received[AT91_USB_ENDPOINTS] =
   { THERE_IS_A_NEW_PACKET_IN_THE_UDP, THERE_IS_A_NEW_PACKET_IN_THE_UDP,
+#if (AT91_USB_ENDPOINTS > 4)
+	THERE_IS_A_NEW_PACKET_IN_THE_UDP, THERE_IS_A_NEW_PACKET_IN_THE_UDP,
+#if (AT91_USB_ENDPOINTS > 6)
+	THERE_IS_A_NEW_PACKET_IN_THE_UDP, THERE_IS_A_NEW_PACKET_IN_THE_UDP,
+#endif
+#endif
     THERE_IS_A_NEW_PACKET_IN_THE_UDP, THERE_IS_A_NEW_PACKET_IN_THE_UDP};
 
 static cyg_interrupt usbs_at91_intr_data;
@@ -196,6 +291,58 @@ usbs_rx_endpoint usbs_at91_ep3 = {
   halted:         0,
 };
 
+#if (AT91_USB_ENDPOINTS > 4)
+// Endpoint 4 Receive control structure
+usbs_rx_endpoint usbs_at91_ep4 = {
+  start_rx_fn:    usbs_at91_endpoint_start,
+  set_halted_fn:  usbs_at91_endpoint_set_halted,
+  complete_fn:    (void (*)(void *, int)) 0,
+  complete_data:  (void *) 0,
+  buffer:         (unsigned char *) 0,
+  buffer_size:    0,
+  halted:         0,
+};
+#endif
+
+#if (AT91_USB_ENDPOINTS > 5)
+// Endpoint 5 Receive control structure
+usbs_rx_endpoint usbs_at91_ep5 = {
+  start_rx_fn:    usbs_at91_endpoint_start,
+  set_halted_fn:  usbs_at91_endpoint_set_halted,
+  complete_fn:    (void (*)(void *, int)) 0,
+  complete_data:  (void *) 0,
+  buffer:         (unsigned char *) 0,
+  buffer_size:    0,
+  halted:         0,
+};
+#endif
+
+#if (AT91_USB_ENDPOINTS > 6)
+// Endpoint 6 Receive control structure
+usbs_rx_endpoint usbs_at91_ep6 = {
+  start_rx_fn:    usbs_at91_endpoint_start,
+  set_halted_fn:  usbs_at91_endpoint_set_halted,
+  complete_fn:    (void (*)(void *, int)) 0,
+  complete_data:  (void *) 0,
+  buffer:         (unsigned char *) 0,
+  buffer_size:    0,
+  halted:         0,
+};
+#endif
+
+#if (AT91_USB_ENDPOINTS > 7)
+// Endpoint 7 Receive control structure
+usbs_rx_endpoint usbs_at91_ep7 = {
+  start_rx_fn:    usbs_at91_endpoint_start,
+  set_halted_fn:  usbs_at91_endpoint_set_halted,
+  complete_fn:    (void (*)(void *, int)) 0,
+  complete_data:  (void *) 0,
+  buffer:         (unsigned char *) 0,
+  buffer_size:    0,
+  halted:         0,
+};
+#endif
+
 // Array of end points. Used for translating end point pointer to an
 // end point number
 static const void *usbs_at91_endpoints[AT91_USB_ENDPOINTS] = {
@@ -203,6 +350,12 @@ static const void *usbs_at91_endpoints[A
   (void *) &usbs_at91_ep1,
   (void *) &usbs_at91_ep2,
   (void *) &usbs_at91_ep3
+#if (AT91_USB_ENDPOINTS > 4)
+  ,(void *) &usbs_at91_ep4, (void *) &usbs_at91_ep5
+#if (AT91_USB_ENDPOINTS > 6)
+  ,(void *) &usbs_at91_ep6, (void *) &usbs_at91_ep7
+#endif
+#endif
 };
 
 // Convert an endpoint pointer to an endpoint number, using the array
@@ -276,6 +429,16 @@ write_fifo_uint8 (cyg_addrword_t pdest, 
 static void
 usbs_at91_set_pullup (bool set)
 {                
+#ifdef CYGDAT_DEVS_USB_AT91_GPIO_SET_PULLUP_INTERNAL
+  cyg_uint32 txvc;
+  HAL_READ_UINT32(AT91_UDP + AT91_UDP_TXVC, buf);
+  if (set) {
+    txvc |= AT91_UDP_TXVC_PUON;
+  } else {
+    txvc &= ~AT91_UDP_TXVC_PUON;
+  }
+  HAL_WRITE_UINT32(AT91_UDP + AT91_UDP_TXVC, txvc);
+#endif // CYGDAT_DEVS_USB_AT91_GPIO_SET_PULLUP_INTERNAL
 
 #ifndef CYGDAT_DEVS_USB_AT91_GPIO_SET_PULLUP_PIN_NONE
   if (
@@ -466,13 +629,9 @@ usbs_at91_endpoint_init (usbs_rx_endpoin
 }
 
 static void
-usbs_at91_handle_reset (void)
+usbs_at91_reset_device (void)
 {
   int epn;
-  const usb_endpoint_descriptor *usb_endpoints;
-  cyg_uint8 endpoint_type;
-  
-   cyg_uint8 endpoint_number;
 
   usbs_end_all_transfers (-EPIPE);
   
@@ -490,6 +649,18 @@ usbs_at91_handle_reset (void)
     usbs_at91_endpoint_init ((usbs_rx_endpoint *)usbs_at91_endpoints[epn], 
                              0, false);
   }
+}
+
+static void
+usbs_at91_handle_reset (void)
+{
+  int epn;
+  const usb_endpoint_descriptor *usb_endpoints;
+  cyg_uint8 endpoint_type;
+
+  cyg_uint8 endpoint_number;
+
+  usbs_at91_reset_device ();
 
   // Now walk the endpoints configuring them correctly. This only
   // works if there is one interface.
@@ -505,11 +676,11 @@ usbs_at91_handle_reset (void)
                       USB_ENDPOINT_DESCRIPTOR_ENDPOINT_IN : 
                       USB_ENDPOINT_DESCRIPTOR_ENDPOINT_OUT));
     endpoint_number = usb_endpoints[epn-1].endpoint & ~(USB_ENDPOINT_DESCRIPTOR_ENDPOINT_IN); 
-    if ( endpoint_number < AT91_USB_ENDPOINTS )
-    {
-        usbs_at91_endpoint_init((usbs_rx_endpoint *)usbs_at91_endpoints[endpoint_number],
-                                endpoint_type,
-                                true);
+
+    if ( endpoint_number < AT91_USB_ENDPOINTS ) {
+      usbs_at91_endpoint_init((usbs_rx_endpoint *)usbs_at91_endpoints[endpoint_number],
+                              endpoint_type,
+                              true);
     }
   }
 }
@@ -527,6 +698,7 @@ usbs_at91_ep0_start (usbs_control_endpoi
 #endif
   
   usbs_at91_set_pullup (true);
+  CLEAR_BITS(AT91_UDP + AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS);
 }
 
 static void
@@ -1323,7 +1495,7 @@ usbs_at91_init (void)
   HAL_ARM_AT91_GPIO_CFG_DIRECTION(CYGDAT_DEVS_USB_AT91_GPIO_READ_POWER_PIN,
                                   AT91_PIN_IN);
 #endif
-  usbs_at91_handle_reset ();
+  usbs_at91_reset_device ();
   
   cyg_drv_interrupt_create (CYGNUM_HAL_INTERRUPT_UDP, 
                             6,  // priority
@@ -1335,8 +1507,6 @@ usbs_at91_init (void)
   cyg_drv_interrupt_attach (usbs_at91_intr_handle);
   cyg_drv_interrupt_unmask (CYGNUM_HAL_INTERRUPT_UDP);
   
-  HAL_WRITE_UINT32 (AT91_UDP + AT91_UDP_TXVC, 0);
-  
   usbs_at91_ep0.state = USBS_STATE_POWERED;
   usbs_state_notify (&usbs_at91_ep0);
 }
--- a/packages/devs/usb/at91/current/src/usbs_at91_data.cxx
+++ b/packages/devs/usb/at91/current/src/usbs_at91_data.cxx
@@ -121,14 +121,17 @@ CHAR_DEVTAB_ENTRY(usbs_at91_ep0_devtab_e
 
 #if defined(CYGVAR_DEVS_USB_AT91_EP1_DEVTAB_ENTRY) || \
     defined(CYGVAR_DEVS_USB_AT91_EP2_DEVTAB_ENTRY) || \
-    defined(CYGVAR_DEVS_USB_AT91_EP3_DEVTAB_ENTRY)
+    defined(CYGVAR_DEVS_USB_AT91_EP3_DEVTAB_ENTRY) || \
+    defined(CYGVAR_DEVS_USB_AT91_EP4_DEVTAB_ENTRY) || \
+    defined(CYGVAR_DEVS_USB_AT91_EP5_DEVTAB_ENTRY) || \
+    defined(CYGVAR_DEVS_USB_AT91_EP6_DEVTAB_ENTRY) || \
+    defined(CYGVAR_DEVS_USB_AT91_EP7_DEVTAB_ENTRY)
 
 static bool usbs_at91_devtab_dummy_init(struct cyg_devtab_entry* tab){
   
     CYG_UNUSED_PARAM(struct cyg_devtab_entry*, tab);
     return true;
 }
-
 #endif
 
 #ifdef CYGVAR_DEVS_USB_AT91_EP1_DEVTAB_ENTRY
@@ -181,3 +184,71 @@ CHAR_DEVTAB_ENTRY(usbs_at91_ep3_devtab_e
                   0,
                   (void*) &usbs_at91_ep3);
 #endif
+
+#ifdef CYGVAR_DEVS_USB_AT91_EP4_DEVTAB_ENTRY
+CHAR_DEVIO_TABLE(usbs_at91_ep4_devtab_functions,
+                 &usbs_devtab_cwrite,
+                 &usbs_devtab_cread,
+                 &cyg_devio_select,
+                 &usbs_devtab_get_config,
+                 &usbs_devtab_set_config);
+
+CHAR_DEVTAB_ENTRY(usbs_at91_ep4_devtab_entry,
+                  CYGDAT_DEVS_USB_AT91_DEVTAB_BASENAME "4",
+                  0,
+                  &usbs_at91_ep4_devtab_functions,
+                  &usbs_at91_devtab_dummy_init,
+                  0,
+                  (void*) &usbs_at91_ep4);
+#endif
+
+#ifdef CYGVAR_DEVS_USB_AT91_EP5_DEVTAB_ENTRY
+CHAR_DEVIO_TABLE(usbs_at91_ep5_devtab_functions,
+                 &usbs_devtab_cwrite,
+                 &usbs_devtab_cread,
+                 &cyg_devio_select,
+                 &usbs_devtab_get_config,
+                 &usbs_devtab_set_config);
+
+CHAR_DEVTAB_ENTRY(usbs_at91_ep5_devtab_entry,
+                  CYGDAT_DEVS_USB_AT91_DEVTAB_BASENAME "5",
+                  0,
+                  &usbs_at91_ep5_devtab_functions,
+                  &usbs_at91_devtab_dummy_init,
+                  0,
+                  (void*) &usbs_at91_ep5);
+#endif
+
+#ifdef CYGVAR_DEVS_USB_AT91_EP6_DEVTAB_ENTRY
+CHAR_DEVIO_TABLE(usbs_at91_ep6_devtab_functions,
+                 &usbs_devtab_cwrite,
+                 &usbs_devtab_cread,
+                 &cyg_devio_select,
+                 &usbs_devtab_get_config,
+                 &usbs_devtab_set_config);
+
+CHAR_DEVTAB_ENTRY(usbs_at91_ep6_devtab_entry,
+                  CYGDAT_DEVS_USB_AT91_DEVTAB_BASENAME "6",
+                  0,
+                  &usbs_at91_ep6_devtab_functions,
+                  &usbs_at91_devtab_dummy_init,
+                  0,
+                  (void*) &usbs_at91_ep6);
+#endif
+
+#ifdef CYGVAR_DEVS_USB_AT91_EP7_DEVTAB_ENTRY
+CHAR_DEVIO_TABLE(usbs_at91_ep7_devtab_functions,
+                 &usbs_devtab_cwrite,
+                 &usbs_devtab_cread,
+                 &cyg_devio_select,
+                 &usbs_devtab_get_config,
+                 &usbs_devtab_set_config);
+
+CHAR_DEVTAB_ENTRY(usbs_at91_ep7_devtab_entry,
+                  CYGDAT_DEVS_USB_AT91_DEVTAB_BASENAME "7",
+                  0,
+                  &usbs_at91_ep7_devtab_functions,
+                  &usbs_at91_devtab_dummy_init,
+                  0,
+                  (void*) &usbs_at91_ep7);
+#endif