Fast / non-blocking SPI using interrupts
Posted: Mon May 11, 2020 3:51 pm
Hi,
I was looking for a way to send SPI data almost continuously without blocking the CPU. I usually use PlatformIO / Arduino SDK for developing and its SPI class only supports blocking writes for SPI. I also couldn't find any usable code in the RTOS SDK. So I wrote my own:
https://github.com/xsrf/nbSPI
Basically, it fills the SPI buffer with up to 64 Bytes of data and sends it. If more data must be sent, it enables the TRANSMISSION_END Interrupt and uses it to refill the buffer.
I'd appreciate your thoughts about this
I'm not at all sure if I'm handling the interrupts correct. As far as I did understand, interrupts for SPI1 and SPI0 trigger the same ISR.
I'm actually ignoring and clearing Interrupts for SPI0. Could this cause problems? So far it works...
See https://github.com/xsrf/nbSPI/issues/1
I was looking for a way to send SPI data almost continuously without blocking the CPU. I usually use PlatformIO / Arduino SDK for developing and its SPI class only supports blocking writes for SPI. I also couldn't find any usable code in the RTOS SDK. So I wrote my own:
https://github.com/xsrf/nbSPI
Basically, it fills the SPI buffer with up to 64 Bytes of data and sends it. If more data must be sent, it enables the TRANSMISSION_END Interrupt and uses it to refill the buffer.
I'd appreciate your thoughts about this
I'm not at all sure if I'm handling the interrupts correct. As far as I did understand, interrupts for SPI1 and SPI0 trigger the same ISR.
I'm actually ignoring and clearing Interrupts for SPI0. Could this cause problems? So far it works...
See https://github.com/xsrf/nbSPI/issues/1
Code: Select all
ICACHE_RAM_ATTR void nbSPI_ISR() {
if(SPIIR & (1 << SPII0)) {
// SPI0 Interrupt
SPI0S &= ~(0x1F); // Disable and clear all interrupts on SPI0
}
if(SPIIR & (1 << SPII1)) {
// SPI1 Interrupt
SPI1S &= ~(0x1F); // Disable and clear all interrupts on SPI1
nbSPI_writeChunk(); // Write remaining data
}
}