diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs index 57d06ac..c00a722 100644 --- a/.settings/org.eclipse.core.resources.prefs +++ b/.settings/org.eclipse.core.resources.prefs @@ -22,6 +22,8 @@ encoding//libraries/hal_drivers/drv_usart.h=GBK encoding//libraries/hal_libraries/bmsis/include/core_riscv.h=GBK encoding//libraries/hal_libraries/bmsis/source/startup_ch32v30x.S=GBK encoding//libraries/hal_libraries/ch32v303_hal/include/ch32v30x_gpio.h=GBK +encoding//libraries/hal_libraries/ch32v303_hal/include/ch32v30x_rcc.h=GBK +encoding//libraries/hal_libraries/ch32v303_hal/source/ch32v30x_gpio.c=GBK encoding//packages/at_device-2.1.0/at_device.c=GBK encoding//packages/at_device-2.1.0/at_device.h=GBK encoding//packages/rt_vsnprintf_full-master/rt_vsnprintf.c=GBK diff --git a/bsp/inc/bsp_adc.h b/bsp/inc/bsp_adc.h index 477d2e5..02bde07 100644 --- a/bsp/inc/bsp_adc.h +++ b/bsp/inc/bsp_adc.h @@ -15,7 +15,11 @@ //#define TEST_BSP_ADC +#define GAS_POWER_SWITCH_GPIO_PIN GPIO_Pin_9 +#define GAS_POWER_SWITCH_GPIO_PORT GPIOC +#define GAS_POWER_OPEN GPIO_WriteBit(GAS_POWER_SWITCH_GPIO_PORT, GAS_POWER_SWITCH_GPIO_PIN, Bit_SET) +#define GAS_POWER_CLOSE GPIO_WriteBit(GAS_POWER_SWITCH_GPIO_PORT, GAS_POWER_SWITCH_GPIO_PIN, Bit_RESET) // ADC要采集的通道个数 #define NUM_OF_CHANNEL (2U) // ADC要采集的次数 diff --git a/bsp/inc/bsp_bt.h b/bsp/inc/bsp_bt.h index f08a873..adcc82b 100644 --- a/bsp/inc/bsp_bt.h +++ b/bsp/inc/bsp_bt.h @@ -1,12 +1,12 @@ -/*** +/*** * @Author: mbw * @Date: 2024-12-03 10:31:59 * @LastEditors: mbw && 1600520629@qq.com - * @LastEditTime: 2024-12-07 17:07:51 + * @LastEditTime: 2024-12-10 14:51:37 * @FilePath: \ble_bjq_ch303rct6_ml307\bsp\inc\bsp_bt.h - * @Description: + * @Description: * @ - * @Copyright (c) 2024 by ${git_name_email}, All Rights Reserved. + * @Copyright (c) 2024 by ${git_name_email}, All Rights Reserved. */ #ifndef __BSP_BT_H__ #define __BSP_BT_H__ @@ -15,19 +15,20 @@ #include "board.h" #include "drv_gpio.h" -#define BT_FRAME_HEAD_LEN (2) -#define BT_FRAME_TAIL_LEN (2) +#define BT_FRAME_HEAD_LEN (2) +#define BT_FRAME_TAIL_LEN (2) #define BT_FRAME_MAX_LEN (32) -#define BT_FRAME_HEAD_DATA (0xAA) -#define BT_FRAME_TAIL_DATA (0x55) +#define BT_FRAME_HEAD_DATA (0xAA) +#define BT_FRAME_TAIL_DATA (0x55) typedef enum { - WirelessValveClose, - WirelessValveOpen, + WirelessValveClose = 0x01, + WirelessValveOpen, } WireLessState; -typedef enum { +typedef enum +{ kValveCmdCtr = 0X01, kValveCmdReg, kValveCmdRem, @@ -35,13 +36,28 @@ typedef enum { kValveCmdMax } ValveCmdType; +/*事件类型: 1: 阀门控制响应 + 2: 阀门注册响应 + 3:阀门移除响应 + 4: 阀门更换响应 + 5:阀门状态上报 +*/ +typedef enum +{ + kValveEventCtr = 0x01, + kValveEventReg, + kValveEventRem, + kValveEventRep, + kValveEventStatus, + kValveEventMax + +}ValveEventType; typedef struct __attribute__((packed)) { rt_uint8_t cmd; uint8_t buf[]; -}BtData_t; - +} BtData_t; typedef struct __attribute__((packed)) { @@ -49,32 +65,11 @@ typedef struct __attribute__((packed)) rt_uint8_t buf[256]; } BTFrameData; +extern struct rt_semaphore bt_ctr_sem; //控制阀门信号量 +extern struct rt_semaphore bt_reg_sem; //注册阀门信号量 +extern struct rt_semaphore bt_rem_sem; //移除阀门信号量 +extern struct rt_semaphore bt_rep_sem; //更换阀门信号量 + +int Bt_Valve_Handler(ValveCmdType type, rt_uint8_t id, rt_uint8_t *data); #endif // BSP_BT_H__ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/bsp/inc/bsp_button.h b/bsp/inc/bsp_button.h index 208fe2f..0121440 100644 --- a/bsp/inc/bsp_button.h +++ b/bsp/inc/bsp_button.h @@ -5,7 +5,11 @@ #include "drv_gpio.h" #ifndef BUTTON_0 -#define BUTTON_0 GET_PIN(B, 15) +#define BUTTON_0 GET_PIN(B, 15)//自检按键 +#endif + +#ifndef BUTTON_1 +#define BUTTON_1 GET_PIN(C, 4) //消音按键 #endif // 不然就是用 timer 实现按键扫描处理 diff --git a/bsp/inc/bsp_ml307.h b/bsp/inc/bsp_ml307.h index 0cfae0f..237f7c3 100644 --- a/bsp/inc/bsp_ml307.h +++ b/bsp/inc/bsp_ml307.h @@ -233,5 +233,5 @@ struct Ml307_Ops extern struct Ml307_Ops ml307_ops; extern rt_sem_t ml307_recv_sem; extern rt_uint8_t ml307_conncet_tcp_flag; - +extern rt_sem_t ml307_life_sem; void Ml307_Send_Event(Ml307Event event_type); diff --git a/bsp/src/at_device_ml307.c b/bsp/src/at_device_ml307.c index ce4a9a9..2337291 100644 --- a/bsp/src/at_device_ml307.c +++ b/bsp/src/at_device_ml307.c @@ -314,13 +314,16 @@ static void urc_tcp_disconnect(struct at_client *client, const char *data, rt_si switch (state) { case 1: - LOG_D("ml307 tcp server disconnect"); + LOG_D("服务器断开连接"); + rt_sem_release(ml307_life_sem); break; case 2: // 连接异常 - LOG_D("ml307 tcp server connect error"); + LOG_D("连接异常"); + rt_sem_release(ml307_life_sem); break; case 3: // PDP去激活 LOG_D("ml307 tcp server PDP deactivate"); + rt_sem_release(ml307_life_sem); break; default: break; @@ -438,7 +441,7 @@ int at_device_ml307_socket_creat(struct at_device *device) static int at_device_ml307_connect_tcp(struct at_device *device) { - rt_err_t ret = RT_EOK; + rt_err_t ret = RT_ERROR; ASSERT(device); rt_uint8_t retry = (rt_uint8_t)Flash_Get_SysCfg(kIotRetryId); at_response_t resp = at_create_resp(64, 2, 2000); @@ -488,6 +491,7 @@ static int at_device_ml307_connect_tcp(struct at_device *device) if (ml307_conncet_tcp_flag == RT_TRUE) { LOG_D("ml307 connect to tcp server success"); + ret = RT_EOK; break; } } @@ -777,7 +781,7 @@ static void ml307_check_link_status_entry(void *parameter) } } -static int ml307_netdev_check_link_status(struct netdev *netdev) +int ml307_netdev_check_link_status(struct netdev *netdev) { #define ML307_LINK_THREAD_TICK 20 #define ML307_LINK_THREAD_STACK_SIZE (1024) diff --git a/bsp/src/bsp_adc.c b/bsp/src/bsp_adc.c index f40fc50..654dd98 100644 --- a/bsp/src/bsp_adc.c +++ b/bsp/src/bsp_adc.c @@ -2,13 +2,15 @@ * @Author : yzy * @Date : 2023-01-30 12:50:12 * @LastEditors: mbw && 1600520629@qq.com - * @LastEditTime: 2024-12-03 17:42:59 + * @LastEditTime: 2024-12-11 09:23:14 * @FilePath: \ble_bjq_ch303rct6_ml307\bsp\src\bsp_adc.c * @Description : * * Copyright (c) 2023 by yzy, All Rights Reserved. */ #include "bsp_adc.h" +#include "finsh.h" + #define LOG_TAG "bsp_adc" // 该模块对应的标签。不定义时,默认:NO_TAG #define LOG_LVL LOG_LVL_DBG // 该模块对应的日志输出级别。不定义时,默认:调试级别 @@ -42,19 +44,29 @@ static void _USED_ADC_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStructure = {0}; - // 使能 GPIO 时钟 GPIOA + // 使能 GPIO 时钟 GPIOC USED_ADC_GPIO_CLK_ENABLE(); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); + + GPIO_InitStructure.GPIO_Pin = GAS_POWER_SWITCH_GPIO_PIN; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_Init(GAS_POWER_SWITCH_GPIO_PORT, &GPIO_InitStructure); + + // 配置 IO GPIO_InitStructure.GPIO_Pin = VIN_ADC_GPIO_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(USED_ADC_GPIO_PORT, &GPIO_InitStructure); // 配置 IO GPIO_InitStructure.GPIO_Pin = GAS_ADC_GPIO_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GAS_ADC_GPIO_PORT, &GPIO_InitStructure); + GAS_POWER_OPEN; } static void _USED_ADC_DMA_Init(void) diff --git a/bsp/src/bsp_bt.c b/bsp/src/bsp_bt.c index cf650da..96c2c00 100644 --- a/bsp/src/bsp_bt.c +++ b/bsp/src/bsp_bt.c @@ -1,56 +1,67 @@ +/* + * @Author: mbw + * @Date: 2024-12-03 10:31:45 + * @LastEditors: mbw && 1600520629@qq.com + * @LastEditTime: 2024-12-13 18:09:14 + * @FilePath: \ble_bjq_ch303rct6_ml307\bsp\src\bsp_bt.c + * @Description: + * + * Copyright (c) 2024 by ${git_name_email}, All Rights Reserved. + */ #include "bsp_bt.h" #include "bsp_ml307.h" #include "bsp_flash.h" #include "rtdef.h" #include "lwrb.h" - +#include "finsh.h" #include "user_sys.h" - #define LOG_TAG "bsp_bt" #define LOG_LVL LOG_LVL_DBG #include #define BT_UART "uart5" -rt_timer_t bt_timer; -struct rt_semaphore bt_rx_sem; static rt_device_t rt_bt_device; +static struct rt_semaphore bt_rx_sem; // +struct rt_semaphore bt_ctr_sem; // 控制阀门信号量 +struct rt_semaphore bt_reg_sem; // 注册阀门信号量 +struct rt_semaphore bt_rem_sem; // 移除阀门信号量 +struct rt_semaphore bt_rep_sem; // 更换阀门信号量 + #define BT_THREAD_TIMESLICE (5) #define BT_THREAD_PRIORITY (10) #define BT_THREAD_STACK_SIZE (2048) - ALIGN(RT_ALIGN_SIZE) static rt_uint8_t bt_thread_stack[BT_THREAD_STACK_SIZE] = {0}; static struct rt_thread bt_thread = {0}; lwrb_t bt_lwrb_rx; static char bt_rx_buffer[256] = {0}; -BTFrameData bt_frame = {0}; +BTFrameData bt_frame = {0}; valve_data_t valve_t[MAX_VALVE_NUM]; - rt_size_t BSP_Bt_Send_Data(uint8_t *data, size_t size) { - return rt_device_write(rt_bt_device, 0, data, size);; + return rt_device_write(rt_bt_device, 0, data, size); } rt_size_t BSP_Bt_Recv_Data(uint8_t *data, size_t size) { - return lwrb_read(&bt_lwrb_rx, data, size); + return lwrb_read(&bt_lwrb_rx, data, size); } int BSP_BT_Init(void) { - rt_uint8_t num = Flash_Get_Valve_Num(); + rt_uint8_t num = Flash_Get_Valve_Num(); rt_uint8_t mac_buf[FLASH_VALVE_MAC_ADDR_LEN] = {0}; if (num != 0) { for (size_t i = 0; i < MAX_VALVE_NUM; i++) { - valve_t[i].valve_id = (i + 1);//1-8 + valve_t[i].valve_id = (i + 1); // 1-8 if (Flash_Get_Mac_Addr(valve_t[i].valve_mac, i) == RT_EOK) { rt_memcpy(valve_t[i].valve_mac, mac_buf, 6); @@ -68,9 +79,6 @@ int BSP_BT_Init(void) } INIT_PREV_EXPORT(BSP_BT_Init); - - - static rt_err_t bt_getchar(char *ch, rt_int32_t timeout) { rt_err_t result = RT_EOK; @@ -90,37 +98,30 @@ static int bt_recv_readline(void) { rt_size_t read_len = 0; char ch = 0, last_ch = 0; - rt_bool_t is_full = RT_FALSE; - rt_err_t result = RT_EOK; + rt_bool_t is_full = RT_FALSE; while (1) { - result = bt_getchar(&ch, RT_WAITING_FOREVER); - if (result != RT_EOK) + bt_getchar(&ch, RT_WAITING_FOREVER); + if (read_len < lwrb_get_free(&bt_lwrb_rx)) { - LOG_D("get sem bt_rx_sem error"); + lwrb_write(&bt_lwrb_rx, &ch, 1); } else { - if (read_len < lwrb_get_free(&bt_lwrb_rx)) - { - lwrb_write(&bt_lwrb_rx, &ch, 1); - } - else - { - is_full = RT_TRUE; - } - if (ch == '\n' && last_ch == '\r') - { - if (is_full) - { - LOG_E("read line failed. The line data length is out of buffer size(%d)!", lwrb_get_free(&bt_lwrb_rx)); - return -RT_EFULL; - } - break; - } - last_ch = ch; + is_full = RT_TRUE; } + if ((ch == '\n' && last_ch == '\r') || ch == 0x55) + { + if (is_full) + { + LOG_E("read line failed. The line data length is out of buffer size(%d)!", lwrb_get_free(&bt_lwrb_rx)); + return -RT_EFULL; + } + + break; + } + last_ch = ch; } return lwrb_get_full(&bt_lwrb_rx); } @@ -147,106 +148,240 @@ rt_uint8_t BT_GenerateRawFrame(BTFrameData *pRawData, const rt_uint8_t *p_src, r return RT_EOK; } - /*用于控制阀门的状态 * id: 1-8 * mac_addr: 6字节 * status: 0-关闭 1-打开 -*/ + */ int BSP_Bt_Valve_Ctr(rt_uint8_t id, rt_uint8_t *mac_addr, WireLessState status) { + rt_uint8_t ret = 0; + BtData_t *ptr = (BtData_t *)rt_malloc(sizeof(BtData_t) + 8); - ptr->cmd = kValveCmdCtr; - ptr->buf[0] = id; + ptr->cmd = kValveCmdCtr; + ptr->buf[0] = id; rt_memcpy(&ptr->buf[1], mac_addr, 6); ptr->buf[7] = status; BT_GenerateRawFrame(&bt_frame, (rt_uint8_t *)ptr, 9); rt_free(ptr); - return BSP_Bt_Send_Data((rt_uint8_t *)&bt_frame.buf[0], bt_frame.len); + ret = BSP_Bt_Send_Data((rt_uint8_t *)&bt_frame.buf[0], bt_frame.len); + if (ret == bt_frame.len) + { + return RT_EOK; + } + + return RT_ERROR; } /*注册阀门信息*/ int BSP_Bt_Register_Valve(rt_uint8_t id, rt_uint8_t *mac_addr) { - BtData_t *ptr = (BtData_t *)rt_malloc(sizeof(BtData_t) + 7); - ptr->cmd = kValveCmdReg; - ptr->buf[0] = id; + rt_uint8_t ret = 0; + BtData_t *ptr = (BtData_t *)rt_malloc(sizeof(BtData_t) + 7); + ptr->cmd = kValveCmdReg; + ptr->buf[0] = id; rt_memcpy(&ptr->buf[1], mac_addr, 6); BT_GenerateRawFrame(&bt_frame, (rt_uint8_t *)ptr, 8); rt_free(ptr); + ret = BSP_Bt_Send_Data((rt_uint8_t *)&bt_frame.buf[0], bt_frame.len); + if (ret == bt_frame.len) + { + return RT_EOK; + } - return BSP_Bt_Send_Data((rt_uint8_t *)&bt_frame.buf[0], bt_frame.len); + return RT_ERROR; } /*移除阀门信息*/ int BSP_Bt_Remove_Valve(rt_uint8_t id, rt_uint8_t *mac_addr) { + rt_uint8_t ret = 0; + BtData_t *ptr = (BtData_t *)rt_malloc(sizeof(BtData_t) + 7); - ptr->cmd = kValveCmdRem; - ptr->buf[0] = id; + ptr->cmd = kValveCmdRem; + ptr->buf[0] = id; rt_memcpy(&ptr->buf[1], mac_addr, 6); BT_GenerateRawFrame(&bt_frame, (rt_uint8_t *)ptr, 8); rt_free(ptr); - return BSP_Bt_Send_Data((rt_uint8_t *)&bt_frame.buf[0], bt_frame.len); + ret = BSP_Bt_Send_Data((rt_uint8_t *)&bt_frame.buf[0], bt_frame.len); + if (ret == bt_frame.len) + { + return RT_EOK; + } + + return RT_ERROR; } /*更换阀门信息*/ int BSP_Bt_Replace_Valve(rt_uint8_t id, rt_uint8_t *mac_addr, rt_uint8_t *new_mac_addr) { + rt_uint8_t ret = 0; + BtData_t *ptr = (BtData_t *)rt_malloc(sizeof(BtData_t) + 14); - ptr->cmd = kValveCmdRep; - ptr->buf[0] = id; + ptr->cmd = kValveCmdRep; + ptr->buf[0] = id; rt_memcpy(&ptr->buf[1], mac_addr, 6); rt_memcpy(&ptr->buf[7], new_mac_addr, 6); BT_GenerateRawFrame(&bt_frame, (rt_uint8_t *)ptr, (sizeof(BtData_t) + 14)); rt_free(ptr); - return BSP_Bt_Send_Data((rt_uint8_t *)&bt_frame.buf[0], bt_frame.len); + ret = BSP_Bt_Send_Data((rt_uint8_t *)&bt_frame.buf[0], bt_frame.len); + if (ret == bt_frame.len) + { + return RT_EOK; + } + + return RT_ERROR; } -int Bt_Valve_Handler(ValveCmdType type) +// 这个ID是真实id减一,例:第一个阀门,则为 1 - 1 = 0 +/*data 数据用作阀门更换时的新MAC参数6字节*/ +int Bt_Valve_Handler(ValveCmdType type, rt_uint8_t id, rt_uint8_t *data) { + int ret = RT_EOK; + switch (type) { - case kValveCmdCtr://阀门控制 - BSP_Bt_Valve_Ctr(valve_t[0].valve_id, valve_t[0].valve_mac, WirelessValveClose);//关阀门 - break; - case kValveCmdReg://阀门注册 - BSP_Bt_Register_Valve(valve_t[0].valve_id, valve_t[0].valve_mac); - break; - case kValveCmdRem://阀门移除 - BSP_Bt_Remove_Valve(valve_t[0].valve_id, valve_t[0].valve_mac); - break; - case kValveCmdRep://阀门更换 - BSP_Bt_Replace_Valve(valve_t[0].valve_id, valve_t[0].valve_mac, valve_t[0].valve_mac); - break; - default: - LOG_E("unknown valve command type"); - break; + case kValveCmdCtr: // 阀门控制 + ret = BSP_Bt_Valve_Ctr(valve_t[id].valve_id, valve_t[id].valve_mac, WirelessValveClose); // 关阀门 + break; + case kValveCmdReg: // 阀门注册 + ret = BSP_Bt_Register_Valve(valve_t[id].valve_id, valve_t[id].valve_mac); + break; + case kValveCmdRem: // 阀门移除 + ret = BSP_Bt_Remove_Valve(valve_t[id].valve_id, valve_t[id].valve_mac); + break; + case kValveCmdRep: // 阀门更换 + ret = BSP_Bt_Replace_Valve(valve_t[id].valve_id, valve_t[id].valve_mac, data); + if (ret == RT_EOK) + { + rt_memcpy(valve_t[id].valve_mac, data, 6); + Flash_Set_Mac_Addr(valve_t[id].valve_mac, valve_t[id].valve_id - 1); + } + break; + default: + ret = -RT_ERROR; + LOG_E("unknown valve command type"); + break; } - return RT_EOK; + return ret; } +int BSP_Bt_Process(uint8_t *data, uint16_t len) +{ + int ret = 0; + uint16_t index = 0; + uint8_t data_buf[256] = {0}; + // 解析接收到的数据帧,先寻找AA开头,然后再找AA下一个字节,其代表了数据长度,然后找到代表长度的值的长度的下一位,其为校验码,校验码后为结束码0x55, + // 如果数据正确,则提取数据,不正确,则不处理 + LOG_HEX("BT_RX_DATA", 16, data, len); + if (len < 4) + { // 至少需要 4 个字节:起始码、长度、校验码、结束码 + LOG_E("BT_RX_DATA_LEN_ERROR"); + return 1; + } + while (index < len && data[index] != 0xAA) // 寻找起始码 0xAA + { + index++; + } + if (index >= len - 3) // 不够空间容纳长度、校验码和结束码 + { + LOG_E("BT_RX_DATA_LEN_ERROR"); + return 2; + } + uint16_t datalength = data[index + 1]; // 读取数据长度 + if (index + 2 + datalength + 1 >= len) // 检查数据长度是否合理 数据长度 + 校验码 + 结束码 + { + LOG_E("BT_RX_DATA_LEN_ERROR"); + return 3; // + } + + uint8_t rx_sum = data[index + 2 + datalength]; // 读取校验码 + uint8_t calculated_sum = XOR_CheckSum(&data[0], datalength + 2); // 计算校验码 + if (rx_sum != calculated_sum) + { + LOG_E("BT_RX_DATA_SUM_ERROR"); + return 4; + } + + if (data[index + 2 + datalength + 1] != 0x55) // 检查结束码 + { + LOG_E("BT_RX_DATA_END_ERROR"); + return 5; + } + // 当程序走到这里时,就说明接收到了正确的数据帧,开始解析响应 + rt_memcpy(data_buf, &data[index + 3], datalength); + switch (data[index + 2]) + { + case kValveEventCtr: + LOG_D("valve control event"); + if (data[index + datalength - 3] == WirelessValveClose) // 关闭成功 + { + rt_sem_release(&bt_ctr_sem); + } + break; + case kValveEventReg: + LOG_D("valve register event"); + if (data[index + datalength - 3] == RT_TRUE) // 注册成功 + { + rt_sem_release(&bt_reg_sem); + } + break; + case kValveEventRem: + LOG_D("valve remove event"); + if (data[index + datalength - 3] == RT_TRUE) // 移除成功 + { + rt_sem_release(&bt_rem_sem); + } + break; + case kValveEventRep: + LOG_D("valve replace event"); + if (data[index + datalength - 3] == RT_TRUE) // 更换成功 + { + rt_sem_release(&bt_rep_sem); + } + break; + case kValveEventStatus: + LOG_D("valve status event"); + // TODO:添加阀门数据处理函数 + break; + default: + LOG_W("unknow cmd: %02X", data[index + 2]); + break; + } + + return ret; +} static void BSP_Bt_Parse_Data(void) { - rt_size_t size = lwrb_get_full(&bt_lwrb_rx); - char *rx_ptr = rt_calloc(1, size + 1); - BSP_Bt_Recv_Data(rx_ptr, size); - LOG_D("data: %s\r\n", rx_ptr); - + LOG_D("parse data:"); + rt_size_t len = lwrb_get_full(&bt_lwrb_rx); + char *rx_ptr = rt_calloc(1, len + 1); + BSP_Bt_Recv_Data(rx_ptr, len); + // 发送过来的数据格式为:帧头 + 数据长度 + 事件类型 + 数据 + 校验码 + 帧尾 + BSP_Bt_Process(rx_ptr, len); rt_free(rx_ptr); } static void Bt_Thread_Entry(void *parameter) { + //初始化阀门信息 + valve_t[0].valve_id = 1; + valve_t[0].valve_mac[0] = 0xb6; + valve_t[0].valve_mac[1] = 0xb4; + valve_t[0].valve_mac[2] = 0x8f; + valve_t[0].valve_mac[3] = 0x10; + valve_t[0].valve_mac[4] = 0x53; + valve_t[0].valve_mac[5] = 0x5c; + LOG_D("Bt_Thread_Entry"); while (1) { - if (bt_recv_readline() > 0) + if (bt_recv_readline()) { BSP_Bt_Parse_Data(); } @@ -281,16 +416,17 @@ int BSP_Bt_Init(void) LOG_E("rt_device_open failed!\n"); return RT_ERROR; } - rt_sem_init(&bt_rx_sem, "bt_rx_sem", 0, RT_IPC_FLAG_PRIO); /* 初始化信号量 */ + rt_sem_init(&bt_rx_sem, "bt_rx_sem", 0, RT_IPC_FLAG_PRIO); /* 接收来自蓝牙主机的信号量 */ + rt_sem_init(&bt_ctr_sem, "bt_ctr_sem", 0, RT_IPC_FLAG_PRIO); + rt_sem_init(&bt_reg_sem, "bt_reg_sem", 0, RT_IPC_FLAG_PRIO); + rt_sem_init(&bt_rem_sem, "bt_rem_sem", 0, RT_IPC_FLAG_PRIO); + rt_sem_init(&bt_rep_sem, "bt_rep_sem", 0, RT_IPC_FLAG_PRIO); /* 设置接收回调函数 */ if (rt_device_set_rx_indicate(rt_bt_device, Bt_Rcv_Cb) != RT_EOK) { LOG_E("rt_device_set_rx_indicate failed!\n"); return RT_ERROR; } - rt_device_write(rt_bt_device, 0, "test bt_uart send\r\n", strlen("test bt_uart send\r\n")); - rt_uint8_t buf_test[3] = {0x01, 0x02, 0x03}; - BSP_Bt_Send_Data(buf_test, 3); /* 静态初始化线程 1*/ ret = rt_thread_init(&bt_thread, // 该线程用于数据解析 "bt_thread", @@ -308,32 +444,30 @@ int BSP_Bt_Init(void) INIT_DEVICE_EXPORT(BSP_Bt_Init); #ifdef TEST_ENABLE - static void TEST_BT_Send_Data(int argc, char **argv) { - if (argc == 2) + if (argc == 3) { int mode = atoi(argv[1]); + int id = atoi(argv[2]) - 1; switch (mode) { case 1: - Bt_Valve_Handler(kValveCmdCtr); + Bt_Valve_Handler(kValveCmdCtr, id, RT_NULL); break; case 2: - Bt_Valve_Handler(kValveCmdReg); + Bt_Valve_Handler(kValveCmdReg, id, RT_NULL); break; case 3: - Bt_Valve_Handler(kValveCmdRem); + Bt_Valve_Handler(kValveCmdRem, id, RT_NULL); break; case 4: - Bt_Valve_Handler(kValveCmdRep); + Bt_Valve_Handler(kValveCmdRep, id, RT_NULL); break; default: - break; + break; } } } MSH_CMD_EXPORT(TEST_BT_Send_Data, "TEST_BT_Send_Data"); - - -#endif \ No newline at end of file +#endif diff --git a/bsp/src/bsp_button.c b/bsp/src/bsp_button.c index 2507593..022b964 100644 --- a/bsp/src/bsp_button.c +++ b/bsp/src/bsp_button.c @@ -23,6 +23,7 @@ static rt_timer_t button_timer; typedef enum { USER_BUTTON_0 = 0, + USER_BUTTON_1 , USER_BUTTON_MAX } user_button_t; @@ -37,9 +38,10 @@ static uint8_t _CommonBtnRead(void *arg) { case USER_BUTTON_0: value = rt_pin_read(BUTTON_0); - // return rt_pin_read(BUTTON_0); break; - + case USER_BUTTON_1: + value = rt_pin_read(BUTTON_1); + break; default: RT_ASSERT(0); } @@ -58,12 +60,12 @@ static void _CommonBtnEvtCb(void *arg) { static rt_uint8_t button_cnt = 0; - if (flex_button_event_read(&user_button[USER_BUTTON_0]) == FLEX_BTN_PRESS_DOUBLE_CLICK) + if (flex_button_event_read(&user_button[USER_BUTTON_1]) == FLEX_BTN_PRESS_CLICK) { - Send_Laser_Alarm_Event(KMuteEvent); + Send_Laser_Alarm_Event(kSelfCheckEvent); } #if 1 - if (flex_button_event_read(&user_button[USER_BUTTON_0]) == FLEX_BTN_PRESS_CLICK) + if ((flex_button_event_read(&user_button[USER_BUTTON_0]) == FLEX_BTN_PRESS_DOUBLE_CLICK)|| (flex_button_event_read(&user_button[USER_BUTTON_1]) == FLEX_BTN_PRESS_DOUBLE_CLICK)) { button_cnt++; if (button_cnt == 1) @@ -84,10 +86,9 @@ static void _CommonBtnEvtCb(void *arg) } } #endif - - else if (flex_button_event_read(&user_button[USER_BUTTON_0]) == FLEX_BTN_PRESS_LONG_HOLD) + else if (flex_button_event_read(&user_button[USER_BUTTON_0]) == FLEX_BTN_PRESS_CLICK) { - Send_Laser_Alarm_Event(kSelfCheckEvent); + Send_Laser_Alarm_Event(KMuteEvent); } } @@ -112,7 +113,8 @@ int BSP_BUTTON_Init(void) rt_memset(&user_button[0], 0x0, sizeof(user_button)); rt_pin_mode(BUTTON_0, PIN_MODE_INPUT_PULLUP); /* set KEY pin mode to input */ - + rt_pin_mode(BUTTON_1, PIN_MODE_INPUT_PULLUP); /* set KEY pin mode to input */ + for (uint8_t i = 0; i < USER_BUTTON_MAX; i++) { user_button[i].id = i; diff --git a/bsp/src/bsp_flash.c b/bsp/src/bsp_flash.c index ee73b62..0110e79 100644 --- a/bsp/src/bsp_flash.c +++ b/bsp/src/bsp_flash.c @@ -12,6 +12,17 @@ #include +//在此修改默认的服务器地址 +struct flash_sever_info sever_info = +{ + .server_url = "8.130.122.162", + .server_port = "7153", + // .server_port = "36078", + // .server_url = "8.135.10.183", +}; + + + extern int Convert_To_Hex(const struct flash_sever_info *sever_info, uint8_t *hex_array); #define GETATTR(info, id) ((id) == kHwVerId ? (&(info)->hw_ver) \ : (id) == kSwVerId ? (&(info)->sw_ver) \ @@ -89,13 +100,6 @@ rt_uint8_t sys_temp_alarm_threshold = 0x32; rt_uint8_t sys_emagnetic_switch = 0x04; // 具备阀门功能 rt_uint8_t sys_relay_switch = 0x04; // 具备继电器功能 -struct flash_sever_info sever_info = -{ - .server_url = "47.94.169.135", - .server_port = "7150", - // .server_port = "36078", - // .server_url = "8.135.10.183", -}; static void BSP_Flash_UnLock(void) diff --git a/bsp/src/bsp_ml307.c b/bsp/src/bsp_ml307.c index 9f09c9a..afb3b07 100644 --- a/bsp/src/bsp_ml307.c +++ b/bsp/src/bsp_ml307.c @@ -2,7 +2,7 @@ * @Author: mbw * @Date: 2024-11-30 15:46:21 * @LastEditors: mbw && 1600520629@qq.com - * @LastEditTime: 2024-12-06 16:48:54 + * @LastEditTime: 2024-12-11 13:04:23 * @FilePath: \ble_bjq_ch303rct6_ml307\bsp\src\bsp_ml307.c * @Description: * @@ -49,12 +49,11 @@ static struct rt_thread ml307_life_thread; struct rt_event at_device_event; rt_sem_t ml307_recv_sem; rt_sem_t ml307_life_sem; -static rt_timer_t ml307_timer; // 上报心跳 -static rt_timer_t ml307_upload_timer; // 更新本地时间定时器 -static rt_timer_t ml307_power_error_timer; // 上电失败情况下启动定时器 -/*生命周期窗口定时器,用于管理tcp连接的断开*/ -static rt_timer_t ml307_life_timer; +static rt_timer_t ml307_timer; // 上报心跳 +static rt_timer_t ml307_upload_timer; // 更新本地时间定时器 +static rt_timer_t ml307_power_error_timer; // 上电失败情况下启动定时器 static rt_timer_t ml307_heartbeat_check_timer; // 用于检测定时器是否工作 + rt_uint8_t ml307_conncet_tcp_flag; Ml307EventIndex ml307_event_index; @@ -173,13 +172,6 @@ static void Ml307_Ht_Timer_Cb(void *parameter) Ml307_Send_Event(kMl307HeartbeatEvent); } -// 定时器回调函数,当1分钟内没有数据交互时,关闭tcp连接 -static void Ml307_Life_Timer_Cb(void *parameter) -{ - // rt_sem_release(ml307_life_sem); -} - -// 定时器回调函数,当1分钟内没有数据交互时,关闭tcp连接 static void Ml307_Error_Timer_Cb(void *parameter) { if (power_on_send_flag) // 上电成功时,停止定时器 @@ -211,15 +203,6 @@ static void Ml307_Heartbeat_check_Timer_Cb(void *parameter) // } } -// 重置定时器 -void Reset_Ml307_Life_Timer(void) -{ - if (ml307_life_timer != RT_NULL) - { - rt_timer_start(ml307_life_timer); - } -} - int _Pack_Send(struct Ml307_Ops *ops, char *buf) { char ml307_send_buf[1024] = {0}; // 发送缓冲区,用于存储最终发送的数据 @@ -330,7 +313,7 @@ int _Update_Valve_Data(struct Ml307_Ops *ops) if (ops->body->valve_num == 0) // 确保至少有一个阀门数据体 { LOG_D("No valve data"); - rt_memset(&ops->body->valve_data, 0, sizeof(struct valve_data));//直接全部发送0 + rt_memset(&ops->body->valve_data, 0, sizeof(struct valve_data)); // 直接全部发送0 // rt_memcpy(&ops->body->valve_data, &valve_data_t[0], sizeof(struct valve_data)); } else @@ -979,13 +962,13 @@ void Handle_Mute(struct Ml307_Ops *ops) rt_err_t Handle_Close_Valve(struct Ml307_Ops *ops) { LOG_D("服务器下发关闭阀门指令\n"); - int i = 0; + int i = 0; rt_uint8_t data[FLASH_VALVE_MAC_ADDR_LEN + 1] = {0}; - rt_uint8_t mac_addr[6] = {0}; - char imei[16] = {0}; + rt_uint8_t mac_addr[6] = {0}; + char imei[16] = {0}; Get_Iot_Imei(imei, FLASH_NB_IMEI_LEN); char temp[32] = "0"; - String2Hex(temp, imei); // 将字符串转为十六进制字符串 + String2Hex(temp, imei); // 将字符串转为十六进制字符串 rt_memcpy(data, (ops->recv->recv_data.res_data + 8), FLASH_VALVE_MAC_ADDR_LEN + 1); LOG_D("data[0] = %x data[1] = %x data[2] = %x data[3] = %x data[4] = %x, data[5] = %x data[6] = %x", data[0], data[1], data[2], data[3], data[4], data[5], data[6]); if ((data[0] > 0) && (data[0] < MAX_VALVE_NUM)) // 不为零则说明关闭无线阀门 @@ -996,12 +979,12 @@ rt_err_t Handle_Close_Valve(struct Ml307_Ops *ops) /*对两个数组进行比较,如果值不同则退出*/ for (; i < FLASH_VALVE_MAC_ADDR_LEN; i++) { - if (mac_addr[i] != data[i+1]) + if (mac_addr[i] != data[i + 1]) { - LOG_E("mac_addr[%d][%x]!= data[%d][%x]\n", i, mac_addr[i], i+1, data[i+1]); + LOG_E("mac_addr[%d][%x]!= data[%d][%x]\n", i, mac_addr[i], i + 1, data[i + 1]); ops->Resp(ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_ML307, INSTRUCTION_DOWN_CLOSE_VALVE, temp, RESPONSE_CODE_ACTION_FAILURE); - + return RT_ERROR; } } @@ -1229,34 +1212,53 @@ rt_err_t Handle_Valve_Add(struct Ml307_Ops *ops) ops->Resp(ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_ML307, INSTRUCTION_DOWN_VALVE_ADD, temp, RESPONSE_CODE_ACTION_FAILURE); return RT_ERROR; } - rt_memcpy(data, (ops->recv->recv_data.res_data + 8), FLASH_VALVE_MAC_ADDR_LEN + 1); LOG_D("data[0] = %x data[1] = %x data[2] = %x data[3] = %x data[4] = %x, data[5] = %x data[6] = %x", data[0], data[1], data[2], data[3], data[4], data[5], data[6]); - - //无阀门数据时添加,有阀门数据时不添加 - if ((Flash_Get_Mac_Addr(mac_addr, data[0]) == RT_EEMPTY)||((Flash_Get_Mac_Addr(mac_addr, data[0]) == RT_EOK))) + + // 无阀门数据时添加,有阀门数据时不添加 + if ((Flash_Get_Mac_Addr(mac_addr, data[0]) == RT_EEMPTY) || ((Flash_Get_Mac_Addr(mac_addr, data[0]) == RT_EOK))) { - if (mac_addr[0] == 0)//无MAC地址数据,写入MAC地址数据 + if (mac_addr[0] == 0) // 无MAC地址数据,写入MAC地址数据 { - if (Flash_Set_Mac_Addr(&data[1], (data[0] - 1)) == RESET) + valve_t[data[0] - 1].valve_id = data[0]; + rt_memcpy(valve_t[data[0] - 1].valve_mac, &data[1], FLASH_VALVE_MAC_ADDR_LEN);//将信息更新 + if (Bt_Valve_Handler(kValveCmdReg, data[0] - 1, RT_NULL) != RT_EOK) { LOG_E("新增阀门设备失败\n"); ops->Resp(ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_ML307, INSTRUCTION_DOWN_VALVE_ADD, temp, RESPONSE_CODE_ACTION_FAILURE); return RT_ERROR; } - LOG_D("新增阀门设备成功\n"); - Flash_Set_Valve_Num(cnt + 1); - ops->Resp(ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_ML307, INSTRUCTION_DOWN_VALVE_ADD, temp, RESPONSE_CODE_SUCCESS); - return RT_EOK; + //TODO:此处需要等待蓝牙响应数据 + if(rt_sem_take(&bt_reg_sem, 10000) != RT_EOK) //等待十秒获取信号量 + { + LOG_E("获取信号量失败\n"); + ops->Resp(ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_ML307, INSTRUCTION_DOWN_VALVE_ADD, temp, RESPONSE_CODE_ACTION_FAILURE); + return RT_ERROR; + } + else + { + if (Flash_Set_Mac_Addr(&data[1], (data[0] - 1)) == RESET) + { + LOG_E("阀门设备写入FLash失败\n"); + ops->Resp(ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_ML307, INSTRUCTION_DOWN_VALVE_ADD, temp, RESPONSE_CODE_ACTION_FAILURE); + return RT_ERROR; + } + LOG_D("新增阀门设备成功\n"); + Flash_Set_Valve_Num(cnt + 1); + ops->Resp(ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_ML307, INSTRUCTION_DOWN_VALVE_ADD, temp, RESPONSE_CODE_SUCCESS); + return RT_EOK; + } } - else//不为空,不添加 + else // 不为空,不添加 { LOG_E("该阀门设备已存在,请选择更换阀门编号后重试\n"); ops->Resp(ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_ML307, INSTRUCTION_DOWN_VALVE_ADD, temp, RESPONSE_CODE_OTHER_ERROR); return RT_EOK; } } + + return RT_EOK; } /*更换阀门设备*/ @@ -1280,7 +1282,7 @@ rt_err_t Handle_Valve_Replace(struct Ml307_Ops *ops) { LOG_E("旧阀门MAC地址错误\n"); ops->Resp(ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_ML307, INSTRUCTION_DOWN_VALVE_REPLACE, temp, RESPONSE_CODE_OTHER_ERROR); - + return RT_ERROR; } } @@ -1288,6 +1290,12 @@ rt_err_t Handle_Valve_Replace(struct Ml307_Ops *ops) data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8], data[9], data[10], data[11], data[12]); if (i == FLASH_VALVE_MAC_ADDR_LEN) { + if (Bt_Valve_Handler(kValveCmdRep, data[0] - 1, &data[2]) != RT_EOK) + { + LOG_E("更换阀门设备失败\n"); + ops->Resp(ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_ML307, INSTRUCTION_DOWN_VALVE_REPLACE, temp, RESPONSE_CODE_ACTION_FAILURE); + return RT_ERROR; + } if (Flash_Set_Mac_Addr(&data[2], data[0]) == RESET) { LOG_E("更换阀门设备失败\n"); @@ -1326,17 +1334,24 @@ rt_err_t Handle_Remove_Valve(struct Ml307_Ops *ops) { LOG_E("阀门设备数量为0, 无法移除\n"); ops->Resp(ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_ML307, INSTRUCTION_DOWN_VALVE_REMOVE, temp, RESPONSE_CODE_ACTION_FAILURE); - + return RT_ERROR; } rt_memcpy(data, (ops->recv->recv_data.res_data + 8), FLASH_VALVE_MAC_ADDR_LEN + 1); LOG_D("data[0] = %x data[1] = %x data[2] = %x data[3] = %x data[4] = %x, data[5] = %x", data[0], data[1], data[2], data[3], data[4], data[5], data[6]); rt_memset(&data[1], 0, sizeof(data) - 1); + if (Bt_Valve_Handler(kValveCmdRem, data[0] - 1, RT_NULL) != RT_EOK) + { + LOG_E("移除阀门设备失败\n"); + ops->Resp(ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_ML307, INSTRUCTION_DOWN_VALVE_REMOVE, temp, RESPONSE_CODE_ACTION_FAILURE); + + return RT_ERROR; + } if (Flash_Set_Mac_Addr(&data[1], data[0] - 1) == RESET) { LOG_E("移除阀门设备失败\n"); ops->Resp(ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_ML307, INSTRUCTION_DOWN_VALVE_REMOVE, temp, RESPONSE_CODE_ACTION_FAILURE); - + return RT_ERROR; } else @@ -1344,7 +1359,7 @@ rt_err_t Handle_Remove_Valve(struct Ml307_Ops *ops) LOG_D("移除阀门设备成功\n"); Flash_Set_Valve_Num(cnt - 1); ops->Resp(ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_ML307, INSTRUCTION_DOWN_VALVE_REMOVE, temp, RESPONSE_CODE_SUCCESS); - + return RT_EOK; } } @@ -1518,7 +1533,6 @@ static void Ml307_Send_Thread_Entry(void *param) if (device->class->device_ops->control(device, AT_DEVICE_CTRL_NET_CONN, RT_NULL) == RT_EOK) // 打开连接 { LOG_I("ml307 connect tcp success\n"); - // rt_timer_start(ml307_life_timer); } else { @@ -1755,16 +1769,6 @@ int BSP_Ml307_Thread_Init(void) rt_kprintf("创建定时器失败\n"); return -1; } - // ml307_life_timer = rt_timer_create("ml307_life", - // Ml307_Life_Timer_Cb, - // RT_NULL, - // 30 * RT_TICK_PER_SECOND, - // RT_TIMER_FLAG_ONE_SHOT); - // if (ml307_life_timer == RT_NULL) - // { - // rt_kprintf("创建定时器失败\n"); - // return -1; - // } ml307_power_error_timer = rt_timer_create("ml307_error_timer", Ml307_Error_Timer_Cb, RT_NULL, @@ -1814,7 +1818,7 @@ int BSP_Ml307_Thread_Init(void) sizeof(ml307_life_thread_stack), ML307_LIFE_THREAD_PRIORITY, ML307_LIFE_THREAD_TICKS); - // rt_thread_startup(&ml307_life_thread); + rt_thread_startup(&ml307_life_thread); return ret; } diff --git a/bsp/src/bsp_mq.c b/bsp/src/bsp_mq.c index 97c9a6d..1d53bdd 100644 --- a/bsp/src/bsp_mq.c +++ b/bsp/src/bsp_mq.c @@ -2,7 +2,7 @@ * @Author : stark1898y 1658608470@qq.com * @Date : 2024-06-18 15:48:01 * @LastEditors: mbw && 1600520629@qq.com - * @LastEditTime: 2024-12-06 16:09:12 + * @LastEditTime: 2024-12-11 09:00:40 * @FilePath: \ble_bjq_ch303rct6_ml307\bsp\src\bsp_mq.c * @Description : * @@ -23,6 +23,8 @@ #include "bsp_flash.h" #include "bsp_rtc.h" #include "user_sys.h" +#include "finsh.h" + #define LOG_TAG "bsp_mq" // 该模块对应的标签。不定义时,默认:NO_TAG @@ -39,7 +41,7 @@ TsSensor_t Sensor_device; uint16_t Get_Gas_VoltageInt1000x(void) { uint16_t voltage = (Get_ADC_Average(kGasAdc) * 3.3 / 4096) * MQ_VOLTAGE_RATIO * 1000; - // LOG_D("Get_Gas_VoltageInt1000x = %04d", voltage); +// LOG_D("Get_Gas_VoltageInt1000x = %04d", voltage); return voltage; } diff --git a/rt-thread/rtconfig.h b/rt-thread/rtconfig.h index 4ec2e0f..a234189 100644 --- a/rt-thread/rtconfig.h +++ b/rt-thread/rtconfig.h @@ -149,7 +149,7 @@ #define AT_SW_VERSION_NUM 0x10301 /* end of Network */ -#define IOT_MODULE_SWITCH 1 // 开启NB物联网功能 +#define IOT_MODULE_SWITCH 0 // 开启NB物联网功能 /* Utilities */ #define TEST_ENABLE //打开所有的终端测试程序