2121#include " SPI.h"
2222#include < hardware/spi.h>
2323#include < hardware/gpio.h>
24+ #include < hardware/structs/iobank0.h>
25+ #include < hardware/irq.h>
2426
2527#ifdef USE_TINYUSB
2628// For Serial when selecting TinyUSB. Can't include in the core because Arduino IDE
@@ -191,10 +193,33 @@ void SPIClassRP2040::beginTransaction(SPISettings settings) {
191193 DEBUGSPI (" SPI: actual baudrate=%u\n " , spi_get_baudrate (_spi));
192194 _initted = true ;
193195 }
196+ // Disable any IRQs that are being used for SPI
197+ io_irq_ctrl_hw_t *irq_ctrl_base = get_core_num () ? &iobank0_hw->proc1_irq_ctrl : &iobank0_hw->proc0_irq_ctrl ;
198+ DEBUGSPI (" SPI: IRQ masks before = %08x %08x %08x %08x\n " , (unsigned )irq_ctrl_base->inte [0 ], (unsigned )irq_ctrl_base->inte [1 ], (unsigned )irq_ctrl_base->inte [2 ], (unsigned )irq_ctrl_base->inte [3 ]);
199+ for (auto entry : _usingIRQs) {
200+ int gpio = entry.first ;
201+
202+ // There is no gpio_get_irq, so manually twiddle the register
203+ io_rw_32 *en_reg = &irq_ctrl_base->inte [gpio / 8 ];
204+ uint32_t val = ((*en_reg) >> (4 * (gpio % 8 ))) & 0xf ;
205+ _usingIRQs.insert_or_assign (gpio, val);
206+ DEBUGSPI (" SPI: GPIO %d = %d\n " , gpio, val);
207+ (*en_reg) ^= val << (4 * (gpio % 8 ));
208+ }
209+ DEBUGSPI (" SPI: IRQ masks after = %08x %08x %08x %08x\n " , (unsigned )irq_ctrl_base->inte [0 ], (unsigned )irq_ctrl_base->inte [1 ], (unsigned )irq_ctrl_base->inte [2 ], (unsigned )irq_ctrl_base->inte [3 ]);
194210}
195211
196212void SPIClassRP2040::endTransaction (void ) {
197213 DEBUGSPI (" SPI::endTransaction()\n " );
214+ // Re-enablke IRQs
215+ for (auto entry : _usingIRQs) {
216+ int gpio = entry.first ;
217+ int mode = entry.second ;
218+ gpio_set_irq_enabled (gpio, mode, true );
219+ }
220+ io_irq_ctrl_hw_t *irq_ctrl_base = get_core_num () ? &iobank0_hw->proc1_irq_ctrl : &iobank0_hw->proc0_irq_ctrl ;
221+ (void ) irq_ctrl_base;
222+ DEBUGSPI (" SPI: IRQ masks = %08x %08x %08x %08x\n " , (unsigned )irq_ctrl_base->inte [0 ], (unsigned )irq_ctrl_base->inte [1 ], (unsigned )irq_ctrl_base->inte [2 ], (unsigned )irq_ctrl_base->inte [3 ]);
198223}
199224
200225bool SPIClassRP2040::setRX (pin_size_t pin) {
@@ -292,6 +317,7 @@ void SPIClassRP2040::begin(bool hwCS) {
292317 gpio_set_function (_TX, GPIO_FUNC_SPI);
293318 // Give a default config in case user doesn't use beginTransaction
294319 beginTransaction (_spis);
320+ endTransaction ();
295321}
296322
297323void SPIClassRP2040::end () {
@@ -312,11 +338,13 @@ void SPIClassRP2040::end() {
312338void SPIClassRP2040::setBitOrder (BitOrder order) {
313339 _spis = SPISettings (_spis.getClockFreq (), order, _spis.getDataMode ());
314340 beginTransaction (_spis);
341+ endTransaction ();
315342}
316343
317344void SPIClassRP2040::setDataMode (uint8_t uc_mode) {
318345 _spis = SPISettings (_spis.getClockFreq (), _spis.getBitOrder (), uc_mode);
319346 beginTransaction (_spis);
347+ endTransaction ();
320348}
321349
322350void SPIClassRP2040::setClockDivider (uint8_t uc_div) {
0 commit comments