Skip to main content
Visitor II
February 27, 2025
Question

LIS2MDL SPI 4 Wires

  • February 27, 2025
  • 3 replies
  • 578 views

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 ? 

    This topic has been closed for replies.

    3 replies

    Super User
    February 27, 2025

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

    AKE1Author
    Visitor II
    February 27, 2025

     

    /**
     ******************************************************************************
     * @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;
    }

     

    AKE1Author
    Visitor II
    February 27, 2025
    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);
    }