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>
pull/13555/head
Damien George 2024-01-30 12:28:30 +11:00
rodzic d19371cb23
commit 807c25d05a
3 zmienionych plików z 10 dodań i 11 usunięć

Wyświetl plik

@ -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}"

Wyświetl plik

@ -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);
}
}

Wyświetl plik

@ -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);
}