2024-12-30 11:50:48 +08:00
|
|
|
|
/*
|
|
|
|
|
* @Author: mbw
|
|
|
|
|
* @Date: 2024-11-14 10:21:04
|
|
|
|
|
* @LastEditors: mbw && 1600520629@qq.com
|
2025-02-06 09:30:52 +08:00
|
|
|
|
* @LastEditTime: 2025-02-06 09:16:14
|
2025-01-09 15:29:36 +08:00
|
|
|
|
* @FilePath: \JT-DT-YD4N02A_RTT_MRS-NT26K\bsp\src\bsp_h308.c
|
2024-12-30 11:50:48 +08:00
|
|
|
|
* @Description:
|
|
|
|
|
*
|
|
|
|
|
* Copyright (c) 2024 by ${git_name_email}, All Rights Reserved.
|
|
|
|
|
*/
|
|
|
|
|
#include "bsp_h308.h"
|
|
|
|
|
// #include "drv_usart.h"
|
|
|
|
|
#include "lwrb.h"
|
|
|
|
|
|
|
|
|
|
// 用到了atoi
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include "bsp_flash.h"
|
|
|
|
|
#include "bsp_rtc.h"
|
|
|
|
|
#include "user_sys.h"
|
2025-01-23 09:24:23 +08:00
|
|
|
|
#include "bsp_led.h"
|
2025-01-25 15:11:34 +08:00
|
|
|
|
#include "at_device_nt26k.h"
|
|
|
|
|
|
2024-12-30 11:50:48 +08:00
|
|
|
|
#define LOG_TAG "bsp_h308"
|
|
|
|
|
#define LOG_LVL LOG_LVL_DBG
|
|
|
|
|
#include <ulog.h>
|
|
|
|
|
|
|
|
|
|
// 用了浮点打印
|
|
|
|
|
ALIGN(8)
|
|
|
|
|
static char h308_thread_stack[H308_THREAD_STACK_SIZE];
|
|
|
|
|
static struct rt_thread h308_thread;
|
|
|
|
|
|
|
|
|
|
#define UART4_RX_RB_LENGTH (128U)
|
|
|
|
|
|
|
|
|
|
static lwrb_t uart4_rx_rb;
|
|
|
|
|
static rt_uint8_t uart4_rx_rb_data[UART4_RX_RB_LENGTH];
|
|
|
|
|
|
|
|
|
|
static rt_sem_t uart4_rx_ok_sem;
|
|
|
|
|
|
2025-01-23 08:50:12 +08:00
|
|
|
|
static struct rt_timer uart4_rx_timer;
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
2025-01-25 15:09:53 +08:00
|
|
|
|
uint8_t sensor_rx_flag = 0; // 接收缓冲区中,已经收到的数据包数量static rt_uint8_t alarm_flag = 0, fault_flag = 0;
|
2025-01-25 14:43:42 +08:00
|
|
|
|
rt_uint8_t alarm_flag = 0, fault_flag = 0;
|
2025-02-06 09:30:52 +08:00
|
|
|
|
TsH308 H308 = {0};
|
|
|
|
|
static rt_uint8_t alarm_status_buffer[H308_SAMPLING_TIMS] = {0};
|
|
|
|
|
static rt_uint8_t fault_buf[H308_SAMPLING_TIMS] = {0};
|
2024-12-30 11:50:48 +08:00
|
|
|
|
void _UART4_RxTimeout(void *parameter)
|
|
|
|
|
{
|
2025-01-22 13:33:38 +08:00
|
|
|
|
sensor_rx_flag = 0;
|
2024-12-30 11:50:48 +08:00
|
|
|
|
rt_sem_release(uart4_rx_ok_sem);
|
2025-01-23 08:50:12 +08:00
|
|
|
|
rt_timer_stop(&uart4_rx_timer);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static uint8_t H308_XorChecksum(char *str, int len)
|
|
|
|
|
{
|
|
|
|
|
uint8_t xorvalue = 0;
|
|
|
|
|
|
|
|
|
|
if (str == RT_NULL || len < 2)
|
|
|
|
|
{
|
|
|
|
|
// 处理错误或返回
|
|
|
|
|
return 0; // 或者选择抛出异常
|
|
|
|
|
}
|
|
|
|
|
for (int i = 0; i < len - 4; i++) // 校验值前面的空格要,
|
|
|
|
|
{
|
|
|
|
|
xorvalue ^= str[i];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return xorvalue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// float打印问题
|
|
|
|
|
// https://www.wch.cn/bbs/thread-108241-1.html
|
|
|
|
|
// https://www.wch.cn/bbs/thread-91909-1.html
|
|
|
|
|
// https://club.rt-thread.org/ask/article/1d040664a33a7b46.html
|
|
|
|
|
// https://club.rt-thread.org/ask/article/1d040664a33a7b46.html
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief 打印数据
|
|
|
|
|
* @param data:使用8字节对齐就好着,4字节对齐就出现问题,问题解决,在cpuport.c中将RT_ALIGN_DOWN((rt_ubase_t)stk, REGBYTES)改为RT_ALIGN_DOWN((rt_ubase_t)stk, 8);
|
|
|
|
|
* @retval None
|
|
|
|
|
*/
|
|
|
|
|
void H308_ShowData(TsH308Data data)
|
|
|
|
|
{
|
|
|
|
|
// A+000.00 +31.1 0657.80 +18.1 B+008.0 00 12
|
|
|
|
|
LOG_D("H308Data: %6.2f, %5.1f, %7.2f, %5.1f, %5.1f, %02X, %02X", data.lel, data.temp, data.laser_temp, data.signal_strength, data.gain, data.fault_code, data.checksum);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef TEST_ENABLE
|
|
|
|
|
void Sensor_ShowData(void)
|
|
|
|
|
{
|
|
|
|
|
H308_ShowData(H308.Data);
|
|
|
|
|
}
|
|
|
|
|
MSH_CMD_EXPORT(Sensor_ShowData, Sensor_ShowData);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
uint8_t H308_GetFrameData(const char *p_src, const rt_uint8_t src_len, TsH308Data *pData)
|
|
|
|
|
{
|
2025-02-06 08:57:18 +08:00
|
|
|
|
// A+000.00 +31.1 0657.80 +18.1 B+008.0 00 12
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
2025-02-06 08:57:18 +08:00
|
|
|
|
rt_uint8_t xor = 0;
|
|
|
|
|
uint8_t ret = 0;
|
2025-02-06 09:30:52 +08:00
|
|
|
|
char *p_str = rt_strstr(p_src, "A+"); // 查找子字符串的位置
|
|
|
|
|
uint32_t offset = p_str - p_src; // 计算偏移量
|
2025-02-06 08:57:18 +08:00
|
|
|
|
|
|
|
|
|
TsH308StrData _H308StrData = {0};
|
2025-01-25 14:11:51 +08:00
|
|
|
|
|
2025-02-06 08:57:18 +08:00
|
|
|
|
if ((p_str != NULL) && (offset <= src_len - 44))
|
2024-12-30 11:50:48 +08:00
|
|
|
|
{
|
2025-02-06 08:57:18 +08:00
|
|
|
|
if (sscanf(p_str, "A+%6s %6s %8s %6s B+%6s %2s %2s",
|
|
|
|
|
_H308StrData.vol, _H308StrData.temp, _H308StrData.laser_temp, _H308StrData.signal_strength,
|
|
|
|
|
_H308StrData.gain, _H308StrData.fault_code, _H308StrData.checksum) == 7)
|
2024-12-30 11:50:48 +08:00
|
|
|
|
{
|
|
|
|
|
pData->checksum = (rt_uint8_t)strtol(_H308StrData.checksum, NULL, 16);
|
|
|
|
|
xor = H308_XorChecksum(p_str, 44); // 对数据进行异或校验
|
2025-02-06 09:30:52 +08:00
|
|
|
|
if (xor == pData->checksum)
|
2024-12-30 11:50:48 +08:00
|
|
|
|
{
|
2025-02-06 08:57:18 +08:00
|
|
|
|
pData->lel = (float)(atof(_H308StrData.vol) * 20);
|
|
|
|
|
pData->temp = (float)atof(_H308StrData.temp);
|
|
|
|
|
pData->laser_temp = (float)atof(_H308StrData.laser_temp);
|
|
|
|
|
pData->signal_strength = (float)atof(_H308StrData.signal_strength);
|
|
|
|
|
pData->gain = (float)atof(_H308StrData.gain);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
pData->fault_code = (rt_uint8_t)strtol(_H308StrData.fault_code, NULL, 16);
|
2025-02-06 08:57:18 +08:00
|
|
|
|
pData->checksum = (rt_uint8_t)strtol(_H308StrData.checksum, NULL, 16);
|
|
|
|
|
ret = 0;
|
2024-12-30 11:50:48 +08:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2025-02-06 08:57:18 +08:00
|
|
|
|
LOG_E("xor failed");
|
2024-12-30 11:50:48 +08:00
|
|
|
|
ret = RT_ERROR;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ret = RT_ERROR;
|
2025-02-06 08:57:18 +08:00
|
|
|
|
LOG_E("H308_ExtractData failed");
|
2024-12-30 11:50:48 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static uint8_t H308_Count(const rt_uint8_t *buffer, uint8_t value, uint8_t size)
|
|
|
|
|
{
|
|
|
|
|
uint8_t count = 0;
|
|
|
|
|
for (uint8_t i = 0; i < size; i++)
|
|
|
|
|
{
|
|
|
|
|
if (buffer[i] == value)
|
|
|
|
|
{
|
|
|
|
|
count++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return count;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// static void H308_HandleAbnormal(uint8_t count, uint8_t *flag, uint8_t threshold)
|
|
|
|
|
//{
|
|
|
|
|
// if (count > threshold && *flag == 0)
|
|
|
|
|
// {
|
|
|
|
|
// H308.detection_flag = kH308Abnormal;
|
|
|
|
|
// Send_Laser_Alarm_Event(kAlarmExceptionEvent);
|
|
|
|
|
// *flag = 1;
|
|
|
|
|
// }
|
|
|
|
|
// else if (*flag == 1 && count < threshold)
|
|
|
|
|
// {
|
|
|
|
|
// *flag = 0;
|
|
|
|
|
// H308.detection_flag = kH308Normal;
|
|
|
|
|
// Send_Laser_Alarm_Event(kNormalDetectionEvents);
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
|
2025-01-25 14:43:42 +08:00
|
|
|
|
static void H308_HandleAlarm(uint8_t count, uint8_t threshold)
|
2024-12-30 11:50:48 +08:00
|
|
|
|
{
|
2025-01-25 14:43:42 +08:00
|
|
|
|
if (count >= threshold && alarm_flag == 0)
|
2024-12-30 11:50:48 +08:00
|
|
|
|
{
|
2025-01-25 14:11:51 +08:00
|
|
|
|
if (H308.Data.lel > H308.alarm_value)
|
|
|
|
|
{
|
2025-01-25 15:09:53 +08:00
|
|
|
|
alarm_flag = 1;
|
2025-01-25 14:11:51 +08:00
|
|
|
|
H308.detection_flag = kH308Alarm;
|
2025-01-25 15:09:53 +08:00
|
|
|
|
Send_Laser_Alarm_Event(kAlarmEvent);
|
2025-01-25 14:11:51 +08:00
|
|
|
|
}
|
2024-12-30 11:50:48 +08:00
|
|
|
|
}
|
2025-01-25 14:43:42 +08:00
|
|
|
|
else if (alarm_flag == 1 && count == 0)
|
2024-12-30 11:50:48 +08:00
|
|
|
|
{
|
2025-01-25 15:09:53 +08:00
|
|
|
|
alarm_flag = 0;
|
2024-12-30 11:50:48 +08:00
|
|
|
|
H308.detection_flag = kH308Normal;
|
|
|
|
|
Send_Laser_Alarm_Event(kAlarmRcyEvent);
|
|
|
|
|
}
|
2025-01-25 14:43:42 +08:00
|
|
|
|
else if ((H308.Data.lel == 0) && (count == 0))
|
|
|
|
|
{
|
2025-01-25 15:09:53 +08:00
|
|
|
|
alarm_flag = 0;
|
2025-01-25 14:43:42 +08:00
|
|
|
|
H308.detection_flag = kH308Alarm;
|
|
|
|
|
}
|
2024-12-30 11:50:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
2025-01-25 14:43:42 +08:00
|
|
|
|
static void H308_HandleFault(uint8_t count, uint8_t threshold)
|
2024-12-30 11:50:48 +08:00
|
|
|
|
{
|
2025-01-25 14:43:42 +08:00
|
|
|
|
if (count >= threshold && fault_flag != 1)
|
2024-12-30 11:50:48 +08:00
|
|
|
|
{
|
2025-01-25 15:09:53 +08:00
|
|
|
|
fault_flag = 1;
|
2024-12-30 11:50:48 +08:00
|
|
|
|
H308.detection_flag = kH308Fault;
|
2025-01-25 14:43:42 +08:00
|
|
|
|
rt_thread_mdelay(1);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
Send_Laser_Alarm_Event(kFaultEvent);
|
|
|
|
|
}
|
2025-01-25 14:43:42 +08:00
|
|
|
|
else if (fault_flag == 1 && count == 0)
|
2024-12-30 11:50:48 +08:00
|
|
|
|
{
|
2025-01-25 15:09:53 +08:00
|
|
|
|
fault_flag = 0;
|
2024-12-30 11:50:48 +08:00
|
|
|
|
H308.detection_flag = kH308Normal;
|
2025-01-25 14:43:42 +08:00
|
|
|
|
rt_thread_mdelay(1);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
Send_Laser_Alarm_Event(kFaultRcyEvent);
|
|
|
|
|
}
|
2025-01-25 14:11:51 +08:00
|
|
|
|
else if (rt_pin_read(LED_Y_PIN) == PIN_HIGH && (count == 0))
|
2025-01-23 09:24:23 +08:00
|
|
|
|
{
|
2025-01-25 15:09:53 +08:00
|
|
|
|
fault_flag = 0;
|
2025-01-23 09:24:23 +08:00
|
|
|
|
H308.detection_flag = kH308Normal;
|
|
|
|
|
}
|
2024-12-30 11:50:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
2025-01-25 14:43:42 +08:00
|
|
|
|
static uint8_t H308_CheckData(void)
|
2024-12-30 11:50:48 +08:00
|
|
|
|
{
|
|
|
|
|
static rt_uint8_t alarm_count = 0, fault_count = 0;
|
2025-02-06 09:30:52 +08:00
|
|
|
|
static rt_uint8_t index = 0;
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
|
|
|
|
alarm_status_buffer[index] = (H308.Data.lel < (float)H308.alarm_value) ? kH308Normal : kH308Alarm;
|
|
|
|
|
fault_buf[index] = (H308.Data.fault_code == 0) ? kH308Normal : kH308Fault;
|
|
|
|
|
index++;
|
|
|
|
|
if (index >= H308_SAMPLING_TIMS)
|
|
|
|
|
{
|
|
|
|
|
index = 0;
|
|
|
|
|
}
|
|
|
|
|
alarm_count = H308_Count(alarm_status_buffer, kH308Alarm, H308_SAMPLING_TIMS);
|
2025-01-25 14:43:42 +08:00
|
|
|
|
rt_thread_mdelay(1);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
fault_count = H308_Count(fault_buf, kH308Fault, H308_SAMPLING_TIMS);
|
2025-01-25 14:43:42 +08:00
|
|
|
|
rt_thread_mdelay(1);
|
|
|
|
|
H308_HandleAlarm(alarm_count, H308_SAMPLING_TIMS);
|
|
|
|
|
rt_thread_mdelay(1);
|
|
|
|
|
H308_HandleFault(fault_count, H308_SAMPLING_TIMS);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
|
|
|
|
return RT_EOK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TODO: 寿命检测
|
|
|
|
|
uint8_t IS_H308_EndOfLife(void)
|
|
|
|
|
{
|
2025-01-25 15:09:53 +08:00
|
|
|
|
if (ntp_flag) // 是否同步网络时间
|
2024-12-30 11:50:48 +08:00
|
|
|
|
{
|
2025-01-25 15:09:53 +08:00
|
|
|
|
ntp_flag = 0;
|
|
|
|
|
RTC_GetTime();
|
|
|
|
|
|
2025-01-25 15:11:34 +08:00
|
|
|
|
if ((RtcDateTime.year >= 2035) && (work_duration >= 6 * 365)) // 至少大于2035年且实际使用时长超过6年
|
2025-01-17 10:52:36 +08:00
|
|
|
|
{
|
2025-01-25 15:09:53 +08:00
|
|
|
|
if (RTC_GetCounter() >= H308.expiration_seconds)
|
|
|
|
|
{
|
|
|
|
|
H308.end_of_life = 1;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
H308.end_of_life = 0;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2025-01-17 10:52:36 +08:00
|
|
|
|
}
|
2025-01-23 08:43:49 +08:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
H308.end_of_life = 0;
|
2025-01-25 15:09:53 +08:00
|
|
|
|
return 0;
|
2025-01-23 08:43:49 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
H308.end_of_life = 0;
|
2025-01-25 14:43:42 +08:00
|
|
|
|
return 0;
|
2024-12-30 11:50:48 +08:00
|
|
|
|
}
|
2025-01-20 16:34:30 +08:00
|
|
|
|
return H308.end_of_life;
|
2024-12-30 11:50:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
2025-01-15 09:56:50 +08:00
|
|
|
|
void UART4_Init(void)
|
|
|
|
|
{
|
|
|
|
|
GPIO_InitTypeDef GPIO_InitStructure = {0};
|
|
|
|
|
USART_InitTypeDef USART_InitStructure = {0};
|
|
|
|
|
NVIC_InitTypeDef NVIC_InitStructure = {0};
|
|
|
|
|
|
|
|
|
|
lwrb_init(&uart4_rx_rb, uart4_rx_rb_data, sizeof(uart4_rx_rb_data));
|
|
|
|
|
|
|
|
|
|
USART_DeInit(UART4); // 寄存器恢复默认值
|
|
|
|
|
|
|
|
|
|
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
|
|
|
|
|
RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE);
|
|
|
|
|
|
|
|
|
|
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
|
|
|
|
|
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
|
|
|
|
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
|
|
|
|
|
GPIO_Init(GPIOC, &GPIO_InitStructure);
|
|
|
|
|
|
|
|
|
|
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
|
|
|
|
|
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
|
|
|
|
|
GPIO_Init(GPIOC, &GPIO_InitStructure);
|
|
|
|
|
|
|
|
|
|
USART_InitStructure.USART_BaudRate = 9600;
|
|
|
|
|
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
|
|
|
|
|
USART_InitStructure.USART_StopBits = USART_StopBits_1;
|
|
|
|
|
USART_InitStructure.USART_Parity = USART_Parity_No;
|
|
|
|
|
|
|
|
|
|
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
|
|
|
|
|
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
|
|
|
|
|
USART_Init(UART4, &USART_InitStructure);
|
|
|
|
|
|
|
|
|
|
USART_ITConfig(UART4, USART_IT_RXNE, ENABLE);
|
|
|
|
|
|
|
|
|
|
NVIC_InitStructure.NVIC_IRQChannel = UART4_IRQn;
|
|
|
|
|
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
|
|
|
|
|
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
|
|
|
|
|
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
|
|
|
|
NVIC_Init(&NVIC_InitStructure);
|
|
|
|
|
|
|
|
|
|
USART_Cmd(UART4, ENABLE);
|
|
|
|
|
LOG_I("UART4 Init");
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-30 11:50:48 +08:00
|
|
|
|
static void h308_thread_entry(void *param)
|
|
|
|
|
{
|
2025-01-20 18:39:59 +08:00
|
|
|
|
rt_err_t ret;
|
2024-12-30 11:50:48 +08:00
|
|
|
|
static uint8_t str[UART4_RX_RB_LENGTH] = {0};
|
|
|
|
|
static uint8_t h308_rx_timout_cnt = 0;
|
|
|
|
|
static uint8_t h308_err_cnt = 0;
|
2025-01-20 18:39:59 +08:00
|
|
|
|
rt_thread_mdelay(1000);
|
2025-01-25 14:43:42 +08:00
|
|
|
|
rt_uint8_t alarm_value = Flash_Get_SysCfg(kAlarmLValueId); // 获取系统报警阈值;
|
|
|
|
|
if (alarm_value > 25)
|
|
|
|
|
{
|
|
|
|
|
alarm_value = 10;
|
|
|
|
|
}
|
2025-01-25 15:09:53 +08:00
|
|
|
|
|
2025-01-25 14:43:42 +08:00
|
|
|
|
H308.alarm_value = alarm_value;
|
2025-01-15 09:56:50 +08:00
|
|
|
|
LOG_D("报警阈值:%d%LEL", H308.alarm_value);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
|
|
|
|
while (1)
|
|
|
|
|
{
|
|
|
|
|
ret = rt_sem_take(uart4_rx_ok_sem, 3000);
|
|
|
|
|
if (ret == RT_EOK)
|
|
|
|
|
{
|
|
|
|
|
uint8_t len = lwrb_get_full(&uart4_rx_rb);
|
|
|
|
|
lwrb_read(&uart4_rx_rb, str, len);
|
2025-02-06 08:57:18 +08:00
|
|
|
|
rt_memset(&str[len - 2], 0, 2);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
if (len >= 44)
|
|
|
|
|
{
|
2025-01-15 09:56:50 +08:00
|
|
|
|
ret = H308_GetFrameData((const char *)str, len, &H308.Data);
|
2025-01-25 14:11:51 +08:00
|
|
|
|
LOG_I("str:%s", str);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
if (ret == 0)
|
|
|
|
|
{
|
2025-01-25 14:43:42 +08:00
|
|
|
|
H308_CheckData();
|
2024-12-30 11:50:48 +08:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
h308_err_cnt++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
h308_err_cnt++;
|
2025-01-25 15:09:53 +08:00
|
|
|
|
|
2024-12-30 11:50:48 +08:00
|
|
|
|
LOG_E("(len = %d) < 44, error data:[%s]", len, str);
|
|
|
|
|
if (h308_err_cnt >= 5)
|
|
|
|
|
{
|
|
|
|
|
H308_RST_ON;
|
|
|
|
|
rt_thread_mdelay(100);
|
|
|
|
|
H308_RST_OFF;
|
|
|
|
|
rt_thread_mdelay(10000);
|
|
|
|
|
h308_err_cnt = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-01-09 15:29:36 +08:00
|
|
|
|
rt_memset(str, 0, len);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
|
|
|
|
if (h308_rx_timout_cnt)
|
|
|
|
|
{
|
|
|
|
|
h308_rx_timout_cnt = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-01-20 18:39:59 +08:00
|
|
|
|
else if (ret == -RT_ETIMEOUT) // 这个主要是考虑传感器未焊接好,或者脱落的情况,国标要求30s内反应 3*5 = 15s,符合国标
|
2024-12-30 11:50:48 +08:00
|
|
|
|
{
|
|
|
|
|
h308_rx_timout_cnt++;
|
2025-01-23 16:29:51 +08:00
|
|
|
|
if (h308_rx_timout_cnt >= 6)
|
2024-12-30 11:50:48 +08:00
|
|
|
|
{
|
|
|
|
|
H308_RST_ON;
|
|
|
|
|
rt_thread_mdelay(100);
|
2025-01-20 18:39:59 +08:00
|
|
|
|
H308_RST_OFF; // 复位一下
|
2024-12-30 11:50:48 +08:00
|
|
|
|
h308_rx_timout_cnt = 0;
|
|
|
|
|
if (H308.detection_flag != kH308Fault)
|
|
|
|
|
{
|
|
|
|
|
H308.detection_flag = kH308Fault;
|
2025-01-25 14:11:51 +08:00
|
|
|
|
fault_flag = 1;
|
2024-12-30 11:50:48 +08:00
|
|
|
|
Send_Laser_Alarm_Event(kFaultEvent);
|
|
|
|
|
}
|
2025-01-25 15:09:53 +08:00
|
|
|
|
// 重置接收缓冲区和相关标志
|
2025-01-25 14:11:51 +08:00
|
|
|
|
lwrb_reset(&uart4_rx_rb);
|
|
|
|
|
sensor_rx_flag = 0;
|
2024-12-30 11:50:48 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int BSP_H308_Init(void)
|
|
|
|
|
{
|
|
|
|
|
rt_pin_mode(H308_PWR_PIN, PIN_MODE_OUTPUT);
|
|
|
|
|
rt_pin_mode(H308_RST_PIN, PIN_MODE_OUTPUT);
|
|
|
|
|
H308_RST_OFF;
|
2025-01-15 09:56:50 +08:00
|
|
|
|
H308_PWR_ON;
|
2025-01-20 18:39:59 +08:00
|
|
|
|
|
2025-02-06 09:30:52 +08:00
|
|
|
|
uart4_rx_ok_sem = rt_sem_create("uart4_rx", 0, RT_IPC_FLAG_PRIO);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
if (uart4_rx_ok_sem == RT_NULL)
|
|
|
|
|
{
|
|
|
|
|
LOG_E("uart4_rx_ok_sem create failed");
|
|
|
|
|
}
|
2025-01-20 18:39:59 +08:00
|
|
|
|
// TODO:这里改的静态
|
2025-01-23 08:50:12 +08:00
|
|
|
|
rt_timer_init(&uart4_rx_timer, "_UART4_RxTimeout", _UART4_RxTimeout, RT_NULL, 200, RT_TIMER_FLAG_PERIODIC);
|
2025-01-15 09:56:50 +08:00
|
|
|
|
UART4_Init();
|
2024-12-30 11:50:48 +08:00
|
|
|
|
rt_err_t ret = rt_thread_init(&h308_thread,
|
|
|
|
|
"h308_thread",
|
|
|
|
|
h308_thread_entry,
|
|
|
|
|
RT_NULL,
|
|
|
|
|
&h308_thread_stack[0],
|
|
|
|
|
sizeof(h308_thread_stack),
|
|
|
|
|
H308_THREAD_PRIORITY, H308_THREAD_TIMESLICE);
|
|
|
|
|
|
|
|
|
|
if (ret == RT_EOK)
|
|
|
|
|
{
|
|
|
|
|
rt_thread_startup(&h308_thread);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
LOG_E("rt_thread_init h308_thread Failed");
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
2025-01-20 16:34:30 +08:00
|
|
|
|
INIT_DEVICE_EXPORT(BSP_H308_Init);
|
2024-12-30 11:50:48 +08:00
|
|
|
|
|
|
|
|
|
void UART4_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
|
|
|
|
|
void UART4_IRQHandler(void)
|
|
|
|
|
{
|
|
|
|
|
GET_INT_SP();
|
|
|
|
|
rt_interrupt_enter();
|
|
|
|
|
|
|
|
|
|
if (USART_GetITStatus(UART4, USART_IT_RXNE) != RESET)
|
|
|
|
|
{
|
|
|
|
|
uint8_t temp = USART_ReceiveData(UART4);
|
|
|
|
|
lwrb_write(&uart4_rx_rb, &temp, 1);
|
2025-01-22 13:33:38 +08:00
|
|
|
|
if (sensor_rx_flag == 0)
|
|
|
|
|
{
|
|
|
|
|
sensor_rx_flag = 1;
|
|
|
|
|
rt_timer_start(&uart4_rx_timer);
|
2025-01-23 16:29:51 +08:00
|
|
|
|
}
|
2024-12-30 11:50:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rt_interrupt_leave();
|
|
|
|
|
FREE_INT_SP();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef TEST_ENABLE
|
|
|
|
|
static void TEST_H308(int argc, char **argv)
|
|
|
|
|
{
|
|
|
|
|
if (argc == 2)
|
|
|
|
|
{
|
|
|
|
|
int cmd = atoi(argv[1]);
|
|
|
|
|
switch (cmd)
|
|
|
|
|
{
|
|
|
|
|
case 0:
|
|
|
|
|
H308_PWR_OFF;
|
|
|
|
|
LOG_D("H308_PWR_OFF");
|
|
|
|
|
break;
|
|
|
|
|
case 1:
|
|
|
|
|
H308_PWR_ON;
|
|
|
|
|
LOG_D("H308_PWR_ON");
|
|
|
|
|
break;
|
|
|
|
|
case 2:
|
|
|
|
|
H308_RST_OFF;
|
|
|
|
|
LOG_D("H308_RST_OFF");
|
|
|
|
|
break;
|
|
|
|
|
case 3:
|
|
|
|
|
H308_RST_ON;
|
|
|
|
|
LOG_D("H308_RST_ON");
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
LOG_E("TEST_H308 --use _cmd_ [mode] 0:PWR_OFF 1:PWR_ON 2:RST_OFF 3:RST_ON");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
MSH_CMD_EXPORT(TEST_H308, "TEST_H308");
|
|
|
|
|
|
|
|
|
|
static void TEST_H308_EndOfLife(void)
|
|
|
|
|
{
|
|
|
|
|
H308.end_of_life = 1;
|
|
|
|
|
}
|
|
|
|
|
MSH_CMD_EXPORT(TEST_H308_EndOfLife, TEST_H308_EndOfLife);
|
|
|
|
|
|
|
|
|
|
#endif
|