INTEGRATING MULTIPLE SPI LIBRARIES
The initial Cosa SPI class extended the Arduino SPI library with SPI/USI bus controller, slave device support, interrupt handling and a rich set of functions for typical SPI device interaction. Unfortunately it did not address one of the more important SPI issues.
On this forum there are a number of requests for support with integrating several SPI devices/libraries. The problem is often that the devices have different SPI bus usage, e.g. different speed, bit order, mode, etc, resulting in conflicts and confusion. Each library will work perfectly on its own but not together. Most of these support requests end with a recommendation to use SoftSPI and avoid the problem by using more pins. There are also very few SPI device libraries that use interrupts and do not work very well in low power applications as they require polling.
What are the requirements on the SPI library? Obviously it should be able to handle multiple devices with different settings. It should also support chip select and interrupt signals. Be available for both ATmega and ATtiny, i.e., SPI and USI hardware modules and allow replacement with a bit-banging version when needed through simple configuration.
As the TWI/Wire the functions begin() and end() should be used to define an SPI interaction block. The current usage in the Arduino SPI library is more or less a setup. Most SPI device libraries assume that there is only one device on the bus.
Addressing the interrupt issue is especially interesting as the interrupt handle will want to perform SPI transfers (read/write) to at least check the interrupt status register in the serviced device. Without special care this gives concurrency problems as an interrupt could be issued during an ongoing SPI transaction. This becomes even more challenging if the interrupt is issued from another SPI device on the same bus. Simply disabling interrupts is not a very good idea as this may affect other concurrent activities such as incoming data in other hardware modules (TWI, UART, etc).
The design must support architectures with multiple SPI bus controllers.
The ongoing Cosa SPI redesign tries to address the above issues and attempts to meet the requirements.
The design so far has resulted in the evolution of the initial SPI::Driver root class to hold the context of the SPI hardware (SPI control register) and chip select pin (OutputPin) so that spi.begin()---spi.end() will perform
- loading of the SPI hardware state,
- toggling the chip select pin,
- disabling interrupt handlers to allow mutual exclusive access.
- handle the clock pin polarity for ATtiny/USI implementation to achieve all four SPI modes
The ripple effect is a major update of the Cosa's SPI device driver. Which then results in a large batch of regression testing before pushing the update.