203 lines
5.6 KiB
C
203 lines
5.6 KiB
C
/*----------------------------------------------------------------------------
|
||
* Tencent is pleased to support the open source community by making TencentOS
|
||
* available.
|
||
*
|
||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||
*
|
||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||
* License, except for the third-party components listed below which are
|
||
* subject to different license terms. Your integration of TencentOS into your
|
||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||
* as the other licenses applicable to the third-party components included
|
||
* within TencentOS.
|
||
*---------------------------------------------------------------------------*/
|
||
#include "ch20_parser.h"
|
||
|
||
static ch20_parser_ctrl_t ch20_parser_ctrl;
|
||
|
||
static k_stack_t ch20_parser_task_stack[CH20_PARSER_TASK_STACK_SIZE];
|
||
|
||
static uint8_t ch20_parser_buffer[CH20_PARSER_BUFFER_SIZE];
|
||
|
||
/**
|
||
* @brief 向ch20解析器中送入一个字节数据
|
||
* @param data 送入的数据
|
||
* @retval none
|
||
* @note 需要用户在串口中断函数中手动调用
|
||
*/
|
||
void ch20_parser_input_byte(uint8_t data)
|
||
{
|
||
if (tos_chr_fifo_push(&ch20_parser_ctrl.parser_rx_fifo, data) == K_ERR_NONE) {
|
||
/* 送入数据成功,释放信号量,计数 */
|
||
tos_sem_post(&ch20_parser_ctrl.parser_rx_sem);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @brief ch20解析器从chr fifo中取出一个字节数据
|
||
* @param none
|
||
* @retval 正常返回读取数据,错误返回-1
|
||
*/
|
||
static int ch20_parser_getchar(void)
|
||
{
|
||
uint8_t chr;
|
||
k_err_t err;
|
||
|
||
/* 永久等待信号量,信号量为空表示chr fifo中无数据 */
|
||
if (tos_sem_pend(&ch20_parser_ctrl.parser_rx_sem, TOS_TIME_FOREVER) != K_ERR_NONE) {
|
||
return -1;
|
||
}
|
||
|
||
/* 从chr fifo中取出数据 */
|
||
err = tos_chr_fifo_pop(&ch20_parser_ctrl.parser_rx_fifo, &chr);
|
||
|
||
return err == K_ERR_NONE ? chr : -1;
|
||
}
|
||
|
||
/**
|
||
* @brief ch20读取传感器原始数据并解析
|
||
* @param void
|
||
* @retval 解析成功返回0,解析失败返回-1
|
||
*/
|
||
static int ch20_parser_read_raw_data(ch20_data_t *ch20_data)
|
||
{
|
||
uint8_t data;
|
||
uint8_t data_h, data_l;
|
||
uint8_t check_sum_cal = 0x17;
|
||
|
||
/* 读取气体浓度单位 */
|
||
data = ch20_parser_getchar();
|
||
if (data != 0x04) {
|
||
return -1;
|
||
}
|
||
CH20_DEBUG_LOG("--->[%#02x]\r\n", data);
|
||
check_sum_cal += data;
|
||
|
||
/* 读取小数位数 */
|
||
data = ch20_parser_getchar();
|
||
if (data != 0x00) {
|
||
return -1;
|
||
}
|
||
CH20_DEBUG_LOG("--->[%#02x]\r\n", data);
|
||
check_sum_cal += data;
|
||
|
||
/* 读取气体浓度高位 */
|
||
data = ch20_parser_getchar();
|
||
if (data == 0xFF) {
|
||
return -1;
|
||
}
|
||
CH20_DEBUG_LOG("--->[%#02x]\r\n", data);
|
||
data_h = data;
|
||
check_sum_cal += data;
|
||
|
||
/* 读取气体浓度低位 */
|
||
data = ch20_parser_getchar();
|
||
if (data == 0xFF) {
|
||
return -1;
|
||
}
|
||
CH20_DEBUG_LOG("--->[%#02x]\r\n", data);
|
||
data_l = data;
|
||
check_sum_cal += data;
|
||
|
||
/* 读取满量程高位 */
|
||
data = ch20_parser_getchar();
|
||
if (data != 0x07) {
|
||
return -1;
|
||
}
|
||
CH20_DEBUG_LOG("--->[%#02x]\r\n", data);
|
||
check_sum_cal += data;
|
||
|
||
/* 读取满量程低位 */
|
||
data = ch20_parser_getchar();
|
||
if (data != 0xD0) {
|
||
return -1;
|
||
}
|
||
CH20_DEBUG_LOG("--->[%#02x]\r\n", data);
|
||
check_sum_cal += data;
|
||
|
||
/* 和校验 */
|
||
data = ch20_parser_getchar();
|
||
CH20_DEBUG_LOG("--->[%#02x]\r\n", data);
|
||
check_sum_cal = ~(check_sum_cal) + 1;
|
||
CH20_DEBUG_LOG("check_sum_cal is 0x%02x \r\n", check_sum_cal);
|
||
if (check_sum_cal != data) {
|
||
return -1;
|
||
}
|
||
|
||
/* 存储数据 */
|
||
ch20_data->data = (data_h << 8) + data_l;
|
||
CH20_DEBUG_LOG("ch20_data->data is 0x%04x\r\n", ch20_data->data);
|
||
|
||
return 0;
|
||
}
|
||
|
||
extern k_mail_q_t mail_q;
|
||
ch20_data_t ch20_data;
|
||
|
||
/**
|
||
* @brief ch20解析器任务
|
||
*/
|
||
static void ch20_parser_task_entry(void *arg)
|
||
{
|
||
int chr, last_chr = 0;
|
||
|
||
while (1) {
|
||
|
||
chr = ch20_parser_getchar();
|
||
if (chr < 0) {
|
||
printf("parser task get char fail!\r\n");
|
||
continue;
|
||
}
|
||
|
||
if (chr == 0x17 && last_chr == 0xFF) {
|
||
/* 解析到包头 */
|
||
if (0 == ch20_parser_read_raw_data(&ch20_data)) {
|
||
/* 正常解析之后通过邮箱发送 */
|
||
tos_mail_q_post(&mail_q, &ch20_data, sizeof(ch20_data_t));
|
||
}
|
||
}
|
||
|
||
last_chr = chr;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @brief 初始化ch20解析器
|
||
* @param none
|
||
* @retval 全部创建成功返回0,任何一个创建失败则返回-1
|
||
*/
|
||
int ch20_parser_init(void)
|
||
{
|
||
k_err_t ret;
|
||
|
||
memset((ch20_parser_ctrl_t*)&ch20_parser_ctrl, 0, sizeof(ch20_parser_ctrl));
|
||
|
||
/* 创建 chr fifo */
|
||
ret = tos_chr_fifo_create(&ch20_parser_ctrl.parser_rx_fifo, ch20_parser_buffer, sizeof(ch20_parser_buffer));
|
||
if (ret != K_ERR_NONE) {
|
||
printf("ch20 parser chr fifo create fail, ret = %d\r\n", ret);
|
||
return -1;
|
||
}
|
||
|
||
/* 创建信号量 */
|
||
ret = tos_sem_create(&ch20_parser_ctrl.parser_rx_sem, 0);
|
||
if (ret != K_ERR_NONE) {
|
||
printf("ch20 parser_rx_sem create fail, ret = %d\r\n", ret);
|
||
return -1;
|
||
}
|
||
|
||
/* 创建线程 */
|
||
ret = tos_task_create(&ch20_parser_ctrl.parser_task, "ch20_parser_task",
|
||
ch20_parser_task_entry, NULL, CH20_PARSER_TASK_PRIO,
|
||
ch20_parser_task_stack,CH20_PARSER_TASK_STACK_SIZE,0);
|
||
if (ret != K_ERR_NONE) {
|
||
printf("ch20 parser task create fail, ret = %d\r\n", ret);
|
||
return -1;
|
||
}
|
||
|
||
return 0;
|
||
}
|