这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » STM32 » 说说SensorTile例程里传感器配置的文件结构

共1条 1/1 1 跳转至

说说SensorTile例程里传感器配置的文件结构

菜鸟
2017-06-13 15:09:19     打赏

STSW-STLKT01例程里的LSM6DSM加速度传感器的初始化为例分析一下各种函数是怎么调用的

 

绘图2.png (719.56 KB, 下载次数: 2)

下载附件  保存到相册

2017-1-21 23:23 上传

 

main.c文件中有一个initializeAllSensors函数,用来初始化所有传感器

通过调用BSP_ACCELERO_Init( LSM6DSM_X_0, &LSM6DSM_X_0_handle ) 实现LSM6DSM加速度传感器的初始化

  if (BSP_ACCELERO_Init( LSM6DSM_X_0, &LSM6DSM_X_0_handle ) != COMPONENT_OK)

  {

    while(1);

  }

BSP_ACCELERO_Init函数在SensorTile_accelero.c

现在的文件关系是main.c ->SensorTile_accelero.c

SensorTile_accelero.c里的DrvStatusTypeDef BSP_ACCELERO_Init( ACCELERO_ID_t id, void **handle )函数通过id来判断初始化哪个加速度传感器

因为SensorTile上有2IC都有加速度功能

idACCELERO_SENSORS_AUTO时先初始化LSM6DSM里的加速度传感器,如果LSM6DSM初始化失败再初始化LSM303AGR

idLSM6DSM_X_0时初始化LSM6DSM

idLSM303AGR_X_0时初始化LSM303AGR

见下边代码

DrvStatusTypeDef BSP_ACCELERO_Init( ACCELERO_ID_t id, void **handle )

{

 

  *handle = NULL;

 

  switch(id)

  {

    case ACCELERO_SENSORS_AUTO:

    default:

    { 

      /* Try to init the LSM6DSM before */

      if(BSP_LSM6DSM_ACCELERO_Init(handle) == COMPONENT_ERROR )

      {

        /* Normally it must not happen */

        /* Try to init the LSM303AGR accelerometer */

        if( BSP_LSM303AGR_ACCELERO_Init(handle) == COMPONENT_ERROR )

        {

          return COMPONENT_ERROR;

        }

      }

      break;

    }

    case LSM6DSM_X_0:

    {

      if( BSP_LSM6DSM_ACCELERO_Init(handle) == COMPONENT_ERROR )

      {

        return COMPONENT_ERROR;

      }

      break;

    }

    case LSM303AGR_X_0:

    {

      if( BSP_LSM303AGR_ACCELERO_Init(handle) == COMPONENT_ERROR )

      {

        return COMPONENT_ERROR;

      }

      break;

    }

  }

 

  return COMPONENT_OK;

}

 

 

idLSM6DSM_X_0 时执行了static DrvStatusTypeDef BSP_LSM6DSM_ACCELERO_Init( void **handle )函数

 

static DrvStatusTypeDef BSP_LSM6DSM_ACCELERO_Init( void **handle )

