101 lines
5.0 KiB
C
101 lines
5.0 KiB
C
#include "bsp_dwt.h"
|
|
#include "ist8310.h"
|
|
#include "bsp_log.h"
|
|
#include <memory.h>
|
|
#include <stdlib.h>
|
|
|
|
// 一般这个模块只有一个实例,所以直接保存在这里,实际上不保存也可以,application可以自己保存
|
|
static IST8310Instance *ist8310_instance = NULL; // 用于存储IST8310实例的指针
|
|
|
|
#define IST8310_WRITE_REG_NUM 4 // 方便阅读
|
|
#define IST8310_DATA_REG 0x03 // ist8310的数据寄存器
|
|
#define IST8310_WHO_AM_I 0x00 // ist8310 id 寄存器值
|
|
#define IST8310_WHO_AM_I_VALUE 0x10 // 用于检测是否连接成功,读取ist8310的whoami会返回该值
|
|
|
|
// -------------------初始化写入数组,只使用一次,详见datasheet-------------------------
|
|
// the first column:the registers of IST8310. 第一列:IST8310的寄存器
|
|
// the second column: the value to be writed to the registers.第二列:需要写入的寄存器值
|
|
// the third column: return error value.第三列:返回的错误码
|
|
static uint8_t ist8310_write_reg_data_error[IST8310_WRITE_REG_NUM][3] = {
|
|
{0x0B, 0x08, 0x01}, // enalbe interrupt and low pin polarity.开启中断,并且设置低电平
|
|
{0x41, 0x09, 0x02}, // average 2 times.平均采样两次
|
|
{0x42, 0xC0, 0x03}, // must be 0xC0. 必须是0xC0
|
|
{0x0A, 0x0B, 0x04}}; // 200Hz output rate.200Hz输出频率
|
|
|
|
/**
|
|
* @brief IST8310解码函数,EXTI中断来临时被调用,将数据放到ist.mag中
|
|
* @note 如果使用IT或DMA方式传输IIC,则传输完成后也会进入此函数
|
|
*
|
|
* @param ist 发生中断的IST8310实例
|
|
*/
|
|
static void IST8310Decode(IICInstance *iic)
|
|
{
|
|
int16_t temp[3]; // 用于存储解码后的数据
|
|
IST8310Instance *ist = (IST8310Instance *)(iic->id); // iic的id保存了IST8310实例的指针(父指针)
|
|
|
|
memcpy(temp, ist->iic_buffer, 6 * sizeof(uint8_t)); // 不要强制转换,直接cpy
|
|
for (uint8_t i = 0; i < 3; i++)
|
|
ist->mag[i] = (float)temp[i] * MAG_SEN; // 乘以灵敏度转换成uT(微特斯拉)
|
|
}
|
|
|
|
/**
|
|
* @brief EXTI中断回调函数,说明DRDY拉低.主机启动传输并在结束后调用IST8310Decode进行数据解析
|
|
* @note 注意IICAccessMem是阻塞的
|
|
*
|
|
* @param gpio 发生中断的GPIO实例
|
|
*/
|
|
static void IST8310StartTransfer(GPIOInstance *gpio)
|
|
{
|
|
// 先获取IST8310实例的指针(通过gpio实例的父指针id)
|
|
IST8310Instance *ist_for_transfer = (IST8310Instance *)gpio->id;
|
|
// 中断说明ist已经准备好读取数据寄存器;6个字节,读取后会进入IST8310Decode函数
|
|
IICAccessMem(ist_for_transfer->iic, IST8310_DATA_REG, ist_for_transfer->iic_buffer, 6, IIC_READ_MEM, 1);
|
|
// 传输完成后会进入IST8310Decode函数进行数据解析
|
|
IST8310Decode(ist_for_transfer->iic);
|
|
}
|
|
|
|
IST8310Instance *IST8310Init(IST8310_Init_Config_s *config)
|
|
{
|
|
static const uint8_t sleepTime = 50; // 50ms,ist8310的复位时间
|
|
uint8_t check_who_i_am = 0; // 用于检测ist8310是否连接成功
|
|
// 这个变量只会用到一次,出了这个函数就没用了,所以不用分配空间,直接定义在栈上(因为多看一眼就会爆炸)
|
|
|
|
// 分配空间,清除flash防止已经填充的垃圾值
|
|
IST8310Instance *ist = (IST8310Instance *)malloc(sizeof(IST8310Instance));
|
|
memset(ist, 0, sizeof(IST8310Instance));
|
|
|
|
// c语言赋值从右到左,全部指向同一个地址(这些bspinstnace的父节点都是ist,即ist拥有这些instances)
|
|
config->iic_config.id = config->gpio_conf_exti.id = config->gpio_conf_rst.id = ist;
|
|
// 传入回调函数
|
|
config->iic_config.callback = IST8310Decode;
|
|
config->gpio_conf_exti.gpio_model_callback = IST8310StartTransfer;
|
|
// 分别注册两个GPIO和IIC
|
|
ist->iic = IICRegister(&config->iic_config);
|
|
ist->gpio_exti = GPIORegister(&config->gpio_conf_exti);
|
|
ist->gpio_rst = GPIORegister(&config->gpio_conf_rst);
|
|
|
|
// 重置IST8310,需要HAL_Delay()等待传感器完成Reset
|
|
GPIOReset(ist->gpio_rst);
|
|
HAL_Delay(sleepTime);
|
|
GPIOSet(ist->gpio_rst);
|
|
HAL_Delay(sleepTime);
|
|
|
|
// 读取IST8310的ID,如果不是0x10(whoami macro的值),则返回错误
|
|
IICAccessMem(ist->iic, IST8310_WHO_AM_I, &check_who_i_am, 1, IIC_READ_MEM, 1);
|
|
if (check_who_i_am != IST8310_WHO_AM_I_VALUE)
|
|
return NULL; // while(1)
|
|
|
|
// 进行初始化配置写入并检查是否写入成功,这里用循环把最上面初始化数组的东西都写进去
|
|
for (uint8_t i = 0; i < IST8310_WRITE_REG_NUM; i++)
|
|
{ // 写入配置,写一句就读一下看看ist8310是否仍然在线
|
|
IICAccessMem(ist->iic, ist8310_write_reg_data_error[i][0], &ist8310_write_reg_data_error[i][1], 1, IIC_WRITE_MEM, 1);
|
|
IICAccessMem(ist->iic, ist8310_write_reg_data_error[i][0], &check_who_i_am, 1, IIC_READ_MEM, 1); // 读回自身id
|
|
if (check_who_i_am != ist8310_write_reg_data_error[i][1])
|
|
while (1)
|
|
LOGERROR("[ist8310] init error, code %d", ist8310_write_reg_data_error[i][2]); // 掉线/写入失败/未知错误,会返回对应的错误码
|
|
}
|
|
|
|
ist8310_instance = ist; // 保存ist8310实例的指针
|
|
return ist;
|
|
}
|