Skip to content

Commit e04f15f

Browse files
authored
Merge pull request hathach#1280 from kasjer/kasjer/nrf5x-dma-race
nrf5x: Fix DMA access race condition
2 parents e188117 + 36b6ed8 commit e04f15f

File tree

1 file changed

+14
-2
lines changed

1 file changed

+14
-2
lines changed

src/portable/nordic/nrf5x/dcd_nrf5x.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ typedef struct
7979

8080
} xfer_td_t;
8181

82+
static osal_mutex_def_t dcd_mutex_def;
83+
static osal_mutex_t dcd_mutex;
84+
8285
// Data for managing dcd
8386
static struct
8487
{
@@ -154,6 +157,7 @@ static void edpt_dma_start(volatile uint32_t* reg_startep)
154157
// Should be safe to blocking wait until previous DMA transfer complete
155158
uint8_t const rhport = 0;
156159
bool started = false;
160+
osal_mutex_lock(dcd_mutex, OSAL_TIMEOUT_WAIT_FOREVER);
157161
while(!started)
158162
{
159163
// LDREX/STREX may be needed in form of std atomic (required C11) or
@@ -170,6 +174,7 @@ static void edpt_dma_start(volatile uint32_t* reg_startep)
170174

171175
// osal_yield();
172176
}
177+
osal_mutex_unlock(dcd_mutex);
173178
}
174179
}
175180

@@ -243,6 +248,7 @@ static void xact_in_dma(uint8_t epnum)
243248
void dcd_init (uint8_t rhport)
244249
{
245250
TU_LOG1("dcd init\r\n");
251+
dcd_mutex = osal_mutex_create(&dcd_mutex_def);
246252
(void) rhport;
247253
}
248254

@@ -457,11 +463,17 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t
457463

458464
xfer_td_t* xfer = get_td(epnum, dir);
459465

460-
dcd_int_disable(rhport);
466+
if (!is_in_isr()) {
467+
osal_mutex_lock(dcd_mutex, OSAL_TIMEOUT_WAIT_FOREVER);
468+
dcd_int_disable(rhport);
469+
}
461470
xfer->buffer = buffer;
462471
xfer->total_len = total_bytes;
463472
xfer->actual_len = 0;
464-
dcd_int_enable(rhport);
473+
if (!is_in_isr()) {
474+
dcd_int_enable(rhport);
475+
osal_mutex_unlock(dcd_mutex);
476+
}
465477

466478
// Control endpoint with zero-length packet and opposite direction to 1st request byte --> status stage
467479
bool const control_status = (epnum == 0 && total_bytes == 0 && dir != tu_edpt_dir(NRF_USBD->BMREQUESTTYPE));

0 commit comments

Comments
 (0)