LPS25HB 寄存器读写程序解读

LPS25HB 寄存器读写程序解读

一般地,芯片公司都会提供芯片驱动的一些驱动代码,以LPS25HB 为例,该Mems工作时,与主MCU通信通过IIC或者SPI的方式进行,从而实现Mems的寄存器的读写。

1、读写功能的统一接口函数

为了兼容IIC和SPI的通信,我们这里设计两个基于STM32 HAL 库的的读写函数platform_write()、platform_read():

static int32_t platform_write(void *handle, uint8_t Reg, uint8_t *Bufp,
                              uint16_t len)
{
  if (handle == &hi2c1)
  {
    /* enable auto incremented in multiple read/write commands */
    Reg |= 0x80;
    HAL_I2C_Mem_Write(handle, LPS25HB_I2C_ADD_L, Reg,
                      I2C_MEMADD_SIZE_8BIT, Bufp, len, 1000);
  }
#ifdef MKI109V2
  else if (handle == &hspi2)
  {
    /* enable auto incremented in multiple read/write commands */
    Reg |= 0x40;
    HAL_GPIO_WritePin(CS_SPI2_GPIO_Port, CS_SPI2_Pin, GPIO_PIN_RESET);
    HAL_SPI_Transmit(handle, &Reg, 1, 1000);
    HAL_SPI_Transmit(handle, Bufp, len, 1000);
    HAL_GPIO_WritePin(CS_SPI2_GPIO_Port, CS_SPI2_Pin, GPIO_PIN_SET);
  }
  else if (handle == &hspi1)
  {
    /* enable auto incremented in multiple read/write commands */
    Reg |= 0x40;
    HAL_GPIO_WritePin(CS_SPI1_GPIO_Port, CS_SPI1_Pin, GPIO_PIN_RESET);
    HAL_SPI_Transmit(handle, &Reg, 1, 1000);
    HAL_SPI_Transmit(handle, Bufp, len, 1000);
    HAL_GPIO_WritePin(CS_SPI1_GPIO_Port, CS_SPI1_Pin, GPIO_PIN_SET);
  }
#endif
  return 0;
}

static int32_t platform_read(void *handle, uint8_t Reg, uint8_t *Bufp,
                             uint16_t len)
{
  if (handle == &hi2c1)
  {
    /* enable auto incremented in multiple read/write commands */
    Reg |= 0x80;
    HAL_I2C_Mem_Read(handle, LPS25HB_I2C_ADD_L, Reg,
                     I2C_MEMADD_SIZE_8BIT, Bufp, len, 1000);
  }
#ifdef MKI109V2
  else if (handle == &hspi2)
  {
    /* enable auto incremented in multiple read/write commands */
    Reg |= 0xC0;
    HAL_GPIO_WritePin(CS_DEV_GPIO_Port, CS_DEV_Pin, GPIO_PIN_RESET);
    HAL_SPI_Transmit(handle, &Reg, 1, 1000);
    HAL_SPI_Receive(handle, Bufp, len, 1000);
    HAL_GPIO_WritePin(CS_DEV_GPIO_Port, CS_DEV_Pin, GPIO_PIN_SET);
  }
  else
  {
    /* enable auto incremented in multiple read/write commands */
    Reg |= 0xC0;
    HAL_GPIO_WritePin(CS_RF_GPIO_Port, CS_RF_Pin, GPIO_PIN_RESET);
    HAL_SPI_Transmit(handle, &Reg, 1, 1000);
    HAL_SPI_Receive(handle, Bufp, len, 1000);
    HAL_GPIO_WritePin(CS_RF_GPIO_Port, CS_RF_Pin, GPIO_PIN_SET);
  }
#endif
  return 0;
}

2、设计结构体函数指针来调用统一的读写函数

typedef int32_t (*lps25hb_write_ptr)(void *, uint8_t, uint8_t*, uint16_t);
typedef int32_t (*lps25hb_read_ptr) (void *, uint8_t, uint8_t*, uint16_t);

typedef struct {
  /** Component mandatory fields **/
  lps25hb_write_ptr  write_reg;
  lps25hb_read_ptr   read_reg;
  /** Customizable optional pointer **/
  void *handle;
} lps25hb_ctx_t;

这样我们定义了一个结构体lps25hb_ctx_t,该结构体中设计了三个指针。通过声明一个该结构体的变量,将变量的成员指向统一的读写结构函数。

 /* Initialize mems driver interface */
  lps25hb_ctx_t dev_ctx;
  dev_ctx.write_reg = platform_write;
  dev_ctx.read_reg = platform_read;
  dev_ctx.handle = &hi2c1;

这样Mems 的驱动接口就实现了。但是为了程序更好的可读性,我们需要将Mems 寄存器读写的具体功能函数进一步实现。

这里我们设计与上层接口函数无关的寄存器读写函数,利用还函数实现Mems内部所有寄存器的读写。

3、与通信方式无关的寄存器读写抽象函数接口

