Teensy 4.0 : Strange issue when connecting multiple slaves on the secondary SPI bus

Zter

Member
Good morning everyone.
Sory to disturb you but I got a really annoying issue when using the secoundary SPI bus.
To give you some context :
I need to read the data from 8 accelerometers (and an IMU ic on top of that) nearly silmutanously and reccord that data straight into an SD card as fast as possible to have the highest stable sampling rate.
I made it as a self-sufficient device with every components soldered on one main and two secondary pcbs, wich are connected with 3cm long shielded cables, the pcbs don't exceed 20cm in length
To get below the 100Hz limitation with I2C communication (it takes some time to read 8 times 6 registers) I switced to spi communication beetween LSM6DSOX (as sensors) and a teensy 4.0 (not a 4.1 due to space constraints as the device is self contained)
To avoid getting issues with the SD logging on the main SPI line, I used the seondary one (I soldered headers on the two corresponding pads on the underside to solder every point directly to the pcb)

my issue is that when I test only the main pcb with 4 accelerometers and the IMU everything worked (-ish one accelerometer didn't respond due to a broken track), when I connect on the bus the other accelerometers on the other pcbs everything works, except when I plug the accelerometer n°2, wich is located on the upper pcb, and that ones makes everyone on the bus silent, I can't even get a proper response of the who_am_i registers for any of the sensors

I tried to visualise the sensors initialisation signals as I though that the core issue may lay there (having a four channel oscillioscope is handy), and I run this little program taht only writes into two separate registers to initialise each accelerometers (activation, measurment range, noise filtering, ...).
As expected, (first picture) when the accelerometer n°2 wasn't connected everything worked, and the comunication lasts for exactly 4 bytes
but after connecting it without modifying the code the first accelerometers (second picture) comunication misses the last byte (the CS line goes up back 8 clock cycles too early) and the 5th accelerometer (third picture) misses the first and last bytes, but everything works when the 2nd accelerometer isn't connected
to check the chronograms : yellow is SCK, purple is MOSI, blue is MISO and green is CS (which CS depends on wich picture)
You also get this weird drop to GND on the MISO line when the 2nd accelerometer is connected

To give you more info, I struggled with noise due to too-long jumping wires during the early tests of the concept (multiple accelerometers and SD card on the same board) and got rid of it by twisting the corresponding CS lines with a gnd wire. Not knowing anything about RF circuits I tried to mimick the thing by putting two gnd tracks at each side of the cs lines and the SCK/MOSI/MISO bus with lots of straping wires to connect grounds as I worked with a single-sided pcb.

I don't think that the issue comes from the accelerometer breakout board (Adafruit LSM6DSOX) as I have already replaced it (before probing with the oscilloscope) and the issues remained


To be fair I think tha maybe my modules are at fault (as I power them with 3.3V due to these damned integrated level-shifters) and all the pull-up resistors that may add-up, but I clearly see that the issue lays on the CS lines, that are separate, and I can't explain it, signal interference or paraisitc capacitances shouldn't make such clear CS ill-timed transitions

Thanks a LOT to everyone that took time to read my grumbling, and if anyone has an dea, I am all ears.
Thanks in advance
 

Attachments

  • 1 ACC1 normal response with ACC2 unplugged-min.jpg
    1 ACC1 normal response with ACC2 unplugged-min.jpg
    280.9 KB · Views: 17
  • 2 ACC1 distubed response with ACC2 plugged-min.jpg
    2 ACC1 distubed response with ACC2 plugged-min.jpg
    282.7 KB · Views: 21
  • 3 ACC5 distubed response with ACC2 plugged-min.jpg
    3 ACC5 distubed response with ACC2 plugged-min.jpg
    296.3 KB · Views: 20
  • bebug_circuits.ino
    3.9 KB · Views: 18
There might be contention on MISO line, either units are fighting each other or there is too low an impedance on that line. When CS is high it is in I2C mode, when low it is in SPI mode. If you've left the I2C pins in the wrong state it might do odd things maybe?

Have you tried adding a pull-up on the MISO line so you can see if anything is trying to drive it - or use an old trick of touching the MISO signal (careful not to zap it, discharge yourself to ground first), then when MISO is floating it will be obvious due to mains pickup waggling it when it is high-Z.
 
Connecting the ST MEMS chips to Teensy4 over SPI comes with all sorts of pitfalls. These were my stumbling blocks:

* The ST MEMS can do both I2C and SPI. It is quite easy to end up with I2C activated by accident. Then you're lost because once in I2C mode, it may pull down the data line irrespective of CS state. With the default T4 SPI library, for some ST MEMS chips it is impossible to guarantee not ending up in I2C mode by accident. That's because the state of the SDA line at the time of starting a transaction can be either 0 or 1, depending on the state of the last bit sent in a previous transaction.
* Some ST MEMS chips cannot do 4 wire SPI, so you must use 3 wire 'SPI' were the data line is bi-directional. If so, then the default SPI Teensy drivers cannot be used.
* The max SPI clock rate for the ST MEMS chips is pretty high. The bandwidth of the SPI clock output from the Teensy is also pretty high. The rise and fall times are fast. Therefore expect issues with long wires. Long as in >>10 cm.
* On the Teensy side, the SPI master, the SCK line pin is both output and input (!). The SPI TX and RX shift register clock inputs are wired to this pin, and the pin is driven by other logic inside. As a consequence, it is possible to screw up the RX and TX clocks to levels that are different from what this other logic is driving the SCK pin to! So when there's bouncing due to long wires, you can easily get spurious shifts in both registers.

From the scope images that you shared, it looks like there's quite a bit of ringing around the edges of all signals.

To get it working, I wrote my own T4 SPI driver, DMA based, supporting both 3 and 4 wire SPI transactions - and pullups, hysteresis where needed.
 
Back
Top