cancel
Showing results for 
Search instead for 
Did you mean: 

LIS3DH polling acceleration data only work with patching Register 10h

lospaul
Associate II

Hi community,

I'm using a LIS3DH MEMS on our propriety board with a ST32L476 MCU.

When trying to read x, y, z, channels I get correct data for y and z, but x (Registers 0x28 and 0x29) always return 0x80 0x80.

Sometimes after power up the board, all three channels work as expected!

The behaviour is the same with SPI or I2C interface.

I made a dump of all registers to see the configuration:

SELFTEST OK, all channels are readable.

Reg: 0x7 = 0xFF

Reg: 0x8 = 0x0

Reg: 0x9 = 0x0

Reg: 0xA = 0x0

Reg: 0xB = 0x0

Reg: 0xC = 0x0

Reg: 0xD = 0x0

Reg: 0xE = 0x0

Reg: 0xF = 0x33

Reg: 0x10 = 0x9C

Reg: 0x11 = 0xB

Reg: 0x12 = 0x90

Reg: 0x13 = 0x31

Reg: 0x14 = 0xB1

Reg: 0x15 = 0x33

Reg: 0x16 = 0x1C

Reg: 0x17 = 0x24

Reg: 0x18 = 0x28

Reg: 0x19 = 0x9E

Reg: 0x1A = 0x70

Reg: 0x1B = 0x75

Reg: 0x1C = 0xC0

Reg: 0x1D = 0x0

Reg: 0x1E = 0x10

Reg: 0x1F = 0x0

Reg: 0x20 = 0x27

Reg: 0x21 = 0x0

Reg: 0x22 = 0x0

Reg: 0x23 = 0x0

Reg: 0x24 = 0x0

Reg: 0x25 = 0x0

Reg: 0x26 = 0x0

Reg: 0x27 = 0xFF

Reg: 0x28 = 0x0

Reg: 0x29 = 0x3

Reg: 0x2A = 0x80

Reg: 0x2B = 0xFF

Reg: 0x2C = 0xC0

Reg: 0x2D = 0x3D

Reg: 0x2E = 0x0

Reg: 0x2F = 0x20

Reg: 0x30 = 0x0

Reg: 0x31 = 0x0

Reg: 0x32 = 0x0

Reg: 0x33 = 0x0

Reg: 0x34 = 0x0

Reg: 0x35 = 0x0

Reg: 0x36 = 0x0

Reg: 0x37 = 0x0

Reg: 0x38 = 0x0

Reg: 0x39 = 0x0

Reg: 0x3A = 0x0

Reg: 0x3B = 0x0

Reg: 0x3C = 0x0

Reg: 0x3D = 0x0

Reg: 0x3E = 0x0

Reg: 0x3F = 0x0

SELFTEST FAILED, only y and z are readable,

Reg: 0x7 = 0xFF

Reg: 0x8 = 0x0

Reg: 0x9 = 0x0

Reg: 0xA = 0x0

Reg: 0xB = 0x0

Reg: 0xC = 0x0

Reg: 0xD = 0x0

Reg: 0xE = 0x0

Reg: 0xF = 0x33

Reg: 0x10 = 0x35

Reg: 0x11 = 0xC

Reg: 0x12 = 0x22

Reg: 0x13 = 0x31

Reg: 0x14 = 0xB1

Reg: 0x15 = 0x35

Reg: 0x16 = 0x28

Reg: 0x17 = 0x22

Reg: 0x18 = 0x1B

Reg: 0x19 = 0xAD

Reg: 0x1A = 0x80

Reg: 0x1B = 0x85

Reg: 0x1C = 0xC0

Reg: 0x1D = 0x0

Reg: 0x1E = 0x10

Reg: 0x1F = 0x0

Reg: 0x20 = 0x27

Reg: 0x21 = 0x0

Reg: 0x22 = 0x0

Reg: 0x23 = 0x0

Reg: 0x24 = 0x0

Reg: 0x25 = 0x0

Reg: 0x26 = 0x0

Reg: 0x27 = 0xFF

Reg: 0x28 = 0x80

Reg: 0x29 = 0x80

Reg: 0x2A = 0x80

Reg: 0x2B = 0xF8

Reg: 0x2C = 0xC0

Reg: 0x2D = 0x3D

Reg: 0x2E = 0x0

Reg: 0x2F = 0x20

Reg: 0x30 = 0x0

