2018-09-13 04:25 PM
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:
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:
STEP 1: Successful R/W of 10 into CTRL_REG1 (address 0x21).
STEP 2: Successful R/W of 30 into CTRL_REG4 (address 0x20). Here transmission pipeline is being packed full (solution #1).
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).
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.
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:
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.