Additional multicore fixes, BOOTSEL and PIO (#123)

BOOTSEL needs to be multicore protected, too.
Reading BOOTSEL required disabling the flash interface, so the other
core needs to be idles while this runs.

Make the PIO program object multicore safe, too, so that if both cores
try to load a program they won't step on each other.
This commit is contained in:
Earle F. Philhower, III 2021-05-07 16:03:21 -07:00 committed by GitHub
parent 2da190f5b4
commit 763846aee8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 10 additions and 3 deletions

View file

@ -26,7 +26,8 @@ static bool __no_inline_not_in_flash_func(get_bootsel_button)() {
// Must disable interrupts, as interrupt handlers may be in flash, and we // Must disable interrupts, as interrupt handlers may be in flash, and we
// are about to temporarily disable flash access! // are about to temporarily disable flash access!
uint32_t flags = save_and_disable_interrupts(); noInterrupts();
rp2040.idleOtherCore();
// Set chip select to Hi-Z // Set chip select to Hi-Z
hw_write_masked(&ioqspi_hw->io[CS_PIN_INDEX].ctrl, hw_write_masked(&ioqspi_hw->io[CS_PIN_INDEX].ctrl,
@ -46,7 +47,8 @@ static bool __no_inline_not_in_flash_func(get_bootsel_button)() {
GPIO_OVERRIDE_NORMAL << IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_LSB, GPIO_OVERRIDE_NORMAL << IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_LSB,
IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_BITS); IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_BITS);
restore_interrupts(flags); interrupts();
rp2040.resumeOtherCore();
return button_state; return button_state;
} }

View file

@ -23,6 +23,7 @@
#include <hardware/pio.h> #include <hardware/pio.h>
#include <pico/multicore.h> #include <pico/multicore.h>
#include <pico/util/queue.h> #include <pico/util/queue.h>
#include <CoreMutex.h>
class _MFIFO { class _MFIFO {
public: public:
@ -132,7 +133,6 @@ public:
extern RP2040 rp2040; extern RP2040 rp2040;
// Wrapper class for PIO programs, abstracting common operations out // Wrapper class for PIO programs, abstracting common operations out
// TODO - Make dualcore safe
// TODO - Add unload/destructor // TODO - Add unload/destructor
class PIOProgram { class PIOProgram {
public: public:
@ -140,6 +140,8 @@ public:
// Possibly load into a PIO and allocate a SM // Possibly load into a PIO and allocate a SM
bool prepare(PIO *pio, int *sm, int *offset) { bool prepare(PIO *pio, int *sm, int *offset) {
extern mutex_t _pioMutex;
CoreMutex m(&_pioMutex);
// Is there an open slot to run in, first? // Is there an open slot to run in, first?
if (!_findFreeSM(pio, sm)) return false; if (!_findFreeSM(pio, sm)) return false;
// Is it loaded on that PIO? // Is it loaded on that PIO?

View file

@ -26,6 +26,9 @@ RP2040 rp2040;
volatile bool _MFIFO::_otherIdled = false; volatile bool _MFIFO::_otherIdled = false;
auto_init_mutex(_pioMutex);
extern void setup(); extern void setup();
extern void loop(); extern void loop();