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:
2026-09-03 16:15:09 +08:00
parent 706eb1247e
commit 93e00b8b0a
5 changed files with 387 additions and 358 deletions
+112 -78
View File
@@ -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