cancel
Showing results for 
Search instead for 
Did you mean: 

LIS3MDL sometimes freezes for around 63 seconds

George Ruinelli
Associate

We are using the LIS3MDL in conjunction with a microcontroller (STM32F051).

In most cases, the sensor responds correctly to our initialization and provides its data with around 1.068 kHz.

However we sometimes experience that the sensor freezes for around 63 seconds, meaning after the last data read it takes 63 seconds until the DRDY line goes high again.

It happens directly after we (for testing) restart the MCU and re-initialize the sensor.

We are connecting the sensor using I2C to the MCU. There is no other device on the I2C bus.

We use the sensor in the 1 kHz mode. Whenever the DRDY line goes high, we read the 6 data bytes (Address 0x28-0x2D) using DMA.

We configure the sensor as following:

  • CTRL_REG1: 0x02 (Temperature Sensor disabled, Operation Mode = Low Power, Data Output Rate = 0, , Fast Output Data Rate = 1 kHz, Self Test disabled)
  • CTRL_REG2: 0x00 (Fullscale = 4 gauss, Reboot = 0, Soft Reset = 0)
  • CTRL_REG3: 0x00 (Low Power Mode = Use Output Data Rate Configuration, SPI Mode = 4-wire (not relevant since we use I2C), Operating Mode = Continuous conversion)
  • CTRL_REG4: 0x02 (Z-Axis Operation Mode = Low Power Mode, Big/Little Endian = Big)
  • CTRL_REG5: 0x40 (Disable Fast Read, Block Data Update: Only after LSB and MSB got read)

(See code below).

In the examples CTRL_REG2 gets configured before CTRL_REG1, how ever this does not fix the issue.

