delay() breaks within SPI.beginTransaction()

xxxajk

Well-known member
As it says in the title. This will lock up.



Code:
SPI.beginTransaction(SPI_Settings);
delay(100);
SPI.endTransaction();
 
Interesting. On what processor, IDE version of Teensyduino.

I tried this on my version of SPI, Current Teensuduino... 1.8.2 T3.6
Code:
#include <SPI.h>
void setup() {
  while (!Serial && millis() < 3000) ;
  Serial.begin(115200);
  SPI.begin();
  delay(50);
}

void loop() {
  Serial.println("Before Begin Transaction");
  SPI.beginTransaction(SPISettings(8000000, MSBFIRST, SPI_MODE0));
  delay(100);
  SPI.endTransaction();
  Serial.println("After End Transaction");
}

Note It will hang in SPI.beginTransaction, if you have not called SPI.begin
 
Exactly what I observed.
I'm not using loop() either, everything is in setup()
Thanks for the verification. Try it all within setup()...

Teensy 3.2, ard 1.6.12, td 1.35
 
Yes - it SPI.beginTransaction will fault, unless you have called SPI.begin.

In particular, it will fault on the first instruction that tries to touch any of the hardware registers associated with SPI.

Why? This method does not enable it. That is on a T3.x to talk to SPI0, you need to have turned on the appropriate Clock gate:
In particular: SIM_SCGC6 |= SIM_SCGC6_SPI0;

The Begin method does this and a few other methods that may be called before begin like(setBitOrder, setDataMode, setClockDivider), do so as well.

Obviously this can be added here as well. But nothing will work as the pins have not been initialized nor other settings.

Also your program will also fault if you just start it off with: SPI.transfer(0);

So the question is, does it make sense to bloat all of the SPI calls a bit with class to bail if SPI has not init?

It has been done on some other code paths, like if you do: Serial3.write(0);
The underlying call serial3_putchar starts off with: if (!(SIM_SCGC4 & SIM_SCGC4_UART2)) return;
So it bails Serial3.begin(...) has not been called.

But there is only one copy of this code. Where SPI.transfer(0), the code is setup as inline so that code would be replicated for each call to transfer.
Again doable but not sure it is worth it.
 
Oddly if I have a Serial.print() and Serial.flush() *before* the delay() the data does print, and it locks at delay()?? strangeness.

Either way, you are correct, should write the code the correct way, and use begin.
I was just wondering if this was a known pitfall or not.
 
Back
Top