I’ve noticed that lv_micropython firmware for RP2040 does not support DMA (the SPI interface uses DMA for data transfer, but only in blocking mode). Also, there is no DMA IRQ support. So I modified the MicroPython source code (files: ports/rp2/machine_spi.c and extmod/machine_spi.c), but some problems occurred.
What I’ve done
I have added two extra functions to the ports/rp2/machine_spi.c file.
These functions will be used to set the DMA TX IRQ handler and enable the IRQ immediately.
I have tried three different approaches, and the ISR implementations are as follows (I placed cs.High() and flush_ready() inside the ISR):

1. ishard = false, using mp_irq_handler to call
In this scenario, I must call flush_ready() in flush_cb. However, cs.High() is not synchronized with the data—meaning it is called too late. If I remove flush_ready() from flush_cb, the ISR will not be triggered, and MicroPython will get blocked in flush_cb.
2. ishard = true, using mp_irq_handler to call
In this scenario, I must call flush_ready() in flush_cb, and cs.High() is triggered at the correct time. If I remove flush_ready() from flush_cb, the ISR will not be triggered, and MicroPython will get blocked in flush_cb.
3. ishard = true, using mp_call_function_1 to call (this means mp_sched_lock() and gc_lock() are not invoked)
In this scenario, flush_ready() and cs.High() are triggered at the correct time. However, MicroPython will stop responding after a few times.
Question
What happened, and how can I fix it? I think using mp_call_function_1 (without invoking mp_sched_lock() and gc_lock()) should be the correct approach, but it only works a few times.
Here you can find what I’ve done in micropython code:
http://fnos.feng-arch.cn:35128/fengqi/lv_micropython/pulls/1/files#diff-145b98f48b64fc48faaf3a8ef0f659962c5e319b