/**
  * @brief  Read generic device register
  *
  * @param  ctx   read / write interface definitions(ptr)
  * @param  reg   register to read
  * @param  data  pointer to buffer that store the data read(ptr)
  * @param  len   number of consecutive register to read
  * @retval       interface status (MANDATORY: return 0 -> no Error)
  *
  */
int32_t lps25hb_read_reg(lps25hb_ctx_t* ctx, uint8_t reg, uint8_t* data,
                         uint16_t len)
{
  int32_t ret;
  ret = ctx->read_reg(ctx->handle, reg, data, len);
  return ret;
}

/**
  * @brief  Write generic device register
  *
  * @param  ctx   read / write interface definitions(ptr)
  * @param  reg   register to write
  * @param  data  pointer to data to write in register reg(ptr)
  * @param  len   number of consecutive register to write
  * @retval       interface status (MANDATORY: return 0 -> no Error)
  *
  */
int32_t lps25hb_write_reg(lps25hb_ctx_t* ctx, uint8_t reg, uint8_t* data,
                          uint16_t len)
{
  int32_t ret;
  ret = ctx->write_reg(ctx->handle, reg, data, len);
  return ret;
}

这样,我们就实现了接口函数的对应关系在这里插入图片描述

于是,我们可以根据Mems的寄存器表进行相关的寄存器读写设计了。

如:


/**
  * @brief  The Reference pressure value is a 24-bit data expressed as 2’s
  *         complement. The value is used when AUTOZERO or AUTORIFP function
  *         is enabled.[set]
  *
  * @param  ctx    Read / write interface definitions.(ptr)
  * @param  buff   Buffer that contains data to write
  * @retval        Interface status (MANDATORY: return 0 -> no Error).
  *
  */
int32_t lps25hb_pressure_ref_set(lps25hb_ctx_t *ctx, uint8_t *buff)
{
  int32_t ret;
  ret = lps25hb_read_reg(ctx, LPS25HB_REF_P_XL,  buff, 3);
  return ret;
}

/**
  * @brief  The Reference pressure value is a 24-bit data expressed as 2’s
  *         complement. The value is used when AUTOZERO or AUTORIFP function
  *         is enabled.[get]
  *
  * @param  ctx    Read / write interface definitions.(ptr)
  * @param  buff   Buffer that stores data read.(ptr)
  * @retval        Interface status (MANDATORY: return 0 -> no Error).
  *
  */
int32_t lps25hb_pressure_ref_get(lps25hb_ctx_t *ctx, uint8_t *buff)
{
  int32_t ret;
  ret = lps25hb_read_reg(ctx, LPS25HB_REF_P_XL,  buff, 3);
  return ret;
}

4、寄存器的数据描述:
寄存器表的数据描述包括 define 定义、结构体数据类型定义、枚举变量的定义

例如:


#define LPS25HB_CTRL_REG1       0x20U
typedef struct {
  uint8_t sim              : 1;
  uint8_t reset_az         : 1;
  uint8_t bdu              : 1;
  uint8_t diff_en          : 1;
  uint8_t odr              : 4; /* pd + odr -> odr */
} lps25hb_ctrl_reg1_t;

#define LPS25HB_CTRL_REG2       0x21U
typedef struct {
  uint8_t one_shot         : 1;
  uint8_t autozero         : 1;
  uint8_t swreset          : 1;
  uint8_t i2c_dis          : 1;
  uint8_t fifo_mean_dec    : 1;
  uint8_t stop_on_fth      : 1;
  uint8_t fifo_en          : 1;
  uint8_t boot             : 1;
} lps25hb_ctrl_reg2_t;

#define LPS25HB_CTRL_REG3       0x22U
typedef struct {
  uint8_t int_s           : 2;
  uint8_t not_used_01     : 4;
  uint8_t pp_od           : 1;
  uint8_t int_h_l         : 1;
} lps25hb_ctrl_reg3_t;

#define LPS25HB_CTRL_REG4       0x23U
typedef struct {
  uint8_t drdy            : 1;
  uint8_t f_ovr           : 1;
  uint8_t f_fth           : 1;
  uint8_t f_empty         : 1;
  uint8_t not_used_01     : 4;
} lps25hb_ctrl_reg4_t;


typedef enum {
  LPS25HB_BYPASS_MODE               = 0,
  LPS25HB_FIFO_MODE                 = 1,
  LPS25HB_STREAM_MODE               = 2,
  LPS25HB_Stream_to_FIFO_mode      = 3,
  LPS25HB_BYPASS_TO_STREAM_MODE    = 4,
  LPS25HB_MEAN_MODE                 = 6,
  LPS25HB_BYPASS_TO_FIFO_MODE      = 7,
} lps25hb_f_mode_t;

这样,依赖这些个寄存器变量的描述,设计相关的具体的某一个寄存器读写函数,Mems 的驱动程序代码就可以轻松实现了。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值