SPI Communication with a LIS2DE12 Accelerometer

Thread Starter

Luís Henrique Meneghetti

Joined Oct 7, 2019
5
Hi! I am trying to establish a SPI communication with an LIS2DE12 accelerometer. First, I would like to say that I have checked phase, polarity, msbFirst and CS. I am using an EM9304 as the master of the communication, and the spi clock frequency is aproppriated.

Writing or reading from the sensor, makes it sends an weird symmetrical waveform in to MISO pin.

(This symmetrical waveform is equal to the LIS2DE12 ID (0X33 = 00110011), but I don't know if its a coincidence.)

I had tried many different registers (writing and reading) and the sensor only send this signal. I read both datasheets and couldnt figure how to make it work or get to the conclusion that I have a hardware problem.

- MOSI Signal
https://imgur.com/a/mNf0r0y

- MISO Signal
https://imgur.com/a/EGDG0Pv

These are the prints from the oscilloscope with the MOSI and MISO signals. In the MOSI print, I am sending a write commando to CTRL_REG4 (0x23) and an 8bit data (0x34). In the following pack of bytes, I am trying to read te content of this same register (CTRL_REG4). As you can see, the module keeps sending 0x33 through MISO.

Thanks in advance for any kind of help! Bye.
 

Thread Starter

Luís Henrique Meneghetti

Joined Oct 7, 2019
5
Hi, Eric! Yes, the data is read on the rising edge. I am using this method. A Write/Read bit, the MS bit and 6bits address. For read operation, I am sending 8bits of 0s through MOSI to keep the clock signal and let the sensor send data. Here's the struct used to pass the bytes and the function used from my SPI library.

Code:
typedef struct{

        struct{

            uint8_t address        : 6;   //6bit address
            uint8_t ms             : 1;   //If 0, keep the address unchanged, else, it increments the address in case of writing/reading multiple bytes
            uint8_t mode         : 1;   //Read/Write

        }control;

        uint8_t data;             //8bit data

}SPIM_Transaction_t;

Function:

Code:
/**
* @brief Performs one or more read and write operations.
*
* This is a non-blocking operation. The read buffer will be overwritten once
* the transaction has completed.
*
* @param chipSelectGpio Number of the GPIO to use for the chip select.
* @param[in] pWriteBuffer An array of data to write to the device.
* @param[out] pReadBuffer The memory location to save the read data.
* @param bytes The number of entries in the source array.
* @param[in] callbackFunction The function to call after the transaction is
*   complete, the return status is passed as an argument.
* @param[in] pUserData The data to pass to the callback function.
* @param frequency Maximum clock frequency to send the transaction at or 0 to
*   not change the clock frequency (previous frequency is used).
* @returns true if the transaction was scheduled, false otherwise.
*/
//lint -function( fopen(1), SPIM_TransferBytes(2) ) // arg cannot be null
//lint -function( fopen(1), SPIM_TransferBytes(3) ) // arg cannot be null
bool SPIM_TransferBytes(uint8_t chipSelectGpio, const uint8_t *pWriteBuffer,
    uint8_t *pReadBuffer, uint8_t bytes, Driver_Callback_t callbackFunction,
    void *pUserData, uint32_t frequency);
Code:
/**
* @brief Performs one or more read operations.
*
* This is a non-blocking operation. The input buffer will be overwritten once
* the transaction has completed.
*
* @param chipSelectGpio Number of the GPIO to use for the chip select.
* @param[out] pReadBuffer The memory location to save the read data.
* @param bytes The number of bytes to read.
* @param[in] callbackFunction The function to call after the transaction is
*   complete, the return status is passed as an argument.
* @param[in] pUserData The data to pass to the callback function.
* @param frequency Maximum clock frequency to send the transaction at or 0 to
*   not change the clock frequency (previous frequency is used).
* @returns true if the transaction was scheduled, false otherwise.
*/
//lint -function( fopen(1), SPIM_ReadBytes(2) ) // arg cannot be null
bool SPIM_ReadBytes(uint8_t chipSelectGpio, uint8_t *pReadBuffer,
    uint8_t bytes, Driver_Callback_t callbackFunction, void *pUserData,
    uint32_t frequency);
 

mckenney

Joined Nov 10, 2018
69
I have checked phase, polarity, msbFirst and CS
How did you check CS exactly? The fact that the device is driving MISO during the "first" byte of the transaction suggests it isn't seeing the /CS transitions, and thinks this is all one infinitely-long transaction.

Your traces indicate that you're using CPOL=0, CPHA=0, but based on DS Fig 6 the device expects CPOL=1, CPHA=1. The device is probably fetching MOSI bits while they're transitioning.
 

Thread Starter

Luís Henrique Meneghetti

Joined Oct 7, 2019
5
How did you check CS exactly? The fact that the device is driving MISO during the "first" byte of the transaction suggests it isn't seeing the /CS transitions, and thinks this is all one infinitely-long transaction.

Your traces indicate that you're using CPOL=0, CPHA=0, but based on DS Fig 6 the device expects CPOL=1, CPHA=1. The device is probably fetching MOSI bits while they're transitioning.
That's might be the problem. The guy that designed the hardware thought that it was ok to ground the CS pin because this module is the only slave.

Thanks for the help!
 
Top