We also do a reboot and a soft reset before we initialize the sensor, but again this does not fix it.

 debug("Initializing Mag Field Sensor...");
 
  /**
   * Perform a memory reboot and soft reset
   * We dont know if it is needed since there is almost no documentation available.
   * However it might be wise to do it and it does not seem to hurt.
   *   - Reboot = 1 (Bit 3 = 1)
   *   - Soft Reset = 1 (Bit 2 = 1)
   *   - Other bits = 0
   *   => Value: 0x06
   */
  regWriteValue = 0x06;
  if (LIS3MDL_MAG_WriteReg(magFieldSensorHandle, LIS3MDL_MAG_CTRL_REG2, &regWriteValue, 1) != MEMS_SUCCESS) {
    debug("Magnetic Field Sensor Error: Failed to write CTRL_REG2!");
    return false;
  }
 
  
  /** Register WHO_AM_I **/
  /* Read WHO AM I register */
  if (LIS3MDL_MAG_R_WHO_AM_I_((void *)magFieldSensorHandle, (uint8_t *)&who_am_i) == MEMS_ERROR) {
    debug("Magnetic Field Sensor Error: Failed to read whoami register!");
    return false;
  }
 
  /* Validate Chip ID (Who am I) */
  if (who_am_i != LIS3MDL_MAG_WHO_AM_I) { // Chip ID mismatch
    debug("Magnetic Field Sensor Error: Read wrong Chip ID: 0x%02X, expected: 0x%02X!", who_am_i, LIS3MDL_MAG_WHO_AM_I);
    return false;
  }
 
 
  /** Register CTRL_REG2
   *   - Fullscale = 4gauss (Bit 5, 6 = 0)
   *   - Reboot = 0 (Bit 3 = 0)
   *   - Soft Reset = 0 (Bit 2 = 0)
   *   - Bit 7, 4, 0, 1 = 0
   *   => Value: 0x00
   */
  regWriteValue = 0x00;
  if (LIS3MDL_MAG_WriteReg(magFieldSensorHandle, LIS3MDL_MAG_CTRL_REG2, &regWriteValue, 1) != MEMS_SUCCESS) {
    debug("Magnetic Field Sensor Error: Failed to write CTRL_REG2!");
    return false;
  }
 
  if (LIS3MDL_MAG_ReadReg(magFieldSensorHandle, LIS3MDL_MAG_CTRL_REG2, &regReadValue, 1) != MEMS_SUCCESS) {
    debug("Magnetic Field Sensor Error: Failed to read CTRL_REG2!");
    return false;
  }
 
  if (regReadValue != regWriteValue) {
    debug("Register CTRL_REG2 Write Validation failed! Written: 0x%02X, read back: 0x%02X",
        regWriteValue, regReadValue);
    return false;
  }
 
 
  /** Register CTRL_REG1
   *   - Disable Temperature Sensor (Bit 7 = 0)
   *   - Operation Mode = Low Power (Bit 6, 5 = 0)
   *   - Data Output Rate = 0 (ignored (Bit 4, 3, 2 = 0)
   *   - Fast Output Data Rate = 1 kHz (Output Mode = Low Power) (Bit 1 = 1)
   *   - Disable Self Test (Bit 0 = 0)
   *   => Value: 0x02
   */
  regWriteValue = 0x02;
  if (LIS3MDL_MAG_WriteReg(magFieldSensorHandle, LIS3MDL_MAG_CTRL_REG1, &regWriteValue, 1) != MEMS_SUCCESS) {
    debug("Magnetic Field Sensor Error: Failed to write CTRL_REG1!");
    return false;
  }
 
  if (LIS3MDL_MAG_ReadReg(magFieldSensorHandle, LIS3MDL_MAG_CTRL_REG1, &regReadValue, 1) != MEMS_SUCCESS) {
    debug("Magnetic Field Sensor Error: Failed to read CTRL_REG1!");
    return false;
  }
 
  if (regReadValue != regWriteValue) {
    debug("Register CTRL_REG1 Write Validation failed! Written: 0x%02X, read back: 0x%02X",
        regWriteValue, regReadValue);
    return false;
  }
 
 
  /** Register CTRL_REG3
   *  - Low Power Mode = Use Output Data Rate Configuration (Bit 5 = 0
   *  - SPI Mode = 4-wire (Bit 2 = 0)
   *  - Operating Mode = Continuous conversion (Bit 0, 1 = 0)
   *  - Bit 7, 4, 3 = 0
   *   => Value: 0x00
   */
  regWriteValue = 0x00;
  if (LIS3MDL_MAG_WriteReg(magFieldSensorHandle, LIS3MDL_MAG_CTRL_REG3, &regWriteValue, 1) != MEMS_SUCCESS) {
    debug("Magnetic Field Sensor Error: Failed to write CTRL_REG3!");
    return false;
  }
 
  if (LIS3MDL_MAG_ReadReg(magFieldSensorHandle, LIS3MDL_MAG_CTRL_REG3, &regReadValue, 1) != MEMS_SUCCESS) {
    debug("Magnetic Field Sensor Error: Failed to read CTRL_REG3!");
    return false;
  }
 
  if (regReadValue != regWriteValue) {
    debug("Register CTRL_REG3 Write Validation failed! Written: 0x%02X, read back: 0x%02X",
        regWriteValue, regReadValue);
    return false;
  }
 
 
  /** Register CTRL_REG4
   *  - Z-Axis Operation Mode = Low Power Mode (Bit 3, 2 = 0)
   *  - Big/Little Endian = Big (Bit 1 = 1)
   *  - Bit 7-4, 0 = 0
   *   => Value: 0x02
   */
  regWriteValue = 0x02;
  if (LIS3MDL_MAG_WriteReg(magFieldSensorHandle, LIS3MDL_MAG_CTRL_REG4, &regWriteValue, 1) != MEMS_SUCCESS) {
    debug("Magnetic Field Sensor Error: Failed to write CTRL_REG4!");
    return false;
  }
 
  if (LIS3MDL_MAG_ReadReg(magFieldSensorHandle, LIS3MDL_MAG_CTRL_REG4, &regReadValue, 1) != MEMS_SUCCESS) {
    debug("Magnetic Field Sensor Error: Failed to read CTRL_REG4!");
    return false;
  }
 
  if (regReadValue != regWriteValue) {
    debug("Register CTRL_REG4 Write Validation failed! Written: 0x%02X, read back: 0x%02X",
        regWriteValue, regReadValue);
    return false;
  }
 
 
  /** Register CTRL_REG5
   *   - Disable Fast Read (bit 7 = 0), only useful if we only want to read the high byte of an axis!
   *   - Block Data Update: Only after LSB and MSB got read (bit 6 = 1)
   *   - Bit 0..5 = 0
   *   => Value: 0x40
   */
  regWriteValue = 0x40;
  if (LIS3MDL_MAG_WriteReg(magFieldSensorHandle, LIS3MDL_MAG_CTRL_REG5, &regWriteValue, 1) != MEMS_SUCCESS) {
    debug("Magnetic Field Sensor Error: Failed to write CTRL_REG5!");
    return false;
  }
 
  if (LIS3MDL_MAG_ReadReg(magFieldSensorHandle, LIS3MDL_MAG_CTRL_REG5, &regReadValue, 1) != MEMS_SUCCESS) {
    debug("Magnetic Field Sensor Error: Failed to read CTRL_REG5!");
    return false;
  }
 
  if (regReadValue != regWriteValue) {
    debug("Register CTRL_REG5 Write Validation failed! Written: 0x%02X, read back: 0x%02X",
        regWriteValue, regReadValue);
    return false;
  }
 
 
  debug("Initial Magnetic Field Sensor Readout");
  if (LIS3MDL_MAG_ReadReg(magFieldSensorHandle, LIS3MDL_MAG_OUTX_L, (uint8_t *)(&magFieldSensorData), 6)
      != MEMS_SUCCESS) { // Read once the all 3 axis to trigger the next Data Ready Signal
    debug("Magnetic Field Sensor Error: Readout to start first conversion failed!");
    return false;
  }

1 REPLY 1
Miroslav BATEK
ST Employee

You said: It happens directly after we (for testing) restart the MCU and re-initialize the sensor.

I think it is related to the MCU restart, can you capture the I2C signals and VDD during this operation (restart the MCU, sensor initialization, data reading).