While I like the idea of remembering settings for different SPI devices on the AVR devices, why does it need another API with begin/end etc?
The extended SPI API for the Due already does this pretty neatly... just pass the desired SS pin # as a reference with setBitOrder, setDataMode and setClockDivider, and store the settings. Then pass the same SS again with each transfer. A quick check in each transfer to see whether the last SS used is the same as the current avoids having to unnecessarily set/reset settings each time if the same device is being used. Then use SPI_CONTINUE and SPI_LAST flags to decide whether to toggle the SS. This way it keeps compatibility with existing libraries too.
C
--
You received this message because you are subscribed to the Google Groups "Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to developers+unsubscribe@arduino.cc.
C
--
You received this message because you are subscribed to the Google Groups "Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to developers+...@arduino.cc.
--
You received this message because you are subscribed to the Google Groups "Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to developers+unsubscribe@arduino.cc.
Thanks for explaining. I thought I was missing something!
Thinking about it more, one thing that bothers me is that this requires the SPI library to know about interrupts (even if not very much), which seems opposed to modularity. For example, you could imagine wanting similar functionality for many other libraries. Also, it makes the SPI library dependent on the interrupt API, e.g. if we added attachPinChangeInterrupt(), we'd also need to add SPI.usingPinChangeInterrupt(), etc. (Yes, you could do attachInterrupt(PINCHANGE0) instead, but this is same problem in reverse: the interrupt API is then being constrained by the fact that the SPI library depends on it.) Of course, it's good to solve the problems that people are actually running into (and I believe you, Paul, that these are mostly with SPI) but it would be good to do it in a more general way.
One idea would be for the SPI library to set a flag when it's in a transaction, so that you could code your ISR to refrain from using SPI if there's a transaction in progress, e.g.
void myInterruptHandler(){if (SPI.isTransmitting()) return;
// ...}
Or do the actual use cases require the interrupt to be buffered until the current SPI transaction completes?
Another thought is that the typical way for one module to do something (in a flexible way) based on actions in another module is using events. So, for example, a library that uses SPI inside an ISR could do something like:
void BLE::begin(){attachInterrupt(0, bleReceive);SPI.onBeginTransaction(disableInterrupt0);SPI.onEndTransaction(enableInterrupt0);// ...}
void disableInterrupt0() { disableInterrupt(0); }void enableInterrupt0() { enableInterrupt(0); }
I know this is more verbose than simply calling SPI.usingInterrupt(0), but it seems much more flexible and modular.
Anyway, just throwing some ideas out there. What do you think?
David
On Tue, Apr 15, 2014 at 3:55 PM, Paul Stoffregen <pa...@pjrc.com> wrote:
On 04/15/2014 10:06 AM, Cristian Maglie wrote:Yes, a perfect summary of the interrupt awareness feature!
Exactly, the idea is that Library B decalares to the SPI library that he uses
SPI bus inside ISRx, so it's SPI lib that disable ISRx every time a
transcation is started (by A or B or anyone else), to guarantee that the
transaction itself is not corrupted.
With this feature, and always establishing the correct setting at the beginning of each transaction, my hope is to make all SPI-using libraries "just work" together. Of course, there's a caveat that an extremely long transaction could delay an interrupt, but I believe this approach will give the maximum possible compatibility between existing libraries.
This conversation clearly shows there's a great desire to add more features to the SPI library. I'm not opposed to adding features, but I'm personally not very interested in doing so. My main interest is making the many library combinations that today fail work together as seamlessly as possible. I believe limiting the scope of a software project greatly improves the odds of success, so my hope is to focus only on this compatibility problem. More features can always be added as a separate effort.
These SPI sharing failures are driving people away from the Arduino platform, to Linux and complex RTOS systems (or just giving up), for increasingly common needs, such as using SD card storage and Bluetooth LE together in the same project. I really want to solve this problem, and start submitting patches to the main SPI-based libraries, so Arduino can be a viable platform for these projects that use multiple SPI devices with libraries from different 3rd party developers.
--
You received this message because you are subscribed to the Google Groups "Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to developers+...@arduino.cc.
--
You received this message because you are subscribed to the Google Groups "Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to developers+...@arduino.cc.
Paul,
I just want to throw in my support for your proposal. It's becoming an increasingly urgent problem we are facing as we try and integrate more SPI peripherals.
Cheers,
Vic
--
You received this message because you are subscribed to the Google Groups "Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to developers+...@arduino.cc.
Thanks Paul for the encouraging words.On 04/18/2014 10:01 PM, Paul Stoffregen wrote:
Mikael, your Cosa project is truly beautiful. I've read source code from many projects and nearly all widely used Arduino libraries. Rarely have I see APIs and implementations with elegance even approaching Cosa.
I really like how you've provided a room() function. Arduino really needs something like that!
Over the last few days I've put quite a bit of time into analyzing how several existing libraries really use SPI. The more I look into this, the more I believe SPI chip select should have its own API rather than being rolled into the transaction level.
For example, Ethernet involves many small transfers that require separate assertions of SS. Even just reading a 16 bit register on the W5100 chip requires two sets of 4 byte transfers. There are places where a 16 bit register is read repeatedly until 2 consecutive readings agree, to guard against reading the MSB and LSB from different values. Maybe these should be single transactions, even though they involve asserting the SS pin several times?
Really, I'm asking here. I'm still studying how several libraries really work and where indivisible SPI transactions really make sense.
The chip select pin is a valid part of the SPI::Driver base class so it is fine for the driver to assert the pin as many times as needed within the transaction block.
BW: The W5100 Ethernet chip is a marvel of inefficient SPI ;-).
Yet another example is the shift register LCD adapter which requires a pulse at the end of the transaction. The eight bit write to the LCD even has a pulse in the "middle" of the transaction.
https://github.com/mikaelpatel/Cosa/blob/master/cores/cosa/Cosa/LCD/Driver/HD44780_IO_SR3WSPI.cpp#L50
/** Chip select pulse width;* 0 for active low logic during the transaction,* 1 for active high logic,* 2 pulse on end of transaction.*/uint8_t m_pulse;
I have followed this discussion and it is really a good example of the sharing of ideas within the Arduino community. Great inspiration!Really, I'm asking here. I'm still studying how several libraries really work and where indivisible SPI transactions really make sense.