Skip to content

Commit c61b55b

Browse files
committed
dcd wrap data to dcd_data_t, add padding for setup_packet to match cache line size
1 parent b3b8bd8 commit c61b55b

File tree

1 file changed

+57
-46
lines changed

1 file changed

+57
-46
lines changed

src/portable/synopsys/dwc2/dcd_dwc2.c

Lines changed: 57 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,6 @@
4646
//--------------------------------------------------------------------+
4747
// MACRO TYPEDEF CONSTANT ENUM
4848
//--------------------------------------------------------------------+
49-
static CFG_TUD_MEM_SECTION CFG_TUD_MEM_ALIGN uint32_t _setup_packet[2];
50-
5149
typedef struct {
5250
uint8_t* buffer;
5351
tu_fifo_t* ff;
@@ -59,15 +57,26 @@ typedef struct {
5957
static 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
167176
static 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

794805
static 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

Comments
 (0)