From 656b83b1a7354d96ab640190d889e7ca92d132d5 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Date: Wed, 29 Aug 2012 17:43:34 +0200 Subject: [PATCH] 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; }