cancel
Showing results for 
Search instead for 
Did you mean: 

Failure reading from LIS3DSH SPI interface

GioP
Associate II

I am interfacing a LIS3DSH using SPI. My MCU is a Texas Instruments MSP432.

When writing and checking configuration registers, even-addressed ones do not return the expected value.

After sending a byte, MSP432 MOSI retains the value of its MSB. This is noticeable while spinning on SPI RX interrupt flag after sending address byte: MOSI is low if the register is being accessed in write mode, high otherwise, whichever the address was. I presume the SPI transmission shift register turns transparent towards TX buffer while waiting for a new byte to send. This causes MOSI to toggle low-to-high after sending an even address in read mode, and keep such value until next transmission starts.

I found two workarounds:

  1. Polling on SPI TX interrupt flag: transmission pipeline is packed full as subsequent bytes are sent one immediately after another. This avoids the pause between transmissions, so MCU never shows a meaningless logic value to the slave during the whole communication process.
  2. Forcing address LSB on MOSI wire between address and dummy byte. This adds some cumbersome GPIO operations to the routine.

At first I was convinced that 'read bit' popping up with CLK high and CS low triggered sensor I2C functionalities, acting as the "STOP CONDITION" on SDA and crippling the SPI protocol; but forcing address LSB on MOSI takes a few clock cycles and cannot avoid the unwanted value to show up for a short time after clock goes inactive-high. This toggling on data line should be enough to wake up I2C interface if it was the case. Another idea, also proposed by @Rick Schue​, is that LIS3DSH SPI samples every eighth bit on CLK falling edge, so it is important to restore address LSB on the line before next byte transmission begins. Actually, this second hypothesis seems the most reasonable.

I share some oscilloscope traces demonstating what stated above; data is always written packing the pipeline full, with no interval after sending the address byte, so the reader can focus on the various readout methods and their outcomes:

  • yellow: CS
  • cyan: MOSI
  • pink: CLK
  • green: MISO

STEP 1: Successful R/W of 10 into CTRL_REG1 (address 0x21).

0690X000006C44SQAS.png

STEP 2: Successful R/W of 30 into CTRL_REG4 (address 0x20). Here transmission pipeline is being packed full (solution #1).

0690X000006C3yoQAC.png

STEP 3: Successful R/W of 30 into CTRL_REG4 again. This time forcing MOSI low prior to sending the dummy byte, as a '1' shows up after address transmission (solution #2).

0690X000006C3z8QAC.png

STEP 4: Without taking countermeasures, writing 30 into CTRL_REG4 a 10 is read back (value previously set into CTRL_REG1). Please notice logic '1' persisting on MOSI line until dummy byte is sent.

0690X000006C3zSQAS.png

The same sequence gives identical results using CTRL_REG6 (address 0x25) in place of CTRL_REG1 and CTRL_REG5 (address 0x24) in place of CTRL_REG4:

0690X000006C3zwQAC.png

0690X000006C401QAC.png

0690X000006C406QAC.png

 0690X000006C44XQAS.png

Can anyone please shed some light on this? Is there any SPI standard forbidding MOSI to toggle with CLK being inactive? In such case MSP432 SPI is not fully compliant, otherwise I think LIS3DSH datasheet should warn users to control MOSI pin between transmissions or to pack the transmit pipeline full.

You can also view @Rick Schue​'s post here:

https://community.st.com/s/question/0D50X00009XkWCOSA3/lis3dsh-spi-interface-issue-bug

similar issue, different microcontroller.

0 REPLIES 0