From 9a505d25b2f205abfd7808fef03d1f2fe9f38d0c Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Wed, 29 Aug 2012 12:13:42 +0200 Subject: [PATCH 1/5] Added optimized write(buffer,size) method in CDC class --- hardware/arduino/sam/cores/arduino/USB/CDC.cpp | 8 ++++++-- hardware/arduino/sam/cores/arduino/USB/USBAPI.h | 3 ++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/hardware/arduino/sam/cores/arduino/USB/CDC.cpp b/hardware/arduino/sam/cores/arduino/USB/CDC.cpp index 3c4f9feaf..b53bf8974 100644 --- a/hardware/arduino/sam/cores/arduino/USB/CDC.cpp +++ b/hardware/arduino/sam/cores/arduino/USB/CDC.cpp @@ -211,7 +211,7 @@ void Serial_::flush(void) USBD_Flush(CDC_TX); } -size_t Serial_::write(uint8_t c) +size_t Serial_::write(const uint8_t *buffer, size_t size) { /* only try to send bytes if the high-level CDC connection itself is open (not just the pipe) - the OS should set lineState when the port @@ -224,7 +224,7 @@ size_t Serial_::write(uint8_t c) // or locks up, or host virtual serial port hangs) if (_usbLineInfo.lineState > 0) { - int r = USBD_Send(CDC_TX,&c,1); + int r = USBD_Send(CDC_TX, buffer, size); if (r > 0) { @@ -239,6 +239,10 @@ size_t Serial_::write(uint8_t c) return 0; } +size_t Serial_::write(uint8_t c) { + return write(&c, 1); +} + // This operator is a convenient way for a sketch to check whether the // port has actually been configured and opened by the host (as opposed // to just being connected to the host). It can be used, for example, in diff --git a/hardware/arduino/sam/cores/arduino/USB/USBAPI.h b/hardware/arduino/sam/cores/arduino/USB/USBAPI.h index de9889599..7ccd1e219 100644 --- a/hardware/arduino/sam/cores/arduino/USB/USBAPI.h +++ b/hardware/arduino/sam/cores/arduino/USB/USBAPI.h @@ -57,7 +57,8 @@ public: virtual int read(void); virtual void flush(void); virtual size_t write(uint8_t); - using Print::write; // pull in write(str) and write(buf, size) from Print + virtual size_t write(const uint8_t *buffer, size_t size); + using Print::write; // pull in write(str) from Print operator bool(); }; extern Serial_ Serial; From 656b83b1a7354d96ab640190d889e7ca92d132d5 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Date: Wed, 29 Aug 2012 17:43:34 +0200 Subject: [PATCH 2/5] correct CDC transmit, add device qualifier. --- .../arduino/sam/cores/arduino/USB/CDC.cpp | 9 +- .../arduino/sam/cores/arduino/USB/USBCore.cpp | 99 +++++++++++++++++-- .../arduino/sam/cores/arduino/USB/USBCore.h | 5 + .../sam/system/libsam/source/uotghs_device.c | 8 +- 4 files changed, 104 insertions(+), 17 deletions(-) diff --git a/hardware/arduino/sam/cores/arduino/USB/CDC.cpp b/hardware/arduino/sam/cores/arduino/USB/CDC.cpp index b53bf8974..97797ab26 100644 --- a/hardware/arduino/sam/cores/arduino/USB/CDC.cpp +++ b/hardware/arduino/sam/cores/arduino/USB/CDC.cpp @@ -58,12 +58,12 @@ static const CDCDescriptor _cdcInterface = D_CDCCS(CDC_CALL_MANAGEMENT,1,1), // Device handles call management (not) D_CDCCS4(CDC_ABSTRACT_CONTROL_MANAGEMENT,6), // SET_LINE_CODING, GET_LINE_CODING, SET_CONTROL_LINE_STATE supported D_CDCCS(CDC_UNION,CDC_ACM_INTERFACE,CDC_DATA_INTERFACE), // Communication interface is master, data interface is slave 0 - D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_ACM),USB_ENDPOINT_TYPE_INTERRUPT,0x10,0x40), + D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_ACM),USB_ENDPOINT_TYPE_INTERRUPT,0x10,0x10/*0x40*/), // CDC data interface D_INTERFACE(CDC_DATA_INTERFACE,2,CDC_DATA_INTERFACE_CLASS,0,0), - D_ENDPOINT(USB_ENDPOINT_OUT(CDC_ENDPOINT_OUT),USB_ENDPOINT_TYPE_BULK,0x40,0), - D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_IN ),USB_ENDPOINT_TYPE_BULK,0x40,0) + D_ENDPOINT(USB_ENDPOINT_OUT(CDC_ENDPOINT_OUT),USB_ENDPOINT_TYPE_BULK,0x200,0), + D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_IN ),USB_ENDPOINT_TYPE_BULK,0x200,0) }; _Pragma("pack()") @@ -227,7 +227,8 @@ size_t Serial_::write(const uint8_t *buffer, size_t size) int r = USBD_Send(CDC_TX, buffer, size); if (r > 0) - { + { + USBD_Flush(CDC_TX); return r; } else { diff --git a/hardware/arduino/sam/cores/arduino/USB/USBCore.cpp b/hardware/arduino/sam/cores/arduino/USB/USBCore.cpp index 61113c20b..166e83cfc 100644 --- a/hardware/arduino/sam/cores/arduino/USB/USBCore.cpp +++ b/hardware/arduino/sam/cores/arduino/USB/USBCore.cpp @@ -40,7 +40,8 @@ static const uint32_t EndPoints[] = #define TX_RX_LED_PULSE_MS 100 volatile uint8_t TxLEDPulse; /**< Milliseconds remaining for data Tx LED pulse */ volatile uint8_t RxLEDPulse; /**< Milliseconds remaining for data Rx LED pulse */ - +static char isRemoteWakeUpEnabled = 0; +static char isEndpointHalt = 0; //================================================================== //================================================================== @@ -86,6 +87,10 @@ const DeviceDescriptor USB_DeviceDescriptor = const DeviceDescriptor USB_DeviceDescriptorA = D_DEVICE(DEVICE_CLASS,0x00,0x00,64,USB_VID,USB_PID,0x100,IMANUFACTURER,IPRODUCT,0,1); +const DeviceDescriptor USB_DeviceQualifier = + D_QUALIFIER(0x00,0x00,0x00,64,1); + + //================================================================== //================================================================== @@ -183,8 +188,9 @@ uint32_t USBD_Send(uint32_t ep, const void* d, uint32_t len) UDD_Send(ep & 0xF, data, n); - if (!UDD_ReadWriteAllowed(ep & 0xF) || ((len == 0) && (ep & TRANSFER_RELEASE))) // Release full buffer - UDD_ReleaseTX(ep & 0xF); + //if (!UDD_ReadWriteAllowed(ep & 0xF) || ((len == 0) && (ep & TRANSFER_RELEASE))){ // Release full buffer + //UDD_ReleaseTX(ep & 0xF); + //} } //TXLED1; // light the TX LED //TxLEDPulse = TX_RX_LED_PULSE_MS; @@ -345,9 +351,24 @@ static bool USBD_SendDescriptor(Setup& setup) desc_addr = (const uint8_t*)&STRING_IPRODUCT; else if (setup.wValueL == IMANUFACTURER) desc_addr = (const uint8_t*)&STRING_IMANUFACTURER; - else + else { return false; + } } + else if (USB_DEVICE_QUALIFIER == t) + { + // Device qualifier descriptor requested + desc_addr = (const uint8_t*)&USB_DeviceQualifier; + } + else if (USB_OTHER_SPEED_CONFIGURATION == t) + { + // TODO + // Other configuration descriptor requested + } + else + { + //printf("Device ERROR"); + } if (desc_addr == 0) { @@ -401,7 +422,7 @@ static void USB_ISR(void) if (Is_udd_sof()) { udd_ack_sof(); - USBD_Flush(CDC_TX); +// USBD_Flush(CDC_TX); } #endif @@ -437,15 +458,70 @@ static void USB_ISR(void) uint8_t r = setup.bRequest; if (GET_STATUS == r) { - TRACE_CORE(puts(">>> EP0 Int: GET_STATUS\r\n");) - UDD_Send8(EP0, 0); // TODO - UDD_Send8(EP0, 0); + if( setup.bmRequestType == 0 ) // device + { + // Send the device status + TRACE_CORE(puts(">>> EP0 Int: GET_STATUS\r\n");) + // Check current configuration for power mode (if device is configured) + // TODO + // Check if remote wake-up is enabled + // TODO + UDD_Send8(EP0, 0); // TODO + UDD_Send8(EP0, 0); + } + // if( setup.bmRequestType == 2 ) // Endpoint: + else + { + // Send the endpoint status + // Check if the endpoint if currently halted + if( isEndpointHalt == 1 ) + UDD_Send8(EP0, 1); // TODO + else + UDD_Send8(EP0, 0); // TODO + UDD_Send8(EP0, 0); + } } else if (CLEAR_FEATURE == r) { - } + // Check which is the selected feature + if( setup.wValueL == 1) // DEVICEREMOTEWAKEUP + { + // Enable remote wake-up and send a ZLP + if( isRemoteWakeUpEnabled == 1 ) + UDD_Send8(EP0, 1); + else + UDD_Send8(EP0, 0); + UDD_Send8(EP0, 0); + } + else // if( setup.wValueL == 0) // ENDPOINTHALT + { + isEndpointHalt = 0; // TODO + UDD_Send8(EP0, 0); + UDD_Send8(EP0, 0); + } + + } else if (SET_FEATURE == r) { + // Check which is the selected feature + if( setup.wValueL == 1) // DEVICEREMOTEWAKEUP + { + // Enable remote wake-up and send a ZLP + isRemoteWakeUpEnabled = 1; + UDD_Send8(EP0, 0); + } + if( setup.wValueL == 0) // ENDPOINTHALT + { + // Halt endpoint + isEndpointHalt = 1; + //USBD_Halt(USBGenericRequest_GetEndpointNumber(pRequest)); + UDD_Send8(EP0, 0); + } + if( setup.wValueL == 2) // TEST_MODE + { + // 7.1.20 Test Mode Support, 9.4.9 SetFeature + // TODO + } } else if (SET_ADDRESS == r) { @@ -466,7 +542,7 @@ static void USB_ISR(void) else if (GET_CONFIGURATION == r) { TRACE_CORE(puts(">>> EP0 Int: GET_CONFIGURATION\r\n");) - UDD_Send8(EP0, 1); + UDD_Send8(EP0, _usbConfiguration); } else if (SET_CONFIGURATION == r) { @@ -491,10 +567,13 @@ static void USB_ISR(void) } else if (GET_INTERFACE == r) { + // TODO TRACE_CORE(puts(">>> EP0 Int: GET_INTERFACE\r\n");) + UDD_Send8(EP0, setup.wIndex); } else if (SET_INTERFACE == r) { + // TODO TRACE_CORE(puts(">>> EP0 Int: SET_INTERFACE\r\n");) } } diff --git a/hardware/arduino/sam/cores/arduino/USB/USBCore.h b/hardware/arduino/sam/cores/arduino/USB/USBCore.h index c4db4f38f..36d044a3e 100644 --- a/hardware/arduino/sam/cores/arduino/USB/USBCore.h +++ b/hardware/arduino/sam/cores/arduino/USB/USBCore.h @@ -77,6 +77,8 @@ #define USB_STRING_DESCRIPTOR_TYPE 3 #define USB_INTERFACE_DESCRIPTOR_TYPE 4 #define USB_ENDPOINT_DESCRIPTOR_TYPE 5 +#define USB_DEVICE_QUALIFIER 6 +#define USB_OTHER_SPEED_CONFIGURATION 7 #define USB_DEVICE_CLASS_COMMUNICATIONS 0x02 #define USB_DEVICE_CLASS_HUMAN_INTERFACE 0x03 @@ -291,6 +293,9 @@ _Pragma("pack()") #define D_ENDPOINT(_addr,_attr,_packetSize, _interval) \ { 7, 5, _addr,_attr,_packetSize, _interval } +#define D_QUALIFIER(_class,_subClass,_proto,_packetSize0,_configs) \ + { 10, 6, 0x200, _class,_subClass,_proto,_packetSize0,_configs } + #define D_IAD(_firstInterface, _count, _class, _subClass, _protocol) \ { 8, 11, _firstInterface, _count, _class, _subClass, _protocol, 0 } diff --git a/hardware/arduino/sam/system/libsam/source/uotghs_device.c b/hardware/arduino/sam/system/libsam/source/uotghs_device.c index 3ebdcb202..0faf482d2 100644 --- a/hardware/arduino/sam/system/libsam/source/uotghs_device.c +++ b/hardware/arduino/sam/system/libsam/source/uotghs_device.c @@ -85,7 +85,7 @@ uint32_t UDD_Init(void) // Enable High Speed udd_low_speed_disable(); - udd_high_speed_disable(); + udd_high_speed_enable(); //otg_ack_vbus_transition(); // Force Vbus interrupt in case of Vbus always with a high level @@ -301,7 +301,8 @@ uint32_t UDD_FifoByteCount(uint32_t ep) void UDD_ReleaseRX(uint32_t ep) { TRACE_UOTGHS_DEVICE(puts("=> UDD_ReleaseRX\r\n");) - UOTGHS->UOTGHS_DEVEPTICR[ep] = (UOTGHS_DEVEPTICR_NAKOUTIC | UOTGHS_DEVEPTICR_RXOUTIC); +// UOTGHS->UOTGHS_DEVEPTICR[ep] = (UOTGHS_DEVEPTICR_NAKOUTIC | UOTGHS_DEVEPTICR_RXOUTIC); + UOTGHS->UOTGHS_DEVEPTICR[ep] = UOTGHS_DEVEPTICR_RXOUTIC; UOTGHS->UOTGHS_DEVEPTIDR[ep] = UOTGHS_DEVEPTIDR_FIFOCONC; ul_recv_fifo_ptr[ep] = 0; } @@ -309,7 +310,8 @@ void UDD_ReleaseRX(uint32_t ep) void UDD_ReleaseTX(uint32_t ep) { TRACE_UOTGHS_DEVICE(printf("=> UDD_ReleaseTX ep=%lu\r\n", ep);) - UOTGHS->UOTGHS_DEVEPTICR[ep] = (UOTGHS_DEVEPTICR_NAKINIC | UOTGHS_DEVEPTICR_RXOUTIC | UOTGHS_DEVEPTICR_TXINIC); +// UOTGHS->UOTGHS_DEVEPTICR[ep] = (UOTGHS_DEVEPTICR_NAKINIC | UOTGHS_DEVEPTICR_RXOUTIC | UOTGHS_DEVEPTICR_TXINIC); + UOTGHS->UOTGHS_DEVEPTICR[ep] = UOTGHS_DEVEPTICR_TXINIC; UOTGHS->UOTGHS_DEVEPTIDR[ep] = UOTGHS_DEVEPTIDR_FIFOCONC; ul_send_fifo_ptr[ep] = 0; } From 22c828def00d506508664465959c3e92a1ad734b Mon Sep 17 00:00:00 2001 From: Jean-Christophe Date: Thu, 6 Sep 2012 16:44:29 +0200 Subject: [PATCH 3/5] update for USB, USB High Speed software, for betatest, need some improvment. USBCV not passed, USB3.0 passed --- .../arduino/sam/cores/arduino/USB/CDC.cpp | 15 ++-- .../arduino/sam/cores/arduino/USB/USBCore.cpp | 76 ++++++++++--------- .../sam/system/libsam/include/uotghs_device.h | 4 +- .../sam/system/libsam/source/uotghs_device.c | 24 +++--- 4 files changed, 64 insertions(+), 55 deletions(-) diff --git a/hardware/arduino/sam/cores/arduino/USB/CDC.cpp b/hardware/arduino/sam/cores/arduino/USB/CDC.cpp index 97797ab26..4ceca33f6 100644 --- a/hardware/arduino/sam/cores/arduino/USB/CDC.cpp +++ b/hardware/arduino/sam/cores/arduino/USB/CDC.cpp @@ -19,7 +19,7 @@ #ifdef CDC_ENABLED -#define CDC_SERIAL_BUFFER_SIZE 64 +#define CDC_SERIAL_BUFFER_SIZE 512 /* For information purpose only since RTS is not always handled by the terminal application */ #define CDC_LINESTATE_DTR 0x01 // Data Terminal Ready @@ -45,7 +45,13 @@ typedef struct uint8_t lineState; } LineInfo; -static volatile LineInfo _usbLineInfo = { 57600, 0x00, 0x00, 0x00, 0x00 }; +static volatile LineInfo _usbLineInfo = { + 57600, // dWDTERate + 0x00, // bCharFormat + 0x00, // bParityType + 0x08, // bDataBits + 0x00 // lineState +}; _Pragma("pack(1)") static const CDCDescriptor _cdcInterface = @@ -62,8 +68,8 @@ static const CDCDescriptor _cdcInterface = // CDC data interface D_INTERFACE(CDC_DATA_INTERFACE,2,CDC_DATA_INTERFACE_CLASS,0,0), - D_ENDPOINT(USB_ENDPOINT_OUT(CDC_ENDPOINT_OUT),USB_ENDPOINT_TYPE_BULK,0x200,0), - D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_IN ),USB_ENDPOINT_TYPE_BULK,0x200,0) + D_ENDPOINT(USB_ENDPOINT_OUT(CDC_ENDPOINT_OUT),USB_ENDPOINT_TYPE_BULK,512,0), + D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_IN ),USB_ENDPOINT_TYPE_BULK,512,0) }; _Pragma("pack()") @@ -228,7 +234,6 @@ size_t Serial_::write(const uint8_t *buffer, size_t size) if (r > 0) { - USBD_Flush(CDC_TX); return r; } else { diff --git a/hardware/arduino/sam/cores/arduino/USB/USBCore.cpp b/hardware/arduino/sam/cores/arduino/USB/USBCore.cpp index 166e83cfc..f255f19d3 100644 --- a/hardware/arduino/sam/cores/arduino/USB/USBCore.cpp +++ b/hardware/arduino/sam/cores/arduino/USB/USBCore.cpp @@ -26,9 +26,9 @@ static const uint32_t EndPoints[] = EP_TYPE_CONTROL, #ifdef CDC_ENABLED - EP_TYPE_BULK_IN, // CDC_ENDPOINT_IN - EP_TYPE_BULK_OUT, // CDC_ENDPOINT_OUT EP_TYPE_INTERRUPT_IN, // CDC_ENDPOINT_ACM + EP_TYPE_BULK_OUT, // CDC_ENDPOINT_OUT + EP_TYPE_BULK_IN, // CDC_ENDPOINT_IN #endif #ifdef HID_ENABLED @@ -153,45 +153,42 @@ uint32_t USBD_Recv(uint32_t ep) } // Space in send EP -uint32_t USBD_SendSpace(uint32_t ep) -{ - LockEP lock(ep); - if (!UDD_ReadWriteAllowed(ep & 0xF)) - return 0; - return 64 - UDD_FifoByteCount(ep & 0xF); -} +//uint32_t USBD_SendSpace(uint32_t ep) +//{ + //LockEP lock(ep); +//// if (!UDD_ReadWriteAllowed(ep & 0xF)) + ////{ + ////printf("pb "); // UOTGHS->UOTGHS_DEVEPTISR[%d]=0x%X\n\r", ep, UOTGHS->UOTGHS_DEVEPTISR[ep]); + ////return 0; + ////} + + //if(ep==0) return 64 - UDD_FifoByteCount(ep & 0xF); // EP0_SIZE jcb + //else return 512 - UDD_FifoByteCount(ep & 0xF); // EPX_SIZE jcb +//} // Blocking Send of data to an endpoint uint32_t USBD_Send(uint32_t ep, const void* d, uint32_t len) { - if (!_usbConfiguration) - return -1; - + uint32_t n; int r = len; const uint8_t* data = (const uint8_t*)d; - uint8_t timeout = 250; // 250ms timeout on send? TODO + + if (!_usbConfiguration) + { + printf("pb conf\n\r"); + return -1; + } while (len) { - uint8_t n = USBD_SendSpace(ep); - if (n == 0) - { - if (!(--timeout)) - return -1; - delay(1); - continue; - } - + if(ep==0) n= EP0_SIZE; + else n = EPX_SIZE; if (n > len) n = len; len -= n; UDD_Send(ep & 0xF, data, n); - - //if (!UDD_ReadWriteAllowed(ep & 0xF) || ((len == 0) && (ep & TRANSFER_RELEASE))){ // Release full buffer - //UDD_ReleaseTX(ep & 0xF); - //} - } + } //TXLED1; // light the TX LED //TxLEDPulse = TX_RX_LED_PULSE_MS; return r; @@ -345,15 +342,24 @@ static bool USBD_SendDescriptor(Setup& setup) else if (USB_STRING_DESCRIPTOR_TYPE == t) { TRACE_CORE(puts("=> USBD_SendDescriptor : USB_STRING_DESCRIPTOR_TYPE\r\n");) - if (setup.wValueL == 0) + if (setup.wValueL == 0) { desc_addr = (const uint8_t*)&STRING_LANGUAGE; - else if (setup.wValueL == IPRODUCT) + printf("St1=%d\n\r", *desc_addr); + } + else if (setup.wValueL == IPRODUCT) { desc_addr = (const uint8_t*)&STRING_IPRODUCT; - else if (setup.wValueL == IMANUFACTURER) + printf("St2=%d\n\r", *desc_addr); + } + else if (setup.wValueL == IMANUFACTURER) { desc_addr = (const uint8_t*)&STRING_IMANUFACTURER; + printf("St3=%d\n\r", *desc_addr); + } else { return false; } + if( *desc_addr > setup.wLength ) { + desc_length = setup.wLength; + } } else if (USB_DEVICE_QUALIFIER == t) { @@ -386,10 +392,13 @@ static bool USBD_SendDescriptor(Setup& setup) return true; } +//unsigned int iii=0; // Endpoint 0 interrupt static void USB_ISR(void) { - // End of Reset +// printf("ISR=0x%X\n\r", UOTGHS->UOTGHS_DEVISR); // jcb +// if( iii++ > 1500 ) while(1); // jcb + // End of bus reset if (Is_udd_reset()) { TRACE_CORE(printf(">>> End of Reset\r\n");) @@ -422,14 +431,13 @@ static void USB_ISR(void) if (Is_udd_sof()) { udd_ack_sof(); -// USBD_Flush(CDC_TX); + // USBD_Flush(CDC_TX); // jcb } #endif // EP 0 Interrupt - if (Is_udd_endpoint_interrupt(0)) + if (Is_udd_endpoint_interrupt(0) ) { - if (!UDD_ReceivedSetupInt()) { return; diff --git a/hardware/arduino/sam/system/libsam/include/uotghs_device.h b/hardware/arduino/sam/system/libsam/include/uotghs_device.h index 3f266bd27..e2ae9447a 100644 --- a/hardware/arduino/sam/system/libsam/include/uotghs_device.h +++ b/hardware/arduino/sam/system/libsam/include/uotghs_device.h @@ -34,7 +34,7 @@ #define MAX_ENDPOINTS 10 #define EP0 0 #define EP0_SIZE 64 -#define EPX_SIZE 1024 +#define EPX_SIZE 512 #define EP_SINGLE_64 (0x32UL) // EP0 #define EP_DOUBLE_64 (0x36UL) // Other endpoints @@ -116,7 +116,7 @@ //! Get maximal number of banks of endpoints #define udd_get_endpoint_bank_max_nbr(ep) ((ep == 0) ? 1 : (( ep <= 2) ? 3 : 2)) //! Get maximal size of endpoint (3X, 1024/64) -#define udd_get_endpoint_size_max(ep) (((ep) == 0) ? 64 : 1024) +#define udd_get_endpoint_size_max(ep) (((ep) == 0) ? 64 : 512) // for bulk //! Get DMA support of endpoints #define Is_udd_endpoint_dma_supported(ep) ((((ep) >= 1) && ((ep) <= 6)) ? true : false) //! Get High Band Width support of endpoints diff --git a/hardware/arduino/sam/system/libsam/source/uotghs_device.c b/hardware/arduino/sam/system/libsam/source/uotghs_device.c index 0faf482d2..6ffa3576e 100644 --- a/hardware/arduino/sam/system/libsam/source/uotghs_device.c +++ b/hardware/arduino/sam/system/libsam/source/uotghs_device.c @@ -115,7 +115,7 @@ void UDD_Attach(void) // Enable USB line events udd_enable_reset_interrupt(); - udd_enable_sof_interrupt(); +// udd_enable_sof_interrupt(); cpu_irq_restore(flags); } @@ -139,6 +139,7 @@ void UDD_InitEP( uint32_t ul_ep_nb, uint32_t ul_ep_cfg ) if (!Is_udd_endpoint_configured(ul_ep_nb)) { TRACE_UOTGHS_DEVICE(printf("=> UDD_InitEP : ERROR FAILED TO INIT EP %lu\r\n", ul_ep_nb);) + while(1); } } @@ -156,6 +157,7 @@ void UDD_InitEndpoints(const uint32_t* eps_table, const uint32_t ul_eps_table_si if (!Is_udd_endpoint_configured(ul_ep_nb)) { TRACE_UOTGHS_DEVICE(printf("=> UDD_InitEP : ERROR FAILED TO INIT EP %lu\r\n", ul_ep_nb);) + while(1); } } } @@ -215,6 +217,8 @@ uint32_t UDD_Send(uint32_t ep, const void* data, uint32_t len) TRACE_UOTGHS_DEVICE(printf("=> UDD_Send (1): ep=%lu ul_send_fifo_ptr=%lu len=%lu\r\n", ep, ul_send_fifo_ptr[ep], len);) + while( UOTGHS_DEVEPTISR_TXINI != (UOTGHS->UOTGHS_DEVEPTISR[ep] & UOTGHS_DEVEPTISR_TXINI )) {} + if (ep == EP0) { if (ul_send_fifo_ptr[ep] + len > EP0_SIZE) @@ -222,34 +226,26 @@ uint32_t UDD_Send(uint32_t ep, const void* data, uint32_t len) } else { - if (ul_send_fifo_ptr[ep] + len > EPX_SIZE) - len = EPX_SIZE - ul_send_fifo_ptr[ep]; + ul_send_fifo_ptr[ep] = 0; } - for (i = 0, ptr_dest += ul_send_fifo_ptr[ep]; i < len; ++i) *ptr_dest++ = *ptr_src++; ul_send_fifo_ptr[ep] += i; - if (ep == EP0) { TRACE_UOTGHS_DEVICE(printf("=> UDD_Send (2): ep=%lu ptr_dest=%lu maxlen=%d\r\n", ep, ul_send_fifo_ptr[ep], EP0_SIZE);) if (ul_send_fifo_ptr[ep] == EP0_SIZE) { - UDD_ClearIN(); // Fifo is full, release this packet - UDD_WaitIN(); // Wait for new FIFO buffer to be ready - } + UDD_ClearIN(); // Fifo is full, release this packet // UOTGHS->UOTGHS_DEVEPTICR[EP0] = UOTGHS_DEVEPTICR_TXINIC; + } } else { - if (ul_send_fifo_ptr[ep] == EPX_SIZE) - { - UDD_ClearIN(); // Fifo is full, release this packet - UDD_WaitIN(); // Wait for new FIFO buffer to be ready - } + UOTGHS->UOTGHS_DEVEPTICR[ep] = UOTGHS_DEVEPTICR_TXINIC; + UOTGHS->UOTGHS_DEVEPTIDR[ep] = UOTGHS_DEVEPTIDR_FIFOCONC; } - return len; } From 3a61bc4bd3e28ee6e9582413e9b9f52442fd7211 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Date: Thu, 6 Sep 2012 18:36:58 +0200 Subject: [PATCH 4/5] usbcv chapter 9 tests: passed --- .../arduino/sam/cores/arduino/USB/CDC.cpp | 25 ++++++++- .../arduino/sam/cores/arduino/USB/USBAPI.h | 1 + .../arduino/sam/cores/arduino/USB/USBCore.cpp | 55 ++++++++++++++++--- .../arduino/sam/cores/arduino/USB/USBCore.h | 3 + 4 files changed, 76 insertions(+), 8 deletions(-) diff --git a/hardware/arduino/sam/cores/arduino/USB/CDC.cpp b/hardware/arduino/sam/cores/arduino/USB/CDC.cpp index 4ceca33f6..83e70f55f 100644 --- a/hardware/arduino/sam/cores/arduino/USB/CDC.cpp +++ b/hardware/arduino/sam/cores/arduino/USB/CDC.cpp @@ -64,13 +64,30 @@ static const CDCDescriptor _cdcInterface = D_CDCCS(CDC_CALL_MANAGEMENT,1,1), // Device handles call management (not) D_CDCCS4(CDC_ABSTRACT_CONTROL_MANAGEMENT,6), // SET_LINE_CODING, GET_LINE_CODING, SET_CONTROL_LINE_STATE supported D_CDCCS(CDC_UNION,CDC_ACM_INTERFACE,CDC_DATA_INTERFACE), // Communication interface is master, data interface is slave 0 - D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_ACM),USB_ENDPOINT_TYPE_INTERRUPT,0x10,0x10/*0x40*/), + D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_ACM),USB_ENDPOINT_TYPE_INTERRUPT,0x10, 0x10), // CDC data interface D_INTERFACE(CDC_DATA_INTERFACE,2,CDC_DATA_INTERFACE_CLASS,0,0), D_ENDPOINT(USB_ENDPOINT_OUT(CDC_ENDPOINT_OUT),USB_ENDPOINT_TYPE_BULK,512,0), D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_IN ),USB_ENDPOINT_TYPE_BULK,512,0) }; +static const CDCDescriptor _cdcOtherInterface = +{ + D_IAD(0,2,CDC_COMMUNICATION_INTERFACE_CLASS,CDC_ABSTRACT_CONTROL_MODEL,1), + + // CDC communication interface + D_INTERFACE(CDC_ACM_INTERFACE,1,CDC_COMMUNICATION_INTERFACE_CLASS,CDC_ABSTRACT_CONTROL_MODEL,0), + D_CDCCS(CDC_HEADER,0x10,0x01), // Header (1.10 bcd) + D_CDCCS(CDC_CALL_MANAGEMENT,1,1), // Device handles call management (not) + D_CDCCS4(CDC_ABSTRACT_CONTROL_MANAGEMENT,6), // SET_LINE_CODING, GET_LINE_CODING, SET_CONTROL_LINE_STATE supported + D_CDCCS(CDC_UNION,CDC_ACM_INTERFACE,CDC_DATA_INTERFACE), // Communication interface is master, data interface is slave 0 + D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_ACM),USB_ENDPOINT_TYPE_INTERRUPT,0x10, 0x10), + + // CDC data interface + D_INTERFACE(CDC_DATA_INTERFACE,2,CDC_DATA_INTERFACE_CLASS,0,0), + D_ENDPOINT(USB_ENDPOINT_OUT(CDC_ENDPOINT_OUT),USB_ENDPOINT_TYPE_BULK,64,0), + D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_IN ),USB_ENDPOINT_TYPE_BULK,64,0) +}; _Pragma("pack()") int WEAK CDC_GetInterface(uint8_t* interfaceNum) @@ -79,6 +96,12 @@ int WEAK CDC_GetInterface(uint8_t* interfaceNum) return USBD_SendControl(0,&_cdcInterface,sizeof(_cdcInterface)); } +int WEAK CDC_GetOtherInterface(uint8_t* interfaceNum) +{ + interfaceNum[0] += 2; // uses 2 + return USBD_SendControl(0,&_cdcOtherInterface,sizeof(_cdcOtherInterface)); +} + __attribute__ ((long_call, section (".ramfunc"))) void banzai() { // Disable all interrupts diff --git a/hardware/arduino/sam/cores/arduino/USB/USBAPI.h b/hardware/arduino/sam/cores/arduino/USB/USBAPI.h index 7ccd1e219..8f10cff99 100644 --- a/hardware/arduino/sam/cores/arduino/USB/USBAPI.h +++ b/hardware/arduino/sam/cores/arduino/USB/USBAPI.h @@ -191,6 +191,7 @@ bool MSC_Data(uint8_t rx,uint8_t tx); // CSC 'Driver' int CDC_GetInterface(uint8_t* interfaceNum); +int CDC_GetOtherInterface(uint8_t* interfaceNum); int CDC_GetDescriptor(int i); bool CDC_Setup(Setup& setup); diff --git a/hardware/arduino/sam/cores/arduino/USB/USBCore.cpp b/hardware/arduino/sam/cores/arduino/USB/USBCore.cpp index f255f19d3..d5f0f9e0c 100644 --- a/hardware/arduino/sam/cores/arduino/USB/USBCore.cpp +++ b/hardware/arduino/sam/cores/arduino/USB/USBCore.cpp @@ -96,6 +96,7 @@ const DeviceDescriptor USB_DeviceQualifier = volatile uint32_t _usbConfiguration = 0; volatile uint32_t _usbInitialized = 0; +uint32_t _usbSetInterface = 0; uint32_t _cdcComposite = 0; //================================================================== @@ -283,6 +284,24 @@ int USBD_SendInterfaces(void) return interfaces; } +int USBD_SendOtherInterfaces(void) +{ + int total = 0; + uint8_t interfaces = 0; + +#ifdef CDC_ENABLED + total = CDC_GetOtherInterface(&interfaces); +#endif + +#ifdef HID_ENABLED + total += HID_GetInterface(&interfaces); +#endif + + total = total; // Get rid of compiler warning + TRACE_CORE(printf("=> USBD_SendInterfaces, total=%d interfaces=%d\r\n", total, interfaces);) + return interfaces; +} + // Construct a dynamic configuration descriptor // This really needs dynamic endpoint allocation etc // TODO @@ -309,6 +328,29 @@ _Pragma("pack()") return true; } +static bool USBD_SendOtherConfiguration(int maxlen) +{ + // Count and measure interfaces + USBD_InitControl(0); + //TRACE_CORE(printf("=> USBD_SendConfiguration _cmark1=%d\r\n", _cmark);) + int interfaces = USBD_SendOtherInterfaces(); + //TRACE_CORE(printf("=> USBD_SendConfiguration _cmark2=%d\r\n", _cmark);) + //TRACE_CORE(printf("=> USBD_SendConfiguration sizeof=%d\r\n", sizeof(ConfigDescriptor));) + +_Pragma("pack(1)") + ConfigDescriptor config = D_OTHERCONFIG(_cmark + sizeof(ConfigDescriptor),interfaces); +_Pragma("pack()") + //TRACE_CORE(printf("=> USBD_SendConfiguration clen=%d\r\n", config.clen);) + + //TRACE_CORE(printf("=> USBD_SendConfiguration maxlen=%d\r\n", maxlen);) + + // Now send them + USBD_InitControl(maxlen); + USBD_SendControl(0,&config,sizeof(ConfigDescriptor)); + USBD_SendOtherInterfaces(); + return true; +} + static bool USBD_SendDescriptor(Setup& setup) { uint8_t t = setup.wValueH; @@ -344,15 +386,12 @@ static bool USBD_SendDescriptor(Setup& setup) TRACE_CORE(puts("=> USBD_SendDescriptor : USB_STRING_DESCRIPTOR_TYPE\r\n");) if (setup.wValueL == 0) { desc_addr = (const uint8_t*)&STRING_LANGUAGE; - printf("St1=%d\n\r", *desc_addr); } else if (setup.wValueL == IPRODUCT) { desc_addr = (const uint8_t*)&STRING_IPRODUCT; - printf("St2=%d\n\r", *desc_addr); } else if (setup.wValueL == IMANUFACTURER) { desc_addr = (const uint8_t*)&STRING_IMANUFACTURER; - printf("St3=%d\n\r", *desc_addr); } else { return false; @@ -365,11 +404,14 @@ static bool USBD_SendDescriptor(Setup& setup) { // Device qualifier descriptor requested desc_addr = (const uint8_t*)&USB_DeviceQualifier; + if( *desc_addr > setup.wLength ) { + desc_length = setup.wLength; + } } else if (USB_OTHER_SPEED_CONFIGURATION == t) { - // TODO // Other configuration descriptor requested + return USBD_SendOtherConfiguration(setup.wLength); } else { @@ -575,13 +617,12 @@ static void USB_ISR(void) } else if (GET_INTERFACE == r) { - // TODO TRACE_CORE(puts(">>> EP0 Int: GET_INTERFACE\r\n");) - UDD_Send8(EP0, setup.wIndex); + UDD_Send8(EP0, _usbSetInterface); } else if (SET_INTERFACE == r) { - // TODO + _usbSetInterface = setup.wValueL; TRACE_CORE(puts(">>> EP0 Int: SET_INTERFACE\r\n");) } } diff --git a/hardware/arduino/sam/cores/arduino/USB/USBCore.h b/hardware/arduino/sam/cores/arduino/USB/USBCore.h index 36d044a3e..b01d7576a 100644 --- a/hardware/arduino/sam/cores/arduino/USB/USBCore.h +++ b/hardware/arduino/sam/cores/arduino/USB/USBCore.h @@ -287,6 +287,9 @@ _Pragma("pack()") #define D_CONFIG(_totalLength,_interfaces) \ { 9, 2, _totalLength,_interfaces, 1, 0, USB_CONFIG_SELF_POWERED, USB_CONFIG_POWER_MA(500) } +#define D_OTHERCONFIG(_totalLength,_interfaces) \ + { 9, 7, _totalLength,_interfaces, 1, 0, USB_CONFIG_SELF_POWERED, USB_CONFIG_POWER_MA(500) } + #define D_INTERFACE(_n,_numEndpoints,_class,_subClass,_protocol) \ { 9, 4, _n, 0, _numEndpoints, _class,_subClass, _protocol, 0 } From 5f23172cc4ec8a53049a49a2318f4a8f2ba4f580 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Mon, 10 Sep 2012 00:22:36 +0200 Subject: [PATCH 5/5] Updated libsam binary --- .../arduino_due_x/libsam_sam3x8e_gcc_rel.a | Bin 86338 -> 86354 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/hardware/arduino/sam/variants/arduino_due_x/libsam_sam3x8e_gcc_rel.a b/hardware/arduino/sam/variants/arduino_due_x/libsam_sam3x8e_gcc_rel.a index b3f2d942d7084bbd8e7a20268127d65cab339653..a8f27438f547a868fc9aa6f040b888e1f3d1bd1f 100644 GIT binary patch delta 1669 zcmb`HYfPI}7=X|FU7(ZzAJEdPqx3>cs8Vjj%}Gj2I-rVIE7KW`n!sRD zqGZFJWM@AhI&|5>qRCdVgQx>G|LA@UrcTr-L=qA+BZMydT!`_UkFQIMfBfM|Pu{-I zdw<)U*)ef`OdPgkH`LTL?0B&5g8hQf+mFEaA8*r11pn`iwBp|$I2~UXSB+{@KJq~m zlw2(RNmN0#0^+iBMVm=Bs`gi?q-N9S%_mAr(}^KI`C55FIw^^7yuFg0K`suztjPfJ z;ZwofOtSjn@l;UlW~q_$>#2?vVu*iy_36B<&Bfv+ry=g0e^pG^r*A%COqG)dGap{9I7BOJMK!FC5ecf9w{*kI6P)ak8%p&HcU7vl~ro{k|Ekzh?p*x$Q-Z zxor_yc#&W8iviiy1+G#5_Xq2P-*rc2p|VJgg4%Zjzmo->v)cHz4ggy~E<=O0dy;)k0ofsWazZ^{pv!Cq zvd;puz>)i`Pzk_;s~|uVxjso)RgY_166d) zLZ+DGt(2<2w#5-~2pJVetsNw|N-TC--guAhWAqw%mQf$2PQ`beQZY(ZNvU2z)2CNI zkg|}wEc`I}a|amoP1Gfa&7hud=^7-`-~fjx@CbQWs>0|Nr)4tW05|95ael}kZ86>= zH<&TXj7j2f(xwM#YGo7p_h~f!+*{=cwOEyL-f_}#E>V^KP_&1{mNFaU3d^*t zIL!DB`RP*#Mxt{;xhM&0og$7-pI*l);9nX`$m=dzq&elKXUk;&4VqLr9n|6>@0Ea# zeB*)wQPGulI@NsaFT+j;K0Re1=5o5(0eqz2Eq+QvU%}PS7oXTBK__{moHje8N9Z;_ zR9TE8+q#I^4Tqr_&$O7xIX8sBgZH*th}Hu-sKZBEEs32TH~?@ISBFiBOBL`n2km6Q z3sr@zXc5Xq%T%(Vc9APy=!M}#@P7INl{ZtwJxM2LGNQ^y5E@kVAtv{e79TvE@#rMR Qd~iofJxvMvvX2$~1K}B*(EtDd delta 1622 zcmb_cZA@Eb6n;;8ue1f)V!tVY(vP)E3%g`MwyESow+^U=GH1k0V{s$t{K&ewMWRb! zlW3wb!`&Zm<7P5&Zi!!UTv-EZfQ27s?#G573o>Vo#wGJ3G(fyA`{B8l+lBJWAKu)z z=bqr8lh?4)7p%}TlY41iAX;O;BqfgY-tVJB+ME?fUTEs5ief?HR5i&OX zqOJ%KhcnUAVr22X6U9a1=?|9*6F1Av9pcBc&y=fG3St){b1xM(p(4}QA20Z*RZTyg zGpbdqI~S!t->)j_o}Dznbxkq!Njc0HpjGeeSu?nqBCG5TD;(6S(5i}QZfN9AdP88P z)Cm*NM!Q|mw51~MN*%g5we<7};;l@YI_D&!^DGbYmoQewO5@*1jLy6~*!9mc4cs%jO}m{k0xh)vVJ#kXWH&u zLyYJ@*S1`58sqNxAVXnZ?JF;*YQ>QGf_zH!3)lCi`(am1$UZyDsZmtu2 zMqiZ$eiZnXRz~!~_ufqH$e5LxZhNs+Pa(DKSSL&&Go%Q&`B3R8mm??#vF9PhsSY){w_lgYK4}lgNFTJqVM>ijK=&>#iq6DG0>O&Xgq{z zl``t*>n1pZOhoB(8HMz=?C_iHa77_zcn7TxAhykqKg|IoqVAy~g<%N++M@1isP>@zNHk@gRE| zO^yf+FIY}io6ENw3E@fzsYA_U!bsT79<~v(A{-1`ghX{x$oy!fu^=R&U6^Ti(di(> zz$0{bxT*ZNg@|yh!=2p~f_(t}LPOk@y}A)DYal^SMPO4!2wm?drQ}zP^0pf3LIeh2 zD7&W)FOm9ogfvg#4&|6o<0FLhtNBqm?j>YUj=i*pgNKUlkL(x+f13-pOcpP`QPaO6 CUz*7P