在锁里面用了cc1310来做前后面板的通信,所以需要通过cc1310的wor模式来通信
wor模式是通过控制rf核打开时间来实现的,及rf打开较短时间来抓包,其余时间都休眠,从而实现低功耗
具体实现代码如下
/*********************************************
* @文件: driverRf.c
* @作者: cjx
* @版本: v1.0.1
* @时间: 2017-01-15
* @概要: RF接收采用wor模式 发送
采用连续发送
*********************************************/
#include
#include
#include
#include
#include
#include "Board.h"
#include "RFQueue.h"
#include "RFConf.h"
#include "smartrf_settings.h"
#include "driverFile.h"
#include "driverTimer.h"
#include "driverTime.h"
#include "driverKey.h"
#include "ioctrl.h"
#include "queue.h"
#include "assert.h"
/* 基础宏配置 */
#define RF_RX_INT 500 //接收间隔用来调节功耗 ms
#define RF_TX_INT 10 //连续发送的间隔 ms
#define RF_TX_MAX_CNT (2 * (RF_RX_INT / RF_TX_INT)) //连续发送最多的次数 这个根据RX休眠时间来定 如果有丢包可调节此参数
#define WOR_WAKEUPS_PER_SECOND (1000/RF_RX_INT) //每秒rf醒来的次数 用于功耗调节
#define DATA_ENTRY_HEADER_SIZE 8 /* Constant header size of a Generic Data Entry */
#define NUM_DATA_ENTRIES 1 /* NOTE: Only two data entries supported at the moment */
#define NUM_APPENDED_BYTES 1 /* Length byte included in the stored packet */
#define FCFG1_BASE_ADDR 0x50001000
#define FCFG1_MAC_ADDR ((T_VOID *)(FCFG1_BASE_ADDR + 0x2F0)) //MAC地址
/* 属性变量 */
static RF_Object rfObject;
static RF_Handle rfHandle;
static rfc_propRxOutput_t rxStatistics;
static rfc_CMD_PROP_RX_SNIFF_t RF_cmdPropRxSniff; //接收抓包属性
static rfc_CMD_PROP_TX_ADV_t RF_cmdPropTxAdv; //发送广播属性
/* RF数据包定义 */
typedef struct
{
T_U8 u8H[DATA_ENTRY_HEADER_SIZE]; //发送前导码
T_U8 len;
T_U32 u32AbsTime; //绝对时间 用于滤数据
T_U8 u8Data[RF_DATA_MAX_LENGTH];
T_U8 u8R[10]; //做接收扩充预留
}T_RFRxData;
typedef struct
{
T_U8 len;
T_U32 u32AbsTime; //绝对时间 用于滤数据
T_U8 u8Data[RF_DATA_MAX_LENGTH];
}T_RFTxData;
static T_RFTxData g_stTxPacket; //发送缓存
static T_RFRxData g_stRxPacket; //接收缓存
typedef enum
{
RF_M_RX_RUN = 0, //正常模式下接收
RF_M_TX_RUN, //RF 发送模式
RF_M_RX_SLEEP, //RF 休眠抓包模式
}E_RF_M;
/* RF控制数据*/
typedef struct
{
T_U8 u8TaskM; //RF_IOCTL_CMD
T_U8 u8RfM; //E_RF_M
T_U8 u8TxCnt; //发送次数计数
T_U32 u32OldAbsTime; //用于记录上一次结收数据包的时间
}T_RFCtl; //rf控制数据
static T_RFCtl g_RFCtl;
static T_U8 g_u8RfPopFlag = 0;
static T_U8 g_u8RfReadCache[RF_DATA_MAX_LENGTH];
static T_VOID Rf_TaskHandler(T_VOID *pvData);
/********************************************
*功能:RF 初始化
*输入:无
*输出:无
*条件:无
*返回:无
注意:
*********************************************/
static PIN_Handle ledPinHandle;
static PIN_State ledPinState;
PIN_Config pinTable[] =
{
IOID_7 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
IOID_6 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
PIN_TERMINATE
};
static T_VOID Rf_Init(T_VOID)
{
RF_Params stRfParams;
RF_Params_init(&stRfParams);
/* 初始化rf */
rfHandle = RF_open(&rfObject, &RF_prop, (RF_RadioSetup*)&RF_cmdPropRadioDivSetup, &stRfParams);
RF_runCmd(rfHandle, (RF_Op*)&RF_cmdFs, RF_PriorityNormal, NULL, 0);
memset(&g_RFCtl, 0, sizeof(T_RFCtl));
ledPinHandle = PIN_open(&ledPinState, pinTable);
}
/********************************************
*功能:RF 设置整个工作模式
*输入:模式
*输出:无
*条件:无
*返回:无
注意:
*********************************************/
static T_VOID Rf_SetTaskMode(RF_IOCTL_CMD emM)
{
g_RFCtl.u8TaskM = emM;
}
/********************************************
*功能:RF 设置模式
*输入:模式
*输出:无
*条件:无
*返回:无
注意:
*********************************************/
static T_VOID Rf_SetMode(E_RF_M emM)
{
T_U32 stTick;
TimerHandle stTimeNode;
TimeTick stTimeTick;
g_RFCtl.u8RfM= emM;
g_RFCtl.u8TxCnt = 0;
MDL_TIME_GetTimeTick(&stTimeTick);
stTick = stTimeTick.u32Sec*1000 + stTimeTick.s32MSec;
stTimeNode.fTimerHandle = Rf_TaskHandler;
stTimeNode.pvData = T_NULL;
stTimeNode.s32MSec = stTick + 100;
MDL_DRVTIMER_AddTimer(&stTimeNode);
}
/********************************************
*功能:RF 接收抓包配置
*输入:u8WkPerS :每秒唤醒次数
*输出:无
*条件:无
*返回:无
注意:
*********************************************/
static T_VOID Rf_RxConf(T_U8 u8WkPerS)
{
T_U32 u32Datarate;
dataQueue_t stDataQueue;
/* 创建接收数据入口 */
if (RFQueue_defineQueue(&stDataQueue,
(uint8_t *)&g_stRxPacket,
sizeof(g_stRxPacket),
NUM_DATA_ENTRIES,
sizeof(T_RFTxData) + NUM_APPENDED_BYTES)) //RF_DATA_MAX_LENGTH + NUM_APPENDED_BYTES))
{
while(1);
}
/* 初始化抓包属性 */
initializeSniffCmdFromRxCmd(&RF_cmdPropRxSniff, &RF_cmdPropRx);
RF_cmdPropRxSniff.pQueue = &stDataQueue;
RF_cmdPropRxSniff.pOutput = (uint8_t*)&rxStatistics;
RF_cmdPropRxSniff.maxPktLen = sizeof(T_RFTxData);//RF_DATA_MAX_LENGTH;
RF_cmdPropRxSniff.rxConf.bAutoFlushIgnored = 1;
RF_cmdPropRxSniff.rxConf.bAutoFlushCrcErr = 1;
u32Datarate = calculateSymbolRate(RF_cmdPropRadioDivSetup.symbolRate.preScale,
RF_cmdPropRadioDivSetup.symbolRate.rateWord);
configureSniffCmd(&RF_cmdPropRxSniff, WOR_MODE, u32Datarate, u8WkPerS);
RF_cmdPropRxSniff.startTime = RF_getCurrentTime();
RF_cmdPropRxSniff.startTime += WOR_WAKE_UP_INTERVAL_RAT_TICKS(u8WkPerS);
}
/********************************************
*功能:RF 发送配置
*输入:数据
*输出:无
*条件:无
*返回:无
注意:
*********************************************/
static T_VOID Rf_TxConf(T_U8 *pu8W, T_U32 u32Len)
{
g_stTxPacket.len = sizeof(g_stTxPacket)-1;
g_stTxPacket.u32AbsTime = RF_getCurrentTime();
memcpy(&g_stTxPacket.u8Data, pu8W, u32Len);
initializeTxAdvCmdFromTxCmd(&RF_cmdPropTxAdv, &RF_cmdPropTx);
RF_cmdPropTxAdv.pktLen = sizeof(T_RFTxData); /* +1 for length byte */
RF_cmdPropTxAdv.pPkt = (uint8_t *)&g_stTxPacket;
RF_cmdPropTxAdv.preTrigger.triggerType = TRIG_REL_START;
RF_cmdPropTxAdv.preTime = WOR_PREAMBLE_TIME_RAT_TICKS(1000 / 10);
}
/********************************************
*功能:RF 接收
*输入:模式
*输出:无
*条件:无
*返回:无
注意:
*********************************************/
static T_VOID Rf_RxCheck(T_VOID)
{
switch(RF_cmdPropRxSniff.status)
{
case PROP_DONE_IDLE:
{
} break;
case PROP_DONE_IDLETIMEOUT:
{
} break;
case PROP_DONE_RXTIMEOUT:
{
} break;
case PROP_DONE_OK:
{
if(g_RFCtl.u32OldAbsTime != g_stRxPacket.u32AbsTime)
{
/*不是重复包*/
memcpy(g_u8RfReadCache, &g_stRxPacket.u8Data, RF_DATA_MAX_LENGTH);
g_u8RfPopFlag = 1;
g_RFCtl.u32OldAbsTime = g_stRxPacket.u32AbsTime;
}
} break;
case PROP_ERROR_RXBUF:
{
} break;
default:
break;
}
}
/********************************************
*功能:RF 事件回调
*输入:模式
*输出:无
*条件:无
*返回:无
注意:
*********************************************/
void RF_EventCallBack(RF_Handle h, RF_CmdHandle ch, RF_EventMask e)
{
e = e;
}
/********************************************
*功能:RF 控制
*输入:数据
*输出:无
*条件:无
*返回:无
注意:
*********************************************/
static T_VOID Rf_TaskHandler(T_VOID *pvData)
{
T_U32 stTick;
TimerHandle stTimeNode;
TimeTick stTimeTick;
if(RF_M_RX_RUN == g_RFCtl.u8RfM)
{
/*
在整个任务不休眠的情况下
rf采用间隔时间抓包
抓包等待时间设置要短 避免影响
其他程 序运行
*/
Rf_RxConf(100);
RF_runCmd(rfHandle, (RF_Op*)&RF_cmdPropRxSniff, RF_PriorityNormal, &RF_EventCallBack, RF_EventRxEntryDone); //会阻塞休眠
Rf_RxCheck();
if(RF_SLEEP_CMD == g_RFCtl.u8TaskM)
{
Rf_SetMode(RF_M_RX_SLEEP);
}
MDL_TIME_GetTimeTick(&stTimeTick);
stTick = stTimeTick.u32Sec*1000 + stTimeTick.s32MSec;
stTimeNode.fTimerHandle = Rf_TaskHandler;
stTimeNode.pvData = T_NULL;
stTimeNode.s32MSec = stTick + RF_RX_INT;
MDL_DRVTIMER_AddTimer(&stTimeNode);
}
if(RF_M_RX_SLEEP == g_RFCtl.u8RfM)
{
/*
休眠情况下
rf采用间隔时间抓包
抓包等待时间设置合理可以
降低功耗
*/
SysTickStop(); //关闭系统时钟
Rf_RxConf(WOR_WAKEUPS_PER_SECOND);
RF_runCmd(rfHandle, (RF_Op*)&RF_cmdPropRxSniff, RF_PriorityNormal, &RF_EventCallBack, RF_EventRxEntryDone); //这里会休眠
Rf_RxCheck();
PIN_setOutputValue(ledPinHandle, IOID_7, !PIN_getOutputValue(IOID_7));
MDL_TIME_GetTimeTick(&stTimeTick);
stTick = stTimeTick.u32Sec*1000 + stTimeTick.s32MSec;
stTimeNode.fTimerHandle = Rf_TaskHandler;
stTimeNode.pvData = T_NULL;
stTimeNode.s32MSec = stTick; //如果没接到数据立马又接收休眠
MDL_DRVTIMER_AddTimer(&stTimeNode);
SysTickStart();
}
if(RF_M_TX_RUN == g_RFCtl.u8RfM)
{
/*
发送采用连续发包模式
要保证与rf接收唤醒间隔内
能收到至少一次数据
*/
if(g_RFCtl.u8TxCnt++ < RF_TX_MAX_CNT)
{
RF_runCmd(rfHandle, (RF_Op*)&RF_cmdPropTxAdv, RF_PriorityNormal, NULL, 0);
}else
{
g_RFCtl.u8TxCnt = 0;
Rf_SetMode(RF_M_RX_RUN);
}
MDL_TIME_GetTimeTick(&stTimeTick);
stTick = stTimeTick.u32Sec*1000 + stTimeTick.s32MSec;
stTimeNode.fTimerHandle = Rf_TaskHandler;
stTimeNode.pvData = T_NULL;
stTimeNode.s32MSec = stTick + RF_TX_INT;
MDL_DRVTIMER_AddTimer(&stTimeNode);
}
}
/********************************************
*功能:打开函数
*输入:无
*输出:无
*条件:无
*返回:成功:RET_SUCCESS
失败:RET_FAILED
注意:
*********************************************/
static T_S32 _RF_Open(T_VOID)
{
Rf_Init();
Rf_SetMode(RF_M_RX_RUN);
return RET_SUCCESS;
}
/********************************************
*功能:读取函数
*输入:无
*输出:无
*条件:无
*返回:成功:RET_SUCCESS
失败:RET_FAILED
或者长度
注意:
*********************************************/
static T_S32 _RF_Read(T_S8 *ps8DataBuf, T_S32 s32BufLen)
{
ASSERT_EQUAL_RETVAL(ps8DataBuf, T_NULL, RET_FAILED);
ASSERT_EQUAL_RETVAL(s32BufLen, 0, RET_FAILED);
if(1 == g_u8RfPopFlag)
{
g_u8RfPopFlag = 0;
if(s32BufLen >= RF_DATA_MAX_LENGTH)
{
memcpy(ps8DataBuf, g_u8RfReadCache, RF_DATA_MAX_LENGTH);
return RF_DATA_MAX_LENGTH;
}else
{
return RET_FAILED;
}
}
return RET_FAILED;
}
/********************************************
*功能:写入函数
*输入:无
*输出:无
*条件:无
*返回:成功:RET_SUCCESS
失败:RET_FAILED
或者长度
注意:
*********************************************/
static T_S32 _RF_Write(T_S8 *ps8DataBuf, T_S32 s32BufLen)
{
ASSERT_EQUAL_RETVAL(ps8DataBuf, T_NULL, RET_FAILED);
ASSERT_EQUAL_RETVAL(s32BufLen, 0, RET_FAILED);
Rf_TxConf((T_U8 *)ps8DataBuf, s32BufLen);
Rf_SetMode(RF_M_TX_RUN);
return s32BufLen;
}
/********************************************
*功能:控制接口
*输入:s32Cmd :命令类型RF_IOCTL_CMD
pvData:暂无数据
*条件:无
*返回:成功:RET_SUCCESS
失败:RET_FAILED
*********************************************/
static T_S32 _RF_Ioctl(T_S32 s32Cmd, T_VOID *pvData)
{
if(s32Cmd < RF_GET_MAC_CMD)
{
Rf_SetTaskMode((RF_IOCTL_CMD)s32Cmd);
}else
{
ASSERT_EQUAL_RETVAL(pvData, T_NULL, RET_FAILED);
memcpy(pvData, FCFG1_MAC_ADDR, RF_MAC_LENGTH);
}
return RET_SUCCESS;
}
/********************************************
*功能:事件标志
*输入:无
*输出:无
*条件:无
*返回:成功:RET_SUCCESS
失败:RET_FAILED
注意:
*********************************************/
static T_S32 _RF_Pop(T_VOID)
{
if(0 == g_u8RfPopFlag)
{
return RET_FAILED;
}
return RET_SUCCESS;
}
/********************************************
*功能:初始化DRIVER_RF_Init并且将其
添加至文件列表
*输入:无
*输出:无.
*条件:无
*返回:成功:RET_SUCCESS
失败:RET_FAILED
注意:无
*********************************************/
T_S32 DRIVER_RF_Init(T_VOID)
{
FileOperation stKeyFileOperation;
memset(stKeyFileOperation.s8ModelName, 0, MODEL_NAME_LEN);
strcpy((char *)stKeyFileOperation.s8ModelName, "RF");
stKeyFileOperation.FileIoctl = _RF_Ioctl;
stKeyFileOperation.FileOpen = _RF_Open;
stKeyFileOperation.FileRead = _RF_Read;
stKeyFileOperation.FileWrite = _RF_Write;
stKeyFileOperation.FilePop = _RF_Pop;
stKeyFileOperation.FileClose = T_NULL;
stKeyFileOperation.FileRelease = T_NULL;
return MDL_FILE_AddModel(&stKeyFileOperation);
}