Author Topic: Seeking Help: SPI Glitches on LPC824 Microcontroller & ISM330DLC Accelerometer.  (Read 947 times)

0 Members and 1 Guest are viewing this topic.

Offline teleportboyTopic starter

  • Newbie
  • Posts: 8
  • Country: kg
Hello everyone! ;D

Problem:
On my board, the ISM330DLC accelerometer is integrated with LPC824 microcontroller via SPI interface.
However, at the software level, I encountered problems reading/writing the accelerometer registers. Initially, I simply decided to read data from the WHO_AM_I register, but the data I receive in response does not match what is described in the accelerometer's datasheet. That is, WHO_AM_I should return 0x6A, but it returns 0x88.

A detailed example of my problem: I write two bytes of information to txBuffer: [0x8F, 0x00]. In binary, txBuffer = 10001111 00000000. According to the accelerometer datasheet, the 0th bit is R\W - 0 for write, 1 for read. The next 7 bits are the register address for the operation. Bits 8-15 are for writing; I assume they're ignored during reading. So, the command [0x8F, 0x00] requests a read from the WHO_AM_I register.
However, I get an rxBuffer output of [0xFF, 0x88], which is not what I expected. Also, why is the first byte always 0xFF whenever I try to read any register?

Accelerometer has a register that allows configuring access to other registers, as strange as that might sound (see the first screenshot). In this way, if I don't set the required flag to 1, any read request returns [0xFF, 0x00]. From this, I concluded that writing data works, but reading doesn't. However, I might be wrong, as this is my first experience in embedded development

Code:
To work on the microcontroller, I used the functionality of MCUXpresso SDK.
Link to main.c: https://github.com/teleportboy/lpc824_spi/blob/4c3f20cbc3018be76f213c5112d54ef2cd48b409/source/main.c#L24
Link to init pins: https://github.com/teleportboy/lpc824_spi/blob/4c3f20cbc3018be76f213c5112d54ef2cd48b409/board/pin_mux.c#L72
Link to project: https://github.com/teleportboy/lpc824_spi

I would greatly appreciate any advice.
 

Online nctnico

  • Super Contributor
  • ***
  • Posts: 26912
  • Country: nl
    • NCT Developments
Did you check wether CS is held low during the entire transfer? IIRC the SPI controller in NXP's LPC series will pull CS low for every single word transaction.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline jgrossman

  • Regular Contributor
  • *
  • Posts: 63
  • Country: us
Accelerometer has a register that allows configuring access to other registers, as strange as that might sound (see the first screenshot).

Not _that_ odd, to be honest. Worked with lots of parts with similar mechanism as a sort of safety against accidental configuration. Some MCUs even have internal mechanisms like that (for example, port mapping on MSP430 must be unlocked to make changes).

Anyways, do you have an oscilloscope or logic analyzer? @nctnico may be right about the CS line.

Is it possible you get 0xFF because of an internal (or otherwise) pullup on the data line, and during the first byte of a read the ISM330DLC is high impedance? Since the RX and TX appear to be done at the same time: https://github.com/teleportboy/lpc824_spi/blob/4c3f20cbc3018be76f213c5112d54ef2cd48b409/drivers/fsl_spi.c#L520-L570

I would expect that means the first byte of your receive buffer is being filled with garbage in any case, since you haven't actually sent anything out yet.

 

Offline NorthGuy

  • Super Contributor
  • ***
  • Posts: 3147
  • Country: ca
I am not familiar with LPC SPI module, but I think you might be using a wrong SPI mode.

The device needs an SPI mode where you set data at the first (falling) edge and sample data at the second (rising) edge.

You have chosen kSPI_ClockPhaseFirstEdge which is "First edge on SCK occurs at the middle of the first cycle of a data transfer."

The other choice is kSPI_ClockPhaseSecondEdge which is "First edge on SCK occurs at the start of the first cycle of a data transfer."

This is a very bad description of options, but I would rather choose the second one assuming that the "cycle of a data transfer" starts from setting data and sampling occurs in the middle of the "cycle".

nctnico is familiar with LPC and he will know better.
 
The following users thanked this post: teleportboy

Offline teleportboyTopic starter

  • Newbie
  • Posts: 8
  • Country: kg
Did you check wether CS is held low during the entire transfer? IIRC the SPI controller in NXP's LPC series will pull CS low for every single word transaction.


I'm not quite sure what you mean. Are you suggesting that there's a chance the SPI controller might pull the CS line high after transmitting a word and then automatically pull it low again for the next word transmission?
As a result, there might be a situation where the ISM330DLC starts to respond to the high state of the CS line, but such behavior would corrupt the transmission of 16-bit data (a command to read from or write to a register)?
« Last Edit: October 25, 2023, 07:53:24 am by teleportboy »
 

Offline teleportboyTopic starter

  • Newbie
  • Posts: 8
  • Country: kg
The other choice is kSPI_ClockPhaseSecondEdge which is "First edge on SCK occurs at the start of the first cycle of a data transfer."
Wow, bro, your advice really helped and I finally got 0x6A from the WHO_AM_I register. However, I'm not entirely sure what exactly happened. Could you share some resources or topics for me to study so I can understand all these clocks, first edge, second edge, etc.?
 

Offline NorthGuy

  • Super Contributor
  • ***
  • Posts: 3147
  • Country: ca
The other choice is kSPI_ClockPhaseSecondEdge which is "First edge on SCK occurs at the start of the first cycle of a data transfer."
Wow, bro, your advice really helped and I finally got 0x6A from the WHO_AM_I register. However, I'm not entirely sure what exactly happened. Could you share some resources or topics for me to study so I can understand all these clocks, first edge, second edge, etc.?

There are various manufacturers who use different words, but it is actually very simple. There are 4 different SPI modes and both communicating devices must use the same mode. Google "SPI Modes" - this should bring some explanations.
 

Offline meshtron

  • Regular Contributor
  • *
  • Posts: 132
  • Country: us
This graphic plus my logic analyzer helped me recognize a device I was attempting to communicate with via SPI wanted to chat Mode 1, but I was defaulting to Mode 0:

https://upload.wikimedia.org/wikipedia/commons/thumb/f/f0/SPI_timing_diagram_CS.svg/1920px-SPI_timing_diagram_CS.svg.png
 

Offline ArdWar

  • Frequent Contributor
  • **
  • Posts: 373
  • Country: sc
Next time invest in a decent oscilloscope (or at least a good logic analyzer) and learn how to trigger properly. Being able to see what actually happen down the signal line helps immensely with serial data debugging.
 
The following users thanked this post: nctnico


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf