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 <damien@micropython.org>
This commit is contained in:
parent
2531a15200
commit
f53ee9f12b
|
@ -474,6 +474,7 @@ target_compile_definitions(${MICROPY_TARGET} PRIVATE
|
|||
PICO_FLOAT_PROPAGATE_NANS=1
|
||||
PICO_STACK_SIZE=0x2000
|
||||
PICO_CORE1_STACK_SIZE=0
|
||||
PICO_MAX_SHARED_IRQ_HANDLERS=8 # we need more than the default
|
||||
PICO_PROGRAM_NAME="MicroPython"
|
||||
PICO_NO_PROGRAM_VERSION_STRING=1 # do it ourselves in main.c
|
||||
MICROPY_BUILD_TYPE="${CMAKE_C_COMPILER_ID} ${CMAKE_C_COMPILER_VERSION} ${CMAKE_BUILD_TYPE}"
|
||||
|
|
|
@ -232,20 +232,18 @@ STATIC void feed_dma(machine_i2s_obj_t *self, uint8_t *dma_buffer_p) {
|
|||
|
||||
STATIC void irq_configure(machine_i2s_obj_t *self) {
|
||||
if (self->i2s_id == 0) {
|
||||
irq_set_exclusive_handler(DMA_IRQ_0, dma_irq0_handler);
|
||||
irq_add_shared_handler(DMA_IRQ_0, dma_irq0_handler, PICO_SHARED_IRQ_HANDLER_DEFAULT_ORDER_PRIORITY);
|
||||
irq_set_enabled(DMA_IRQ_0, true);
|
||||
} else {
|
||||
irq_set_exclusive_handler(DMA_IRQ_1, dma_irq1_handler);
|
||||
irq_add_shared_handler(DMA_IRQ_1, dma_irq1_handler, PICO_SHARED_IRQ_HANDLER_DEFAULT_ORDER_PRIORITY);
|
||||
irq_set_enabled(DMA_IRQ_1, true);
|
||||
}
|
||||
}
|
||||
|
||||
STATIC void irq_deinit(machine_i2s_obj_t *self) {
|
||||
if (self->i2s_id == 0) {
|
||||
irq_set_enabled(DMA_IRQ_0, false);
|
||||
irq_remove_handler(DMA_IRQ_0, dma_irq0_handler);
|
||||
} else {
|
||||
irq_set_enabled(DMA_IRQ_1, false);
|
||||
irq_remove_handler(DMA_IRQ_1, dma_irq1_handler);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -98,18 +98,16 @@ STATIC uint32_t rp2_dma_register_value_from_obj(mp_obj_t o, int reg_type) {
|
|||
STATIC void rp2_dma_irq_handler(void) {
|
||||
// Main IRQ handler
|
||||
uint32_t irq_bits = dma_hw->ints0;
|
||||
dma_hw->ints0 = 0xffff;
|
||||
|
||||
for (int i = 0; i < NUM_DMA_CHANNELS; i++) {
|
||||
if (irq_bits & (1u << i)) {
|
||||
mp_irq_obj_t *handler = MP_STATE_PORT(rp2_dma_irq_obj[i]);
|
||||
if (handler) {
|
||||
// An rp2.DMA IRQ handler is registered for this channel, so handle it.
|
||||
dma_channel_acknowledge_irq0(i);
|
||||
rp2_dma_obj_t *self = (rp2_dma_obj_t *)handler->parent;
|
||||
self->irq_flag = 1;
|
||||
mp_irq_handler(handler);
|
||||
} else {
|
||||
// We got an interrupt with no handler. Disable the channel
|
||||
dma_channel_set_irq0_enabled(i, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
|||
if (irq == NULL) {
|
||||
irq = mp_irq_new(&rp2_dma_irq_methods, MP_OBJ_FROM_PTR(self));
|
||||
MP_STATE_PORT(rp2_dma_irq_obj[self->channel]) = irq;
|
||||
|
||||
// Clear any existing IRQs on this DMA channel, they are not for us.
|
||||
dma_channel_acknowledge_irq0(self->channel);
|
||||
}
|
||||
|
||||
if (n_args > 1 || kw_args->used != 0) {
|
||||
|
@ -457,12 +458,11 @@ MP_DEFINE_CONST_OBJ_TYPE(
|
|||
void rp2_dma_init(void) {
|
||||
// Set up interrupts.
|
||||
memset(MP_STATE_PORT(rp2_dma_irq_obj), 0, sizeof(MP_STATE_PORT(rp2_dma_irq_obj)));
|
||||
irq_set_exclusive_handler(DMA_IRQ_0, rp2_dma_irq_handler);
|
||||
irq_add_shared_handler(DMA_IRQ_0, rp2_dma_irq_handler, PICO_SHARED_IRQ_HANDLER_DEFAULT_ORDER_PRIORITY);
|
||||
}
|
||||
|
||||
void rp2_dma_deinit(void) {
|
||||
// Disable and clear interrupts.
|
||||
irq_set_mask_enabled(1u << DMA_IRQ_0, false);
|
||||
// Remove our interrupt handler.
|
||||
irq_remove_handler(DMA_IRQ_0, rp2_dma_irq_handler);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue