fix dr16
This commit is contained in:
parent
a3b4381f7e
commit
511b9809c9
@ -41,12 +41,26 @@
|
|||||||
|
|
||||||
static osThreadId_t thread_alert;
|
static osThreadId_t thread_alert;
|
||||||
static bool inited = false;
|
static bool inited = false;
|
||||||
|
static DR16_t *dr16_instance = NULL; /* 用于空闲中断回调中访问实例 */
|
||||||
|
static uint8_t sync_buf[32]; /* 帧同步时的丢弃缓冲区 */
|
||||||
|
|
||||||
/* Private function -------------------------------------------------------- */
|
/* Private function -------------------------------------------------------- */
|
||||||
static void DR16_RxCpltCallback(void) {
|
static void DR16_RxCpltCallback(void) {
|
||||||
osThreadFlagsSet(thread_alert, SIGNAL_DR16_RAW_REDY);
|
osThreadFlagsSet(thread_alert, SIGNAL_DR16_RAW_REDY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 空闲中断回调 - 用于帧同步
|
||||||
|
* 空闲中断表示一帧传输结束(总线空闲),此时停止当前DMA接收,
|
||||||
|
* 丢弃不完整的数据,这样下一次 StartDmaRecv 就能从帧头开始。
|
||||||
|
*/
|
||||||
|
static void DR16_IdleCallback(void) {
|
||||||
|
/* 停止当前DMA接收(无论收了多少字节) */
|
||||||
|
HAL_UART_AbortReceive(BSP_UART_GetHandle(BSP_UART_DR16));
|
||||||
|
/* 通知任务:可以启动下一次对齐的接收了 */
|
||||||
|
osThreadFlagsSet(thread_alert, SIGNAL_DR16_RAW_REDY);
|
||||||
|
}
|
||||||
|
|
||||||
static bool DR16_DataCorrupted(const DR16_t *dr16) {
|
static bool DR16_DataCorrupted(const DR16_t *dr16) {
|
||||||
if (dr16 == NULL) return DEVICE_ERR_NULL;
|
if (dr16 == NULL) return DEVICE_ERR_NULL;
|
||||||
|
|
||||||
@ -79,16 +93,49 @@ int8_t DR16_Init(DR16_t *dr16) {
|
|||||||
if (inited) return DEVICE_ERR_INITED;
|
if (inited) return DEVICE_ERR_INITED;
|
||||||
if ((thread_alert = osThreadGetId()) == NULL) return DEVICE_ERR_NULL;
|
if ((thread_alert = osThreadGetId()) == NULL) return DEVICE_ERR_NULL;
|
||||||
|
|
||||||
|
dr16_instance = dr16;
|
||||||
|
|
||||||
|
/* 注册 DMA 接收完成回调 */
|
||||||
BSP_UART_RegisterCallback(BSP_UART_DR16, BSP_UART_RX_CPLT_CB,
|
BSP_UART_RegisterCallback(BSP_UART_DR16, BSP_UART_RX_CPLT_CB,
|
||||||
DR16_RxCpltCallback);
|
DR16_RxCpltCallback);
|
||||||
|
|
||||||
|
/* 注册空闲中断回调并使能空闲中断,用于帧同步 */
|
||||||
|
BSP_UART_RegisterCallback(BSP_UART_DR16, BSP_UART_IDLE_LINE_CB,
|
||||||
|
DR16_IdleCallback);
|
||||||
|
__HAL_UART_ENABLE_IT(BSP_UART_GetHandle(BSP_UART_DR16), UART_IT_IDLE);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 首次帧同步:启动一次丢弃式DMA接收。
|
||||||
|
* 如果遥控器已经在发送,DMA会从帧中间开始收,空闲中断到来时
|
||||||
|
* IdleCallback 会 Abort 这次接收并通知任务,下一次 StartDmaRecv
|
||||||
|
* 就能从完整帧头开始。
|
||||||
|
*/
|
||||||
|
HAL_UART_Receive_DMA(BSP_UART_GetHandle(BSP_UART_DR16),
|
||||||
|
sync_buf, sizeof(sync_buf));
|
||||||
|
/* 等待空闲中断完成首次同步(最多50ms,足够等一帧) */
|
||||||
|
osThreadFlagsWait(SIGNAL_DR16_RAW_REDY, osFlagsWaitAll, 50);
|
||||||
|
|
||||||
inited = true;
|
inited = true;
|
||||||
return DEVICE_OK;
|
return DEVICE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int8_t DR16_Restart(void) {
|
int8_t DR16_Restart(void) {
|
||||||
__HAL_UART_DISABLE(BSP_UART_GetHandle(BSP_UART_DR16));
|
UART_HandleTypeDef *huart = BSP_UART_GetHandle(BSP_UART_DR16);
|
||||||
__HAL_UART_ENABLE(BSP_UART_GetHandle(BSP_UART_DR16));
|
|
||||||
|
/* 先终止当前DMA接收 */
|
||||||
|
HAL_UART_AbortReceive(huart);
|
||||||
|
|
||||||
|
/* 重置串口 */
|
||||||
|
__HAL_UART_DISABLE(huart);
|
||||||
|
__HAL_UART_ENABLE(huart);
|
||||||
|
|
||||||
|
/* 重新使能空闲中断 */
|
||||||
|
__HAL_UART_ENABLE_IT(huart, UART_IT_IDLE);
|
||||||
|
|
||||||
|
/* 重新做帧同步:丢弃式接收,等空闲中断对齐 */
|
||||||
|
HAL_UART_Receive_DMA(huart, sync_buf, sizeof(sync_buf));
|
||||||
|
osThreadFlagsWait(SIGNAL_DR16_RAW_REDY, osFlagsWaitAll, 50);
|
||||||
|
|
||||||
return DEVICE_OK;
|
return DEVICE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,6 +156,8 @@ int8_t DR16_ParseData(DR16_t *dr16){
|
|||||||
if (dr16 == NULL) return DEVICE_ERR_NULL;
|
if (dr16 == NULL) return DEVICE_ERR_NULL;
|
||||||
|
|
||||||
if (DR16_DataCorrupted(dr16)) {
|
if (DR16_DataCorrupted(dr16)) {
|
||||||
|
/* 数据损坏说明帧错位了,重启串口并重新同步 */
|
||||||
|
DR16_Restart();
|
||||||
return DEVICE_ERR;
|
return DEVICE_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user