Skip to content

Instantly share code, notes, and snippets.

@jepler
Created February 10, 2025 20:09
Show Gist options
  • Save jepler/07ea94a52525547351fa6221c2cfdf07 to your computer and use it in GitHub Desktop.
Save jepler/07ea94a52525547351fa6221c2cfdf07 to your computer and use it in GitHub Desktop.
diff --git a/ports/raspberrypi/common-hal/microcontroller/__init__.c b/ports/raspberrypi/common-hal/microcontroller/__init__.c
index 7911c21e3c..971c1db9ef 100644
--- a/ports/raspberrypi/common-hal/microcontroller/__init__.c
+++ b/ports/raspberrypi/common-hal/microcontroller/__init__.c
@@ -23,11 +23,13 @@
#include "src/rp2_common/hardware_sync/include/hardware/sync.h"
#include "hardware/watchdog.h"
+#include "hardware/irq.h"
void common_hal_mcu_delay_us(uint32_t delay) {
mp_hal_delay_us(delay);
}
+#ifdef PICO_RP2040
volatile uint32_t nesting_count = 0;
void common_hal_mcu_disable_interrupts(void) {
// We don't use save_and_disable_interrupts() from the sdk because we don't want to worry about PRIMASK.
@@ -48,6 +50,40 @@ void common_hal_mcu_enable_interrupts(void) {
__dmb();
asm volatile ("cpsie i" : : : "memory");
}
+#else
+#include "src/rp2_common/cmsis/stub/CMSIS/Device/RP2350/Include/RP2350.h"
+// on rp2350 we must keep DMA_IRQ_1 (reserved for pico dvi) enabled at all
+// times, including during flash writes. Do this by setting the priority mask
+// (BASEPRI register)
+#define PICO_ELEVATED_IRQ_PRIORITY (0x60) // between PICO_DEFAULT and PIOCO_HIGHEST_IRQ_PRIORITY
+volatile uint32_t nesting_count = 0;
+static uint32_t oldBasePri = PICO_LOWEST_IRQ_PRIORITY;
+void common_hal_mcu_disable_interrupts(void) {
+ // This is what we do on the SAMD21 via CMSIS.
+ if (nesting_count == 0) {
+ // grab old base priority
+ oldBasePri = __get_BASEPRI();
+ // and set the new one
+ __set_BASEPRI_MAX(PICO_ELEVATED_IRQ_PRIORITY);
+ __isb(); // Instruction synchronization barrier
+ }
+ nesting_count++;
+}
+
+void common_hal_mcu_enable_interrupts(void) {
+ uint32_t my_interrupts = save_and_disable_interrupts();
+ if (nesting_count == 0) {
+ reset_into_safe_mode(SAFE_MODE_INTERRUPT_ERROR);
+ }
+ nesting_count--;
+ if (nesting_count == 0) {
+ // return to the old priority setting
+ __set_BASEPRI(oldBasePri);
+ __isb(); // Instruction synchronization barrier
+ }
+ restore_interrupts(my_interrupts);
+}
+#endif
static bool next_reset_to_bootloader = false;
diff --git a/ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c b/ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c
index c3d2b7bea2..44636bf68d 100644
--- a/ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c
+++ b/ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c
@@ -430,6 +430,7 @@ void common_hal_picodvi_framebuffer_construct(picodvi_framebuffer_obj_t *self,
dma_hw->inte1 = (1u << self->dma_pixel_channel);
irq_set_exclusive_handler(DMA_IRQ_1, dma_irq_handler);
irq_set_enabled(DMA_IRQ_1, true);
+ irq_set_priority(DMA_IRQ_1, PICO_HIGHEST_IRQ_PRIORITY);
bus_ctrl_hw->priority = BUSCTRL_BUS_PRIORITY_DMA_W_BITS | BUSCTRL_BUS_PRIORITY_DMA_R_BITS;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment