feat: continuous sensor sampling (10Hz attitude) + LoRa on-demand power + I2C driver hardening
- LSM6DSL: ODR 12.5->52Hz high-performance, gyro FS 2000->500dps, FIFO stream mode, watermark 4 sets (24 words) interrupt driven, 4-sample average output 13Hz, 1s no-data watchdog auto recovery - MMC5983: enable 20Hz continuous measurement mode (was dead code), remove per-read SW_RST, STATUS polling + INT dual path, write-1-clear Meas_M_Done to release INT latch, 2-sample average output 10Hz, timeout auto recovery - I2C driver: add wait timeout and state machine retry limit to read/write, NACK fast-return FALSE, eliminate bus-stuck infinite loop - main.c: continuous acquire loop (no IDLE dead-end on first failure), keep UpdateOk valid to fix up/coll command race, TimingAcquisition compatible with continuous mode, add LoraPowerHandler (LoRa RX during comm, sleep otherwise, saves ~10mA), remove 10Hz hot-path debug prints - Attitude update ~10Hz (IMU 13Hz / mag 10Hz), gateway upload cadence unchanged
This commit is contained in:
+112
-78
@@ -66,11 +66,11 @@
|
||||
|
||||
/**
|
||||
******************************************************************************
|
||||
** \brief I2C设置波特率配置寄存器
|
||||
** \brief I2C设置波特率配置寄存器
|
||||
**
|
||||
** \param [in] u8Tm 波特率配置值
|
||||
** \param [in] u8Tm 波特率配置值
|
||||
**
|
||||
** \retval enRet 成功或失败
|
||||
** \retval enRet 成功或失败
|
||||
**
|
||||
******************************************************************************/
|
||||
en_result_t I2C_SetBaud(M0P_I2C_TypeDef* I2Cx, uint8_t u8Tm)
|
||||
@@ -84,11 +84,11 @@
|
||||
}
|
||||
/**
|
||||
******************************************************************************
|
||||
** \brief I2C功能设置相关函数
|
||||
** \brief I2C功能设置相关函数
|
||||
**
|
||||
** \param [in] enFunc功能参数
|
||||
** \param [in] enFunc功能参数
|
||||
**
|
||||
** \retval enRet 成功或失败
|
||||
** \retval enRet 成功或失败
|
||||
**
|
||||
******************************************************************************/
|
||||
en_result_t I2C_SetFunc(M0P_I2C_TypeDef* I2Cx, en_i2c_func_t enFunc)
|
||||
@@ -102,11 +102,11 @@ en_result_t I2C_SetFunc(M0P_I2C_TypeDef* I2Cx, en_i2c_func_t enFunc)
|
||||
}
|
||||
/**
|
||||
******************************************************************************
|
||||
** \brief I2C功能清除相关函数
|
||||
** \brief I2C功能清除相关函数
|
||||
**
|
||||
** \param [in] enFunc功能参数
|
||||
** \param [in] enFunc功能参数
|
||||
**
|
||||
** \retval enRet 成功或失败
|
||||
** \retval enRet 成功或失败
|
||||
**
|
||||
******************************************************************************/
|
||||
en_result_t I2C_ClearFunc(M0P_I2C_TypeDef* I2Cx, en_i2c_func_t enFunc)
|
||||
@@ -120,11 +120,11 @@ en_result_t I2C_SetFunc(M0P_I2C_TypeDef* I2Cx, en_i2c_func_t enFunc)
|
||||
}
|
||||
/**
|
||||
******************************************************************************
|
||||
** \brief I2C获取中断标记函数
|
||||
** \brief I2C获取中断标记函数
|
||||
**
|
||||
** \param 无
|
||||
** \param 无
|
||||
**
|
||||
** \retval bIrq中断标记
|
||||
** \retval bIrq中断标记
|
||||
**
|
||||
******************************************************************************/
|
||||
boolean_t I2C_GetIrq(M0P_I2C_TypeDef* I2Cx)
|
||||
@@ -140,11 +140,11 @@ boolean_t I2C_GetIrq(M0P_I2C_TypeDef* I2Cx)
|
||||
}
|
||||
/**
|
||||
******************************************************************************
|
||||
** \brief I2C清除中断标记函数
|
||||
** \brief I2C清除中断标记函数
|
||||
**
|
||||
** \param 无
|
||||
** \param 无
|
||||
**
|
||||
** \retval bIrq中断标记
|
||||
** \retval bIrq中断标记
|
||||
**
|
||||
******************************************************************************/
|
||||
en_result_t I2C_ClearIrq(M0P_I2C_TypeDef* I2Cx)
|
||||
@@ -158,11 +158,11 @@ en_result_t I2C_ClearIrq(M0P_I2C_TypeDef* I2Cx)
|
||||
}
|
||||
/**
|
||||
******************************************************************************
|
||||
** \brief I2C获取相关状态
|
||||
** \brief I2C获取相关状态
|
||||
**
|
||||
** \param 无
|
||||
** \param 无
|
||||
**
|
||||
** \retval I2C状态
|
||||
** \retval I2C状态
|
||||
**
|
||||
******************************************************************************/
|
||||
uint8_t I2C_GetState(M0P_I2C_TypeDef* I2Cx)
|
||||
@@ -176,11 +176,11 @@ uint8_t I2C_GetState(M0P_I2C_TypeDef* I2Cx)
|
||||
|
||||
/**
|
||||
******************************************************************************
|
||||
** \brief 字节数据写函数
|
||||
** \brief 字节数据写函数
|
||||
**
|
||||
** \param u8Data写数据
|
||||
** \param u8Data写数据
|
||||
**
|
||||
** \retval 写数据是否成功
|
||||
** \retval 写数据是否成功
|
||||
**
|
||||
******************************************************************************/
|
||||
en_result_t I2C_WriteByte(M0P_I2C_TypeDef* I2Cx, uint8_t u8Data)
|
||||
@@ -194,11 +194,11 @@ en_result_t I2C_WriteByte(M0P_I2C_TypeDef* I2Cx, uint8_t u8Data)
|
||||
}
|
||||
/**
|
||||
******************************************************************************
|
||||
** \brief 字节数据读函数
|
||||
** \brief 字节数据读函数
|
||||
**
|
||||
** \param 无
|
||||
** \param 无
|
||||
**
|
||||
** \retval 读取数据
|
||||
** \retval 读取数据
|
||||
**
|
||||
******************************************************************************/
|
||||
uint8_t I2C_ReadByte(M0P_I2C_TypeDef* I2Cx)
|
||||
@@ -212,11 +212,11 @@ uint8_t I2C_ReadByte(M0P_I2C_TypeDef* I2Cx)
|
||||
|
||||
/**
|
||||
******************************************************************************
|
||||
** \brief I2C模块初始化
|
||||
** \brief I2C模块初始化
|
||||
**
|
||||
** \param pstcI2CCfg初始化配置结构体
|
||||
** \param pstcI2CCfg初始化配置结构体
|
||||
**
|
||||
** \retval 初始化是否成功
|
||||
** \retval 初始化是否成功
|
||||
**
|
||||
******************************************************************************/
|
||||
en_result_t I2C_Init(M0P_I2C_TypeDef* I2Cx, stc_i2c_cfg_t *pstcI2CCfg)
|
||||
@@ -265,71 +265,89 @@ en_result_t I2C_Init(M0P_I2C_TypeDef* I2Cx, stc_i2c_cfg_t *pstcI2CCfg)
|
||||
}
|
||||
/**
|
||||
******************************************************************************
|
||||
** \brief I2C模块接收指定长度函数
|
||||
** \brief I2C模块接收指定长度函数
|
||||
**
|
||||
** \param u8SlaveAddr从机设备地址,u8Addr从机内存地址,pu8Data读数据存放缓存,u32Len读数据长度
|
||||
** \param u8SlaveAddr从机设备地址,u8Addr从机内存地址,pu8Data读数据存放缓存,u32Len读数据长度
|
||||
**
|
||||
** \retval 读数据是否成功
|
||||
** \retval 读数据是否成功
|
||||
**
|
||||
******************************************************************************/
|
||||
boolean_t I2C_MasterReadData(M0P_I2C_TypeDef* I2CX,uint8_t u8SlaveAddr,uint8_t u8Addr,uint8_t *pu8Data,uint32_t u32Len)
|
||||
#define I2C_WAIT_TIMEOUT 20000u ///< 单步等待超时计数,防止总线卡死导致系统死循环
|
||||
#define I2C_READ_PASS_MAX 200u ///< 读传输状态机最大循环次数(48字节FIFO读约需120次)
|
||||
#define I2C_WRITE_PASS_MAX 64u ///< 写传输状态机最大循环次数
|
||||
|
||||
boolean_t I2C_MasterReadData(M0P_I2C_TypeDef* I2CX,uint8_t u8SlaveAddr,uint8_t u8Addr,uint8_t *pu8Data,uint32_t u32Len)
|
||||
{
|
||||
boolean_t enRet = FALSE;
|
||||
uint8_t u8i=0,u8State;
|
||||
|
||||
I2C_SetFunc(I2CX,I2cStart_En);//开始
|
||||
|
||||
uint32_t u32Wait = 0;
|
||||
uint16_t u16Pass = 0;
|
||||
|
||||
I2C_SetFunc(I2CX,I2cStart_En);//开始
|
||||
|
||||
while(1)
|
||||
{
|
||||
while(0 == I2C_GetIrq(I2CX))//获取中断标记函数
|
||||
{;}
|
||||
u8State = I2C_GetState(I2CX);//获取i2c相关状态
|
||||
while(0 == I2C_GetIrq(I2CX))//获取中断标记函数
|
||||
{
|
||||
if(++u32Wait >= I2C_WAIT_TIMEOUT) ///< 等待超时,总线异常
|
||||
{
|
||||
I2C_SetFunc(I2CX,I2cStop_En); ///< 尝试发送停止条件释放总线
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
u32Wait = 0;
|
||||
if(++u16Pass >= I2C_READ_PASS_MAX) ///< 状态机重试超限(持续NACK等),放弃本次传输
|
||||
{
|
||||
I2C_SetFunc(I2CX,I2cStop_En);
|
||||
return FALSE;
|
||||
}
|
||||
u8State = I2C_GetState(I2CX);//获取i2c相关状态
|
||||
switch(u8State)
|
||||
{
|
||||
case 0x08: ///< 主设备向总线已发出了一个起始条件
|
||||
case 0x08: ///< 主设备向总线已发出了一个起始条件
|
||||
I2C_ClearFunc(I2CX,I2cStart_En);
|
||||
I2C_WriteByte(I2CX,(u8SlaveAddr << 1));
|
||||
break;
|
||||
case 0x18: ///< 主设备向总线已发出了一个从设备地址(写方向)并且接收到从设备的应答
|
||||
I2C_WriteByte(I2CX,u8Addr); ///< 发送从机内存地址
|
||||
case 0x18: ///< 主设备向总线已发出了一个从设备地址(写方向)并且接收到从设备的应答
|
||||
I2C_WriteByte(I2CX,u8Addr); ///< 发送从机内存地址
|
||||
break;
|
||||
case 0x28: ///< 已发送数据,接收到ACK, 此处是已发送从机内存地址u8Addr并接收到ACK
|
||||
I2C_SetFunc(I2CX,I2cStart_En); ///< 发送重复起始条件
|
||||
case 0x28: ///< 已发送数据,接收到ACK, 此处是已发送从机内存地址u8Addr并接收到ACK
|
||||
I2C_SetFunc(I2CX,I2cStart_En); ///< 发送重复起始条件
|
||||
break;
|
||||
case 0x10: ///< 主设备向总线已发出了一个重复的起始条件
|
||||
case 0x10: ///< 主设备向总线已发出了一个重复的起始条件
|
||||
I2C_ClearFunc(I2CX,I2cStart_En);
|
||||
I2C_WriteByte(I2CX,(u8SlaveAddr << 1) | 0x01);///< 发送SLA+R,开始从从机读取数据
|
||||
I2C_WriteByte(I2CX,(u8SlaveAddr << 1) | 0x01);///< 发送SLA+R,开始从从机读取数据
|
||||
break;
|
||||
case 0x40: ///< 已发送SLA+R,并接收到ACK
|
||||
case 0x40: ///< 已发送SLA+R,并接收到ACK
|
||||
if(u32Len>1)
|
||||
{
|
||||
I2C_SetFunc(I2CX,I2cAck_En); ///< 使能主机应答功能
|
||||
I2C_SetFunc(I2CX,I2cAck_En); ///< 使能主机应答功能
|
||||
}
|
||||
break;
|
||||
case 0x50: ///< 已接收数据字节,并已返回ACK信号
|
||||
case 0x50: ///< 已接收数据字节,并已返回ACK信号
|
||||
pu8Data[u8i++] = I2C_ReadByte(I2CX);
|
||||
if(u8i==u32Len-1)
|
||||
{
|
||||
I2C_ClearFunc(I2CX,I2cAck_En); ///< 已接收到倒数第二个字节,关闭ACK应答功能
|
||||
I2C_ClearFunc(I2CX,I2cAck_En); ///< 已接收到倒数第二个字节,关闭ACK应答功能
|
||||
}
|
||||
break;
|
||||
case 0x58: ///< 已接收到最后一个数据,NACK已返回
|
||||
case 0x58: ///< 已接收到最后一个数据,NACK已返回
|
||||
pu8Data[u8i++] = I2C_ReadByte(I2CX);
|
||||
I2C_SetFunc(I2CX,I2cStop_En); ///< 发送停止条件
|
||||
I2C_SetFunc(I2CX,I2cStop_En); ///< 发送停止条件
|
||||
break;
|
||||
case 0x38: ///< 在发送地址或数据时,仲裁丢失
|
||||
I2C_SetFunc(I2CX,I2cStart_En); ///< 当总线空闲时发起起始条件
|
||||
case 0x38: ///< 在发送地址或数据时,仲裁丢失
|
||||
I2C_SetFunc(I2CX,I2cStart_En); ///< 当总线空闲时发起起始条件
|
||||
break;
|
||||
case 0x48: ///< 发送SLA+R后,收到一个NACK
|
||||
I2C_SetFunc(I2CX,I2cStop_En); ///< 发送停止条件
|
||||
I2C_SetFunc(I2CX,I2cStart_En); ///< 发送起始条件
|
||||
case 0x48: ///< 发送SLA+R后,收到一个NACK
|
||||
I2C_SetFunc(I2CX,I2cStop_En); ///< 发送停止条件
|
||||
I2C_SetFunc(I2CX,I2cStart_En); ///< 发送起始条件
|
||||
break;
|
||||
default:
|
||||
I2C_SetFunc(I2CX,I2cStart_En); ///< 其他错误状态,重新发送起始条件
|
||||
I2C_SetFunc(I2CX,I2cStart_En); ///< 其他错误状态,重新发送起始条件
|
||||
break;
|
||||
}
|
||||
I2C_ClearIrq(I2CX); ///< 清除中断状态标志位
|
||||
if(u8i==u32Len) ///< 数据全部读取完成,跳出while循环
|
||||
I2C_ClearIrq(I2CX); ///< 清除中断状态标志位
|
||||
if(u8i==u32Len) ///< 数据全部读取完成,跳出while循环
|
||||
{
|
||||
break;
|
||||
}
|
||||
@@ -339,60 +357,76 @@ en_result_t I2C_Init(M0P_I2C_TypeDef* I2Cx, stc_i2c_cfg_t *pstcI2CCfg)
|
||||
}
|
||||
/**
|
||||
******************************************************************************
|
||||
** \brief I2C模块主机发送指定长度函数
|
||||
** \brief I2C模块主机发送指定长度函数
|
||||
**
|
||||
** \param u8SlaveAddr从机设备地址,u8Addr从机内存地址,pu8Data写数据,u32Len写数据长度
|
||||
** \param u8SlaveAddr从机设备地址,u8Addr从机内存地址,pu8Data写数据,u32Len写数据长度
|
||||
**
|
||||
** \retval 写数据是否成功
|
||||
** \retval 写数据是否成功
|
||||
**
|
||||
******************************************************************************/
|
||||
boolean_t I2C_MasterWriteData(M0P_I2C_TypeDef* I2CX,uint8_t u8SlaveAddr,uint8_t u8Addr,uint8_t *pu8Data,uint32_t u32Len)
|
||||
{
|
||||
boolean_t enRet = FALSE;
|
||||
uint8_t u8i=0,u8State, u8Flag=FALSE;
|
||||
uint32_t u32Wait = 0;
|
||||
uint16_t u16Pass = 0;
|
||||
I2C_SetFunc(I2CX,I2cStart_En);
|
||||
while(1)
|
||||
{
|
||||
while(0 == I2C_GetIrq(I2CX))
|
||||
{;}
|
||||
{
|
||||
if(++u32Wait >= I2C_WAIT_TIMEOUT) ///< 等待超时,总线异常
|
||||
{
|
||||
I2C_SetFunc(I2CX,I2cStop_En); ///< 尝试发送停止条件释放总线
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
u32Wait = 0;
|
||||
if(++u16Pass >= I2C_WRITE_PASS_MAX) ///< 状态机重试超限(持续NACK等),放弃本次传输
|
||||
{
|
||||
I2C_SetFunc(I2CX,I2cStop_En);
|
||||
return FALSE;
|
||||
}
|
||||
u8State = I2C_GetState(I2CX);
|
||||
switch(u8State)
|
||||
{
|
||||
case 0x08: ///< 已发送起始条件
|
||||
case 0x08: ///< 已发送起始条件
|
||||
I2C_ClearFunc(I2CX,I2cStart_En);
|
||||
I2C_WriteByte(I2CX,(u8SlaveAddr << 1)); ///< 从设备地址发送
|
||||
I2C_WriteByte(I2CX,(u8SlaveAddr << 1)); ///< 从设备地址发送
|
||||
break;
|
||||
case 0x18: ///< 已发送SLA+W,并接收到ACK
|
||||
I2C_WriteByte(I2CX,u8Addr); ///< 从设备内存地址发送
|
||||
case 0x18: ///< 已发送SLA+W,并接收到ACK
|
||||
I2C_WriteByte(I2CX,u8Addr); ///< 从设备内存地址发送
|
||||
break;
|
||||
case 0x28: ///< 上一次发送数据后接收到ACK
|
||||
case 0x28: ///< 上一次发送数据后接收到ACK
|
||||
if (u8i < u32Len)
|
||||
{
|
||||
I2C_WriteByte(I2CX,pu8Data[u8i++]); ///< 继续发送数据
|
||||
I2C_WriteByte(I2CX,pu8Data[u8i++]); ///< 继续发送数据
|
||||
}else
|
||||
{
|
||||
I2C_SetFunc(I2CX,I2cStop_En); ///< 出停止条件
|
||||
I2C_SetFunc(I2CX,I2cStop_En); ///< 出停止条件
|
||||
u8Flag = TRUE;
|
||||
enRet = TRUE; ///< 全部数据发送完成
|
||||
}
|
||||
break;
|
||||
case 0x38: ///< 上一次在SLA+读或写时丢失仲裁
|
||||
I2C_SetFunc(I2CX,I2cStart_En); ///< 当I2C总线空闲时发送起始条件
|
||||
case 0x38: ///< 上一次在SLA+读或写时丢失仲裁
|
||||
I2C_SetFunc(I2CX,I2cStart_En); ///< 当I2C总线空闲时发送起始条件
|
||||
break;
|
||||
case 0x30: ///< 已发送I2Cx_DATA中的数据,收到NACK,将传输一个STOP条件
|
||||
I2C_SetFunc(I2CX,I2cStop_En); ///< 发送停止条件
|
||||
case 0x30: ///< 已发送I2Cx_DATA中的数据,收到NACK,将传输一个STOP条件
|
||||
I2C_SetFunc(I2CX,I2cStop_En); ///< 发送停止条件
|
||||
u8Flag = TRUE;
|
||||
enRet = FALSE; ///< 从机NACK,本次传输失败
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
I2C_ClearIrq(I2CX); ///< 清除中断状态标志位
|
||||
|
||||
if(u8Flag == TRUE) ///< 数据发送完成
|
||||
{
|
||||
I2C_ClearIrq(I2CX); ///< 清除中断状态标志位
|
||||
|
||||
if(u8Flag == TRUE) ///< 数据发送完成
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
enRet = TRUE;
|
||||
return enRet;
|
||||
}
|
||||
//@} // I2cGroup
|
||||
|
||||
Reference in New Issue
Block a user