diff options
| author | Nathan Conrad <[email protected]> | 2020-04-12 21:07:17 -0400 |
|---|---|---|
| committer | Nathan Conrad <[email protected]> | 2020-04-12 21:27:27 -0400 |
| commit | 0eeaccaf46c28444cc0830895559652cf5638c60 (patch) | |
| tree | 2a31a54dd03a0ff7a413427e3cee6a9036bd85e4 /src/device | |
| parent | 2ff3f765db7e62201d0491093111b0d649446046 (diff) | |
Skeleton, and initial stm32fsdev implementation (that leaks memory)
Diffstat (limited to 'src/device')
| -rw-r--r-- | src/device/dcd.h | 6 | ||||
| -rw-r--r-- | src/device/usbd.c | 61 | ||||
| -rw-r--r-- | src/device/usbd.h | 2 |
3 files changed, 68 insertions, 1 deletions
diff --git a/src/device/dcd.h b/src/device/dcd.h index 487ddb3b6..f48530227 100644 --- a/src/device/dcd.h +++ b/src/device/dcd.h @@ -66,7 +66,7 @@ typedef struct TU_ATTR_ALIGNED(4) // USBD_EVT_XFER_COMPLETE struct { - uint8_t ep_addr; + uint8_t ep_addr; ///< 0xFF signifies that the transfer was aborted. uint8_t result; uint32_t len; }xfer_complete; @@ -123,6 +123,10 @@ void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const * re // Configure endpoint's registers according to descriptor bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc); +// Close an endpoint. +// Since it is weak, caller must TU_ASSERT this function's existence before calling it. +void dcd_edpt_close (uint8_t rhport, uint8_t ep_addr) TU_ATTR_WEAK; + // Submit a transfer, When complete dcd_event_xfer_complete() is invoked to notify the stack bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes); diff --git a/src/device/usbd.c b/src/device/usbd.c index 397a681ed..e46532567 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -420,6 +420,11 @@ void tud_task (void) uint8_t const ep_addr = event.xfer_complete.ep_addr; uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const ep_dir = tu_edpt_dir(ep_addr); + + if(ep_addr == 0xFF) // aborted transfer + { + break; + } TU_LOG2(" Endpoint: 0x%02X, Bytes: %u\r\n", ep_addr, (unsigned int) event.xfer_complete.len); @@ -1036,4 +1041,60 @@ bool usbd_edpt_stalled(uint8_t rhport, uint8_t ep_addr) return _usbd_dev.ep_status[epnum][dir].stalled; } +/** + * Remove queued xfer complete messages from event queue, + * for a particular ep. + */ +static void usbd_abort_transfers(uint8_t rhport, uint8_t ep_addr) +{ + dcd_event_t ev_sentinal = + { + .event_id = DCD_EVENT_COUNT, ///< This is an invalid event ID. + }; + dcd_event_t event; + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const ep_dir = tu_edpt_dir(ep_addr); + + dcd_int_disable(rhport); + // Queue sentinal element + TU_ASSERT(osal_queue_send(_usbd_q, &ev_sentinal, true), /**/); + + TU_ASSERT(osal_queue_receive(_usbd_q, &event), /**/); + + while(event.event_id != DCD_EVENT_COUNT) + { + if((event.rhport == rhport) && (event.event_id == DCD_EVENT_XFER_COMPLETE) + && (event.xfer_complete.ep_addr == ep_addr)) + { + _usbd_dev.ep_status[epnum][ep_dir].busy = false; + event.xfer_complete.ep_addr = 0xFF; // Mark transfer as invalid + } + TU_ASSERT(osal_queue_send(_usbd_q, &event, true), /**/); + TU_ASSERT(osal_queue_receive(_usbd_q, &event), /**/); + } + + dcd_int_enable(rhport); +} + +/** + * tud_edpt_close will disable an endpoint, and clear all pending transfers + * through the particular endpoint. + * + * It must be called from the usb task (i.e. from the control request + * handler while handling SET_ALTERNATE). + */ +void tud_edpt_close(uint8_t rhport, uint8_t ep_addr) +{ + + TU_ASSERT(dcd_edpt_close, /**/); + TU_LOG2(" CLOSING Endpoint: 0x%02X\r\n", ep_addr); + + dcd_edpt_close(rhport, ep_addr); + + /* Now, in progress transfers have to be expunged */ + usbd_abort_transfers(rhport, ep_addr); + + return; +} + #endif diff --git a/src/device/usbd.h b/src/device/usbd.h index 817af20e3..2447c2082 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -79,6 +79,8 @@ static inline bool tud_connect(void) return true; } +void tud_edpt_close(uint8_t rhport, uint8_t ep_addr); + // 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 |
