I'm trying to interface a LSM6DS3TR-C 6-dof IMU with a Raspberry Pi Pico / RP2040. IMU is on the Adafruit breakout. Cables are <10cm long, soldered directly on both sides. I'm using pins 16-19 on Pico. My code is just polling the IMU's WhoAmI register periodically.
Here is the issue: IMU only responds to the register read if at least two oscilloscope probes are connected to SPI data lines
. If not, MISO just stays low. When exactly it works does change with SPI clock, time of the day and probably the weather, but I have not found it to be more reliable at lower clocks. The register read data packet looks perfect otherwise, as per datasheet. I also tested the IMU with FT232HQ USB-SPI bridge - works perfectly and the WhoAmI read looks basically identical on the scope to what I see with the Pico.
The breakout has some level shifters, so I tried connecting my data lines directly to the IMUs pins, which changed exactly nothing - still works omly sometimes, mostly when two or more scope probes are connected. I don't see how scope could affect the signals - it certainly does not look like some lines are floating and being pulled low by scope - the edges are way too quick for that (around 20ns on CS for example).
Honestly, I have absolutely no idea what is happening. Any guesses?
Here is the code (platformio with arduino core) and a scope screenshot of CS (pink), MOSI (blue) and CLK (yellow) lines with signals connected directly to IMU and the probes close to the IMU. In this example, I got a valid WhoAmI reply, because the probes were connected...
#include <Arduino.h>
#include <SPI.h>
#define cs 17
uint8_t read_register(uint8_t addr) {
addr |= 0x80;
uint8_t out[2] = {addr, 0xFF};
uint8_t in[2];
digitalWrite(cs, LOW);
// delay(1);
SPI.beginTransaction(SPISettings(1000000UL, MSBFIRST, SPI_MODE0));
SPI.transfer(out, in, 2);
SPI.endTransaction();
// delay(1);
digitalWrite(cs, HIGH);
return in[1];
}
void setup() {
// put your setup code here, to run once:
pinMode(cs, OUTPUT);
digitalWrite(cs, HIGH);
Serial.begin(115200);
delay(1000);
Serial.println("Hello World");
SPI.setRX(16);
SPI.setTX(19);
SPI.setSCK(18);
// SPI.setCS(cs);
SPI.begin();
}
void loop() {
// put your main code here, to run repeatedly:
uint8_t whoami = read_register(0x0F);
Serial.print("Who am I: ");
Serial.println(whoami, HEX);
Serial.println("heeey");
delay(2000);
}