first submission
This commit is contained in:
@@ -0,0 +1,528 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : lwns_adapter_blemesh_mac.c
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2021/06/20
|
||||
* Description : lwns适配器,模拟ble sig mesh的mac协议
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#include "lwns_adapter_blemesh_mac.h"
|
||||
#include "lwns_sec.h"
|
||||
|
||||
//每个文件单独debug打印的开关,置0可以禁止本文件内部打印
|
||||
#define DEBUG_PRINT_IN_THIS_FILE 1
|
||||
#if DEBUG_PRINT_IN_THIS_FILE
|
||||
#define PRINTF(...) PRINT(__VA_ARGS__)
|
||||
#else
|
||||
#define PRINTF(...) \
|
||||
do \
|
||||
{ \
|
||||
} while(0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 本文件中ble_phy_channelmap为需要发送和接收的通道列表,用户根据自己需求修改为蓝牙通道中的任意三个通道。
|
||||
* 蓝牙mesh是在37、38、39三个广播通道的广播accessaddress:0x8E89BED6进行周期性发送。正确符合相应规则的accessaddress接入地址约有23亿个
|
||||
* 本文件采用的发送通道数量和通道号还有accessaddress可以自定,accessaddress切换通道时不变,通道建议3个,不要太多。
|
||||
*/
|
||||
|
||||
#if LWNS_USE_BLEMESH_MAC //是否使能模仿blemesh的mac协议,注意只能使能一个mac层协议。
|
||||
|
||||
//for lwns_packet_buffer save
|
||||
__attribute__((aligned(4))) static lwns_qbuf_list_t qbuf_memp[QBUF_MANUAL_NUM];
|
||||
|
||||
//for lwns_route_entry manage
|
||||
#if ROUTE_ENTRY_MANUAL_NUM
|
||||
__attribute__((aligned(4))) static lwns_route_entry_data_t route_entry_memp[ROUTE_ENTRY_MANUAL_NUM];
|
||||
#endif
|
||||
|
||||
//for neighbor manage
|
||||
__attribute__((aligned(4))) static lwns_neighbor_list_t neighbor_memp[LWNS_NEIGHBOR_MAX_NUM];
|
||||
|
||||
static void ble_new_neighbor_callback(lwns_addr_t *n); //发现新邻居回调函数
|
||||
static BOOL ble_phy_output(uint8_t *dataptr, uint8_t len); //发送接口函数
|
||||
static void RF_2G4StatusCallBack(uint8_t sta, uint8_t crc, uint8_t *rxBuf);
|
||||
|
||||
static uint8_t lwns_adapter_taskid;
|
||||
static uint16_t lwns_adapter_ProcessEvent(uint8_t task_id, uint16_t events);
|
||||
static uint8_t lwns_phyoutput_taskid;
|
||||
static uint16_t lwns_phyoutput_ProcessEvent(uint8_t task_id, uint16_t events);
|
||||
|
||||
/**
|
||||
* lwns必用的函数接口,将指针传递给lwns库内部使用
|
||||
*/
|
||||
static lwns_fuc_interface_t ble_lwns_fuc_interface = {
|
||||
.lwns_phy_output = ble_phy_output,
|
||||
.lwns_rand = tmos_rand,
|
||||
.lwns_memcpy = tmos_memcpy,
|
||||
.lwns_memcmp = tmos_memcmp,
|
||||
.lwns_memset = tmos_memset,
|
||||
.new_neighbor_callback = ble_new_neighbor_callback,
|
||||
};
|
||||
|
||||
static const uint8_t ble_phy_channelmap[] = {8, 18, 28}; //所需要用到的通道集合,用户自行更换为想要发送的通道集合。
|
||||
static uint8_t ble_phy_channelmap_send_seq = 0, ble_phy_channelmap_receive_seq = 0, ble_phy_send_cnt = 0; //发送接收当前通道序号和发送次数管理
|
||||
static struct blemesh_mac_phy_manage_struct *blemesh_phy_manage_list_head = NULL; //mac管理发送LIST列表指针
|
||||
static struct blemesh_mac_phy_manage_struct blemesh_phy_manage_list[LWNS_MAC_SEND_PACKET_MAX_NUM]; //mac管理发送列表管理数组
|
||||
|
||||
/*********************************************************************
|
||||
* @fn RF_2G4StatusCallBack
|
||||
*
|
||||
* @brief RF 状态回调,注意:不可在此函数中直接调用RF接收或者发送API,需要使用事件的方式调用
|
||||
*
|
||||
* @param sta - 状态类型
|
||||
* @param crc - crc校验结果
|
||||
* @param rxBuf - 数据buf指针
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static void RF_2G4StatusCallBack(uint8_t sta, uint8_t crc, uint8_t *rxBuf)
|
||||
{ //rxBuf[0]为信号强度,rxBuf[1]为本次收到数据的长度
|
||||
switch(sta)
|
||||
{
|
||||
case RX_MODE_RX_DATA:
|
||||
{
|
||||
if(crc == 1)
|
||||
{
|
||||
PRINTF("crc error\n");
|
||||
}
|
||||
else if(crc == 2)
|
||||
{
|
||||
PRINTF("match type error\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t *pMsg;
|
||||
#if LWNS_ENCRYPT_ENABLE //是否启用消息加密
|
||||
if(((rxBuf[1] % 16) == 1) && (rxBuf[1] >= 17) && (rxBuf[1] > rxBuf[2]))
|
||||
{ //对齐后数据区最少16个字节,加上真实数据长度一字节
|
||||
//长度校验通过,所以rxBuf[1] - 1必为16的倍数
|
||||
pMsg = tmos_msg_allocate(rxBuf[1]); //申请内存空间,真实数据长度不需要解密
|
||||
if(pMsg != NULL)
|
||||
{
|
||||
lwns_msg_decrypt(rxBuf + 3, pMsg + 1, rxBuf[1] - 1); //解密数据
|
||||
if((rxBuf[2] ^ pMsg[rxBuf[2]]) == pMsg[rxBuf[2] + 1])
|
||||
{
|
||||
pMsg[0] = rxBuf[2]; //校验通过,存储真实数据长度
|
||||
PRINTF("send rx msg\n"); //发送接收到的数据到接收进程中
|
||||
tmos_msg_send(lwns_adapter_taskid, pMsg);
|
||||
}
|
||||
else
|
||||
{
|
||||
PRINTF("verify rx msg err\n"); //校验失败
|
||||
tmos_msg_deallocate(pMsg);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PRINTF("send rx msg failed\n"); //申请内存失败,无法发送接收到的数据
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PRINTF("bad len\n"); //包长度不对
|
||||
}
|
||||
#else
|
||||
if(rxBuf[1] >= LWNS_PHY_OUTPUT_MIN_SIZE)
|
||||
{ //数据长度符合,才会发送至协议栈内部处理
|
||||
pMsg = tmos_msg_allocate(rxBuf[1] + 1);
|
||||
if(pMsg != NULL)
|
||||
{
|
||||
PRINTF("send rx msg\n"); //发送接收到的数据到接收进程中
|
||||
tmos_memcpy(pMsg, rxBuf + 1, rxBuf[1] + 1);
|
||||
tmos_msg_send(lwns_adapter_taskid, pMsg);
|
||||
}
|
||||
else
|
||||
{
|
||||
PRINTF("send rx msg failed\n"); //申请内存失败,无法发送接收到的数据
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PRINTF("bad len\n"); //包长度不对
|
||||
}
|
||||
#endif
|
||||
}
|
||||
tmos_set_event(lwns_adapter_taskid, LWNS_PHY_RX_OPEN_EVT); //重新打开接收
|
||||
break;
|
||||
}
|
||||
case TX_MODE_TX_FINISH:
|
||||
case TX_MODE_TX_FAIL:
|
||||
tmos_stop_task(lwns_phyoutput_taskid, LWNS_PHY_OUTPUT_FINISH_EVT); //停止超时计数
|
||||
tmos_set_event(lwns_phyoutput_taskid, LWNS_PHY_OUTPUT_FINISH_EVT); //进入发送完成处理
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn RF_Init
|
||||
*
|
||||
* @brief RF 初始化.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
void RF_Init(void)
|
||||
{
|
||||
uint8_t state;
|
||||
rfConfig_t rfConfig;
|
||||
tmos_memset(&rfConfig, 0, sizeof(rfConfig_t));
|
||||
rfConfig.accessAddress = 0x17267162; // 禁止使用0x55555555以及0xAAAAAAAA ( 建议不超过24次位反转,且不超过连续的6个0或1 ),正确符合相应规则的accessaddress接入地址约有23亿个
|
||||
rfConfig.CRCInit = 0x555555;
|
||||
ble_phy_channelmap_receive_seq = 0;
|
||||
rfConfig.Channel = ble_phy_channelmap[0];
|
||||
rfConfig.LLEMode = LLE_MODE_BASIC; //|LLE_MODE_EX_CHANNEL; // 使能 LLE_MODE_EX_CHANNEL 表示 选择 rfConfig.Frequency 作为通信频点
|
||||
rfConfig.rfStatusCB = RF_2G4StatusCallBack;
|
||||
state = RF_Config(&rfConfig);
|
||||
PRINTF("rf 2.4g init: %x\n", state);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn lwns_init
|
||||
*
|
||||
* @brief lwns初始化.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
void lwns_init(void)
|
||||
{
|
||||
uint8_t s;
|
||||
lwns_config_t cfg;
|
||||
tmos_memset(&cfg, 0, sizeof(lwns_config_t));
|
||||
cfg.lwns_lib_name = (uint8_t *)VER_LWNS_FILE; //验证函数库名称,防止版本出错
|
||||
cfg.qbuf_num = QBUF_MANUAL_NUM; //必须分配,至少1个内存单位,根据你程序中使用的端口数对应模块使用的qbuf单位来定义。
|
||||
cfg.qbuf_ptr = qbuf_memp; //mesh最多使用3个qbuf单位,(uni/multi)netflood最多使用2个,其他模块都使用1个。
|
||||
cfg.routetable_num = ROUTE_ENTRY_MANUAL_NUM; //如果需要使用mesh,必须分配路由表内存空间。不然mesh初始化不会成功。
|
||||
#if ROUTE_ENTRY_MANUAL_NUM
|
||||
cfg.routetable_ptr = route_entry_memp;
|
||||
#else
|
||||
cfg.routetable_ptr = NULL;
|
||||
#endif
|
||||
cfg.neighbor_num = LWNS_NEIGHBOR_MAX_NUM; //邻居表数量,必须分配
|
||||
cfg.neighbor_list_ptr = neighbor_memp; //邻居表内存空间
|
||||
cfg.neighbor_mod = LWNS_NEIGHBOR_AUTO_ADD_STATE_RECALL_ADDALL; //邻居表初始化默认管理模式为接收所有包,添加所有邻居并且过滤重复包的模式
|
||||
#if LWNS_ADDR_USE_BLE_MAC
|
||||
FLASH_GetMACAddress(cfg.addr.v8); //蓝牙硬件的mac地址
|
||||
#else
|
||||
//自行定义的地址
|
||||
uint8_t MacAddr[6] = {0, 0, 0, 0, 0, 1};
|
||||
tmos_memcpy(cfg.addr.v8, MacAddr, LWNS_ADDR_SIZE);
|
||||
#endif
|
||||
s = lwns_lib_init(&ble_lwns_fuc_interface, &cfg); //lwns库底层初始化
|
||||
if(s)
|
||||
{
|
||||
PRINTF("%s init err:%d\n", VER_LWNS_FILE, s);
|
||||
}
|
||||
else
|
||||
{
|
||||
PRINTF("%s init ok\n", VER_LWNS_FILE);
|
||||
}
|
||||
lwns_adapter_taskid = TMOS_ProcessEventRegister(lwns_adapter_ProcessEvent);
|
||||
lwns_phyoutput_taskid = TMOS_ProcessEventRegister(lwns_phyoutput_ProcessEvent);
|
||||
tmos_start_task(lwns_phyoutput_taskid, LWNS_HTIMER_PERIOD_EVT, MS1_TO_SYSTEM_TIME(LWNS_HTIMER_PERIOD_MS));
|
||||
tmos_memset(blemesh_phy_manage_list, 0, sizeof(blemesh_phy_manage_list)); //清除发送管理结构体
|
||||
ble_phy_send_cnt = 0; //清空发送次数计数
|
||||
RF_Shut();
|
||||
RF_Rx(NULL, 0, USER_RF_RX_TX_TYPE, USER_RF_RX_TX_TYPE); //打开RF接收,如果需要低功耗管理,在其他地方打开。
|
||||
tmos_start_task(lwns_adapter_taskid, LWNS_PHY_RX_CHANGE_CHANNEL_EVT, MS1_TO_SYSTEM_TIME(LWNS_MAC_PERIOD_MS));
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn ble_new_neighbor_callback
|
||||
*
|
||||
* @brief 当发现一个新邻居时的回调函数.
|
||||
*
|
||||
* @param n - 新邻居的地址.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static void ble_new_neighbor_callback(lwns_addr_t *n)
|
||||
{
|
||||
PRINTF("new neighbor: %02x %02x %02x %02x %02x %02x\n", n->v8[0], n->v8[1],
|
||||
n->v8[2], n->v8[3], n->v8[4], n->v8[5]);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn ble_phy_output
|
||||
*
|
||||
* @brief lwns发送函数接口
|
||||
*
|
||||
* @param dataptr - 待发送的数据缓冲头指针.
|
||||
* @param len - 待发送的数据缓冲长度.
|
||||
*
|
||||
* @return TRUE if success, FLASE is failed.
|
||||
*/
|
||||
static BOOL ble_phy_output(uint8_t *dataptr, uint8_t len)
|
||||
{
|
||||
uint8_t *pMsg, i;
|
||||
struct blemesh_mac_phy_manage_struct *p;
|
||||
for(i = 0; i < LWNS_MAC_SEND_PACKET_MAX_NUM; i++)
|
||||
{
|
||||
if(blemesh_phy_manage_list[i].data == NULL)
|
||||
{
|
||||
break; //寻找到了一个空的结构体可以使用。
|
||||
}
|
||||
else
|
||||
{
|
||||
if(i == (LWNS_MAC_SEND_PACKET_MAX_NUM - 1))
|
||||
{
|
||||
PRINTF("send failed!\n"); //列表满了,发送失败,直接返回。
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
#if LWNS_ENCRYPT_ENABLE
|
||||
pMsg = tmos_msg_allocate((((len + 1 + 15) & 0xf0) + 1 + 1)); //校验位1位加上后再进行16字节对齐,存储发送长度+1,真实数据长度+1
|
||||
#else
|
||||
pMsg = tmos_msg_allocate(len + 1); //申请内存空间存储消息,存储发送长度+1
|
||||
#endif
|
||||
if(pMsg != NULL)
|
||||
{ //成功申请
|
||||
p = blemesh_phy_manage_list_head;
|
||||
if(p != NULL)
|
||||
{
|
||||
while(p->next != NULL)
|
||||
{ //寻找发送链表的终点
|
||||
p = p->next;
|
||||
}
|
||||
}
|
||||
#if LWNS_ENCRYPT_ENABLE
|
||||
//lwns buffer内部预留有两字节,用户可直接使用dataptr[len]进行赋值两字节内容
|
||||
dataptr[len] = dataptr[len - 1] ^ len; //校验字节仅取最后一个字节和长度进行异或运算,首字节相同port是一样的,可能有影响。和校验比较浪费时间,所以不采用
|
||||
pMsg[1] = len; //真实数据长度占一字节,不加密,用来接收做第一步校验
|
||||
pMsg[0] = lwns_msg_encrypt(dataptr, pMsg + 2, len + 1) + 1; //获取数据加密后的长度,也就是需要发送出去的字节数,真实数据长度不加密
|
||||
#else
|
||||
pMsg[0] = len;
|
||||
tmos_memcpy(pMsg + 1, dataptr, len);
|
||||
#endif
|
||||
if(blemesh_phy_manage_list_head != NULL)
|
||||
{
|
||||
p->next = &blemesh_phy_manage_list[i]; //链表添加尾结点
|
||||
}
|
||||
else
|
||||
{
|
||||
blemesh_phy_manage_list_head = &blemesh_phy_manage_list[i]; //链表为空,则节点作为头结点
|
||||
tmos_set_event(lwns_phyoutput_taskid, LWNS_PHY_OUTPUT_PREPARE_EVT); //启动发送,不是头结点不需要启动,因为在发送流程中。
|
||||
}
|
||||
blemesh_phy_manage_list[i].data = pMsg; //绑定消息
|
||||
blemesh_phy_manage_list[i].next = NULL;
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
PRINTF("send failed!\n"); //无法申请到内存,则无法发送
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn lwns_adapter_ProcessEvent
|
||||
*
|
||||
* @brief lwns adapter Task event processor. This function
|
||||
* is called to process all events for the task. Events
|
||||
* include timers, messages and any other user defined events.
|
||||
*
|
||||
* @param task_id - The TMOS assigned task ID.
|
||||
* @param events - events to process. This is a bit map and can
|
||||
* contain more than one event.
|
||||
*
|
||||
* @return events not processed.
|
||||
*/
|
||||
static uint16_t lwns_adapter_ProcessEvent(uint8_t task_id, uint16_t events)
|
||||
{
|
||||
if(events & LWNS_PHY_RX_CHANGE_CHANNEL_EVT) //处理更换接收通道事件
|
||||
{
|
||||
ble_phy_channelmap_receive_seq++;
|
||||
if(ble_phy_channelmap_receive_seq >= sizeof(ble_phy_channelmap))
|
||||
{
|
||||
ble_phy_channelmap_receive_seq = 0;
|
||||
}
|
||||
RF_Shut();
|
||||
RF_SetChannel(ble_phy_channelmap[ble_phy_channelmap_receive_seq]); //周期性更改发送通道
|
||||
RF_Rx(NULL, 0, USER_RF_RX_TX_TYPE, USER_RF_RX_TX_TYPE); //重新打开接收
|
||||
tmos_start_task(lwns_adapter_taskid, LWNS_PHY_RX_CHANGE_CHANNEL_EVT, MS1_TO_SYSTEM_TIME(LWNS_MAC_PERIOD_MS));
|
||||
return ((events & (~LWNS_PHY_RX_OPEN_EVT)) ^ LWNS_PHY_RX_CHANGE_CHANNEL_EVT ); //停止可能已经置位的、可能会打开接收的任务
|
||||
}
|
||||
if(events & LWNS_PHY_RX_OPEN_EVT)
|
||||
{ //重新打开接收事件
|
||||
RF_Shut();
|
||||
RF_Rx(NULL, 0, USER_RF_RX_TX_TYPE, USER_RF_RX_TX_TYPE); //重新打开接收
|
||||
return (events ^ LWNS_PHY_RX_OPEN_EVT);
|
||||
}
|
||||
if(events & SYS_EVENT_MSG)
|
||||
{ //处理打开接收后,再处理数据
|
||||
uint8_t *pMsg;
|
||||
if((pMsg = tmos_msg_receive(lwns_adapter_taskid)) != NULL)
|
||||
{
|
||||
// Release the TMOS message,tmos_msg_allocate
|
||||
lwns_input(pMsg + 1, pMsg[0]); //将数据存入协议栈缓冲区
|
||||
tmos_msg_deallocate(pMsg); //先释放内存,在数据处理前释放,防止数据处理中需要发送数据,而内存不够。
|
||||
lwns_dataHandler(); //调用协议栈处理数据函数
|
||||
}
|
||||
// return unprocessed events
|
||||
return (events ^ SYS_EVENT_MSG);
|
||||
}
|
||||
// Discard unknown events
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn lwns_phyoutput_ProcessEvent
|
||||
*
|
||||
* @brief lwns phyoutput Task event processor. This function
|
||||
* is called to process all events for the task. Events
|
||||
* include timers, messages and any other user defined events.
|
||||
*
|
||||
* @param task_id - The TMOS assigned task ID.
|
||||
* @param events - events to process. This is a bit map and can
|
||||
* contain more than one event.
|
||||
*
|
||||
* @return events not processed.
|
||||
*/
|
||||
static uint16_t lwns_phyoutput_ProcessEvent(uint8_t task_id, uint16_t events)
|
||||
{
|
||||
if(events & LWNS_HTIMER_PERIOD_EVT)
|
||||
{
|
||||
lwns_htimer_update(); //htimer更新。
|
||||
tmos_start_task(lwns_phyoutput_taskid, LWNS_HTIMER_PERIOD_EVT, MS1_TO_SYSTEM_TIME(LWNS_HTIMER_PERIOD_MS)); //周期性更新
|
||||
return (events ^ LWNS_HTIMER_PERIOD_EVT);
|
||||
}
|
||||
if(events & LWNS_PHY_OUTPUT_PREPARE_EVT)
|
||||
{ //准备发送工作
|
||||
uint8_t rand_delay;
|
||||
rand_delay = tmos_rand() % MS1_TO_SYSTEM_TIME(LWNS_MAC_SEND_DELAY_MAX_MS) + BLE_PHY_ONE_PACKET_MAX_625US; //随机延迟
|
||||
ble_phy_channelmap_send_seq = 0; //发送通道序号
|
||||
PRINTF("rand send:%d\n", rand_delay);
|
||||
tmos_start_task(lwns_phyoutput_taskid, LWNS_PHY_OUTPUT_FINISH_EVT, rand_delay); //随机延迟后立刻发送
|
||||
return (events ^ LWNS_PHY_OUTPUT_PREPARE_EVT);
|
||||
}
|
||||
if(events & LWNS_PHY_OUTPUT_FINISH_EVT)
|
||||
{ //发送完成任务
|
||||
if(ble_phy_channelmap_send_seq < sizeof(ble_phy_channelmap))
|
||||
{
|
||||
if(ble_phy_channelmap_send_seq == 0)
|
||||
{ //只需要在开始发送的时候停任务
|
||||
tmos_stop_task(lwns_adapter_taskid, LWNS_PHY_RX_CHANGE_CHANNEL_EVT); //发送期间,停止继续切换接收通道
|
||||
tmos_clear_event(lwns_adapter_taskid, LWNS_PHY_RX_CHANGE_CHANNEL_EVT); //停止可能已经置位的、可能会打开接收的任务
|
||||
tmos_clear_event(lwns_adapter_taskid, LWNS_PHY_RX_OPEN_EVT); //停止可能已经置位的、可能会打开接收的任务
|
||||
}
|
||||
RF_Shut();
|
||||
RF_SetChannel(ble_phy_channelmap[ble_phy_channelmap_send_seq]); //周期性更改发送通道
|
||||
RF_Tx((uint8_t *)(blemesh_phy_manage_list_head->data + 1),
|
||||
blemesh_phy_manage_list_head->data[0], USER_RF_RX_TX_TYPE,
|
||||
USER_RF_RX_TX_TYPE);
|
||||
tmos_start_task(lwns_phyoutput_taskid, LWNS_PHY_OUTPUT_FINISH_EVT, MS1_TO_SYSTEM_TIME(LWNS_PHY_OUTPUT_TIMEOUT_MS)); //开始发送超时计数,防止有意外打断发送,导致无法继续发送
|
||||
ble_phy_channelmap_send_seq++;
|
||||
}
|
||||
else
|
||||
{
|
||||
//三个通道一次发送结束完
|
||||
ble_phy_send_cnt++;
|
||||
tmos_set_event(lwns_adapter_taskid, LWNS_PHY_RX_CHANGE_CHANNEL_EVT); //间隔期间继续接收
|
||||
if(ble_phy_send_cnt < LWNS_MAC_TRANSMIT_TIMES)
|
||||
{ //发送次数不够
|
||||
tmos_set_event(lwns_phyoutput_taskid, LWNS_PHY_OUTPUT_PREPARE_EVT); //启动发送
|
||||
}
|
||||
else
|
||||
{
|
||||
//指定次数发送结束
|
||||
ble_phy_send_cnt = 0; //清空发送次数计数
|
||||
tmos_msg_deallocate(blemesh_phy_manage_list_head->data); //释放内存
|
||||
blemesh_phy_manage_list_head->data = NULL; //恢复默认参数
|
||||
blemesh_phy_manage_list_head = blemesh_phy_manage_list_head->next; //链表pop,去除掉首元素
|
||||
if(blemesh_phy_manage_list_head != NULL)
|
||||
{
|
||||
tmos_set_event(lwns_phyoutput_taskid, LWNS_PHY_OUTPUT_PREPARE_EVT); //启动发送
|
||||
}
|
||||
}
|
||||
}
|
||||
return (events ^ LWNS_PHY_OUTPUT_FINISH_EVT);
|
||||
}
|
||||
if(events & SYS_EVENT_MSG)
|
||||
{
|
||||
uint8_t *pMsg;
|
||||
if((pMsg = tmos_msg_receive(lwns_phyoutput_taskid)) != NULL)
|
||||
{
|
||||
// Release the TMOS message,tmos_msg_allocate
|
||||
tmos_msg_deallocate(pMsg); //释放内存
|
||||
}
|
||||
// return unprocessed events
|
||||
return (events ^ SYS_EVENT_MSG);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn lwns_shut
|
||||
*
|
||||
* @brief 停止lwns,不可以在这lwns_phyoutput_taskid和lwns_adapter_taskid的processEvent中调用。
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
void lwns_shut()
|
||||
{
|
||||
uint8_t *pMsg;
|
||||
RF_Shut(); //关闭RF接收
|
||||
while(blemesh_phy_manage_list_head != NULL)
|
||||
{
|
||||
/* 清除所有缓存中待发送的消息 */
|
||||
tmos_msg_deallocate(blemesh_phy_manage_list_head->data);
|
||||
blemesh_phy_manage_list_head->data = NULL;
|
||||
blemesh_phy_manage_list_head = blemesh_phy_manage_list_head->next;
|
||||
}
|
||||
tmos_stop_task(lwns_phyoutput_taskid, LWNS_HTIMER_PERIOD_EVT); //停止Htimer心跳时钟
|
||||
tmos_clear_event(lwns_phyoutput_taskid, LWNS_HTIMER_PERIOD_EVT);
|
||||
/* 超时重发全部清除 */
|
||||
lwns_htimer_flush_all();
|
||||
tmos_stop_task(lwns_phyoutput_taskid, LWNS_PHY_OUTPUT_PREPARE_EVT);
|
||||
tmos_clear_event(lwns_phyoutput_taskid, LWNS_PHY_OUTPUT_PREPARE_EVT);
|
||||
tmos_stop_task(lwns_phyoutput_taskid, LWNS_PHY_OUTPUT_FINISH_EVT);
|
||||
tmos_clear_event(lwns_phyoutput_taskid, LWNS_PHY_OUTPUT_FINISH_EVT);
|
||||
while((pMsg = tmos_msg_receive(lwns_adapter_taskid)) != NULL)
|
||||
{
|
||||
/* 清除所有缓存的消息 */
|
||||
tmos_msg_deallocate(pMsg);
|
||||
}
|
||||
tmos_stop_task(lwns_adapter_taskid, LWNS_PHY_RX_CHANGE_CHANNEL_EVT); //停止Htimer心跳时钟
|
||||
tmos_clear_event(lwns_adapter_taskid, LWNS_PHY_RX_CHANGE_CHANNEL_EVT);
|
||||
tmos_stop_task(lwns_adapter_taskid, LWNS_PHY_RX_OPEN_EVT);
|
||||
tmos_clear_event(lwns_adapter_taskid, LWNS_PHY_RX_OPEN_EVT);
|
||||
tmos_clear_event(lwns_adapter_taskid, SYS_EVENT_MSG);
|
||||
|
||||
/* 清空发送次数计数 */
|
||||
ble_phy_send_cnt = 0;
|
||||
/* 清空发送序号 */
|
||||
ble_phy_channelmap_send_seq = 0;
|
||||
/* 清空接收通道序号 */
|
||||
ble_phy_channelmap_receive_seq = 0;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn lwns_start
|
||||
*
|
||||
* @brief lwns开始运行,在使用lwns_shut后,重新开始时使用。
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
void lwns_start()
|
||||
{
|
||||
RF_Shut();
|
||||
RF_SetChannel(ble_phy_channelmap[ble_phy_channelmap_receive_seq]); //周期性更改发送通道
|
||||
RF_Rx(NULL, 0, USER_RF_RX_TX_TYPE, USER_RF_RX_TX_TYPE); //打开RF接收,如果需要低功耗管理,在其他地方打开。
|
||||
tmos_start_task(lwns_adapter_taskid, LWNS_PHY_RX_CHANGE_CHANNEL_EVT, MS1_TO_SYSTEM_TIME(LWNS_MAC_PERIOD_MS));
|
||||
tmos_start_task(lwns_phyoutput_taskid, LWNS_HTIMER_PERIOD_EVT, MS1_TO_SYSTEM_TIME(LWNS_HTIMER_PERIOD_MS));
|
||||
}
|
||||
|
||||
#endif /* LWNS_USE_BLEMESH_MAC */
|
||||
Reference in New Issue
Block a user