cancel
Showing results for 
Search instead for 
Did you mean: 

LIS2MDL SPI 4 Wires

AKE1
Associate II

Hi,

I'm trying to use LIS2MDL magnetometer sensor with 4 wire bus but I'm encountering a problem with the library.

Here is my init function:

AKE1_1-1740668649031.png

lis2mdl.c library screenshot:

AKE1_0-1740668313869.png

On line 122,  my instance is always initialized (is_initialized=1) by the init function (line 113) so it always bypass the line 124 to init the SPI 4 wires.

I resolved the problem by replacing the == by != to force the program to init the 4 wires SPI. 

Is there a mistake in the library or do I do something wrong ? 

3 REPLIES 3

Please see How to insert source code - not as images.

AKE1
Associate II

 

/**
  ******************************************************************************
  * @file    lis2mdl.c
  * @author  MEMS Software Solutions Team
  * @brief   LIS2MDL driver file
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2019 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "lis2mdl.h"

/** @addtogroup BSP BSP
  * @{
  */

/** @addtogroup Component Component
  * @{
  */

/** @defgroup LIS2MDL LIS2MDL
  * @{
  */

/** @defgroup LIS2MDL_Exported_Variables LIS2MDL Exported Variables
  * @{
  */

LIS2MDL_CommonDrv_t LIS2MDL_COMMON_Driver =
{
  LIS2MDL_Init,
  LIS2MDL_DeInit,
  LIS2MDL_ReadID,
  LIS2MDL_GetCapabilities,
};

LIS2MDL_MAG_Drv_t LIS2MDL_MAG_Driver =
{
  LIS2MDL_MAG_Enable,
  LIS2MDL_MAG_Disable,
  LIS2MDL_MAG_GetSensitivity,
  LIS2MDL_MAG_GetOutputDataRate,
  LIS2MDL_MAG_SetOutputDataRate,
  LIS2MDL_MAG_GetFullScale,
  LIS2MDL_MAG_SetFullScale,
  LIS2MDL_MAG_GetAxes,
  LIS2MDL_MAG_GetAxesRaw,
};

/**
  * @}
  */

/** @defgroup LIS2MDL_Private_Function_Prototypes LIS2MDL Private Function Prototypes
  * @{
  */
static int32_t ReadMagRegWrap(void *Handle, uint8_t Reg, uint8_t *pData, uint16_t Length);
static int32_t WriteMagRegWrap(void *Handle, uint8_t Reg, uint8_t *pData, uint16_t Length);
static int32_t LSM6DSOX_SENSORHUB_LIS2MDL_ReadShData(LIS2MDL_Object_t *pObj, uint8_t Reg, uint8_t *pData,
                                                     uint16_t Length);
static int32_t LSM6DSOX_SENSORHUB_LIS2MDL_WriteShData(LIS2MDL_Object_t *pObj, uint8_t Reg, uint8_t *pData,
                                                      uint16_t Length);

/**
  * @}
  */

/** @defgroup LIS2MDL_Exported_Functions LIS2MDL Exported Functions
  * @{
  */

/**
  * @brief  Register Component Bus IO operations
  * @PAram  pObj the device pObj
  * @retval 0 in case of success, an error code otherwise
  */
int32_t LIS2MDL_RegisterBusIO(LIS2MDL_Object_t *pObj, LIS2MDL_IO_t *pIO)
{
  int32_t ret = LIS2MDL_OK;

  if (pObj == NULL)
  {
    ret = LIS2MDL_ERROR;
  }
  else
  {
    pObj->IO.Init      = pIO->Init;
    pObj->IO.DeInit    = pIO->DeInit;
    pObj->IO.BusType   = pIO->BusType;
    pObj->IO.Address   = pIO->Address;
    pObj->IO.WriteReg  = pIO->WriteReg;
    pObj->IO.ReadReg   = pIO->ReadReg;
    pObj->IO.GetTick   = pIO->GetTick;

    pObj->Ctx.read_reg  = ReadMagRegWrap;
    pObj->Ctx.write_reg = WriteMagRegWrap;
    pObj->Ctx.mdelay    = pIO->Delay;
    pObj->Ctx.handle    = pObj;

    if (pObj->IO.Init == NULL)
    {
      ret = LIS2MDL_ERROR;
    }
    else if (pObj->IO.Init() != LIS2MDL_OK)
    {
      ret = LIS2MDL_ERROR;
    }
    else
    {
      if (pObj->IO.BusType != LIS2MDL_I2C_BUS) /* If the bus type is not I2C */
      {
        /* Disable I2C interface support and enable eventually SPI 4-Wires only the first time */
        if (pObj->is_initialized == 0U)
        {
          if (pObj->IO.BusType == LIS2MDL_SPI_4WIRES_BUS) /* SPI 4-Wires */
          {
            /* Enable SPI 4-Wires and disable I2C support on the component */
            uint8_t data = 0x34;

            if (LIS2MDL_Write_Reg(pObj, LIS2MDL_CFG_REG_C, data) != LIS2MDL_OK)
            {
              return LIS2MDL_ERROR;
            }
          }
          else if (pObj->IO.BusType == LSM6DSOX_SENSORHUB_LIS2MDL_I2C_BUS) /* LSM6DSOX SensorHub with LIS2MDL example */
          {
            /* Do nothing, just keep I2C support on the component */
            return ret;
          }
          else
          {
            /* Disable I2C interface on the component */
            if (lis2mdl_i2c_interface_set(&(pObj->Ctx), LIS2MDL_I2C_DISABLE) != LIS2MDL_OK)
            {
              return LIS2MDL_ERROR;
            }
          }
        }
      }
    }
  }

  return ret;
}

