mirror of
https://github.com/hathach/tinyusb.git
synced 2025-03-23 13:20:54 +00:00
Merge pull request #388 from hathach/fix-samd-setup-race
fix dcd samd race condition with setup packet
This commit is contained in:
commit
520df6bb53
@ -37,14 +37,11 @@
|
||||
static TU_ATTR_ALIGNED(4) UsbDeviceDescBank sram_registers[8][2];
|
||||
static TU_ATTR_ALIGNED(4) uint8_t _setup_packet[8];
|
||||
|
||||
|
||||
// ready for receiving SETUP packet
|
||||
static inline void prepare_setup(void)
|
||||
{
|
||||
// Only make sure the EP0 OUT buffer is ready
|
||||
sram_registers[0][0].ADDR.reg = (uint32_t) _setup_packet;
|
||||
sram_registers[0][0].PCKSIZE.bit.MULTI_PACKET_SIZE = sizeof(_setup_packet);
|
||||
sram_registers[0][0].PCKSIZE.bit.BYTE_COUNT = 0;
|
||||
}
|
||||
|
||||
// Setup the control endpoint 0.
|
||||
@ -64,7 +61,6 @@ static void bus_reset(void)
|
||||
prepare_setup();
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
/* Controller API
|
||||
*------------------------------------------------------------------*/
|
||||
@ -183,7 +179,7 @@ void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const * re
|
||||
}
|
||||
|
||||
// Just finished status stage, prepare for next setup packet
|
||||
// Note: we may already prepare setup when the last EP0 OUT complete.
|
||||
// Note: we may already prepare setup when queueing the control status.
|
||||
// but it has no harm to do it again here
|
||||
prepare_setup();
|
||||
}
|
||||
@ -235,6 +231,14 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t
|
||||
UsbDeviceEndpoint* ep = &USB->DEVICE.DeviceEndpoint[epnum];
|
||||
|
||||
bank->ADDR.reg = (uint32_t) buffer;
|
||||
|
||||
// A SETUP token can occur immediately after an ZLP Status.
|
||||
// So make sure we have a valid buffer for setup packet.
|
||||
// Status = ZLP EP0 with direction opposite to one in the dir bit of current setup
|
||||
if ( (epnum == 0) && (buffer == NULL) && (total_bytes == 0) && (dir != tu_edpt_dir(_setup_packet[0])) ) {
|
||||
prepare_setup();
|
||||
}
|
||||
|
||||
if ( dir == TUSB_DIR_OUT )
|
||||
{
|
||||
bank->PCKSIZE.bit.MULTI_PACKET_SIZE = total_bytes;
|
||||
@ -297,7 +301,7 @@ void maybe_transfer_complete(void) {
|
||||
// Handle IN completions
|
||||
if ((epintflag & USB_DEVICE_EPINTFLAG_TRCPT1) != 0) {
|
||||
UsbDeviceDescBank* bank = &sram_registers[epnum][TUSB_DIR_IN];
|
||||
uint16_t total_transfer_size = bank->PCKSIZE.bit.BYTE_COUNT;
|
||||
uint16_t const total_transfer_size = bank->PCKSIZE.bit.BYTE_COUNT;
|
||||
|
||||
dcd_event_xfer_complete(0, epnum | TUSB_DIR_IN_MASK, total_transfer_size, XFER_RESULT_SUCCESS, true);
|
||||
|
||||
@ -306,15 +310,8 @@ void maybe_transfer_complete(void) {
|
||||
|
||||
// Handle OUT completions
|
||||
if ((epintflag & USB_DEVICE_EPINTFLAG_TRCPT0) != 0) {
|
||||
|
||||
UsbDeviceDescBank* bank = &sram_registers[epnum][TUSB_DIR_OUT];
|
||||
uint16_t total_transfer_size = bank->PCKSIZE.bit.BYTE_COUNT;
|
||||
|
||||
// A SETUP token can occur immediately after an OUT packet
|
||||
// so make sure we have a valid buffer for the control endpoint.
|
||||
if (epnum == 0) {
|
||||
prepare_setup();
|
||||
}
|
||||
uint16_t const total_transfer_size = bank->PCKSIZE.bit.BYTE_COUNT;
|
||||
|
||||
dcd_event_xfer_complete(0, epnum, total_transfer_size, XFER_RESULT_SUCCESS, true);
|
||||
|
||||
@ -381,7 +378,10 @@ void dcd_int_handler (uint8_t rhport)
|
||||
// This copies the data elsewhere so we can reuse the buffer.
|
||||
dcd_event_setup_received(0, _setup_packet, true);
|
||||
|
||||
USB->DEVICE.DeviceEndpoint[0].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_RXSTP;
|
||||
// Although Setup packet only set RXSTP bit,
|
||||
// TRCPT0 bit could already be set by previous ZLP OUT Status (not handled until now).
|
||||
// Since control status complete event is optional, we can just clear TRCPT0 and skip the status event
|
||||
USB->DEVICE.DeviceEndpoint[0].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_RXSTP | USB_DEVICE_EPINTFLAG_TRCPT0;
|
||||
}
|
||||
|
||||
// Handle complete transfer
|
||||
|
Loading…
x
Reference in New Issue
Block a user