{

  ACCELERO_Drv_t *driver = NULL;

  uint8_t data = 0x0C;

   

  if(ACCELERO_SensorHandle[ LSM6DSM_X_0 ].isInitialized == 1)

  {

    /* We have reached the max num of instance for this component */

    return COMPONENT_ERROR;

  }

 

  if ( Sensor_IO_SPI_Init() == COMPONENT_ERROR )

  {

    return COMPONENT_ERROR;

  }

 

  /* Setup sensor handle. */

  ACCELERO_SensorHandle[ LSM6DSM_X_0 ].who_am_i      = LSM6DSM_ACC_GYRO_WHO_AM_I;

  ACCELERO_SensorHandle[ LSM6DSM_X_0 ].ifType        = 1; // SPI interface

  ACCELERO_SensorHandle[ LSM6DSM_X_0 ].address       = LSM6DSM_ACC_GYRO_I2C_ADDRESS;

  ACCELERO_SensorHandle[ LSM6DSM_X_0 ].spiDevice     = LSM6DSM;

  ACCELERO_SensorHandle[ LSM6DSM_X_0 ].instance      = LSM6DSM_X_0;

  ACCELERO_SensorHandle[ LSM6DSM_X_0 ].isInitialized = 0;

  ACCELERO_SensorHandle[ LSM6DSM_X_0 ].isEnabled     = 0;

  ACCELERO_SensorHandle[ LSM6DSM_X_0 ].isCombo       = 1;

  ACCELERO_SensorHandle[ LSM6DSM_X_0 ].pData         = ( void * )&ACCELERO_Data[ LSM6DSM_X_0 ];

  ACCELERO_SensorHandle[ LSM6DSM_X_0 ].pVTable       = ( void * )&LSM6DSM_X_Drv;

  ACCELERO_SensorHandle[ LSM6DSM_X_0 ].pExtVTable    = ( void * )&LSM6DSM_X_ExtDrv;

 

  LSM6DSM_X_0_Data.comboData = &LSM6DSM_Combo_Data[0];

  ACCELERO_Data[ LSM6DSM_X_0 ].pComponentData = ( void * )&LSM6DSM_X_0_Data;

  ACCELERO_Data[ LSM6DSM_X_0 ].pExtData       = 0;

 

  *handle = (void *)&ACCELERO_SensorHandle[ LSM6DSM_X_0 ];

 

  Sensor_IO_SPI_CS_Init(*handle);

 

  if(LSM6DSM_Combo_Data[0].isGyroInitialized == 0)

  {

    // SPI Serial Interface Mode selection --> 3Wires

    if( Sensor_IO_Write(*handle, LSM6DSM_ACC_GYRO_CTRL3_C, &data, 1) )

    {

      return COMPONENT_ERROR;

    }

  }

 

  driver = ( ACCELERO_Drv_t * )((DrvContextTypeDef *)(*handle))->pVTable;

 

  if ( driver->Init == NULL )

  {

    memset((*handle), 0, sizeof(DrvContextTypeDef));

    *handle = NULL;

    return COMPONENT_ERROR;

  }

 

  if ( driver->Init( (DrvContextTypeDef *)(*handle) ) == COMPONENT_ERROR )

  {

    memset((*handle), 0, sizeof(DrvContextTypeDef));

    *handle = NULL;

    return COMPONENT_ERROR;

  }

 

  /* Configure interrupt lines for LSM6DSM */

  LSM6DSM_Sensor_IO_ITConfig();

 

  return COMPONENT_OK;

}

 

 

红字部分  ACCELERO_SensorHandle[ LSM6DSM_X_0 ].pVTable  = ( void * )&LSM6DSM_X_Drv;中的LSM6DSM_X_Drv类型为ACCELERO_Drv_t结构体,结构体中定义了一些基本函数

LSM6DSM_X_ExtDrv定义了一些额外的扩展函数

 

typedef struct

{

  DrvStatusTypeDef ( *Init            ) ( DrvContextTypeDef* );

  DrvStatusTypeDef ( *DeInit          ) ( DrvContextTypeDef* );

  DrvStatusTypeDef ( *Sensor_Enable   ) ( DrvContextTypeDef* );

  DrvStatusTypeDef ( *Sensor_Disable  ) ( DrvContextTypeDef* );

  DrvStatusTypeDef ( *Get_WhoAmI      ) ( DrvContextTypeDef*, uint8_t* );

  DrvStatusTypeDef ( *Check_WhoAmI    ) ( DrvContextTypeDef* );

  DrvStatusTypeDef ( *Get_Axes        ) ( DrvContextTypeDef*, SensorAxes_t* );

  DrvStatusTypeDef ( *Get_AxesRaw     ) ( DrvContextTypeDef*, SensorAxesRaw_t* );

  DrvStatusTypeDef ( *Get_Sensitivity ) ( DrvContextTypeDef*, float* );

  DrvStatusTypeDef ( *Get_ODR         ) ( DrvContextTypeDef*, float* );

  DrvStatusTypeDef ( *Set_ODR         ) ( DrvContextTypeDef*, SensorOdr_t );

  DrvStatusTypeDef ( *Set_ODR_Value   ) ( DrvContextTypeDef*, float );

  DrvStatusTypeDef ( *Get_FS          ) ( DrvContextTypeDef*, float* );

  DrvStatusTypeDef ( *Set_FS          ) ( DrvContextTypeDef*, SensorFs_t );

  DrvStatusTypeDef ( *Set_FS_Value    ) ( DrvContextTypeDef*, float );

  DrvStatusTypeDef ( *Get_Axes_Status ) ( DrvContextTypeDef*, uint8_t* );

  DrvStatusTypeDef ( *Set_Axes_Status ) ( DrvContextTypeDef*, uint8_t* );

} ACCELERO_Drv_t;

 

 

typedef struct

{

 

  /* Identity */

  uint8_t who_am_i;

 

  /* Configuration */

  uint8_t ifType;        /* 0 means I2C, 1 means SPI, etc. */

  uint8_t address;       /* Sensor I2C address (NOTE: Not a unique sensor ID). */

  uint8_t spiDevice;     /* Sensor Chip Select for SPI Bus */

  uint8_t instance;      /* Sensor instance (NOTE: Sensor ID unique only within its class). */

  uint8_t isInitialized; /* Sensor setup done. */

  uint8_t isEnabled;     /* Sensor ON. */

  uint8_t isCombo;       /* Combo sensor (component consists of more sensors). */

 

  /* Pointer to the Data */

  void *pData;

 

  /* Pointer to the Virtual Table */

  void *pVTable;

  /* Pointer to the Extended Virtual Table */

  void *pExtVTable;

} DrvContextTypeDef;

 

 

初始化的时候把LSM6DSM_ACC_GYRO_driver_HL.c里的基本函数填了进去

ACCELERO_Drv_t LSM6DSM_X_Drv =

{

  LSM6DSM_X_Init,

  LSM6DSM_X_DeInit,

  LSM6DSM_X_Sensor_Enable,

  LSM6DSM_X_Sensor_Disable,

  LSM6DSM_X_Get_WhoAmI,

  LSM6DSM_X_Check_WhoAmI,

  LSM6DSM_X_Get_Axes,

  LSM6DSM_X_Get_AxesRaw,

  LSM6DSM_X_Get_Sensitivity,

  LSM6DSM_X_Get_ODR,

  LSM6DSM_X_Set_ODR,

  LSM6DSM_X_Set_ODR_Value,

  LSM6DSM_X_Get_FS,

  LSM6DSM_X_Set_FS,

  LSM6DSM_X_Set_FS_Value,

  0,

  0

};

 

现在的文件关系是main.c ->SensorTile_accelero.c –> LSM6DSM_ACC_GYRO_driver_HL.c

BSP_LSM6DSM_ACCELERO_Init函数后来通过

driver = ( ACCELERO_Drv_t * )((DrvContextTypeDef *)(*handle))->pVTable;

pVTable赋值给driver

接下来判断driver->Init是否为空

if ( driver->Init == NULL )

然后通过driver->Init调用LSM6DSM_ACC_GYRO_driver_HL.c 中的LSM6DSM_X_Init函数

if ( driver->Init( (DrvContextTypeDef *)(*handle) ) == COMPONENT_ERROR )

初始化函数LSM6DSM_X_Init如下

 

static DrvStatusTypeDef LSM6DSM_X_Init( DrvContextTypeDef *handle )

