SPI clarification recent updates. Need for SPIslave library.

slomobile

Well-known member
I need a Teensy 3.2 as SPI master to a display, SD as logger, and several Teensy 3.2 as SPI slaves. The slave devices will keep track of fast encoders, analog and digital inputs, and output the DAC as commanded by the master. But this post is less about the project and more about the confusion that happened when trying to figure out which SPI libraries to use and how.

I started with the display so that I would have it for debugging.
https://www.pjrc.com/teensy/td_libs_SSD1306.html
The library presented for download is outdated compared to the real Adafruit library, uses software SPI by default which is too slow in my application, does not work with hardware SPI when wired according to comments. TD 1.27, IDE 1.6.7 compiles but screen is dark.
Code:
#define OLED_DC     6
#define OLED_CS     7
#define OLED_RESET  8
Adafruit_SSD1306 display(OLED_DC, OLED_RESET, OLED_CS);
It is left ambiguous where to connect MISO and SCK on Teensy, or why the other pins should change, does not use transactions.
This page and library needs to be updated along the lines of https://www.pjrc.com/store/display_ili9341.html with transactions. I'll work on the library soon.

The examples in the optimized ILI9341 library need these comment lines updated to reflect PJRC hardware instead of Adafruit or Uno.
Code:
// For the Adafruit shield, these are the default.
#define TFT_DC  9
#define TFT_CS 10

// Use hardware SPI (on Uno, #13, #12, #11) and the above for CS/DC
ILI9341_t3 tft = ILI9341_t3(TFT_CS, TFT_DC);
I've temporarily moved to this display to keep the rest of the project on track.

It is nice that you are respecting Adafruit licenses in your support libraries by including all of their sketch preamble and comments, but could you please make the code your own by including your own preamble and moving theirs to a separate attribution.txt file. It gets confusing when trying to compare your code to theirs to use the latest source from both branches and it all looks alike and is named alike. Your Teensy support libraries often include Adafruit or Arduino comments referring to Uno, Mega, or Due boards that are misleading when working with Teensy 2 or 3. It is often ambiguous whether a given library will work with Teensy 2x or Teensy 3x or both. It would be helpful if you prepend or append the names of forked libraries you host and optimize with "T_" or some other stamp to make it yours. I realize this might entail editing #include and library object declaration lines for every library when merging code, but Ctrl-F replace or automated refactoring in your build tools can do that. Perhaps the stamp or preamble could indicate which Teensy and optionally other boards the library supports. That is a common frustration and question that goes unasked because it seems like the answer should be obvious, but isn't. We lose lots of newbies on this low hurdle.x

The next comments refer to https://www.pjrc.com/teensy/td_libs_SPI.html
Given all your recent contributions to the official SPI library, is spi4teensy3 still faster? Should that link still be there?

The page says "The SPI library does not control the SS signals", but you recently said "Those pins labeled CS have special hardware which can automatically create the CS signal. But it doesn't happen automatically unless special Teensy-specific code enables it, so it's only sort-of automatic." I think this would be a great place for an example of the "special Teensy-specific code".

SPI.usingInterrupt(interruptNumber) What is interruptNumber for Teensy 2++ or 3x? must we use SPI.usingInterrupt(digitalPinToInterrupt(pin)) in all cases? or is SPI.usingInterrupt(pin) ok? Is there a 3rd option as on the Arduino page?

You asked under Slave Mode (Not Supported); "The SPI port can work in slave mode, which may be useful if Teensy should appear as a SPI device to be controlled by another Teensy or other board. The SPI library does not support slave mode.

Apart from this AVR example, is there an Arduino library which supports slave mode?"
https://github.com/btmcmahan/Teensy-3.0-SPI-Master---Slave
https://forum.arduino.cc/index.php?topic=184527.0
http://forum.arduino.cc/index.php/topic,43241.0.html
http://forum.arduino.cc/index.php?topic=69734.0
https://github.com/crteensy/DmaSpi Not sure if this one will ever go there, but I hope so.
And there are lots of examples that basically use Nick Gammon's code.

Now that the official SPI library is pretty solid and supporting a wide range of hardware as SPI master, it would be very useful to have a reliable SPI slave library compatible with the same hardware.

Searching for location of hardware SPI pins led to several posts about faster T3 optimized SPI libraries, and Adafruit refusing to incorporate Nick Gammon's hardware SPI speedups. However most of the top search results are no longer true or relevant. They won't get replaced unless we have new pages speaking the current truth.
 
ILI9341_t3 tft = ILI9341_t3(TFT_CS, TFT_DC);

Also, this kind of code, that I see a lot in the Adafruit code, annoys me a lot.
The idiomatic way to initialize a C++ object is to pass the constructor arguments directly:

Code:
ILI9341_t3(TFT_CS, TFT_DC) tft;

Dunno why this bugs me so much, because the compiler knows how to translate the temporary object and assignment into in-place construction, but there it is.


EDIT: Bah, accidentally necroed this thread. Sorry.
 
Last edited:
I was playing around with a SPI client version of the SPI library a little while ago.

In some cases it could be pretty simple to do. The interesting stuff is figuring out how to handle the return data. That is I find it easy to handle the case where the master sends the data to me... But when the master asks for data, it can get a little more complicated. That is if your FIFO queue has entries for 4 items, it gets interesting to know when the fill the fifo... Wonder at times if it would be easier to disable the fifo...

As for which pins to use... For CS it must be one of the Channel 0 CS pins for the SPI buss. So on T3.2 that is either pin 10 or pin 2.
I have a private branch of the SPI library (did not push it up to github), that added some new methods like spi.beginSlave(pin, callback function) and also an setSlaveSettings...

I have a simple test app for T3.6 which was trying to use one SPI buss as master and another as slave...

Wonder if this is worthwhile to continue and/or should be a separate library, like dmaspi is...
 
Back
Top