Reg: 0x31 = 0x0

Reg: 0x32 = 0x0

Reg: 0x33 = 0x0

Reg: 0x34 = 0x0

Reg: 0x35 = 0x0

Reg: 0x36 = 0x0

Reg: 0x37 = 0x0

Reg: 0x38 = 0x0

Reg: 0x39 = 0x0

Reg: 0x3A = 0x0

Reg: 0x3B = 0x0

Reg: 0x3C = 0x0

Reg: 0x3D = 0x0

Reg: 0x3E = 0x0

Reg: 0x3F = 0x0

As you can see, register 0x10, which is reserved, not documented and should not be modified, differs.

But I did and wrote 0x9C in Register 0x10, and by magic everything is fine, all channels are working reliable,

Does anybody has the same experience or can see, what I am doing wrong?

I read my data with the following code:

template<>
bool LIS3DH::raw(int16_t& x, int16_t& y, int16_t& z) const {
    /* --Check if new data is available. */
    while (!GETBIT(status(), ZYXDA));
 
    bool ret = true;
    uint32_t len=7;
    uint8_t buffer[7]; // 2 bytes per channel + register
    buffer[0]=static_cast<uint8_t>(Register::OUT_X_L);
    SETBIT(buffer[0],READBIT);   // set read mode!
    SETBIT(buffer[0],AUTOINC);  // set multiple reads!
 
    ret = read(buffer, len);
    if(ret)
    {
        uint8_t count = 1;
        x = buffer[count] + (buffer[count+1] << 8);
        count += 2;
        y = buffer[count] + (buffer[count+1] << 8);
        count += 2;
        z = buffer[count] + (buffer[count+1] << 8);
 
        fit(x);
        fit(y);
        fit(z);
    }
    return ret;
}

Regards

Jürgen

6 REPLIES 6
Foued_KH
ST Employee

Hello @Jürgen Wübbelmann​ and welcome to the Community 😀

Please do not try to change the content of the reserved registers (like register 0x10) as recommended the Datasheet.0693W00000UolrMQAR.pngFoued

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

lospaul
Associate II

Hello @KHALSI_Foued​ 

thank you for your reply!

Yes, I know I shouldn't do it and I wouldn't do it if the LIS3DH would give me correct values.

But it doesn't and a write to Register 0x10 is the only way to motivate the sensor to give the correct values for the x axis. At every power on we have the "wrong" value again in 0x10.

It seems our sensors do not load the correct calibration values from non-volatile memory at start-up. I don't know why.

Note that the behaviour is not for just one device, nearly all of our PCBs show this behaviour.

Regards,

lospaul

Foued_KH
ST Employee

"Writing to those registers may cause permanent damage to the device.

The content of the registers that are loaded at boot should not be changed. They contain the

factory calibration values.

Their content is automatically restored when the device is powered up." (7. Register mapping (Datasheet LIS3DH))

Foued

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

lospaul
Associate II

Thanks again.

The problem is: We first had the erroneous behaviour and than started looking for a difference and changing reserved registers.

I still don't know what we are doing wrong other then changing reserved registers at a device which for an unknown reason does not do what it is supposed to do. :\

Eleon BORLINI
ST Employee

Hi @Jürgen Wübbelmann​ ,

Are you facing the issue only on 1 device?

The REG 10h is a reserved register, which refers to a coarse calibration, but you should not see the X axis stuck if this register is failing at boot. You might try to characterize the power on event (Vdd ramp, level, Vddio): for example, it is better to keep Vdd and VddIO are suggested to stay at the same level (>2V)

-Eleon

lospaul
Associate II

Hi @Eleon BORLINI​ ,

thank you for your reply.

Unfortunately we face the issue on most, but not all of our boards.

Sometime a board working ok for a while starts to show the strange behaviour without any writes to the reserved registers.

Find below a picture of the Vdd ramp with Vdd = 3.3V, time resolution 50us/div, so after approx. 200us Vdd is stable. Vdd and VddIO are directly connected, as we use a STM32L476RG Nucleo Board with 3.3V on SPI or I2C signals respectively. In my Software I have a 100ms delay before accessing the device for the first time, configuration see in my first post.

I assume that there is a HW or SW problem in our design as the LIS3DH is on the market for years, but I have absolutely no idea what we are doing wrong.

0693W00000VOAbiQAH.png0693W00000VOAWEQA5.png