{

 

  ACCELERO_Data_t *pData = ( ACCELERO_Data_t * )handle->pData;

  LSM6DSM_X_Data_t *pComponentData = ( LSM6DSM_X_Data_t * )pData->pComponentData;

  LSM6DSM_Combo_Data_t *comboData = pComponentData->comboData;

 

  if ( LSM6DSM_Check_WhoAmI( handle ) == COMPONENT_ERROR )

  {

    return COMPONENT_ERROR;

  }

 

  /* Enable register address automatically incremented during a multiple byte

     access with a serial interface. */

  if ( LSM6DSM_ACC_GYRO_W_IF_Addr_Incr( (void *)handle, LSM6DSM_ACC_GYRO_IF_INC_ENABLED ) == MEMS_ERROR )

  {

    return COMPONENT_ERROR;

  }

 

  /* Enable BDU */

  if ( LSM6DSM_ACC_GYRO_W_BDU( (void *)handle, LSM6DSM_ACC_GYRO_BDU_BLOCK_UPDATE ) == MEMS_ERROR )

  {

    return COMPONENT_ERROR;

  }

 

  /* FIFO mode selection */

  if ( LSM6DSM_ACC_GYRO_W_FIFO_MODE( (void *)handle, LSM6DSM_ACC_GYRO_FIFO_MODE_BYPASS ) == MEMS_ERROR )

  {

    return COMPONENT_ERROR;

  }

 

  /* Select default output data rate. */

  pComponentData->Previous_ODR = 104.0f;

 

  /* Output data rate selection - power down. */

  if ( LSM6DSM_ACC_GYRO_W_ODR_XL( (void *)handle, LSM6DSM_ACC_GYRO_ODR_XL_POWER_DOWN ) == MEMS_ERROR )

  {

    return COMPONENT_ERROR;

  }

 

  /* Full scale selection. */

  if ( LSM6DSM_X_Set_FS( handle, FS_LOW ) == COMPONENT_ERROR )

  {

    return COMPONENT_ERROR;

  }

 

  comboData->isAccInitialized = 1;

 

  handle->isInitialized = 1;

 

  return COMPONENT_OK;

}

 

 

LSM6DSM_X_Init函数第一步先判断WhoAmI是否正确

  if ( LSM6DSM_Check_WhoAmI( handle ) == COMPONENT_ERROR )

  {

    return COMPONENT_ERROR;

  }

LSM6DSM_ACC_GYRO_driver_HL.c 中的LSM6DSM_Check_WhoAmI函数

 

static DrvStatusTypeDef LSM6DSM_Check_WhoAmI( DrvContextTypeDef *handle )

{

 

  uint8_t who_am_i = 0x00;

 

  if ( LSM6DSM_Get_WhoAmI( handle, &who_am_i ) == COMPONENT_ERROR )

  {

    return COMPONENT_ERROR;

  }

  if ( who_am_i != handle->who_am_i )

  {

    return COMPONENT_ERROR;

  }

 

  return COMPONENT_OK;

}

 

 

LSM6DSM_Check_WhoAmI函数通过LSM6DSM_Get_WhoAmI函数来读取WhoAmI

static DrvStatusTypeDef LSM6DSM_Get_WhoAmI( DrvContextTypeDef *handle, uint8_t *who_am_i )

{

 

  /* Read WHO AM I register */

  if ( LSM6DSM_ACC_GYRO_R_WHO_AM_I( (void *)handle, ( uint8_t* )who_am_i ) == MEMS_ERROR )

  {

    return COMPONENT_ERROR;

  }

 

  return COMPONENT_OK;

}

 

LSM6DSM_Get_WhoAmI函数调用了LSM6DSM_ACC_GYRO_driver.c文件中的LSM6DSM_ACC_GYRO_R_WHO_AM_I函数

现在的文件关系是main.c ->SensorTile_accelero.c –> LSM6DSM_ACC_GYRO_driver_HL.c -> LSM6DSM_ACC_GYRO_driver.c

 

LSM6DSM_ACC_GYRO_R_WHO_AM_I函数通过LSM6DSM_ACC_GYRO_ReadReg函数来读对应的LSM6DSM_ACC_GYRO_WHO_AM_I_REG寄存器

status_t LSM6DSM_ACC_GYRO_R_WHO_AM_I(void *handle, u8_t *value)

{

 if( !LSM6DSM_ACC_GYRO_ReadReg(handle, LSM6DSM_ACC_GYRO_WHO_AM_I_REG, (u8_t *)value) )

    return MEMS_ERROR;

 

  *value &= LSM6DSM_ACC_GYRO_WHO_AM_I_BIT_MASK; //coerce   

  *value = *value >> LSM6DSM_ACC_GYRO_WHO_AM_I_BIT_POSITION; //mask

 

  return MEMS_SUCCESS;

}

 

 

