2024-12-04 10:31:57 +08:00
|
|
|
|
#include "bsp_bt.h"
|
2024-12-04 18:55:59 +08:00
|
|
|
|
#include "bsp_ml307.h"
|
|
|
|
|
#include "bsp_flash.h"
|
|
|
|
|
#include "rtdef.h"
|
2024-12-07 17:09:57 +08:00
|
|
|
|
#include "lwrb.h"
|
|
|
|
|
|
|
|
|
|
#include "user_sys.h"
|
2024-12-04 10:31:57 +08:00
|
|
|
|
|
|
|
|
|
|
2024-12-06 16:16:12 +08:00
|
|
|
|
#define LOG_TAG "bsp_bt"
|
|
|
|
|
#define LOG_LVL LOG_LVL_DBG
|
|
|
|
|
#include <ulog.h>
|
|
|
|
|
|
|
|
|
|
#define BT_UART "uart5"
|
|
|
|
|
|
|
|
|
|
rt_timer_t bt_timer;
|
|
|
|
|
struct rt_semaphore bt_rx_sem;
|
|
|
|
|
static rt_device_t rt_bt_device;
|
|
|
|
|
|
|
|
|
|
#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};
|
|
|
|
|
|
2024-12-07 17:09:57 +08:00
|
|
|
|
lwrb_t bt_lwrb_rx;
|
|
|
|
|
static char bt_rx_buffer[256] = {0};
|
|
|
|
|
BTFrameData bt_frame = {0};
|
2024-12-06 16:16:12 +08:00
|
|
|
|
|
2024-12-07 17:09:57 +08:00
|
|
|
|
valve_data_t valve_t[MAX_VALVE_NUM];
|
2024-12-06 16:16:12 +08:00
|
|
|
|
|
|
|
|
|
|
2024-12-07 17:09:57 +08:00
|
|
|
|
rt_size_t BSP_Bt_Send_Data(uint8_t *data, size_t size)
|
|
|
|
|
{
|
|
|
|
|
return rt_device_write(rt_bt_device, 0, data, size);;
|
|
|
|
|
}
|
2024-12-04 10:31:57 +08:00
|
|
|
|
|
2024-12-07 17:09:57 +08:00
|
|
|
|
rt_size_t BSP_Bt_Recv_Data(uint8_t *data, size_t size)
|
|
|
|
|
{
|
|
|
|
|
return lwrb_read(&bt_lwrb_rx, data, size);
|
|
|
|
|
}
|
2024-12-04 18:55:59 +08:00
|
|
|
|
int BSP_BT_Init(void)
|
|
|
|
|
{
|
|
|
|
|
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++)
|
|
|
|
|
{
|
2024-12-05 16:57:19 +08:00
|
|
|
|
valve_t[i].valve_id = (i + 1);//1-8
|
2024-12-04 18:55:59 +08:00
|
|
|
|
if (Flash_Get_Mac_Addr(valve_t[i].valve_mac, i) == RT_EOK)
|
|
|
|
|
{
|
|
|
|
|
rt_memcpy(valve_t[i].valve_mac, mac_buf, 6);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
for (size_t i = 0; i < MAX_VALVE_NUM; i++)
|
|
|
|
|
{
|
|
|
|
|
rt_memset(&valve_t[i], 0, sizeof(valve_data_t));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return RT_EOK;
|
|
|
|
|
}
|
|
|
|
|
INIT_PREV_EXPORT(BSP_BT_Init);
|
2024-12-06 16:16:12 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static rt_err_t bt_getchar(char *ch, rt_int32_t timeout)
|
|
|
|
|
{
|
|
|
|
|
rt_err_t result = RT_EOK;
|
|
|
|
|
|
|
|
|
|
while (rt_device_read(rt_bt_device, 0, ch, 1) == 0)
|
|
|
|
|
{
|
|
|
|
|
result = rt_sem_take(&bt_rx_sem, rt_tick_from_millisecond(timeout));
|
|
|
|
|
if (result != RT_EOK)
|
|
|
|
|
{
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return RT_EOK;
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-07 17:09:57 +08:00
|
|
|
|
static int bt_recv_readline(void)
|
2024-12-06 16:16:12 +08:00
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
while (1)
|
|
|
|
|
{
|
|
|
|
|
result = bt_getchar(&ch, RT_WAITING_FOREVER);
|
|
|
|
|
if (result != RT_EOK)
|
|
|
|
|
{
|
|
|
|
|
LOG_D("get sem bt_rx_sem error");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2024-12-07 17:09:57 +08:00
|
|
|
|
if (read_len < lwrb_get_free(&bt_lwrb_rx))
|
2024-12-06 16:16:12 +08:00
|
|
|
|
{
|
2024-12-07 17:09:57 +08:00
|
|
|
|
lwrb_write(&bt_lwrb_rx, &ch, 1);
|
2024-12-06 16:16:12 +08:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
is_full = RT_TRUE;
|
|
|
|
|
}
|
|
|
|
|
if (ch == '\n' && last_ch == '\r')
|
|
|
|
|
{
|
|
|
|
|
if (is_full)
|
|
|
|
|
{
|
2024-12-07 17:09:57 +08:00
|
|
|
|
LOG_E("read line failed. The line data length is out of buffer size(%d)!", lwrb_get_free(&bt_lwrb_rx));
|
2024-12-06 16:16:12 +08:00
|
|
|
|
return -RT_EFULL;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
last_ch = ch;
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-12-07 17:09:57 +08:00
|
|
|
|
return lwrb_get_full(&bt_lwrb_rx);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*发送数据帧处理*/
|
|
|
|
|
rt_uint8_t BT_GenerateRawFrame(BTFrameData *pRawData, const rt_uint8_t *p_src, rt_uint8_t src_len)
|
|
|
|
|
{
|
|
|
|
|
pRawData->len = src_len + 4;
|
|
|
|
|
|
|
|
|
|
rt_memset(pRawData->buf, 0, sizeof(pRawData->buf));
|
|
|
|
|
|
|
|
|
|
pRawData->buf[0] = BT_FRAME_HEAD_DATA;
|
|
|
|
|
pRawData->buf[1] = src_len;
|
|
|
|
|
|
|
|
|
|
rt_memmove(&pRawData->buf[2], p_src, src_len);
|
|
|
|
|
|
|
|
|
|
// 从帧起始符开始到校验码之前所有字节的和的模256
|
|
|
|
|
// ,即各字节不计超过255的溢出值的二进制算术和。
|
|
|
|
|
pRawData->buf[pRawData->len - 2] = XOR_CheckSum(&pRawData->buf[0], pRawData->len - 2);
|
|
|
|
|
pRawData->buf[pRawData->len - 1] = BT_FRAME_TAIL_DATA;
|
2024-12-06 16:16:12 +08:00
|
|
|
|
|
2024-12-07 17:09:57 +08:00
|
|
|
|
LOG_HEX("BTFrameData", 16, &pRawData->buf[0], pRawData->len);
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
{
|
|
|
|
|
BtData_t *ptr = (BtData_t *)rt_malloc(sizeof(BtData_t) + 8);
|
|
|
|
|
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);
|
|
|
|
|
|
2024-12-07 17:31:21 +08:00
|
|
|
|
return BSP_Bt_Send_Data((rt_uint8_t *)&bt_frame.buf[0], bt_frame.len);
|
2024-12-07 17:09:57 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*注册阀门信息*/
|
|
|
|
|
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_memcpy(&ptr->buf[1], mac_addr, 6);
|
|
|
|
|
BT_GenerateRawFrame(&bt_frame, (rt_uint8_t *)ptr, 8);
|
|
|
|
|
rt_free(ptr);
|
|
|
|
|
|
2024-12-07 17:31:21 +08:00
|
|
|
|
return BSP_Bt_Send_Data((rt_uint8_t *)&bt_frame.buf[0], bt_frame.len);
|
2024-12-07 17:09:57 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*移除阀门信息*/
|
|
|
|
|
int BSP_Bt_Remove_Valve(rt_uint8_t id, rt_uint8_t *mac_addr)
|
|
|
|
|
{
|
|
|
|
|
BtData_t *ptr = (BtData_t *)rt_malloc(sizeof(BtData_t) + 7);
|
|
|
|
|
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);
|
|
|
|
|
|
2024-12-07 17:31:21 +08:00
|
|
|
|
return BSP_Bt_Send_Data((rt_uint8_t *)&bt_frame.buf[0], bt_frame.len);
|
2024-12-07 17:09:57 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*更换阀门信息*/
|
|
|
|
|
int BSP_Bt_Replace_Valve(rt_uint8_t id, rt_uint8_t *mac_addr, rt_uint8_t *new_mac_addr)
|
|
|
|
|
{
|
|
|
|
|
BtData_t *ptr = (BtData_t *)rt_malloc(sizeof(BtData_t) + 14);
|
|
|
|
|
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);
|
|
|
|
|
|
2024-12-07 17:31:21 +08:00
|
|
|
|
return BSP_Bt_Send_Data((rt_uint8_t *)&bt_frame.buf[0], bt_frame.len);
|
2024-12-07 17:09:57 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int Bt_Valve_Handler(ValveCmdType type)
|
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
return RT_EOK;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
rt_free(rx_ptr);
|
2024-12-06 16:16:12 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void Bt_Thread_Entry(void *parameter)
|
|
|
|
|
{
|
|
|
|
|
while (1)
|
|
|
|
|
{
|
2024-12-07 17:09:57 +08:00
|
|
|
|
if (bt_recv_readline() > 0)
|
2024-12-06 16:16:12 +08:00
|
|
|
|
{
|
2024-12-07 17:09:57 +08:00
|
|
|
|
BSP_Bt_Parse_Data();
|
2024-12-06 16:16:12 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 接收数据回调函数 */
|
|
|
|
|
static rt_err_t Bt_Rcv_Cb(rt_device_t dev, rt_size_t size)
|
|
|
|
|
{
|
|
|
|
|
rt_sem_release(&bt_rx_sem);
|
|
|
|
|
|
|
|
|
|
return RT_EOK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int BSP_Bt_Init(void)
|
|
|
|
|
{
|
|
|
|
|
rt_err_t ret = RT_EOK;
|
|
|
|
|
|
2024-12-07 17:09:57 +08:00
|
|
|
|
lwrb_init(&bt_lwrb_rx, bt_rx_buffer, sizeof(bt_rx_buffer));
|
|
|
|
|
lwrb_reset(&bt_lwrb_rx);
|
|
|
|
|
|
2024-12-06 16:16:12 +08:00
|
|
|
|
/* 查找系统中的串口设备 */
|
|
|
|
|
rt_bt_device = rt_device_find(BT_UART);
|
|
|
|
|
if (!rt_bt_device)
|
|
|
|
|
{
|
|
|
|
|
LOG_E("find %s failed!\n", BT_UART);
|
|
|
|
|
return RT_ERROR;
|
|
|
|
|
}
|
|
|
|
|
/* 以中断接收模式打开串口设备 */
|
|
|
|
|
if (rt_device_open(rt_bt_device, RT_DEVICE_FLAG_INT_RX) != RT_EOK)
|
|
|
|
|
{
|
|
|
|
|
LOG_E("rt_device_open failed!\n");
|
|
|
|
|
return RT_ERROR;
|
|
|
|
|
}
|
|
|
|
|
rt_sem_init(&bt_rx_sem, "bt_rx_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;
|
|
|
|
|
}
|
2024-12-07 17:09:57 +08:00
|
|
|
|
rt_device_write(rt_bt_device, 0, "test bt_uart send\r\n", strlen("test bt_uart send\r\n"));
|
2024-12-07 17:31:21 +08:00
|
|
|
|
rt_uint8_t buf_test[3] = {0x01, 0x02, 0x03};
|
|
|
|
|
BSP_Bt_Send_Data(buf_test, 3);
|
2024-12-06 16:16:12 +08:00
|
|
|
|
/* 静态初始化线程 1*/
|
|
|
|
|
ret = rt_thread_init(&bt_thread, // 该线程用于数据解析
|
|
|
|
|
"bt_thread",
|
|
|
|
|
Bt_Thread_Entry,
|
|
|
|
|
RT_NULL,
|
|
|
|
|
&bt_thread_stack[0],
|
|
|
|
|
sizeof(bt_thread_stack),
|
|
|
|
|
BT_THREAD_PRIORITY,
|
|
|
|
|
BT_THREAD_TIMESLICE);
|
|
|
|
|
/* 创建成功则启动线程 */
|
|
|
|
|
rt_thread_startup(&bt_thread);
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
INIT_DEVICE_EXPORT(BSP_Bt_Init);
|
2024-12-07 17:09:57 +08:00
|
|
|
|
|
|
|
|
|
#ifdef TEST_ENABLE
|
|
|
|
|
|
|
|
|
|
static void TEST_BT_Send_Data(int argc, char **argv)
|
|
|
|
|
{
|
|
|
|
|
if (argc == 2)
|
|
|
|
|
{
|
|
|
|
|
int mode = atoi(argv[1]);
|
|
|
|
|
switch (mode)
|
|
|
|
|
{
|
|
|
|
|
case 1:
|
|
|
|
|
Bt_Valve_Handler(kValveCmdCtr);
|
|
|
|
|
break;
|
|
|
|
|
case 2:
|
|
|
|
|
Bt_Valve_Handler(kValveCmdReg);
|
|
|
|
|
break;
|
|
|
|
|
case 3:
|
|
|
|
|
Bt_Valve_Handler(kValveCmdRem);
|
|
|
|
|
break;
|
|
|
|
|
case 4:
|
|
|
|
|
Bt_Valve_Handler(kValveCmdRep);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
MSH_CMD_EXPORT(TEST_BT_Send_Data, "TEST_BT_Send_Data");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#endif
|