From 6aa0146c72fec825fcd55584bc9088cbd30fadec Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Wed, 14 Nov 2018 09:46:46 -0800 Subject: [PATCH 1/4] Reset USB peripheral and wait for startup --- src/portable/microchip/samd21/dcd_samd21.c | 11 ++++++++++- src/portable/microchip/samd51/dcd_samd51.c | 10 +++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/portable/microchip/samd21/dcd_samd21.c b/src/portable/microchip/samd21/dcd_samd21.c index c6101f31..93425b63 100644 --- a/src/portable/microchip/samd21/dcd_samd21.c +++ b/src/portable/microchip/samd21/dcd_samd21.c @@ -71,10 +71,19 @@ static void bus_reset(void) { *------------------------------------------------------------------*/ bool dcd_init (uint8_t rhport) { + // Reset to get in a clean state. + USB->DEVICE.CTRLA.bit.SWRST = true; + while (USB->DEVICE.SYNCBUSY.bit.SWRST == 0) { + + } + while (USB->DEVICE.SYNCBUSY.bit.SWRST == 1) {} + (void) rhport; USB->DEVICE.DESCADD.reg = (uint32_t) &sram_registers; USB->DEVICE.CTRLB.reg = USB_DEVICE_CTRLB_SPDCONF_FS; - USB->DEVICE.CTRLA.reg = USB_CTRLA_MODE_DEVICE | USB_CTRLA_ENABLE; + USB->DEVICE.CTRLA.reg = USB_CTRLA_MODE_DEVICE | USB_CTRLA_ENABLE | USB_CTRLA_RUNSTDBY; + while (USB->DEVICE.SYNCBUSY.bit.ENABLE == 1) {} + USB->DEVICE.INTENSET.reg = USB_DEVICE_INTENSET_SOF | USB_DEVICE_INTENSET_EORST; return true; diff --git a/src/portable/microchip/samd51/dcd_samd51.c b/src/portable/microchip/samd51/dcd_samd51.c index 6e8053e5..705e06e6 100644 --- a/src/portable/microchip/samd51/dcd_samd51.c +++ b/src/portable/microchip/samd51/dcd_samd51.c @@ -72,9 +72,17 @@ static void bus_reset(void) { bool dcd_init (uint8_t rhport) { (void) rhport; + // Reset to get in a clean state. + USB->DEVICE.CTRLA.bit.SWRST = true; + while (USB->DEVICE.SYNCBUSY.bit.SWRST == 0) { + + } + while (USB->DEVICE.SYNCBUSY.bit.SWRST == 1) {} + USB->DEVICE.DESCADD.reg = (uint32_t) &sram_registers; USB->DEVICE.CTRLB.reg = USB_DEVICE_CTRLB_SPDCONF_FS; - USB->DEVICE.CTRLA.reg = USB_CTRLA_MODE_DEVICE | USB_CTRLA_ENABLE; + USB->DEVICE.CTRLA.reg = USB_CTRLA_MODE_DEVICE | USB_CTRLA_ENABLE | USB_CTRLA_RUNSTDBY; + while (USB->DEVICE.SYNCBUSY.bit.ENABLE == 1) {} USB->DEVICE.INTENSET.reg = USB_DEVICE_INTENSET_SOF | USB_DEVICE_INTENSET_EORST; return true; From 246c28db1a2bc2a2c0d21c62789bcc72e3fadeae Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Wed, 14 Nov 2018 09:47:22 -0800 Subject: [PATCH 2/4] Turn off interrupts when working with the event queue. --- src/osal/osal_none.h | 35 +++++++++++++++-------------------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/src/osal/osal_none.h b/src/osal/osal_none.h index b21c3332..40ecb9c3 100644 --- a/src/osal/osal_none.h +++ b/src/osal/osal_none.h @@ -43,6 +43,8 @@ #ifndef _TUSB_OSAL_NONE_H_ #define _TUSB_OSAL_NONE_H_ +#include "tusb_hal.h" + #ifdef __cplusplus extern "C" { #endif @@ -135,14 +137,14 @@ static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) static inline bool osal_queue_send(osal_queue_t const queue_hdl, void const * data, bool in_isr) { - (void) in_isr; -// if (!in_isr) tusb_hal_int_disable_all(); - - bool rc = tu_fifo_write( (tu_fifo_t*) queue_hdl, data); - -// if (!in_isr) tusb_hal_int_enable_all(); - - return rc; + if (!in_isr) { + tusb_hal_int_disable_all(); + } + bool success = tu_fifo_write( (tu_fifo_t*) queue_hdl, data); + if (!in_isr) { + tusb_hal_int_enable_all(); + } + return success; } static inline void osal_queue_reset(osal_queue_t const queue_hdl) @@ -152,18 +154,11 @@ static inline void osal_queue_reset(osal_queue_t const queue_hdl) // tusb_hal_int_enable_all(); } - -static inline bool osal_queue_receive(osal_queue_t const queue_hdl, void* data) -{ - // osal none return immediately without blocking - // extern void tusb_hal_int_disable(uint8_t rhport); - // extern void tusb_hal_int_enable(uint8_t rhport); - -// tusb_hal_int_disable(0); - bool rc = tu_fifo_read(queue_hdl, data); -// tusb_hal_int_enable(0); - - return rc; +static inline bool osal_queue_receive(osal_queue_t const queue_hdl, void* data) { + tusb_hal_int_disable_all(); + bool success = tu_fifo_read(queue_hdl, data); + tusb_hal_int_enable_all(); + return success; } #ifdef __cplusplus From bf8c4612dccfc65e0867d03d85d9ebe2e46101e0 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Wed, 14 Nov 2018 14:36:26 -0800 Subject: [PATCH 3/4] Make sure OUT endpoint 0 on the SAMDs always has a valid buffer to store a SETUP token into. --- src/portable/microchip/samd21/dcd_samd21.c | 6 ++++++ src/portable/microchip/samd51/dcd_samd51.c | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/src/portable/microchip/samd21/dcd_samd21.c b/src/portable/microchip/samd21/dcd_samd21.c index 93425b63..c2464d6b 100644 --- a/src/portable/microchip/samd21/dcd_samd21.c +++ b/src/portable/microchip/samd21/dcd_samd21.c @@ -164,6 +164,12 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t UsbDeviceDescBank* bank = &sram_registers[epnum][dir]; UsbDeviceEndpoint* ep = &USB->DEVICE.DeviceEndpoint[epnum]; + // A setup token can occur immediately after an OUT STATUS packet so make sure we have a valid + // buffer for the control endpoint. + if (epnum == 0 && dir == 0 && buffer == NULL) { + buffer = _setup_packet; + } + bank->ADDR.reg = (uint32_t) buffer; if ( dir == TUSB_DIR_OUT ) { diff --git a/src/portable/microchip/samd51/dcd_samd51.c b/src/portable/microchip/samd51/dcd_samd51.c index 705e06e6..e53a8641 100644 --- a/src/portable/microchip/samd51/dcd_samd51.c +++ b/src/portable/microchip/samd51/dcd_samd51.c @@ -163,6 +163,12 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t UsbDeviceDescBank* bank = &sram_registers[epnum][dir]; UsbDeviceEndpoint* ep = &USB->DEVICE.DeviceEndpoint[epnum]; + // A setup token can occur immediately after an OUT STATUS packet so make sure we have a valid + // buffer for the control endpoint. + if (epnum == 0 && dir == 0 && buffer == NULL) { + buffer = _setup_packet; + } + bank->ADDR.reg = (uint32_t) buffer; if ( dir == TUSB_DIR_OUT ) { From 47fabe42edaae4a5da6aa0d48c664a9184578753 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 23 Nov 2018 12:48:55 -0800 Subject: [PATCH 4/4] One tweak to make -Wdiscarded-qualifiers happy. --- src/class/hid/hid_device.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index f1ecec3c..c89c15ac 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -418,7 +418,8 @@ bool hidd_control_request(uint8_t rhport, tusb_control_request_t const * p_reque if (p_request->bRequest == TUSB_REQ_GET_DESCRIPTOR && desc_type == HID_DESC_TYPE_REPORT) { - usbd_control_xfer(rhport, p_request, p_hid->desc_report, p_hid->desc_len); + // Cast away the const on p_hid->desc_report because we know it won't be modified. + usbd_control_xfer(rhport, p_request, (void *)p_hid->desc_report, p_hid->desc_len); }else { return false; // stall unsupported request