Skeleton, and initial stm32fsdev implementation (that leaks memory)
This commit is contained in:
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user