/**
  * @brief  Initialize the LIS2MDL sensor
  * @PAram  pObj the device pObj
  * @retval 0 in case of success, an error code otherwise
  */
int32_t LIS2MDL_Init(LIS2MDL_Object_t *pObj)
{
  lis2mdl_cfg_reg_a_t reg_a;
  lis2mdl_cfg_reg_c_t reg_c;

  if (pObj->IO.BusType == LSM6DSOX_SENSORHUB_LIS2MDL_I2C_BUS) /* LSM6DSOX SensorHub with LIS2MDL example */
  {
    /* Read configuration from CFG_REG_C & CFG_REG_A regs */
    if (LSM6DSOX_SENSORHUB_LIS2MDL_ReadShData(pObj, LIS2MDL_CFG_REG_C, (uint8_t *)&reg_c, 1) != LIS2MDL_OK)
    {
      return LIS2MDL_ERROR;
    }
    if (LSM6DSOX_SENSORHUB_LIS2MDL_ReadShData(pObj, LIS2MDL_CFG_REG_A, (uint8_t *)&reg_a, 1) != LIS2MDL_OK)
    {
      return LIS2MDL_ERROR;
    }

    /* Enable BDU */
    reg_c.bdu = PROPERTY_ENABLE;

    /* Self Test disabled. */
    reg_c.self_test = PROPERTY_DISABLE;

    /* Operating mode selection - power down */
    reg_a.md = LIS2MDL_POWER_DOWN;

    /* Output data rate selection */
    reg_a.odr = LIS2MDL_ODR_100Hz;

    /* Write configuration to CFG_REG_C & CFG_REG_A regs */
    if (LSM6DSOX_SENSORHUB_LIS2MDL_WriteShData(pObj, LIS2MDL_CFG_REG_C, (uint8_t *)&reg_c, 1) != LIS2MDL_OK)
    {
      return LIS2MDL_ERROR;
    }
    if (LSM6DSOX_SENSORHUB_LIS2MDL_WriteShData(pObj, LIS2MDL_CFG_REG_A, (uint8_t *)&reg_a, 1) != LIS2MDL_OK)
    {
      return LIS2MDL_ERROR;
    }
  }
  else
  {
    /* Enable BDU */
    if (lis2mdl_block_data_update_set(&(pObj->Ctx), PROPERTY_ENABLE) != LIS2MDL_OK)
    {
      return LIS2MDL_ERROR;
    }

    /* Operating mode selection - power down */
    if (lis2mdl_operating_mode_set(&(pObj->Ctx), LIS2MDL_POWER_DOWN) != LIS2MDL_OK)
    {
      return LIS2MDL_ERROR;
    }

    /* Output data rate selection */
    if (lis2mdl_data_rate_set(&(pObj->Ctx), LIS2MDL_ODR_100Hz) != LIS2MDL_OK)
    {
      return LIS2MDL_ERROR;
    }

    /* Self Test disabled. */
    if (lis2mdl_self_test_set(&(pObj->Ctx), PROPERTY_DISABLE) != LIS2MDL_OK)
    {
      return LIS2MDL_ERROR;
    }
  }

  pObj->is_initialized = 1;

  return LIS2MDL_OK;
}

 

AKE1
Associate II
void init_MAGNETO(void)
{
	LIS2MDL_IO_t IO_MAGNETO;
	LIS2MDL_Capabilities_t capabilities_MAGNETO;
	uint8_t ID_MAGNETO = 0U;

	IO_MAGNETO.Init = LIS2MDL_Init;
	IO_MAGNETO.DeInit = LIS2MDL_DeInit;
	IO_MAGNETO.BusType = LIS2MDL_SPI_4WIRES_BUS;
	IO_MAGNETO.WriteReg = LIS2MDL_WriteReg_SPI;
	IO_MAGNETO.ReadReg = LIS2MDL_ReadReg_SPI;

	LIS2MDL_RegisterBusIO(&MAGNETO, &IO_MAGNETO);
	LIS2MDL_GetCapabilities(&MAGNETO, &capabilities_MAGNETO);

	HAL_Delay(20);

	LIS2MDL_ReadID(&MAGNETO, &ID_MAGNETO);
	if (ID_MAGNETO != LIS2MDL_ID)
	{
		Error_Handler();
	}

	LIS2MDL_MAG_Enable(&MAGNETO);
}