How can I write to two SPI devices concurrent where one clocks in data on the rising edge and the other on the falling edge?
Note that I am very experienced with C and I have no problem coding right down to the metal. So if I have to tap non-portable interfaces to use the same hardware bus, I'll do that. I'm just hoping there's a reasonable way to do it.
I'm using an Arduino Micro (gotta love Radio Shack!).
How can I write to two SPI devices concurrent where one clocks in data on the rising edge and the other on the falling edge?
Note that I am very experienced with C and I have no problem coding right down to the metal. So if I have to tap non-portable interfaces to use the same hardware bus, I'll do that. I'm just hoping there's a reasonable way to do it.
I'm using an Arduino Micro (gotta love Radio Shack!).
Mike
While I've never done that, I think it should be possible as the SPI library has a setDataMode() function that will support four different modes including clock polarity options. You may have to perform a end function, deselect all SS outputs and then perform the set mode function before calling begin(), When changing from talking to one device to the next, you will have to play with it, but it sure sounds like the Arduino SPI library supports that.
Ok, thanks guys. From looking at the SPI.cpp source code it doesn't look like I would need to call end() and begin() and that I could simply call setDataMode() to change the phase as necessary just before sending data. And in general, what these methods do is trivial often times one-liners that just flip flags on the SPI control register. There's almost no point in using the SPI "library" at all. I will try it and if it doesn't work or if I find something odd I will report back for posterity.
ioplex:
Ok, thanks guys. From looking at the SPI.cpp source code it doesn't look like I would need to call end() and begin() and that I could simply call setDataMode() to change the phase as necessary just before sending data. And in general, what these methods do is trivial often times one-liners that just flip flags on the SPI control register. There's almost no point in using the SPI "library" at all. I will try it and if it doesn't work or if I find something odd I will report back for posterity.
Cool, and if it works you might consider posting some small functional example sketch for anyone in the future that might have to perform the same and does a forum search on this topic.
There's almost no point in using the SPI "library" at all.
Yes I thought that the first time I saw it. Although it does make cross processor working a bit easier if the location of the register or flag changes on another machine.
Adding insult to injury, the design of the standard SPI library makes it impossible to have more than one instance of an SPI interface - any sketches or libraries using the standard SPI library can only ever use the one global hardware SPI interface.
PeterH:
Adding insult to injury, the design of the standard SPI library makes it impossible to have more than one instance of an SPI interface - any sketches or libraries using the standard SPI library can only ever use the one global hardware SPI interface.
How is that different then with the arduino hardware serial library and the Wire library?
PeterH:
Adding insult to injury, the design of the standard SPI library makes it impossible to have more than one instance of an SPI interface - any sketches or libraries using the standard SPI library can only ever use the one global hardware SPI interface.
How is that different then with the arduino hardware serial library and the Wire library?
Lefty
Well, at least with the serial library, if the uP has multiple hardware UARTs (like on the Mega and Due) you can have multiple concurrent serial objects.
I think the better question is do any of the uPs that the Arduino targets have multiple hardware SPI interfaces? If no, there is no need (yet) to add that complexity to the standard SPI library...
PeterH:
Adding insult to injury, the design of the standard SPI library makes it impossible to have more than one instance of an SPI interface - any sketches or libraries using the standard SPI library can only ever use the one global hardware SPI interface.
True in a sense. The 328 chip actually has two lots of SPI hardware if you count the USART chip:
However the code to actually implement the SPI transfer using that hardware is so trivial it probably does not warrant making the base library more complex to allow for it:
// sends/receives one byte
byte MSPIMTransfer (byte c)
{
// wait for transmitter ready
while ((UCSR0A & _BV (UDRE0)) == 0)
{}
// send byte
UDR0 = c;
// wait for receiver ready
while ((UCSR0A & _BV (RXC0)) == 0)
{}
// receive byte, return it
return UDR0;
} // end of MSPIMTransfer
However the code to actually implement the SPI transfer using that hardware is so trivial it probably does not warrant making the base library more complex to allow for it:
I agree. I can imagine that programming is the greatest hurdle for new users. So even though the Arduino SPI interface might seem unsophisticated, I think it is actually a good idea to keep it as simple as possible and lower the learning curve. The rest of us can look at the source and read the datasheet to figure out how to access the full range of features of the chip.
IMO if the hardware abstraction layer had been designed properly, it would have been possible to subclass and define additional instances of the objects representing the various I/O channels transparently to the libraries that make use of them. The implementation looks almost as if the designers have gone out of their way to prevent that - or at the very least not considered it.