4646//--------------------------------------------------------------------+
4747// MACRO TYPEDEF CONSTANT ENUM
4848//--------------------------------------------------------------------+
49- static CFG_TUD_MEM_SECTION CFG_TUD_MEM_ALIGN uint32_t _setup_packet [2 ];
50-
5149typedef struct {
5250 uint8_t * buffer ;
5351 tu_fifo_t * ff ;
@@ -59,15 +57,26 @@ typedef struct {
5957static xfer_ctl_t xfer_status [DWC2_EP_MAX ][2 ];
6058#define XFER_CTL_BASE (_ep , _dir ) (&xfer_status[_ep][_dir])
6159
62- // EP0 transfers are limited to 1 packet - larger sizes has to be split
63- static uint16_t ep0_pending [2 ]; // Index determines direction as tusb_dir_t type
64- static uint16_t _dfifo_top ; // top free location in DFIFO in words
60+ typedef struct {
61+ CFG_TUD_MEM_ALIGN union {
62+ uint32_t setup_packet [2 ];
63+ #if CFG_TUD_MEM_DCACHE_ENABLE
64+ uint8_t setup_packet_cache_padding [CFG_TUD_MEM_DCACHE_LINE_SIZE ];
65+ #endif
66+ } ;
67+
68+ // EP0 transfers are limited to 1 packet - larger sizes has to be split
69+ uint16_t ep0_pending [2 ]; // Index determines direction as tusb_dir_t type
70+ uint16_t dfifo_top ; // top free location in DFIFO in words
6571
66- // Number of IN endpoints active
67- static uint8_t _allocated_ep_in_count ;
72+ // Number of IN endpoints active
73+ uint8_t allocated_epin_count ;
6874
69- // SOF enabling flag - required for SOF to not get disabled in ISR when SOF was enabled by
70- static bool _sof_en ;
75+ // SOF enabling flag - required for SOF to not get disabled in ISR when SOF was enabled by
76+ bool sof_en ;
77+ } dcd_data_t ;
78+
79+ CFG_TUD_MEM_SECTION static dcd_data_t _dcd_data ;
7180
7281//--------------------------------------------------------------------
7382// DMA
@@ -109,7 +118,7 @@ static void dma_setup_prepare(uint8_t rhport) {
109118
110119 // Receive only 1 packet
111120 dwc2 -> epout [0 ].doeptsiz = (1 << DOEPTSIZ_STUPCNT_Pos ) | (1 << DOEPTSIZ_PKTCNT_Pos ) | (8 << DOEPTSIZ_XFRSIZ_Pos );
112- dwc2 -> epout [0 ].doepdma = (uintptr_t )_setup_packet ;
121+ dwc2 -> epout [0 ].doepdma = (uintptr_t ) _dcd_data . setup_packet ;
113122 dwc2 -> epout [0 ].doepctl |= DOEPCTL_EPENA | DOEPCTL_USBAEP ;
114123}
115124
@@ -167,27 +176,27 @@ TU_ATTR_ALWAYS_INLINE static inline uint16_t calc_device_grxfsiz(uint16_t larges
167176static bool dfifo_alloc (uint8_t rhport , uint8_t ep_addr , uint16_t packet_size ) {
168177 dwc2_regs_t * dwc2 = DWC2_REG (rhport );
169178 const dwc2_controller_t * dwc2_controller = & _dwc2_controller [rhport ];
170- uint8_t const ep_count = dwc2_controller -> ep_count ;
171- uint8_t const epnum = tu_edpt_number (ep_addr );
172- uint8_t const dir = tu_edpt_dir (ep_addr );
179+ const uint8_t ep_count = dwc2_controller -> ep_count ;
180+ const uint8_t epnum = tu_edpt_number (ep_addr );
181+ const uint8_t dir = tu_edpt_dir (ep_addr );
173182
174183 TU_ASSERT (epnum < ep_count );
175184
176185 uint16_t fifo_size = tu_div_ceil (packet_size , 4 );
177186 if (dir == TUSB_DIR_OUT ) {
178187 // Calculate required size of RX FIFO
179- uint16_t const new_sz = calc_device_grxfsiz (4 * fifo_size , ep_count );
188+ const uint16_t new_sz = calc_device_grxfsiz (4 * fifo_size , ep_count );
180189
181190 // If size_rx needs to be extended check if there is enough free space
182191 if (dwc2 -> grxfsiz < new_sz ) {
183- TU_ASSERT (new_sz <= _dfifo_top );
192+ TU_ASSERT (new_sz <= _dcd_data . dfifo_top );
184193 dwc2 -> grxfsiz = new_sz ; // Enlarge RX FIFO
185194 }
186195 } else {
187196 // Check IN endpoints concurrently active limit
188197 if (_dwc2_controller -> ep_in_count ) {
189- TU_ASSERT (_allocated_ep_in_count < _dwc2_controller -> ep_in_count );
190- _allocated_ep_in_count ++ ;
198+ TU_ASSERT (_dcd_data . allocated_epin_count < _dwc2_controller -> ep_in_count );
199+ _dcd_data . allocated_epin_count ++ ;
191200 }
192201
193202 // If The TXFELVL is configured as half empty, the fifo must be twice the max_size.
@@ -196,16 +205,16 @@ static bool dfifo_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t packet_size) {
196205 }
197206
198207 // Check if free space is available
199- TU_ASSERT (_dfifo_top >= fifo_size + dwc2 -> grxfsiz );
200- _dfifo_top -= fifo_size ;
201- // TU_LOG(DWC2_DEBUG, " TX FIFO %u: allocated %u words at offset %u\r\n", epnum, fifo_size, _dfifo_top );
208+ TU_ASSERT (_dcd_data . dfifo_top >= fifo_size + dwc2 -> grxfsiz );
209+ _dcd_data . dfifo_top -= fifo_size ;
210+ // TU_LOG(DWC2_DEBUG, " TX FIFO %u: allocated %u words at offset %u\r\n", epnum, fifo_size, dfifo_top );
202211
203212 // Both TXFD and TXSA are in unit of 32-bit words.
204213 if (epnum == 0 ) {
205- dwc2 -> dieptxf0 = (fifo_size << DIEPTXF0_TX0FD_Pos ) | _dfifo_top ;
214+ dwc2 -> dieptxf0 = (fifo_size << DIEPTXF0_TX0FD_Pos ) | _dcd_data . dfifo_top ;
206215 } else {
207216 // DIEPTXF starts at FIFO #1.
208- dwc2 -> dieptxf [epnum - 1 ] = (fifo_size << DIEPTXF_INEPTXFD_Pos ) | _dfifo_top ;
217+ dwc2 -> dieptxf [epnum - 1 ] = (fifo_size << DIEPTXF_INEPTXFD_Pos ) | _dcd_data . dfifo_top ;
209218 }
210219 }
211220
@@ -219,11 +228,11 @@ static void dfifo_device_init(uint8_t rhport) {
219228
220229 // Scatter/Gather DMA mode is not yet supported. Buffer DMA only need 1 words per endpoint direction
221230 const bool is_dma = dma_device_enabled (dwc2 );
222- _dfifo_top = dwc2_controller -> ep_fifo_size /4 ;
231+ _dcd_data . dfifo_top = dwc2_controller -> ep_fifo_size /4 ;
223232 if (is_dma ) {
224- _dfifo_top -= 2 * dwc2_controller -> ep_count ;
233+ _dcd_data . dfifo_top -= 2 * dwc2_controller -> ep_count ;
225234 }
226- dwc2 -> gdfifocfg = (_dfifo_top << GDFIFOCFG_EPINFOBASE_SHIFT ) | _dfifo_top ;
235+ dwc2 -> gdfifocfg = (_dcd_data . dfifo_top << GDFIFOCFG_EPINFOBASE_SHIFT ) | _dcd_data . dfifo_top ;
227236
228237 // Allocate FIFO for EP0 IN
229238 dfifo_alloc (rhport , 0x80 , CFG_TUD_ENDPOINT0_SIZE );
@@ -233,7 +242,7 @@ static void dfifo_device_init(uint8_t rhport) {
233242//--------------------------------------------------------------------
234243// Endpoint
235244//--------------------------------------------------------------------
236- static void edpt_activate (uint8_t rhport , tusb_desc_endpoint_t const * p_endpoint_desc ) {
245+ static void edpt_activate (uint8_t rhport , const tusb_desc_endpoint_t * p_endpoint_desc ) {
237246 dwc2_regs_t * dwc2 = DWC2_REG (rhport );
238247 const uint8_t epnum = tu_edpt_number (p_endpoint_desc -> bEndpointAddress );
239248 const uint8_t dir = tu_edpt_dir (p_endpoint_desc -> bEndpointAddress );
@@ -324,8 +333,8 @@ static void edpt_schedule_packets(uint8_t rhport, const uint8_t epnum, const uin
324333
325334 // EP0 is limited to one packet per xfer
326335 if (epnum == 0 ) {
327- total_bytes = tu_min16 (ep0_pending [dir ], xfer -> max_size );
328- ep0_pending [dir ] -= total_bytes ;
336+ total_bytes = tu_min16 (_dcd_data . ep0_pending [dir ], xfer -> max_size );
337+ _dcd_data . ep0_pending [dir ] -= total_bytes ;
329338 num_packets = 1 ;
330339 } else {
331340 total_bytes = xfer -> total_len ;
@@ -388,6 +397,8 @@ bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) {
388397 (void ) rh_init ;
389398 dwc2_regs_t * dwc2 = DWC2_REG (rhport );
390399
400+ tu_memclr (& _dcd_data , sizeof (_dcd_data ));
401+
391402 // Core Initialization
392403 const bool is_highspeed = dwc2_core_is_highspeed (dwc2 , TUSB_ROLE_DEVICE );
393404 const bool is_dma = dma_device_enabled (dwc2 );
@@ -505,7 +516,7 @@ void dcd_sof_enable(uint8_t rhport, bool en) {
505516 (void ) rhport ;
506517 dwc2_regs_t * dwc2 = DWC2_REG (rhport );
507518
508- _sof_en = en ;
519+ _dcd_data . sof_en = en ;
509520
510521 if (en ) {
511522 dwc2 -> gintsts = GINTSTS_SOF ;
@@ -530,7 +541,7 @@ void dcd_edpt_close_all(uint8_t rhport) {
530541 dwc2_regs_t * dwc2 = DWC2_REG (rhport );
531542 uint8_t const ep_count = _dwc2_controller [rhport ].ep_count ;
532543
533- _allocated_ep_in_count = 1 ;
544+ _dcd_data . allocated_epin_count = 1 ;
534545
535546 // Disable non-control interrupt
536547 dwc2 -> daintmsk = (1 << DAINTMSK_OEPM_Pos ) | (1 << DAINTMSK_IEPM_Pos );
@@ -574,7 +585,7 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t to
574585
575586 // EP0 can only handle one packet
576587 if (epnum == 0 ) {
577- ep0_pending [dir ] = total_bytes ;
588+ _dcd_data . ep0_pending [dir ] = total_bytes ;
578589 }
579590
580591 // Schedule packets to be sent within interrupt
@@ -640,8 +651,8 @@ static void handle_bus_reset(uint8_t rhport) {
640651
641652 tu_memclr (xfer_status , sizeof (xfer_status ));
642653
643- _sof_en = false;
644- _allocated_ep_in_count = 1 ;
654+ _dcd_data . sof_en = false;
655+ _dcd_data . allocated_epin_count = 1 ;
645656
646657 // 1. NAK for all OUT endpoints
647658 for (uint8_t n = 0 ; n < ep_count ; n ++ ) {
@@ -745,8 +756,8 @@ static void handle_rxflvl_irq(uint8_t rhport) {
745756 case GRXSTS_PKTSTS_SETUP_RX :
746757 // Setup packet received
747758 // We can receive up to three setup packets in succession, but only the last one is valid.
748- _setup_packet [0 ] = (* rx_fifo );
749- _setup_packet [1 ] = (* rx_fifo );
759+ _dcd_data . setup_packet [0 ] = (* rx_fifo );
760+ _dcd_data . setup_packet [1 ] = (* rx_fifo );
750761 break ;
751762
752763 case GRXSTS_PKTSTS_SETUP_DONE :
@@ -773,8 +784,8 @@ static void handle_rxflvl_irq(uint8_t rhport) {
773784 if (byte_count < xfer -> max_size ) {
774785 xfer -> total_len -= epout -> tsiz_bm .xfer_size ;
775786 if (epnum == 0 ) {
776- xfer -> total_len -= ep0_pending [TUSB_DIR_OUT ];
777- ep0_pending [TUSB_DIR_OUT ] = 0 ;
787+ xfer -> total_len -= _dcd_data . ep0_pending [TUSB_DIR_OUT ];
788+ _dcd_data . ep0_pending [TUSB_DIR_OUT ] = 0 ;
778789 }
779790 }
780791 }
@@ -793,7 +804,7 @@ static void handle_rxflvl_irq(uint8_t rhport) {
793804
794805static void handle_epout_slave (uint8_t rhport , uint8_t epnum , dwc2_doepint_t doepint_bm ) {
795806 if (doepint_bm .setup_phase_done ) {
796- dcd_event_setup_received (rhport , (uint8_t * ) _setup_packet , true);
807+ dcd_event_setup_received (rhport , (uint8_t * ) _dcd_data . setup_packet , true);
797808 return ;
798809 }
799810
@@ -805,7 +816,7 @@ static void handle_epout_slave(uint8_t rhport, uint8_t epnum, dwc2_doepint_t doe
805816 if (!doepint_bm .status_phase_rx && !doepint_bm .setup_packet_rx ) {
806817 xfer_ctl_t * xfer = XFER_CTL_BASE (epnum , TUSB_DIR_OUT );
807818
808- if ((epnum == 0 ) && ep0_pending [TUSB_DIR_OUT ]) {
819+ if ((epnum == 0 ) && _dcd_data . ep0_pending [TUSB_DIR_OUT ]) {
809820 // EP0 can only handle one packet, Schedule another packet to be received.
810821 edpt_schedule_packets (rhport , epnum , TUSB_DIR_OUT );
811822 } else {
@@ -821,7 +832,7 @@ static void handle_epin_slave(uint8_t rhport, uint8_t epnum, dwc2_diepint_t diep
821832 xfer_ctl_t * xfer = XFER_CTL_BASE (epnum , TUSB_DIR_IN );
822833
823834 if (diepint_bm .xfer_complete ) {
824- if ((epnum == 0 ) && ep0_pending [TUSB_DIR_IN ]) {
835+ if ((epnum == 0 ) && _dcd_data . ep0_pending [TUSB_DIR_IN ]) {
825836 // EP0 can only handle one packet. Schedule another packet to be transmitted.
826837 edpt_schedule_packets (rhport , epnum , TUSB_DIR_IN );
827838 } else {
@@ -869,8 +880,8 @@ static void handle_epout_dma(uint8_t rhport, uint8_t epnum, dwc2_doepint_t doepi
869880
870881 if (doepint_bm .setup_phase_done ) {
871882 dma_setup_prepare (rhport );
872- dcd_dcache_invalidate (_setup_packet , 8 );
873- dcd_event_setup_received (rhport , (uint8_t * ) _setup_packet , true);
883+ dcd_dcache_invalidate (_dcd_data . setup_packet , 8 );
884+ dcd_event_setup_received (rhport , (uint8_t * ) _dcd_data . setup_packet , true);
874885 return ;
875886 }
876887
@@ -879,7 +890,7 @@ static void handle_epout_dma(uint8_t rhport, uint8_t epnum, dwc2_doepint_t doepi
879890 // only handle data skip if it is setup or status related
880891 // Normal OUT transfer complete
881892 if (!doepint_bm .status_phase_rx && !doepint_bm .setup_packet_rx ) {
882- if ((epnum == 0 ) && ep0_pending [TUSB_DIR_OUT ]) {
893+ if ((epnum == 0 ) && _dcd_data . ep0_pending [TUSB_DIR_OUT ]) {
883894 // EP0 can only handle one packet Schedule another packet to be received.
884895 edpt_schedule_packets (rhport , epnum , TUSB_DIR_OUT );
885896 } else {
@@ -907,7 +918,7 @@ static void handle_epin_dma(uint8_t rhport, uint8_t epnum, dwc2_diepint_t diepin
907918 xfer_ctl_t * xfer = XFER_CTL_BASE (epnum , TUSB_DIR_IN );
908919
909920 if (diepint_bm .xfer_complete ) {
910- if ((epnum == 0 ) && ep0_pending [TUSB_DIR_IN ]) {
921+ if ((epnum == 0 ) && _dcd_data . ep0_pending [TUSB_DIR_IN ]) {
911922 // EP0 can only handle one packet. Schedule another packet to be transmitted.
912923 edpt_schedule_packets (rhport , epnum , TUSB_DIR_IN );
913924 } else {
@@ -1007,7 +1018,7 @@ void dcd_int_handler(uint8_t rhport) {
10071018
10081019 if (gintsts & GINTSTS_OTGINT ) {
10091020 // OTG INT bit is read-only
1010- uint32_t const otg_int = dwc2 -> gotgint ;
1021+ const uint32_t otg_int = dwc2 -> gotgint ;
10111022
10121023 if (otg_int & GOTGINT_SEDET ) {
10131024 dcd_event_bus_signal (rhport , DCD_EVENT_UNPLUGGED , true);
@@ -1021,7 +1032,7 @@ void dcd_int_handler(uint8_t rhport) {
10211032 const uint32_t frame = (dwc2 -> dsts & DSTS_FNSOF ) >> DSTS_FNSOF_Pos ;
10221033
10231034 // Disable SOF interrupt if SOF was not explicitly enabled since SOF was used for remote wakeup detection
1024- if (!_sof_en ) {
1035+ if (!_dcd_data . sof_en ) {
10251036 dwc2 -> gintmsk &= ~GINTMSK_SOFM ;
10261037 }
10271038
0 commit comments