cc1310实现wor接收发送低功耗模式

在锁里面用了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);
}


你可能感兴趣的:(物联网)