diff --git a/src/class/midi/midi_device.c b/src/class/midi/midi_device.c index 7e30e5ea4..5be4cb993 100644 --- a/src/class/midi/midi_device.c +++ b/src/class/midi/midi_device.c @@ -68,40 +68,36 @@ typedef struct { osal_mutex_def_t rx_ff_mutex; osal_mutex_def_t tx_ff_mutex; #endif - - // Endpoint Transfer buffer - union { - CFG_TUD_MEM_ALIGN uint8_t epout_buf[CFG_TUD_MIDI_EP_BUFSIZE]; - TUD_DCACHE_PADDING; - }; - union { - CFG_TUD_MEM_ALIGN uint8_t epin_buf[CFG_TUD_MIDI_EP_BUFSIZE]; - TUD_DCACHE_PADDING; - }; } midid_interface_t; #define ITF_MEM_RESET_SIZE offsetof(midid_interface_t, rx_ff) +// Endpoint Transfer buffer +CFG_TUD_MEM_SECTION static struct { + TUD_EPBUF_DEF(epin, CFG_TUD_MIDI_EP_BUFSIZE); + TUD_EPBUF_DEF(epout, CFG_TUD_MIDI_EP_BUFSIZE); +} _midid_epbuf[CFG_TUD_MIDI]; + //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ -CFG_TUD_MEM_SECTION midid_interface_t _midid_itf[CFG_TUD_MIDI]; +static midid_interface_t _midid_itf[CFG_TUD_MIDI]; bool tud_midi_n_mounted (uint8_t itf) { midid_interface_t* midi = &_midid_itf[itf]; return midi->ep_in && midi->ep_out; } -static void _prep_out_transaction (midid_interface_t* p_midi) -{ - uint8_t const rhport = 0; +static void _prep_out_transaction(uint8_t idx) { + const uint8_t rhport = 0; + midid_interface_t* p_midi = &_midid_itf[idx]; uint16_t available = tu_fifo_remaining(&p_midi->rx_ff); // Prepare for incoming data but only allow what we can store in the ring buffer. // TODO Actually we can still carry out the transfer, keeping count of received bytes // and slowly move it to the FIFO when read(). // This pre-check reduces endpoint claiming - TU_VERIFY(available >= sizeof(p_midi->epout_buf), ); + TU_VERIFY(available >= sizeof(_midid_epbuf[idx].epout), ); // claim endpoint TU_VERIFY(usbd_edpt_claim(rhport, p_midi->ep_out), ); @@ -109,8 +105,8 @@ static void _prep_out_transaction (midid_interface_t* p_midi) // fifo can be changed before endpoint is claimed available = tu_fifo_remaining(&p_midi->rx_ff); - if ( available >= sizeof(p_midi->epout_buf) ) { - usbd_edpt_xfer(rhport, p_midi->ep_out, p_midi->epout_buf, sizeof(p_midi->epout_buf)); + if ( available >= CFG_TUD_MIDI_EP_BUFSIZE ) { + usbd_edpt_xfer(rhport, p_midi->ep_out, _midid_epbuf[idx].epout, CFG_TUD_MIDI_EP_BUFSIZE); }else { // Release endpoint since we don't make any transfer @@ -126,7 +122,7 @@ uint32_t tud_midi_n_available(uint8_t itf, uint8_t cable_num) (void) cable_num; midid_interface_t* midi = &_midid_itf[itf]; - midid_stream_t const* stream = &midi->stream_read; + const midid_stream_t* stream = &midi->stream_read; // when using with packet API stream total & index are both zero return tu_fifo_count(&midi->rx_ff) + (uint8_t) (stream->total - stream->index); @@ -207,8 +203,8 @@ bool tud_midi_n_packet_read (uint8_t itf, uint8_t packet[4]) midid_interface_t* midi = &_midid_itf[itf]; TU_VERIFY(midi->ep_out); - uint32_t const num_read = tu_fifo_read_n(&midi->rx_ff, packet, 4); - _prep_out_transaction(midi); + const uint32_t num_read = tu_fifo_read_n(&midi->rx_ff, packet, 4); + _prep_out_transaction(itf); return (num_read == 4); } @@ -216,31 +212,31 @@ bool tud_midi_n_packet_read (uint8_t itf, uint8_t packet[4]) // WRITE API //--------------------------------------------------------------------+ -static uint32_t write_flush(midid_interface_t* midi) -{ - // No data to send - if ( !tu_fifo_count(&midi->tx_ff) ) return 0; +static uint32_t write_flush(uint8_t idx) { + midid_interface_t* midi = &_midid_itf[idx]; - uint8_t const rhport = 0; + if (!tu_fifo_count(&midi->tx_ff)) { + return 0; // No data to send + } + + const uint8_t rhport = 0; // skip if previous transfer not complete TU_VERIFY( usbd_edpt_claim(rhport, midi->ep_in), 0 ); - uint16_t count = tu_fifo_read_n(&midi->tx_ff, midi->epin_buf, CFG_TUD_MIDI_EP_BUFSIZE); + uint16_t count = tu_fifo_read_n(&midi->tx_ff, _midid_epbuf[idx].epin, CFG_TUD_MIDI_EP_BUFSIZE); - if (count) - { - TU_ASSERT( usbd_edpt_xfer(rhport, midi->ep_in, midi->epin_buf, count), 0 ); + if (count) { + TU_ASSERT( usbd_edpt_xfer(rhport, midi->ep_in, _midid_epbuf[idx].epin, count), 0 ); return count; - }else - { + }else { // Release endpoint since we don't make any transfer usbd_edpt_release(rhport, midi->ep_in); return 0; } } -uint32_t tud_midi_n_stream_write(uint8_t itf, uint8_t cable_num, uint8_t const* buffer, uint32_t bufsize) +uint32_t tud_midi_n_stream_write(uint8_t itf, uint8_t cable_num, const uint8_t* buffer, uint32_t bufsize) { midid_interface_t* midi = &_midid_itf[itf]; TU_VERIFY(midi->ep_in, 0); @@ -250,14 +246,13 @@ uint32_t tud_midi_n_stream_write(uint8_t itf, uint8_t cable_num, uint8_t const* uint32_t i = 0; while ( (i < bufsize) && (tu_fifo_remaining(&midi->tx_ff) >= 4) ) { - uint8_t const data = buffer[i]; + const uint8_t data = buffer[i]; i++; if ( stream->index == 0 ) { //------------- New event packet -------------// - - uint8_t const msg = data >> 4; + const uint8_t msg = data >> 4; stream->index = 2; stream->buffer[1] = data; @@ -342,9 +337,11 @@ uint32_t tud_midi_n_stream_write(uint8_t itf, uint8_t cable_num, uint8_t const* if ( stream->index == stream->total ) { // zeroes unused bytes - for(uint8_t idx = stream->total; idx < 4; idx++) stream->buffer[idx] = 0; + for (uint8_t idx = stream->total; idx < 4; idx++) { + stream->buffer[idx] = 0; + } - uint16_t const count = tu_fifo_write_n(&midi->tx_ff, stream->buffer, 4); + const uint16_t count = tu_fifo_write_n(&midi->tx_ff, stream->buffer, 4); // complete current event packet, reset stream stream->index = stream->total = 0; @@ -354,20 +351,21 @@ uint32_t tud_midi_n_stream_write(uint8_t itf, uint8_t cable_num, uint8_t const* } } - write_flush(midi); + write_flush(itf); return i; } -bool tud_midi_n_packet_write (uint8_t itf, uint8_t const packet[4]) -{ +bool tud_midi_n_packet_write (uint8_t itf, const uint8_t packet[4]) { midid_interface_t* midi = &_midid_itf[itf]; TU_VERIFY(midi->ep_in); - if (tu_fifo_remaining(&midi->tx_ff) < 4) return false; + if (tu_fifo_remaining(&midi->tx_ff) < 4) { + return false; + } tu_fifo_write_n(&midi->tx_ff, packet, 4); - write_flush(midi); + write_flush(itf); return true; } @@ -431,7 +429,7 @@ void midid_reset(uint8_t rhport) } } -uint16_t midid_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, uint16_t max_len) +uint16_t midid_open(uint8_t rhport, const tusb_desc_interface_t* desc_itf, uint16_t max_len) { // 1st Interface is Audio Control v1 TU_VERIFY(TUSB_CLASS_AUDIO == desc_itf->bInterfaceClass && @@ -439,7 +437,7 @@ uint16_t midid_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, uint AUDIO_FUNC_PROTOCOL_CODE_UNDEF == desc_itf->bInterfaceProtocol, 0); uint16_t drv_len = tu_desc_len(desc_itf); - uint8_t const * p_desc = tu_desc_next(desc_itf); + const uint8_t* p_desc = tu_desc_next(desc_itf); // Skip Class Specific descriptors while ( TUSB_DESC_CS_INTERFACE == tu_desc_type(p_desc) && drv_len <= max_len ) @@ -450,7 +448,7 @@ uint16_t midid_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, uint // 2nd Interface is MIDI Streaming TU_VERIFY(TUSB_DESC_INTERFACE == tu_desc_type(p_desc), 0); - tusb_desc_interface_t const * desc_midi = (tusb_desc_interface_t const *) p_desc; + const tusb_desc_interface_t* desc_midi = (const tusb_desc_interface_t*) p_desc; TU_VERIFY(TUSB_CLASS_AUDIO == desc_midi->bInterfaceClass && AUDIO_SUBCLASS_MIDI_STREAMING == desc_midi->bInterfaceSubClass && @@ -458,11 +456,10 @@ uint16_t midid_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, uint // Find available interface midid_interface_t * p_midi = NULL; - for(uint8_t i=0; ibEndpointAddress; + TU_ASSERT(usbd_edpt_open(rhport, (const tusb_desc_endpoint_t*) p_desc), 0); + uint8_t ep_addr = ((const tusb_desc_endpoint_t*) p_desc)->bEndpointAddress; if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) { @@ -503,7 +500,7 @@ uint16_t midid_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, uint } // Prepare for incoming data - _prep_out_transaction(p_midi); + _prep_out_transaction(idx); return drv_len; } @@ -511,14 +508,9 @@ uint16_t midid_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, uint // Invoked when a control transfer occurred on an interface of this class // Driver response accordingly to the request and the transfer stage (setup/data/ack) // return false to stall control endpoint (e.g unsupported request) -bool midid_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request) -{ - (void) rhport; - (void) stage; - (void) request; - - // driver doesn't support any request yet - return false; +bool midid_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_request_t* request) { + (void) rhport; (void) stage; (void) request; + return false; // driver doesn't support any request yet } bool midid_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) @@ -526,40 +518,37 @@ bool midid_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32 (void) result; (void) rhport; - uint8_t itf; + uint8_t idx; midid_interface_t* p_midi; // Identify which interface to use - for (itf = 0; itf < CFG_TUD_MIDI; itf++) - { - p_midi = &_midid_itf[itf]; - if ( ( ep_addr == p_midi->ep_out ) || ( ep_addr == p_midi->ep_in ) ) break; + for (idx = 0; idx < CFG_TUD_MIDI; idx++) { + p_midi = &_midid_itf[idx]; + if ((ep_addr == p_midi->ep_out) || (ep_addr == p_midi->ep_in)) { + break; + } } - TU_ASSERT(itf < CFG_TUD_MIDI); + TU_ASSERT(idx < CFG_TUD_MIDI); // receive new data - if ( ep_addr == p_midi->ep_out ) - { - tu_fifo_write_n(&p_midi->rx_ff, p_midi->epout_buf, (uint16_t) xferred_bytes); + if (ep_addr == p_midi->ep_out) { + tu_fifo_write_n(&p_midi->rx_ff, _midid_epbuf[idx].epout, (uint16_t)xferred_bytes); // invoke receive callback if available - if (tud_midi_rx_cb) tud_midi_rx_cb(itf); + if (tud_midi_rx_cb) { + tud_midi_rx_cb(idx); + } // prepare for next // TODO for now ep_out is not used by public API therefore there is no race condition, // and does not need to claim like ep_in - _prep_out_transaction(p_midi); - } - else if ( ep_addr == p_midi->ep_in ) - { - if (0 == write_flush(p_midi)) - { + _prep_out_transaction(idx); + } else if (ep_addr == p_midi->ep_in) { + if (0 == write_flush(idx)) { // If there is no data left, a ZLP should be sent if // xferred_bytes is multiple of EP size and not zero - if ( !tu_fifo_count(&p_midi->tx_ff) && xferred_bytes && (0 == (xferred_bytes % CFG_TUD_MIDI_EP_BUFSIZE)) ) - { - if ( usbd_edpt_claim(rhport, p_midi->ep_in) ) - { + if (!tu_fifo_count(&p_midi->tx_ff) && xferred_bytes && (0 == (xferred_bytes % CFG_TUD_MIDI_EP_BUFSIZE))) { + if (usbd_edpt_claim(rhport, p_midi->ep_in)) { usbd_edpt_xfer(rhport, p_midi->ep_in, NULL, 0); } } diff --git a/src/common/tusb_common.h b/src/common/tusb_common.h index 416bad296..d05032d00 100644 --- a/src/common/tusb_common.h +++ b/src/common/tusb_common.h @@ -58,9 +58,6 @@ // Generate a mask with bit from high (31) to low (0) set, e.g TU_GENMASK(3, 0) = 0b1111 #define TU_GENMASK(h, l) ( (UINT32_MAX << (l)) & (UINT32_MAX >> (31 - (h))) ) -// DCache padding for variable to occupy full cache line -#define TUD_DCACHE_PADDING uint8_t TU_XSTRCAT(dcache_padding_, _TU_COUNTER_)[CFG_TUD_MEM_DCACHE_ENABLE ? CFG_TUD_MEM_DCACHE_LINE_SIZE : 1] - //--------------------------------------------------------------------+ // Includes //--------------------------------------------------------------------+ @@ -179,7 +176,7 @@ TU_ATTR_ALWAYS_INLINE static inline bool tu_is_aligned32(uint32_t value) { retur TU_ATTR_ALWAYS_INLINE static inline bool tu_is_aligned64(uint64_t value) { return (value & 0x3FUL) == 0; } //------------- Mathematics -------------// -TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_div_ceil(uint32_t v, uint32_t d) { return (v + d -1)/d; } +TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_div_ceil(uint32_t v, uint32_t d) { return TU_DIV_CEIL(v, d); } // log2 of a value is its MSB's position // TODO use clz TODO remove diff --git a/src/common/tusb_types.h b/src/common/tusb_types.h index d045a3c8f..d0a5c866f 100644 --- a/src/common/tusb_types.h +++ b/src/common/tusb_types.h @@ -35,6 +35,16 @@ extern "C" { #endif +// DCache padding for variable to occupy full cache line +#define TUD_DCACHE_PADDING uint8_t TU_XSTRCAT(dcache_padding_, _TU_COUNTER_)[CFG_TUD_MEM_DCACHE_ENABLE ? CFG_TUD_MEM_DCACHE_LINE_SIZE : 1] + +#define TUD_EPBUF_DEF(_name, _size) \ + union { \ + CFG_TUD_MEM_ALIGN uint8_t _name[_size]; \ + uint8_t _name##_dcache_padding[CFG_TUD_MEM_DCACHE_ENABLE ? (TU_DIV_CEIL(_size, CFG_TUD_MEM_DCACHE_LINE_SIZE) * CFG_TUD_MEM_DCACHE_LINE_SIZE) : 1]; \ + }; + + /*------------------------------------------------------------------*/ /* CONSTANTS *------------------------------------------------------------------*/ diff --git a/src/device/usbd_control.c b/src/device/usbd_control.c index 59c66eb1e..80a2a2cc1 100644 --- a/src/device/usbd_control.c +++ b/src/device/usbd_control.c @@ -35,7 +35,7 @@ //--------------------------------------------------------------------+ // Callback weak stubs (called if application does not provide) //--------------------------------------------------------------------+ -TU_ATTR_WEAK void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const* request) { +TU_ATTR_WEAK void dcd_edpt0_status_complete(uint8_t rhport, const tusb_control_request_t* request) { (void) rhport; (void) request; } @@ -54,10 +54,6 @@ enum { }; typedef struct { - union { - CFG_TUD_MEM_ALIGN uint8_t ep_buf[CFG_TUD_ENDPOINT0_SIZE]; - TUD_DCACHE_PADDING; - }; tusb_control_request_t request; uint8_t* buffer; uint16_t data_len; @@ -65,21 +61,25 @@ typedef struct { usbd_control_xfer_cb_t complete_cb; } usbd_control_xfer_t; -CFG_TUD_MEM_SECTION CFG_TUD_MEM_ALIGN static usbd_control_xfer_t _ctrl_xfer; +static usbd_control_xfer_t _ctrl_xfer; + +CFG_TUD_MEM_SECTION static struct { + TUD_EPBUF_DEF(buf, CFG_TUD_ENDPOINT0_SIZE); +} _ctrl_epbuf; //--------------------------------------------------------------------+ // Application API //--------------------------------------------------------------------+ // Queue ZLP status transaction -static inline bool status_stage_xact(uint8_t rhport, tusb_control_request_t const* request) { +static inline bool status_stage_xact(uint8_t rhport, const tusb_control_request_t* request) { // Opposite to endpoint in Data Phase - uint8_t const ep_addr = request->bmRequestType_bit.direction ? EDPT_CTRL_OUT : EDPT_CTRL_IN; + const uint8_t ep_addr = request->bmRequestType_bit.direction ? EDPT_CTRL_OUT : EDPT_CTRL_IN; return usbd_edpt_xfer(rhport, ep_addr, NULL, 0); } // Status phase -bool tud_control_status(uint8_t rhport, tusb_control_request_t const* request) { +bool tud_control_status(uint8_t rhport, const tusb_control_request_t* request) { _ctrl_xfer.request = (*request); _ctrl_xfer.buffer = NULL; _ctrl_xfer.total_xferred = 0; @@ -92,24 +92,22 @@ bool tud_control_status(uint8_t rhport, tusb_control_request_t const* request) { // Each transaction has up to Endpoint0's max packet size. // This function can also transfer an zero-length packet static bool data_stage_xact(uint8_t rhport) { - uint16_t const xact_len = tu_min16(_ctrl_xfer.data_len - _ctrl_xfer.total_xferred, - CFG_TUD_ENDPOINT0_SIZE); - + const uint16_t xact_len = tu_min16(_ctrl_xfer.data_len - _ctrl_xfer.total_xferred, CFG_TUD_ENDPOINT0_SIZE); uint8_t ep_addr = EDPT_CTRL_OUT; if (_ctrl_xfer.request.bmRequestType_bit.direction == TUSB_DIR_IN) { ep_addr = EDPT_CTRL_IN; if (xact_len) { - TU_VERIFY(0 == tu_memcpy_s(_ctrl_xfer.ep_buf, CFG_TUD_ENDPOINT0_SIZE, _ctrl_xfer.buffer, xact_len)); + TU_VERIFY(0 == tu_memcpy_s(_ctrl_epbuf.buf, CFG_TUD_ENDPOINT0_SIZE, _ctrl_xfer.buffer, xact_len)); } } - return usbd_edpt_xfer(rhport, ep_addr, xact_len ? _ctrl_xfer.ep_buf : NULL, xact_len); + return usbd_edpt_xfer(rhport, ep_addr, xact_len ? _ctrl_epbuf.buf : NULL, xact_len); } // Transmit data to/from the control endpoint. // If the request's wLength is zero, a status packet is sent instead. -bool tud_control_xfer(uint8_t rhport, tusb_control_request_t const* request, void* buffer, uint16_t len) { +bool tud_control_xfer(uint8_t rhport, const tusb_control_request_t* request, void* buffer, uint16_t len) { _ctrl_xfer.request = (*request); _ctrl_xfer.buffer = (uint8_t*) buffer; _ctrl_xfer.total_xferred = 0U; @@ -119,13 +117,8 @@ bool tud_control_xfer(uint8_t rhport, tusb_control_request_t const* request, voi if (_ctrl_xfer.data_len > 0U) { TU_ASSERT(buffer); } - -// TU_LOG2(" Control total data length is %u bytes\r\n", _ctrl_xfer.data_len); - - // Data stage TU_ASSERT(data_stage_xact(rhport)); } else { - // Status stage TU_ASSERT(status_stage_xact(rhport, request)); } @@ -136,7 +129,7 @@ bool tud_control_xfer(uint8_t rhport, tusb_control_request_t const* request, voi // USBD API //--------------------------------------------------------------------+ void usbd_control_reset(void); -void usbd_control_set_request(tusb_control_request_t const* request); +void usbd_control_set_request(const tusb_control_request_t* request); void usbd_control_set_complete_callback(usbd_control_xfer_cb_t fp); bool usbd_control_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); @@ -150,7 +143,7 @@ void usbd_control_set_complete_callback(usbd_control_xfer_cb_t fp) { } // for dcd_set_address where DCD is responsible for status response -void usbd_control_set_request(tusb_control_request_t const* request) { +void usbd_control_set_request(const tusb_control_request_t* request) { _ctrl_xfer.request = (*request); _ctrl_xfer.buffer = NULL; _ctrl_xfer.total_xferred = 0; @@ -180,7 +173,7 @@ bool usbd_control_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, if (_ctrl_xfer.request.bmRequestType_bit.direction == TUSB_DIR_OUT) { TU_VERIFY(_ctrl_xfer.buffer); - memcpy(_ctrl_xfer.buffer, _ctrl_xfer.ep_buf, xferred_bytes); + memcpy(_ctrl_xfer.buffer, _ctrl_epbuf.buf, xferred_bytes); TU_LOG_MEM(CFG_TUD_LOG_LEVEL, _usbd_ctrl_buf, xferred_bytes, 2); } @@ -205,7 +198,6 @@ bool usbd_control_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, } if (is_ok) { - // Send status TU_ASSERT(status_stage_xact(rhport, &_ctrl_xfer.request)); } else { // Stall both IN and OUT control endpoint diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index f2eb80e12..6c7b94778 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -31,6 +31,10 @@ #if CFG_TUD_ENABLED && defined(TUP_USBIP_DWC2) +#if !CFG_TUD_DWC2_SLAVE_ENABLE && !CFG_TUH_DWC2_DMA_ENABLE +#error DWC2 require either CFG_TUD_DWC2_SLAVE_ENABLE or CFG_TUH_DWC2_DMA_ENABLE to be enabled +#endif + // Debug level for DWC2 #define DWC2_DEBUG 2 @@ -58,11 +62,6 @@ static xfer_ctl_t xfer_status[DWC2_EP_MAX][2]; #define XFER_CTL_BASE(_ep, _dir) (&xfer_status[_ep][_dir]) typedef struct { - union { - CFG_TUD_MEM_ALIGN uint32_t setup_packet[2]; - TUD_DCACHE_PADDING; - }; - // EP0 transfers are limited to 1 packet - larger sizes has to be split uint16_t ep0_pending[2]; // Index determines direction as tusb_dir_t type uint16_t dfifo_top; // top free location in DFIFO in words @@ -74,7 +73,11 @@ typedef struct { bool sof_en; } dcd_data_t; -CFG_TUD_MEM_SECTION static dcd_data_t _dcd_data; +static dcd_data_t _dcd_data; + +CFG_TUD_MEM_SECTION static struct { + TUD_EPBUF_DEF(setup_packet, 8); +} _dcd_usbbuf; //-------------------------------------------------------------------- // DMA @@ -116,7 +119,7 @@ static void dma_setup_prepare(uint8_t rhport) { // Receive only 1 packet dwc2->epout[0].doeptsiz = (1 << DOEPTSIZ_STUPCNT_Pos) | (1 << DOEPTSIZ_PKTCNT_Pos) | (8 << DOEPTSIZ_XFRSIZ_Pos); - dwc2->epout[0].doepdma = (uintptr_t) _dcd_data.setup_packet; + dwc2->epout[0].doepdma = (uintptr_t) _dcd_usbbuf.setup_packet; dwc2->epout[0].doepctl |= DOEPCTL_EPENA | DOEPCTL_USBAEP; } @@ -751,12 +754,14 @@ static void handle_rxflvl_irq(uint8_t rhport) { // Global OUT NAK: do nothing break; - case GRXSTS_PKTSTS_SETUP_RX: + case GRXSTS_PKTSTS_SETUP_RX: { // Setup packet received + uint32_t* setup = (uint32_t*)(uintptr_t) _dcd_usbbuf.setup_packet; // We can receive up to three setup packets in succession, but only the last one is valid. - _dcd_data.setup_packet[0] = (*rx_fifo); - _dcd_data.setup_packet[1] = (*rx_fifo); + setup[0] = (*rx_fifo); + setup[1] = (*rx_fifo); break; + } case GRXSTS_PKTSTS_SETUP_DONE: // Setup packet done: @@ -802,7 +807,7 @@ static void handle_rxflvl_irq(uint8_t rhport) { static void handle_epout_slave(uint8_t rhport, uint8_t epnum, dwc2_doepint_t doepint_bm) { if (doepint_bm.setup_phase_done) { - dcd_event_setup_received(rhport, (uint8_t*) _dcd_data.setup_packet, true); + dcd_event_setup_received(rhport, _dcd_usbbuf.setup_packet, true); return; } @@ -878,8 +883,8 @@ static void handle_epout_dma(uint8_t rhport, uint8_t epnum, dwc2_doepint_t doepi if (doepint_bm.setup_phase_done) { dma_setup_prepare(rhport); - dcd_dcache_invalidate(_dcd_data.setup_packet, 8); - dcd_event_setup_received(rhport, (uint8_t*) _dcd_data.setup_packet, true); + dcd_dcache_invalidate(_dcd_usbbuf.setup_packet, 8); + dcd_event_setup_received(rhport, _dcd_usbbuf.setup_packet, true); return; }