Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f53ee9f

Browse files
committed
rp2: Change machine.I2S and rp2.DMA to use shared DMA IRQ handlers.
These separate drivers must share the DMA resource with each other. Fixes issue #13380. Signed-off-by: Damien George <[email protected]>
1 parent 2531a15 commit f53ee9f

File tree

3 files changed

+10
-11
lines changed

3 files changed

+10
-11
lines changed

ports/rp2/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,7 @@ target_compile_definitions(${MICROPY_TARGET} PRIVATE
474474
PICO_FLOAT_PROPAGATE_NANS=1
475475
PICO_STACK_SIZE=0x2000
476476
PICO_CORE1_STACK_SIZE=0
477+
PICO_MAX_SHARED_IRQ_HANDLERS=8 # we need more than the default
477478
PICO_PROGRAM_NAME="MicroPython"
478479
PICO_NO_PROGRAM_VERSION_STRING=1 # do it ourselves in main.c
479480
MICROPY_BUILD_TYPE="${CMAKE_C_COMPILER_ID} ${CMAKE_C_COMPILER_VERSION} ${CMAKE_BUILD_TYPE}"

ports/rp2/machine_i2s.c

+2-4
Original file line numberDiff line numberDiff line change
@@ -232,20 +232,18 @@ STATIC void feed_dma(machine_i2s_obj_t *self, uint8_t *dma_buffer_p) {
232232

233233
STATIC void irq_configure(machine_i2s_obj_t *self) {
234234
if (self->i2s_id == 0) {
235-
irq_set_exclusive_handler(DMA_IRQ_0, dma_irq0_handler);
235+
irq_add_shared_handler(DMA_IRQ_0, dma_irq0_handler, PICO_SHARED_IRQ_HANDLER_DEFAULT_ORDER_PRIORITY);
236236
irq_set_enabled(DMA_IRQ_0, true);
237237
} else {
238-
irq_set_exclusive_handler(DMA_IRQ_1, dma_irq1_handler);
238+
irq_add_shared_handler(DMA_IRQ_1, dma_irq1_handler, PICO_SHARED_IRQ_HANDLER_DEFAULT_ORDER_PRIORITY);
239239
irq_set_enabled(DMA_IRQ_1, true);
240240
}
241241
}
242242

243243
STATIC void irq_deinit(machine_i2s_obj_t *self) {
244244
if (self->i2s_id == 0) {
245-
irq_set_enabled(DMA_IRQ_0, false);
246245
irq_remove_handler(DMA_IRQ_0, dma_irq0_handler);
247246
} else {
248-
irq_set_enabled(DMA_IRQ_1, false);
249247
irq_remove_handler(DMA_IRQ_1, dma_irq1_handler);
250248
}
251249
}

ports/rp2/rp2_dma.c

+7-7
Original file line numberDiff line numberDiff line change
@@ -98,18 +98,16 @@ STATIC uint32_t rp2_dma_register_value_from_obj(mp_obj_t o, int reg_type) {
9898
STATIC void rp2_dma_irq_handler(void) {
9999
// Main IRQ handler
100100
uint32_t irq_bits = dma_hw->ints0;
101-
dma_hw->ints0 = 0xffff;
102101

103102
for (int i = 0; i < NUM_DMA_CHANNELS; i++) {
104103
if (irq_bits & (1u << i)) {
105104
mp_irq_obj_t *handler = MP_STATE_PORT(rp2_dma_irq_obj[i]);
106105
if (handler) {
106+
// An rp2.DMA IRQ handler is registered for this channel, so handle it.
107+
dma_channel_acknowledge_irq0(i);
107108
rp2_dma_obj_t *self = (rp2_dma_obj_t *)handler->parent;
108109
self->irq_flag = 1;
109110
mp_irq_handler(handler);
110-
} else {
111-
// We got an interrupt with no handler. Disable the channel
112-
dma_channel_set_irq0_enabled(i, false);
113111
}
114112
}
115113
}
@@ -389,6 +387,9 @@ STATIC mp_obj_t rp2_dma_irq(size_t n_args, const mp_obj_t *pos_args, mp_map_t *k
389387
if (irq == NULL) {
390388
irq = mp_irq_new(&rp2_dma_irq_methods, MP_OBJ_FROM_PTR(self));
391389
MP_STATE_PORT(rp2_dma_irq_obj[self->channel]) = irq;
390+
391+
// Clear any existing IRQs on this DMA channel, they are not for us.
392+
dma_channel_acknowledge_irq0(self->channel);
392393
}
393394

394395
if (n_args > 1 || kw_args->used != 0) {
@@ -457,12 +458,11 @@ MP_DEFINE_CONST_OBJ_TYPE(
457458
void rp2_dma_init(void) {
458459
// Set up interrupts.
459460
memset(MP_STATE_PORT(rp2_dma_irq_obj), 0, sizeof(MP_STATE_PORT(rp2_dma_irq_obj)));
460-
irq_set_exclusive_handler(DMA_IRQ_0, rp2_dma_irq_handler);
461+
irq_add_shared_handler(DMA_IRQ_0, rp2_dma_irq_handler, PICO_SHARED_IRQ_HANDLER_DEFAULT_ORDER_PRIORITY);
461462
}
462463

463464
void rp2_dma_deinit(void) {
464-
// Disable and clear interrupts.
465-
irq_set_mask_enabled(1u << DMA_IRQ_0, false);
465+
// Remove our interrupt handler.
466466
irq_remove_handler(DMA_IRQ_0, rp2_dma_irq_handler);
467467
}
468468

0 commit comments

Comments
 (0)