LSM6DSM_ACC_GYRO_ReadReg函数调用SensorTile.c文件中的Sensor_IO_Read函数来读取寄存器数据

 

status_t LSM6DSM_ACC_GYRO_ReadReg(void *handle, u8_t Reg, u8_t* Data)

{

 

  if (Sensor_IO_Read(handle, Reg, Data, 1))

  {

    return MEMS_ERROR;

  }

  else

  {

    return MEMS_SUCCESS;

  }

}

 

 

现在的文件关系是main.c ->SensorTile_accelero.c –> LSM6DSM_ACC_GYRO_driver_HL.c -> LSM6DSM_ACC_GYRO_driver.c -> SensorTile.c

 

Sensor_IO_Read函数通过ifType来决定使用I2C总线还是SPI总线

BSP_LSM6DSM_ACCELERO_Init 函数里有一句话ACCELERO_SensorHandle[ LSM6DSM_X_0 ].ifType        = 1; // SPI interface

确定为使用SPI总线

通过调用Sensor_IO_SPI_Read函数通过SPI读取寄存器数据

 

uint8_t Sensor_IO_Read( void *handle, uint8_t ReadAddr, uint8_t *pBuffer, uint16_t nBytesToRead )

{

 

  DrvContextTypeDef *ctx = (DrvContextTypeDef *)handle;

 

  if(ctx->ifType == 0)

  {

    return Sensor_IO_I2C_Read( handle, ReadAddr, pBuffer, nBytesToRead );

  }

 

  if(ctx->ifType == 1)

  {

    return Sensor_IO_SPI_Read( handle, ReadAddr, pBuffer, nBytesToRead );

  }

 

  return COMPONENT_ERROR;

}

 

 

Sensor_IO_SPI_Read函数通过Sensor_IO_SPI_CS_Enable函数来控制CS线的输出

Sensor_IO_SPI_CS_Enable函数通过调用stm32l4xx_hal_gpio.c里的对应函数来控制CS线的电平

现在的文件关系是main.c ->SensorTile_accelero.c –> LSM6DSM_ACC_GYRO_driver_HL.c -> LSM6DSM_ACC_GYRO_driver.c -> SensorTile.c -> stm32l4xx_hal_gpio.c

 

uint8_t Sensor_IO_SPI_CS_Enable(void *handle)

{

  DrvContextTypeDef *ctx = (DrvContextTypeDef *)handle;

 

  switch(ctx->spiDevice)

  {

  case LSM6DSM:

    HAL_GPIO_WritePin(SENSORTILE_LSM6DSM_SPI_CS_Port, SENSORTILE_LSM6DSM_SPI_CS_Pin, GPIO_PIN_RESET);

    break;

  case LSM303AGR_X:

    HAL_GPIO_WritePin(SENSORTILE_LSM303AGR_X_SPI_CS_Port, SENSORTILE_LSM303AGR_X_SPI_CS_Pin, GPIO_PIN_RESET);

    break;

  case LSM303AGR_M:

    HAL_GPIO_WritePin(SENSORTILE_LSM303AGR_M_SPI_CS_Port, SENSORTILE_LSM303AGR_M_SPI_CS_Pin, GPIO_PIN_RESET);

    break;

  case LPS22HB:

    HAL_GPIO_WritePin(SENSORTILE_LPS22HB_SPI_CS_Port, SENSORTILE_LPS22HB_SPI_CS_Pin, GPIO_PIN_RESET);

    break;

  }

  return COMPONENT_OK;

}

 

 

同时Sensor_IO_SPI_Read函数通过调用SPI_WriteSPI_Read函数来读到数据

 

uint8_t Sensor_IO_SPI_Read( void *handle, uint8_t ReadAddr, uint8_t *pBuffer, uint16_t nBytesToRead )

