21
21
#include " SPI.h"
22
22
#include < hardware/spi.h>
23
23
#include < hardware/gpio.h>
24
+ #include < hardware/structs/iobank0.h>
25
+ #include < hardware/irq.h>
24
26
25
27
#ifdef USE_TINYUSB
26
28
// For Serial when selecting TinyUSB. Can't include in the core because Arduino IDE
@@ -191,10 +193,33 @@ void SPIClassRP2040::beginTransaction(SPISettings settings) {
191
193
DEBUGSPI (" SPI: actual baudrate=%u\n " , spi_get_baudrate (_spi));
192
194
_initted = true ;
193
195
}
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 ]);
194
210
}
195
211
196
212
void SPIClassRP2040::endTransaction (void ) {
197
213
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 ]);
198
223
}
199
224
200
225
bool SPIClassRP2040::setRX (pin_size_t pin) {
@@ -292,6 +317,7 @@ void SPIClassRP2040::begin(bool hwCS) {
292
317
gpio_set_function (_TX, GPIO_FUNC_SPI);
293
318
// Give a default config in case user doesn't use beginTransaction
294
319
beginTransaction (_spis);
320
+ endTransaction ();
295
321
}
296
322
297
323
void SPIClassRP2040::end () {
@@ -312,11 +338,13 @@ void SPIClassRP2040::end() {
312
338
void SPIClassRP2040::setBitOrder (BitOrder order) {
313
339
_spis = SPISettings (_spis.getClockFreq (), order, _spis.getDataMode ());
314
340
beginTransaction (_spis);
341
+ endTransaction ();
315
342
}
316
343
317
344
void SPIClassRP2040::setDataMode (uint8_t uc_mode) {
318
345
_spis = SPISettings (_spis.getClockFreq (), _spis.getBitOrder (), uc_mode);
319
346
beginTransaction (_spis);
347
+ endTransaction ();
320
348
}
321
349
322
350
void SPIClassRP2040::setClockDivider (uint8_t uc_div) {
0 commit comments