一.程序(RF_PHY.c)
/* 头文件包含 */
#include "CONFIG.h"
#include "RF_PHY.h"
#define RF_AUTO_MODE_EXAM 1
uint8_t taskID;
uint8_t TX_DATA[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};
volatile uint8_t tx_end_flag=0;
volatile uint8_t rx_end_flag=0;
/*********************************************************************
* @fn RF_Wait_Tx_End
*
* @brief 手动模式等待发送完成,自动模式等待发送-接收完成,必须在RAM中等待,等待时可以执行用户代码,但需要注意执行的代码必须运行在RAM中,否则影响发送
*
* @return none
*/
__HIGH_CODE
__attribute__((noinline))
void RF_Wait_Tx_End()
{
uint32_t i=0;
while(!tx_end_flag)
{
i++;
__nop();
__nop();
// 约5ms超时
if(i>(FREQ_SYS/1000))
{
tx_end_flag = TRUE;
}
}
}
/*********************************************************************
* @fn RF_Wait_Rx_End
*
* @brief 自动模式等待应答发送完成,必须在RAM中等待,等待时可以执行用户代码,但需要注意执行的代码必须运行在RAM中,否则影响发送
*
* @return none
*/
__HIGH_CODE
__attribute__((noinline))
void RF_Wait_Rx_End()
{
uint32_t i=0;
while(!rx_end_flag)
{
i++;
__nop();
__nop();
// 约5ms超时
if(i>(FREQ_SYS/1000))
{
rx_end_flag = TRUE;
}
}
}
/*********************************************************************
* @fn RF_2G4StatusCallBack
*
* @brief RF 状态回调,此函数在中断中调用。注意:不可在此函数中直接调用RF接收或者发送API,需要使用事件的方式调用
* 在此回调中直接使用或调用函数涉及到的变量需注意,此函数在中断中调用。
*
* @param sta - 状态类型
* @param crc - crc校验结果
* @param rxBuf - 数据buf指针
*
* @return none
*/
void RF_2G4StatusCallBack(uint8_t sta, uint8_t crc, uint8_t *rxBuf)
{
switch(sta)
{
case TX_MODE_TX_FINISH:
{
#if(!RF_AUTO_MODE_EXAM)
tx_end_flag = TRUE;
#endif
break;
}
case TX_MODE_TX_FAIL:
{
tx_end_flag = TRUE;
break;
}
case TX_MODE_RX_DATA:
{
#if(RF_AUTO_MODE_EXAM)
tx_end_flag = TRUE;
if (crc == 0) {
uint8_t i;
PRINT("tx recv,rssi:%d\n", (int8_t)rxBuf[0]);
PRINT("len:%d-", rxBuf[1]);
for (i = 0; i < rxBuf[1]; i++) {
PRINT("%x ", rxBuf[i + 2]);
}
PRINT("\n");
} else {
if (crc & (1<<0)) {
PRINT("crc error\n");
}
if (crc & (1<<1)) {
PRINT("match type error\n");
}
}
#endif
break;
}
case TX_MODE_RX_TIMEOUT: // Timeout is about 200us
{
#if(RF_AUTO_MODE_EXAM)
tx_end_flag = TRUE;
#endif
break;
}
case RX_MODE_RX_DATA:
{
if (crc == 0) {
uint8_t i;
#if(RF_AUTO_MODE_EXAM)
RF_Wait_Rx_End();
#endif
PRINT("rx recv, rssi: %d\n", (int8_t)rxBuf[0]);
PRINT("len:%d-", rxBuf[1]);
for (i = 0; i < rxBuf[1]; i++) {
PRINT("%x ", rxBuf[i + 2]);
}
PRINT("\n");
} else {
if (crc & (1<<0)) {
PRINT("crc error\n");
}
if (crc & (1<<1)) {
PRINT("match type error\n");
}
}
#if(!RF_AUTO_MODE_EXAM)
tmos_set_event(taskID, SBP_RF_RF_RX_EVT);
#endif
break;
}
case RX_MODE_TX_FINISH:
{
#if(RF_AUTO_MODE_EXAM)
rx_end_flag = TRUE;
tmos_set_event(taskID, SBP_RF_RF_RX_EVT);
#endif
break;
}
case RX_MODE_TX_FAIL:
{
#if(RF_AUTO_MODE_EXAM)
rx_end_flag = TRUE;
tmos_set_event(taskID, SBP_RF_RF_RX_EVT);
#endif
break;
}
}
}
/*********************************************************************
* @fn RF_ProcessEvent
*
* @brief RF 事件处理
*
* @param task_id - 任务ID
* @param events - 事件标志
*
* @return 未完成事件
*/
uint16_t RF_ProcessEvent(uint8_t task_id, uint16_t events)
{
if(events & SYS_EVENT_MSG)
{
uint8_t *pMsg;
if((pMsg = tmos_msg_receive(task_id)) != NULL)
{
// Release the TMOS message
tmos_msg_deallocate(pMsg);
}
// return unprocessed events
return (events ^ SYS_EVENT_MSG);
}
if(events & SBP_RF_START_DEVICE_EVT)
{
tmos_start_task(taskID, SBP_RF_PERIODIC_EVT, 1000);
return events ^ SBP_RF_START_DEVICE_EVT;
}
if(events & SBP_RF_PERIODIC_EVT)
{
RF_Shut();
tx_end_flag = FALSE;
if(!RF_Tx(TX_DATA, 10, 0xFF, 0xFF))
{
RF_Wait_Tx_End();
}
PRINT("TX mode send data\n");
tmos_start_task(taskID, SBP_RF_PERIODIC_EVT, 1000);
return events ^ SBP_RF_PERIODIC_EVT;
}
if(events & SBP_RF_RF_RX_EVT)
{
uint8_t state;
RF_Shut();
TX_DATA[0]++;
#if(RF_AUTO_MODE_EXAM)
rx_end_flag = FALSE;
#endif
state = RF_Rx(TX_DATA, 10, 0xFF, 0xFF);
PRINT("RX mode.state = %x\n", state);
return events ^ SBP_RF_RF_RX_EVT;
}
return 0;
}
/*********************************************************************
* @fn RF_Init
*
* @brief RF 初始化
*
* @return none
*/
void RF_Init(void)
{
uint8_t state;
rfConfig_t rf_Config;
tmos_memset(&rf_Config, 0, sizeof(rfConfig_t));
taskID = TMOS_ProcessEventRegister(RF_ProcessEvent);
rf_Config.accessAddress = 0x71764129; // 禁止使用0x55555555以及0xAAAAAAAA ( 建议不超过24次位反转,且不超过连续的6个0或1 )
rf_Config.CRCInit = 0x555555;
rf_Config.Channel = 39;
rf_Config.Frequency = 2480000;
#if(RF_AUTO_MODE_EXAM)
rf_Config.LLEMode = LLE_MODE_AUTO;
#else
rf_Config.LLEMode = LLE_MODE_BASIC | LLE_MODE_EX_CHANNEL; // 使能 LLE_MODE_EX_CHANNEL 表示 选择 rf_Config.Frequency 作为通信频点
#endif
rf_Config.rfStatusCB = RF_2G4StatusCallBack;
rf_Config.RxMaxlen = 251;
state = RF_Config(&rf_Config);
PRINT("rf 2.4g init: %x\n", state);
#if 1
{ // RX mode
#if(RF_AUTO_MODE_EXAM)
rx_end_flag = FALSE;
#endif
state = RF_Rx(TX_DATA, 10, 0xFF, 0xFF);
PRINT("RX mode.state = %x\n", state);
}
#else
{ // TX mode
tmos_set_event( taskID , SBP_RF_PERIODIC_EVT );
}
#endif
}
二.接口说明
/**
* @brief RF_PHY Profile 任务初始化
* @return 0 - 成功
*/
extern bStatus_t RF_RoleInit( void );
/**
* @brief RF 配置
* @param pConfig - 配置结构体指针
* @return 0 - 成功
*/
extern bStatus_t RF_Config( rfConfig_t *pConfig );
/**
* @brief 接收模式
* @param txBuf - 自动模式下需发送的数据(可为 NULL)
* @param txLen - 发送长度(0~251)
* @param pktRxType - 期望接收的包类型(0xFF 广播,其他匹配)
* @param pktTxType - 自动模式下发送包类型(0xFF 广播)
* @return 0 成功,1 访问地址错误,2 忙
*/
extern bStatus_t RF_Rx( uint8_t *txBuf, uint8_t txLen, uint8_t pktRxType, uint8_t pktTxType );
/**
* @brief 发送模式
* @param txBuf - 待发送数据
* @param txLen - 长度(0~251)
* @param pktTxType - 发送包类型(0xFF 广播)
* @param pktRxType - 自动模式下期望接收的包类型
* @return 同上
*/
extern bStatus_t RF_Tx( uint8_t *txBuf, uint8_t txLen, uint8_t pktTxType, uint8_t pktRxType );
/**
* @brief 关闭 RF,停止收发
* @return 0 - 成功
*/
extern bStatus_t RF_Shut( void );
/**
* @brief 设置信道(基本模式)
* @param channel - 信道号
*/
extern void RF_SetChannel( uint32_t channel );
/**
* @brief 设置频点和白化索引(需使能 LLE_MODE_EX_CHANNEL)
* @param frequency - 频点(kHz)
* @param ch - 白化信道索引
* @return 0 - 成功
*/
extern bStatus_t RF_SetFrequency( uint32_t frequency, uint8_t ch );
三.收发打印示例
BASIC 模式 (RF_AUTO_MODE_EXAM = 0)
发送端(周期性发送):
start.
CH59x_BLE_LIB_V1.4.4
rf 2.4g init: 0
TX mode send data
TX mode send data
...
接收端(持续接收):
start.
CH59x_BLE_LIB_V1.4.4
rf 2.4g init: 0
RX mode.state = 0
rx recv, rssi: -43
len:10-1 2 3 4 5 6 7 8 9 0
RX mode.state = 0
rx recv, rssi: -43
len:10-1 2 3 4 5 6 7 8 9 0
...
AUTO 模式 (RF_AUTO_MODE_EXAM = 1)
发送端(发送后自动接收应答):
start.
CH59x_BLE_LIB_V1.4.4
rf 2.4g init: 0
tx recv,rssi:-45
len:10-1 2 3 4 5 6 7 8 9 0
TX mode send data
tx recv,rssi:-45
len:10-2 2 3 4 5 6 7 8 9 0
TX mode send data
...
接收端(接收数据并自动回复):
start.
CH59x_BLE_LIB_V1.4.4
rf 2.4g init: 0
RX mode.state = 0
rx recv, rssi: -44
len:10-1 2 3 4 5 6 7 8 9 0
RX mode.state = 0
rx recv, rssi: -44
len:10-1 2 3 4 5 6 7 8 9 0
...
浙公网安备 33010602011771号