/* * @Author: mbw * @Date: 2024-12-09 11:40:10 * @LastEditors: mbw && 1600520629@qq.com * @LastEditTime: 2025-01-04 13:02:54 * @FilePath: \ble_-tyq_-bjq_-ch584-m\bsp\src\bsp_valve.c * @Description: * * Copyright (c) 2024 by ${git_name_email}, All Rights Reserved. */ #include "bsp_valve.h" #include "bsp_flash.h" #include "CH58xBLE_LIB.h" #include "bsp_uart.h" #include "multiCentral.h" /* 接收的蓝牙从机info: 接收数据帧格式: 帧头 + 命令 + 数据长度 + 心跳数据包 + 校验码 + 帧尾 发送数据帧格式: 帧头 + 命令 + 数据长度 + 控制数据 + 校验码 + 帧尾 */ #undef LOG_ENABLE #define LOG_ENABLE 1 #include "log.h" valve_data_list_t valve_list = {0}; BTFrameData valve_frame_data = {0}; uint8_t Valve_GenerateRawFrame(BTFrameData *pRawData, const uint8_t cmd, const uint8_t *p_src, uint8_t src_len) { pRawData->len = src_len + 5; tmos_memset(pRawData->buf, 0, sizeof(pRawData->buf)); pRawData->buf[0] = 0XAA; pRawData->buf[1] = cmd; pRawData->buf[2] = src_len; if (src_len > 0) { tmos_memcpy(&pRawData->buf[3], p_src, src_len); } pRawData->buf[pRawData->len - 2] = _CheckSum(&pRawData->buf[0], pRawData->len - 2); pRawData->buf[pRawData->len - 1] = 0X55; logInfo("向从机发送的数据:"); logHexDumpAll(pRawData->buf, pRawData->len); return 0; } int BSP_Valve_Close(uint8_t valve_id) { uint8_t num = Flash_Get_Valve_Num(); uint8_t valve_ctr_valve = WirelessValveClose; if ((valve_id > 8) && (num == 0)) { logError("BSP_Valve_Close: valve id error"); return -1; } logDebug("BSP_Valve_Close: valve id: %d", valve_id); // TODO:检查是否连接, 如果连接,则发送数据,将关闭阀门指令发送过去,然后等待数据接收响应,如果接收到响应是关闭状态0x01,则返回成功,否则失败 Valve_GenerateRawFrame(&valve_frame_data, kCmdCloseVavle, &valve_ctr_valve, 1); return BSP_Master_Send(centralConnList, CONNECT0_ITEM, &valve_frame_data.buf[0], valve_frame_data.len); } SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC), BSP_Valve_Close, BSP_Valve_Close, "valve_id:CONNECT0_ITEM = 0"); /*用于控制阀门的状态 * id: 1-8 * mac_addr: 6字节 * status: 0-关闭 1-打开 */ int BSP_Bt_Valve_Ctr(uint8_t *data, uint8_t len) { uint8_t mac_addr[FLASH_MAC_INFO_LEN] = {0}; if ((data[0] >= 1) && (data[0] <= 8)) { Flash_Get_Mac_Addr(mac_addr, data[0]); } else { logError("BSP_Bt_Valve_Ctr: id error"); return -1; } if (tmos_memcmp(&data[1], mac_addr, FLASH_MAC_INFO_LEN) != TRUE) { logError("mac addr error read mac addr : %02X %02X %02X %02X %02X %02X != bt_rx mac addr: %02X %02X %02X %02X %02X %02X", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5], data[1], data[2], data[3], data[4], data[5], data[6]); return -2; } /*如果到这里了,说明ID和MAC地址对应没问题,则关闭对应阀门*/ return BSP_Valve_Close(data[0]); } /*注册阀门信息*/ int BSP_Bt_Register_Valve(uint8_t *data, uint8_t len) { uint8_t mac_addr[FLASH_MAC_INFO_LEN] = {0}; if ((data[0] >= 1) && (data[0] <= 8)) { Flash_Get_Mac_Addr(mac_addr, data[0]); } else { logError("valve id error"); return 1; } if (tmos_isbufset(&data[1], 0, FLASH_MAC_INFO_LEN) == TRUE) { logError("阀门写值错误为0"); return 1; } logDebug("注册阀门信息:"); if (tmos_memcmp(&data[1], mac_addr, FLASH_MAC_INFO_LEN) == TRUE) { logError("已经注册过了"); return 0; // 说明已经注册过了 } else { if (tmos_isbufset(&mac_addr[0], 0xFF, 6) == TRUE) // 说明没有数据,那就全部写入 { logDebug("没有数据,全部写入:"); logDebug("写入MAC 地址: %02X %02X %02X %02X %02X %02X", data[1], data[2], data[3], data[4], data[5], data[6]); if (Flash_Set_Mac_Addr(&data[1], data[0]) != 0) { logError("阀门注册写入flash 错误"); return 3; } else { uint8_t num = Flash_Get_Valve_Num(); Flash_Set_Valve_Num(num + 1); BSP_Bt_Valve_Updata(); // 更新阀门信息 } } else { logDebug("有数据 请检查"); } } return 0; } /*移除阀门信息*/ int BSP_Bt_Remove_Valve(uint8_t *data, uint8_t len) { size_t i = 0; uint8_t mac_addr[FLASH_MAC_INFO_LEN + 2] = {0}; if ((data[0] >= 1) && (data[0] <= 8))// 判断是否是正确的ID { Flash_Get_Mac_Addr(mac_addr, data[0]); } else { logError("valve id error:"); logHexDumpAll(data, len); return -1; } if (tmos_memcmp(&data[1], mac_addr, FLASH_MAC_INFO_LEN) != TRUE)// 判断是否是相同的MAC地址 { logError("mac addr error"); logHexDumpAll(data, len); return -2; } else { tmos_memset(mac_addr, 0xFF, FLASH_MAC_INFO_LEN); if (Flash_Set_Mac_Addr(mac_addr, data[0]) != 0) // 清空掉对应位置MAC数据 { logError("移除阀门信息失败"); logHexDumpAll(data, len); return -2; } uint8_t num = Flash_Get_Valve_Num(); if (Flash_Set_Valve_Num(num - 1) != 0) // 移除一个阀门 { logError("移除阀门信息失败"); logHexDumpAll(data, len); return -2; } BSP_Bt_Valve_Updata(); Master_DisConnect(); } return 0; } /*移除所有阀门信息*/ int BSP_Bt_Remove_All_Valve(void) { uint8_t mac_addr[FLASH_MAC_INFO_LEN + 2] = {0}; uint8_t num = Flash_Get_Valve_Num(); if(num == 0) { logError("没有找到任何阀门信息"); return 0; } tmos_memset(mac_addr, 0xFF, FLASH_MAC_INFO_LEN); if (Flash_Set_Mac_Addr(mac_addr, 1) != 0) { logError("移除阀门信息失败[-2]"); return -2; } if (Flash_Set_Valve_Num(0) != 0) // 移除一个阀门 { logError("移除阀门信息失败[-3]"); return -3; } BSP_Bt_Valve_Updata(); Master_DisConnect(); return 0; } /*更换阀门信息*/ int BSP_Bt_Replace_Valve(uint8_t *data, uint8_t len) { size_t i = 0; uint8_t mac_addr[FLASH_MAC_INFO_LEN] = {0}; logDebug("更换阀门信息:"); logHexDumpAll(data, len); if ((len == 0) || (len < 13))//新旧MAC地址长度加id 6 + 6 + 1 = 13至少要大于12 { logError("data len error"); return -1; } if ((data[0] >= 1) && (data[0] <= 8)) { Flash_Get_Mac_Addr(mac_addr, data[0]); } else { logError("valve id error"); return -2; } if (tmos_memcmp(&data[1], mac_addr, FLASH_MAC_INFO_LEN) == TRUE) { logError("已经注册过了"); // 不需要重复写入 return 0; // 说明已经注册过了 } else { //新阀门数据在前 if (Flash_Set_Mac_Addr(&data[1], data[0]) != 0) { logError("阀门注册写入flash 错误"); return 3; } BSP_Bt_Valve_Updata(); // 更新阀门信息 Master_DisConnect();//更新后先断联接 } return 0; } /*更新阀门信息*/ void BSP_Bt_Valve_Updata(void) { uint8_t cnt = 0; __attribute__((aligned(4))) uint8_t mac[6] = {0}; uint8_t num = Flash_Get_Valve_Num(); logInfo("BSP_Bt_Valve_Updata num: %d ", num); if (num == 0) { return; } tmos_memset(&valve_list, 0, sizeof(valve_data_list_t)); for (int i = 1; i < MAX_VALVE_NUM; i++) // 这个循环是为了将数据拷贝到valve_list中, 并且保证id号和flash对应起来 { if (Flash_Get_Mac_Addr(valve_list.valve_data[cnt].valve_mac, i) == 0) // 说明有MAC数据 { valve_list.valve_data[cnt].valve_id = i; logDebug("updata valve_id: %d, valve_mac: %02X %02X %02X %02X %02X %02X", valve_list.valve_data[cnt].valve_id, valve_list.valve_data[cnt].valve_mac[0], valve_list.valve_data[cnt].valve_mac[1], valve_list.valve_data[cnt].valve_mac[2], valve_list.valve_data[cnt].valve_mac[3], valve_list.valve_data[cnt].valve_mac[4], valve_list.valve_data[cnt].valve_mac[5]); cnt++; valve_list.valve_num = cnt; break; } else { logError("BSP_Bt_Valve_Updata: flash read error"); break; } } Flash_Set_Valve_Num(valve_list.valve_num); } int BSP_Bt_Valve_Resp(uint8_t cmd, uint8_t id, uint8_t *mac_addr, uint8_t state) { uint8_t ret = 0; BtData_t *ptr = (BtData_t *)tmos_msg_allocate(sizeof(struct valve_data)); ptr->cmd = cmd; switch (cmd) { case kValveCmdCtr: case kValveCmdReg: case kValveCmdRem: case kValveCmdRep: ptr->buf[0] = id; tmos_memcpy(&ptr->buf[1], mac_addr, 6); ptr->buf[7] = state; BT_GenerateRawFrame(&valve_frame_data, (uint8_t *)ptr, 9); break; case kValveCmdRemAll: ptr->buf[0] = state; BT_GenerateRawFrame(&valve_frame_data, (uint8_t *)ptr, 2); break; case kValveEventStatus: tmos_memcpy(&ptr->buf[0], &valve_list.valve_data[id - 1], sizeof(struct valve_data)); BT_GenerateRawFrame(&valve_frame_data, (uint8_t *)ptr, sizeof(struct valve_data)); break; default: break; } tmos_msg_deallocate((uint8_t *)ptr); ret = BSP_Uart1_Send_Data((uint8_t *)&valve_frame_data.buf[0], valve_frame_data.len); tmos_start_task(BtRxTaskId, BT_SEND_EVT, 50); if (ret == valve_frame_data.len) { return 0; } return -1; } void BSP_Valve_Init(void) { logDebug("BSP_Valve_Init"); BSP_Bt_Valve_Updata(); }