diff options
Diffstat (limited to 'src/device')
| -rw-r--r-- | src/device/dcd.h | 15 | ||||
| -rw-r--r-- | src/device/usbd.c | 71 | ||||
| -rw-r--r-- | src/device/usbd.h | 6 | ||||
| -rw-r--r-- | src/device/usbd_pvt.h | 5 |
4 files changed, 73 insertions, 24 deletions
diff --git a/src/device/dcd.h b/src/device/dcd.h index bc68c9be6..6b99734fe 100644 --- a/src/device/dcd.h +++ b/src/device/dcd.h @@ -77,6 +77,11 @@ typedef struct TU_ATTR_ALIGNED(4) tusb_speed_t speed; } bus_reset; + // SOF + struct { + uint32_t frame_count; + }sof; + // SETUP_RECEIVED tusb_control_request_t setup_received; @@ -132,6 +137,9 @@ void dcd_connect(uint8_t rhport) TU_ATTR_WEAK; // Disconnect by disabling internal pull-up resistor on D+/D- void dcd_disconnect(uint8_t rhport) TU_ATTR_WEAK; +// Enable/Disable Start-of-frame interrupt. Default is disabled +void dcd_sof_enable(uint8_t rhport, bool en); + //--------------------------------------------------------------------+ // Endpoint API //--------------------------------------------------------------------+ @@ -209,6 +217,13 @@ TU_ATTR_ALWAYS_INLINE static inline void dcd_event_xfer_complete (uint8_t rhport dcd_event_handler(&event, in_isr); } +static inline void dcd_event_sof(uint8_t rhport, uint32_t frame_count, bool in_isr) +{ + dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_SOF }; + event.sof.frame_count = frame_count; + dcd_event_handler(&event, in_isr); +} + #ifdef __cplusplus } #endif diff --git a/src/device/usbd.c b/src/device/usbd.c index 1dd1a352e..fa75c0214 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -69,7 +69,7 @@ typedef struct volatile uint8_t cfg_num; // current active configuration (0x00 is not configured) uint8_t speed; - uint8_t itf2drv[16]; // map interface number to driver (0xff is invalid) + uint8_t itf2drv[CFG_TUD_INTERFACE_MAX]; // map interface number to driver (0xff is invalid) uint8_t ep2drv[CFG_TUD_ENDPPOINT_MAX][2]; // map endpoint to driver ( 0xff is invalid ), can use only 4-bit each tu_edpt_state_t ep_status[CFG_TUD_ENDPPOINT_MAX][2]; @@ -98,7 +98,7 @@ static usbd_class_driver_t const _usbd_driver[] = .open = cdcd_open, .control_xfer_cb = cdcd_control_xfer_cb, .xfer_cb = cdcd_xfer_cb, - .sof = NULL + .sof_isr = NULL }, #endif @@ -110,7 +110,7 @@ static usbd_class_driver_t const _usbd_driver[] = .open = mscd_open, .control_xfer_cb = mscd_control_xfer_cb, .xfer_cb = mscd_xfer_cb, - .sof = NULL + .sof_isr = NULL }, #endif @@ -122,7 +122,7 @@ static usbd_class_driver_t const _usbd_driver[] = .open = hidd_open, .control_xfer_cb = hidd_control_xfer_cb, .xfer_cb = hidd_xfer_cb, - .sof = NULL + .sof_isr = NULL }, #endif @@ -134,7 +134,7 @@ static usbd_class_driver_t const _usbd_driver[] = .open = audiod_open, .control_xfer_cb = audiod_control_xfer_cb, .xfer_cb = audiod_xfer_cb, - .sof = NULL + .sof_isr = audiod_sof_isr }, #endif @@ -146,7 +146,7 @@ static usbd_class_driver_t const _usbd_driver[] = .open = videod_open, .control_xfer_cb = videod_control_xfer_cb, .xfer_cb = videod_xfer_cb, - .sof = NULL + .sof_isr = NULL }, #endif @@ -158,7 +158,7 @@ static usbd_class_driver_t const _usbd_driver[] = .reset = midid_reset, .control_xfer_cb = midid_control_xfer_cb, .xfer_cb = midid_xfer_cb, - .sof = NULL + .sof_isr = NULL }, #endif @@ -170,7 +170,7 @@ static usbd_class_driver_t const _usbd_driver[] = .open = vendord_open, .control_xfer_cb = tud_vendor_control_xfer_cb, .xfer_cb = vendord_xfer_cb, - .sof = NULL + .sof_isr = NULL }, #endif @@ -182,7 +182,7 @@ static usbd_class_driver_t const _usbd_driver[] = .open = usbtmcd_open_cb, .control_xfer_cb = usbtmcd_control_xfer_cb, .xfer_cb = usbtmcd_xfer_cb, - .sof = NULL + .sof_isr = NULL }, #endif @@ -194,7 +194,7 @@ static usbd_class_driver_t const _usbd_driver[] = .open = dfu_rtd_open, .control_xfer_cb = dfu_rtd_control_xfer_cb, .xfer_cb = NULL, - .sof = NULL + .sof_isr = NULL }, #endif @@ -206,7 +206,7 @@ static usbd_class_driver_t const _usbd_driver[] = .open = dfu_moded_open, .control_xfer_cb = dfu_moded_control_xfer_cb, .xfer_cb = NULL, - .sof = NULL + .sof_isr = NULL }, #endif @@ -218,7 +218,7 @@ static usbd_class_driver_t const _usbd_driver[] = .open = netd_open, .control_xfer_cb = netd_control_xfer_cb, .xfer_cb = netd_xfer_cb, - .sof = NULL, + .sof_isr = NULL, }, #endif @@ -230,7 +230,7 @@ static usbd_class_driver_t const _usbd_driver[] = .open = btd_open, .control_xfer_cb = btd_control_xfer_cb, .xfer_cb = btd_xfer_cb, - .sof = NULL + .sof_isr = NULL }, #endif }; @@ -264,6 +264,8 @@ static inline usbd_class_driver_t const * get_driver(uint8_t drvid) // DCD Event //--------------------------------------------------------------------+ +//static tud_sof_isr_t _sof_isr = NULL; + enum { RHPORT_INVALID = 0xFFu }; static uint8_t _usbd_rhport = RHPORT_INVALID; @@ -371,6 +373,12 @@ bool tud_connect(void) return true; } +//void tud_sof_isr_set(tud_sof_isr_t sof_isr) +//{ +// _sof_isr = sof_isr; +// dcd_sof_enable(_usbd_rhport, _sof_isr != NULL); +//} + //--------------------------------------------------------------------+ // USBD Task //--------------------------------------------------------------------+ @@ -413,11 +421,13 @@ bool tud_init (uint8_t rhport) driver->init(); } + _usbd_rhport = rhport; + //_sof_isr = NULL; + // Init device controller driver dcd_init(rhport); dcd_int_enable(rhport); - _usbd_rhport = rhport; return true; } @@ -576,20 +586,12 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr) } break; - case DCD_EVENT_SOF: - TU_LOG2("\r\n"); - for ( uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++ ) - { - usbd_class_driver_t const * driver = get_driver(i); - if ( driver->sof ) driver->sof(event.rhport); - } - break; - case USBD_EVENT_FUNC_CALL: TU_LOG2("\r\n"); if ( event.func_call.func ) event.func_call.func(event.func_call.param); break; + case DCD_EVENT_SOF: default: TU_BREAKPOINT(); break; @@ -1105,14 +1107,30 @@ TU_ATTR_FAST_FUNC void dcd_event_handler(dcd_event_t const * event, bool in_isr) break; case DCD_EVENT_SOF: + // SOF driver handler in ISR context + for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) + { + usbd_class_driver_t const * driver = get_driver(i); + if (driver->sof_isr) + { + driver->sof_isr(event->rhport, event->sof.frame_count); + } + } + + // SOF user handler in ISR context + // if (_sof_isr) _sof_isr(event->sof.frame_count); + // Some MCUs after running dcd_remote_wakeup() does not have way to detect the end of remote wakeup // which last 1-15 ms. DCD can use SOF as a clear indicator that bus is back to operational if ( _usbd_dev.suspended ) { _usbd_dev.suspended = 0; + dcd_event_t const event_resume = { .rhport = event->rhport, .event_id = DCD_EVENT_RESUME }; osal_queue_send(_usbd_q, &event_resume, in_isr); } + + // skip osal queue for SOF in usbd task break; default: @@ -1357,4 +1375,11 @@ void usbd_edpt_close(uint8_t rhport, uint8_t ep_addr) return; } +void usbd_sof_enable(uint8_t rhport, bool en) +{ + // TODO: Check needed if all drivers including the user sof_cb does not need an active SOF ISR any more. + // Only if all drivers switched off SOF calls the SOF interrupt may be disabled + dcd_sof_enable(rhport, en); +} + #endif diff --git a/src/device/usbd.h b/src/device/usbd.h index 964cfb992..f1312f6ec 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -33,6 +33,8 @@ extern "C" { #endif +// typedef void (*tud_sof_isr_t) (uint32_t frame_count); + //--------------------------------------------------------------------+ // Application API //--------------------------------------------------------------------+ @@ -93,6 +95,10 @@ bool tud_disconnect(void); // Return false on unsupported MCUs bool tud_connect(void); +// Set Start-of-frame (1ms interval) IRQ handler +// NULL means disabled, frame_count may not be supported on mcus +// void tud_sof_isr_set(tud_sof_isr_t sof_isr); + // Carry out Data and Status stage of control transfer // - If len = 0, it is equivalent to sending status only // - If len > wLength : it will be truncated diff --git a/src/device/usbd_pvt.h b/src/device/usbd_pvt.h index 29753451e..603ffc936 100644 --- a/src/device/usbd_pvt.h +++ b/src/device/usbd_pvt.h @@ -48,7 +48,7 @@ typedef struct uint16_t (* open ) (uint8_t rhport, tusb_desc_interface_t const * desc_intf, uint16_t max_len); bool (* control_xfer_cb ) (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); bool (* xfer_cb ) (uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); - void (* sof ) (uint8_t rhport); /* optional */ + void (* sof_isr ) (uint8_t rhport, uint32_t frame_count); // optional } usbd_class_driver_t; // Invoked when initializing device stack to get additional class drivers. @@ -102,6 +102,9 @@ bool usbd_edpt_ready(uint8_t rhport, uint8_t ep_addr) return !usbd_edpt_busy(rhport, ep_addr) && !usbd_edpt_stalled(rhport, ep_addr); } +// Enable SOF interrupt +void usbd_sof_enable(uint8_t rhport, bool en); + /*------------------------------------------------------------------*/ /* Helper *------------------------------------------------------------------*/ |
