Projectitis
Well-known member
Hi all,
I've been writing a bunch of cross-platform SPI code, and it's a bit of a pain to have to implement _cont and _last for KINETISK based hardware. It makes the code more complex, and (depending on the situation) often adds an additional compare within a loop.
It also means that in my abstraction layer for non-KINETISK hardware I still have to have a _cont and _last method (e.g. writeData8_cont and writeData8_last) even though they both map to the same underlying method.
My code end up looking like this:
My first question is, can I just use the _cont method the entire time, and then write at the end call _last with NOOP operation (e.g. most displays have a NOOP).
Second question is, is there a way to use SPIClass only, without KINETISK-specific code, and simplify the implementation to make it more cross-platform compatible?
For example, do I need the KINETISK code as below, or can I just use _spi->write(c); or _spi->transfer(d); on Teensy?
Cheers!
Peter
I've been writing a bunch of cross-platform SPI code, and it's a bit of a pain to have to implement _cont and _last for KINETISK based hardware. It makes the code more complex, and (depending on the situation) often adds an additional compare within a loop.
It also means that in my abstraction layer for non-KINETISK hardware I still have to have a _cont and _last method (e.g. writeData8_cont and writeData8_last) even though they both map to the same underlying method.
My code end up looking like this:
Code:
/**
* @brief Write an SPI command
*/
ALWAYS_INLINE void writeCommand(uint8_t c) {
if (_dc != UNUSED_PIN) digitalWrite(_dc, LOW);
_spi->write(c);
if (_dc != UNUSED_PIN) digitalWrite(_dc, HIGH);
}
ALWAYS_INLINE void writeCommand_last(uint8_t c) {
writeCommand(c); // Just map to writeCommand
}
/**
* @brief Write SPI data
*/
ALWAYS_INLINE void writeData8(uint8_t d) {
_spi->write(d);
}
ALWAYS_INLINE void writeData8_last(uint8_t d) {
writeData8(d); // Just map to writeData8
}
ALWAYS_INLINE void writeData16(uint16_t d) {
_spi->write16(d);
}
ALWAYS_INLINE void writeData16_last(uint16_t d) {
writeData16(d); // Just map to writeData16
}
My first question is, can I just use the _cont method the entire time, and then write at the end call _last with NOOP operation (e.g. most displays have a NOOP).
Code:
while (looping_data) writeData8(d);
writeCommand_last(NOOP);
Second question is, is there a way to use SPIClass only, without KINETISK-specific code, and simplify the implementation to make it more cross-platform compatible?
For example, do I need the KINETISK code as below, or can I just use _spi->write(c); or _spi->transfer(d); on Teensy?
Code:
#if defined(KINETISK)
ALWAYS_INLINE void writeCommand(uint8_t c) {
KINETISK_SPI0.PUSHR = c | (_pcs_command << 16) | SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT;
waitFifoNotFull();
}
ALWAYS_INLINE void writeCommand_last(uint8_t c) {
uint32_t mcr = SPI0_MCR;
KINETISK_SPI0.PUSHR = c | (_pcs_command << 16) | SPI_PUSHR_CTAS(0) | SPI_PUSHR_EOQ;
waitTransmitComplete(mcr);
}
// ... etc
Cheers!
Peter