BLE_TYQ_BJQ_CH584M/bsp/src/bsp_valve.c

382 lines
11 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* @Author: mbw
* @Date: 2024-12-09 11:40:10
* @LastEditors: mbw && 1600520629@qq.com
* @LastEditTime: 2025-05-23 11:08:46
* @FilePath: \zbf_master_ch584m\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_Ctr(uint8_t valve_id, const uint8_t cmd)
{
uint8_t num = Flash_Get_Valve_Num();
uint8_t valve_ctr_valve = cmd;
if ((valve_id > 8) && (num == 0))
{
logError("BSP_Valve_Close: valve id error");
return -1;
}
logDebug("BSP_Valve_Close: valve id: %d", valve_id);
if (cmd == kCmdCloseVavle)
{
Valve_GenerateRawFrame(&valve_frame_data, kCmdCloseVavle, &valve_ctr_valve, 1);
}
else
{
Valve_GenerateRawFrame(&valve_frame_data, kCmdOpenVavle, &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_Ctr, BSP_Valve_Ctr, "valve_id: 0, close: 0x01, open :0x02");
/*用于控制阀门的状态
* 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地址对应没问题则控制对应阀门*/
if (data[7] == WirelessValveClose)
{
logDebug("recv cmd: 0x01, 执行的动作是关闭阀门");
return BSP_Valve_Ctr(data[0], kCmdCloseVavle);
}
else if (data[7] == WirelessValveOpen)
{
logDebug("recv cmd: 0x02, 执行的动作是打开阀门");
return BSP_Valve_Ctr(data[0], kCmdOpenVavle);
}
logDebug("data[7] = %#x", data[7]);
return -1;
}
/*注册阀门信息*/
int BSP_Bt_Register_Valve(uint8_t *data, uint8_t len)
{
logDebug("recv cmd: 0x02, 执行的动作是注册阀门");
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;
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);
}
// 蓝牙主机对报警器的响应函数。 state表示此对应的项目可能是执行成功与否可能是蓝牙连接状态码具体参考对应的case
int BSP_Bt_Valve_Resp(ValveCmdType cmd, uint8_t id, uint8_t *mac_addr, uint8_t state)
{
uint8_t ret = 0;
BtData_t *ptr = (BtData_t *)tmos_msg_allocate(sizeof(valve_data));
ptr->cmd = cmd;
switch (cmd)
{
case kValveCmdCtr:
case kValveCmdReg:
case kValveCmdRem:
case kValveCmdRep:
// TODO:待完成从机的一些主动上报信息解析
case kValveCmdOverPressure:
case kValveCmdUnderPressure:
case kValveCmdOverCurrent:
case kValveCmdMicroLeak:
case kValveCmdTimer:
case kValveCmdOpenWithStove:
case kValveCmdCloseWithStove:
case kValveCmdOverTemperature:
case kValveCmdDelayClose:
ptr->buf[0] = id;
tmos_memcpy(&ptr->buf[1], mac_addr, 6);
ptr->buf[26] = state;
BT_GenerateRawFrame(&valve_frame_data, (uint8_t *)ptr, 28);
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(valve_data));
BT_GenerateRawFrame(&valve_frame_data, (uint8_t *)ptr, sizeof(valve_data));
break;
case kValveConncetStatus:
ptr->buf[0] = id;
tmos_memcpy(&ptr->buf[1], mac_addr, 6);
ptr->buf[7] = state; // 0表示断开1表示连接
logDebug("连接状态:%d", ptr->buf[7]);
BT_GenerateRawFrame(&valve_frame_data, (uint8_t *)ptr, 9);
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();
}