{

  uint8_t i;

 

// Select the correct device

  Sensor_IO_SPI_CS_Enable(handle);

 

  SPI_Write(&SPI_Sensor_Handle, ReadAddr | 0x80);

//  SYNCHRO_WAIT(SYNCHRO_SPI_DELAY);

  __HAL_SPI_DISABLE(&SPI_Sensor_Handle);

  SPI_1LINE_RX(&SPI_Sensor_Handle);

//  SYNCHRO_WAIT(SYNCHRO_SPI_DELAY);

 

  for(i=0;i<nBytesToRead;i++)

  {

    SPI_Read(&SPI_Sensor_Handle, pBuffer++);

  }

//  SYNCHRO_WAIT(SYNCHRO_SPI_DELAY);

  SPI_1LINE_TX(&SPI_Sensor_Handle);

  __HAL_SPI_ENABLE(&SPI_Sensor_Handle);

//  SYNCHRO_WAIT(SYNCHRO_SPI_DELAY);

 

  // Deselect the device

  Sensor_IO_SPI_CS_Disable(handle);

 

  return COMPONENT_OK;

}

 

 

SPI_WriteSPI_Read直接操作SPI寄存器

 

/**

 * @brief  This function send a command through SPI bus.

 * @param  command : command id.

 * @param  val : value.

 * @retval None

 */

void SPI_Read(SPI_HandleTypeDef* xSpiHandle, uint8_t *val)

{

  /* In master RX mode the clock is automaticaly generated on the SPI enable.

  So to guarantee the clock generation for only one data, the clock must be

  disabled after the first bit and before the latest bit */

  /* Interrupts should be disabled during this operation */

 

  __disable_irq();

 

  __HAL_SPI_ENABLE(xSpiHandle);

  __asm("dsb\n");

  __asm("dsb\n");

  __HAL_SPI_DISABLE(xSpiHandle);

 

  __enable_irq();

 

  while ((xSpiHandle->Instance->SR & SPI_FLAG_RXNE) != SPI_FLAG_RXNE);

  /* read the received data */

  *val = *(__IO uint8_t *) &xSpiHandle->Instance->DR;

  while ((xSpiHandle->Instance->SR & SPI_FLAG_BSY) == SPI_FLAG_BSY);

}

 

/**

 * @brief  This function send a command through SPI bus.

 * @param  command : command id.

 * @param  val : value.

 * @retval None

 */

void SPI_Write(SPI_HandleTypeDef* xSpiHandle, uint8_t val)

{

  /* check TXE flag */

  while ((xSpiHandle->Instance->SR & SPI_FLAG_TXE) != SPI_FLAG_TXE);

 

  /* Write the data */

  *((__IO uint8_t*) &xSpiHandle->Instance->DR) = val;

 

  /* Wait BSY flag */

  while ((xSpiHandle->Instance->SR & SPI_FLAG_FTLVL) != SPI_FTLVL_EMPTY);

  while ((xSpiHandle->Instance->SR & SPI_FLAG_BSY) == SPI_FLAG_BSY);

}

 

 

 

 

同时Sensor_IO_SPI_Read函数还调用了stm32l4xx_hal_spi.h文件中的SPI_1LINE_RXSPI_1LINE_TX函数(宏定义)

 

 

/** @brief  Set the SPI transmit-only mode.

  * @param  __HANDLE__: specifies the SPI Handle.

  *         This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral.

  * @retval None

  */

#define SPI_1LINE_TX(__HANDLE__) ((__HANDLE__)->Instance->CR1 |= SPI_CR1_BIDIOE)

 

/** @brief  Set the SPI receive-only mode.

  * @param  __HANDLE__: specifies the SPI Handle.

  *         This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral.

  * @retval None

  */

#define SPI_1LINE_RX(__HANDLE__) ((__HANDLE__)->Instance->CR1 &= (~SPI_CR1_BIDIOE))

 

 

最后的文件关系是

main.c ->SensorTile_accelero.c –> LSM6DSM_ACC_GYRO_driver_HL.c -> LSM6DSM_ACC_GYRO_driver.c -> SensorTile.c -> stm32l4xx_hal_gpio.c

 

main.c ->SensorTile_accelero.c –> LSM6DSM_ACC_GYRO_driver_HL.c -> LSM6DSM_ACC_GYRO_driver.c -> SensorTile.c ->stm32l4xx_hal_spi.h




关键词: 传感器     SensorTile    

共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]