嵌入式杂货铺

1 驱动层开发

1.1 器件读写接口

  嵌入式产品中的器件,如传感器,都需要通过 SPI/I2C 等接口实现配置和功能应用。在不同的开发平台上,SPI/I2C 读写的 API 接口是不一样的。因此,在编写器件驱动程序时,首先会封装出 SPI/I2C 的读写函数,屏蔽掉平台接口的影响。
  下面通过几个例子来分享下器件驱动编写时的技巧方法。

案例一 (STM32-I2C)

  简单地,在 STM32 平台上的 Max17050 的 I2C 驱动接口可如下所示,这样做的好处

  • 经过第一级封装,屏蔽掉了平台的 API 接口及其错误提醒
  • 经过第二级封装,屏蔽掉了两个不同器件的 I2C 地址,输入参数聚焦在要写入的寄存器和寄存器值
HAL_StatusTypeDef charger_box_i2c_write_byte_poll(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)
{
    HAL_StatusTypeDef state = HAL_OK;
    state = HAL_I2C_Mem_Write(hi2c, DevAddress, MemAddress, MemAddSize, pData, Size, Timeout);
    if(state != HAL_OK)
    {
        I2C_ERROR_Handler(hi2c);
    }
    return state;
}

HAL_StatusTypeDef bsp_ir_driver_pa2240_write_register(IR_ID_E ir_id, uint8_t register_addr, uint8_t register_value)
{
    if(ir_id == IR_ID_LEFT)
    {
        return charger_box_i2c_write_byte_poll(&hi2c1, PA22A_I2C_ADDRESS, register_addr, 1, &register_value, 1, 1000);
    }
    else if( ir_id == IR_ID_RIGHT)
    {
        return charger_box_i2c_write_byte_poll(&hi2c2, PA22A_I2C_ADDRESS, register_addr, 1, &register_value, 1, 1000);
    }
    else
    {
        return HAL_ERROR;
    }
}
案例二 (Nordic-I2C)

   STM32 I2C 读写 API 中,器件地址,寄存器地址和寄存器值是分开的,但在其他平台中,要求寄存器地址和寄存器值合并在一起作为写入数据,如 Nordic 平台。
   此时有两种处理方法,一种是寄存器地址和寄存器值分别调用一条 API 写入另一是将寄存器地址和寄存器值合并后调用一条 API 写入

static int32_t platform_write(void *handle, uint8_t reg, uint8_t *pbuf,
                              uint16_t len)
{
	nrf_drv_twi_tx(handle, LIS2DW12_ADDR, &reg, 1, false);   // 发送寄存器地址
    nrf_drv_twi_tx(handle, LIS2DW12_ADDR, pbuf, len, false); // 发送寄存器值

    return 0;
}
static uint8_t Txbuff[10];
static volatile bool twi_xfer_done = false;

static int32_t platform_write(void *handle, uint8_t reg, uint8_t *pbuf,
                              uint16_t len)
{
    Txbuff[0] = reg;
    memcpy((Txbuff + 1), pbuf, len);

    twi_xfer_done = false;
    do{
        nrf_drv_twi_tx(handle, LIS2DW12_ADDR, Txbuff, len + 1, false);
    }while(!twi_xfer_done);
    
    return 0;
}
案例三 (Cypress-SPI)

  相比 I2C 标准协议,采用 SPI 通信的器件对 SPI 发送的数据序列和数据大小可能会有个性化规定,如 MAX86141,要求发送的第一个 byte 为寄存器地址,第二个 byte 为读写模式,第三个 byte 才是寄存器值。

void MAX86141_ReadByte(uint8_t Reg_addr,uint8_t *pBuf , uint8_t Len)
{
	uint8_t data_arr[3] = {0};
	
	data_arr[0] = Reg_addr;
	data_arr[1] = READ_IC_MODE;         //READ =0x80
	MAX86141_ENABLE;
	wiced_hal_pspi_tx_data(SPI1,2, data_arr);
	wiced_hal_pspi_rx_data(SPI1,Len, pBuf);
	MAX86141_DISABLE;
	
}

void MAX86141_WriteByte(uint8_t Reg_addr, uint8_t Data)
{
	uint8_t data_arr[3] = {0};
	
	data_arr[0] = Reg_addr;
	data_arr[1] = WRITE_IC_MODE;
	data_arr[2] = Data;
	MAX86141_ENABLE;
	wiced_hal_pspi_tx_data(SPI1,3, data_arr);
	MAX86141_DISABLE;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

la_fe_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值