一.程序(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 
...
 
posted on 2026-08-31 15:16  WCH蓝牙应用分享  阅读(10)  评论(0)    收藏  举报