Files
ch32v20x-examples/EVT/EXAM/BLE/RF_PHY_Auto/APP/RF_PHY.c
T
2023-09-06 10:08:11 +08:00

263 lines
7.0 KiB
C

/********************************** (C) COPYRIGHT *******************************
* File Name : main.c
* Author : WCH
* Version : V1.0
* Date : 2020/08/06
* Description :
*********************************************************************************
* 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.
*******************************************************************************/
/******************************************************************************/
/* Header file contains */
#include "CONFIG.h"
#include "RF_PHY.h"
/*********************************************************************
* GLOBAL TYPEDEFS
*/
#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
*/
__attribute__((section(".highcode")))
__attribute__((noinline))
void RF_Wait_Tx_End()
{
uint32_t i=0;
while(!tx_end_flag)
{
i++;
__NOP();
__NOP();
// 约5ms超时
if(i>(SystemCoreClock/1000))
{
tx_end_flag = TRUE;
}
}
}
/*********************************************************************
* @fn RF_Wait_Rx_End
*
* @brief 自动模式等待应答发送完成,必须在RAM中等待,等待时可以执行用户代码,但需要注意执行的代码必须运行在RAM中,否则影响发送
*
* @return none
*/
__attribute__((section(".highcode")))
__attribute__((noinline))
void RF_Wait_Rx_End()
{
uint32_t i=0;
while(!rx_end_flag)
{
i++;
__NOP();
__NOP();
// 约5ms超时
if(i>(SystemCoreClock/1000))
{
rx_end_flag = TRUE;
}
}
}
/*********************************************************************
* @fn RF_2G4StatusCallBack
*
* @brief RF status callback
* @Note Do not call RF receiving or sending APIs in this function directly,
* setting the event instead
*
* @param sta - State
* @param crc - CRC verification results
* @param rxBuf - Data BUF pointer
*
* @return none
*/
void RF_2G4StatusCallBack(uint8_t sta, uint8_t crc, uint8_t *rxBuf)
{
switch(sta)
{
case TX_MODE_TX_FINISH:
{
break;
}
case TX_MODE_TX_FAIL:
{
tx_end_flag = TRUE;
break;
}
case TX_MODE_RX_DATA:
{
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");
}
}
break;
}
case TX_MODE_RX_TIMEOUT: // Timeout is about 200us
{
tx_end_flag = TRUE;
break;
}
case RX_MODE_RX_DATA:
{
if (crc == 0) {
uint8_t i;
RF_Wait_Rx_End();
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");
}
}
break;
}
case RX_MODE_TX_FINISH:
{
rx_end_flag = TRUE;
tmos_set_event(taskID, SBP_RF_RF_RX_EVT);
break;
}
case RX_MODE_TX_FAIL:
{
rx_end_flag = TRUE;
tmos_set_event(taskID, SBP_RF_RF_RX_EVT);
break;
}
}
}
/*********************************************************************
* @fn RF_ProcessEvent
*
* @brief RF event processing
*
* @param task_id - Task ID
* @param events - Event logo
*
* @return Unfinished events
*/
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();
}
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]++;
rx_end_flag = FALSE;
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 initialization
*
* @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);
// 0x55555555 and 0xAAAAAAAA are prohibited (recommended no more than 24 bit reversals, and no more than 6 consecutive 0 or 1)
rf_Config.accessAddress = 0x71764129;
rf_Config.CRCInit = 0x555555;
rf_Config.Channel = 39;
rf_Config.Frequency = 2480000;
// Enabling LLE_MODE_EX_CHANNEL means selecting rfConfig.Frequency as the communication frequency
rf_Config.LLEMode = LLE_MODE_AUTO;
rf_Config.rfStatusCB = RF_2G4StatusCallBack;
rf_Config.RxMaxlen = 251;
state = RF_Config(&rf_Config);
PRINT("rf 2.4g init: %x\n", state);
// { // RX mode
// rx_end_flag = FALSE;
// state = RF_Rx(TX_DATA, 10, 0xFF, 0xFF);
// PRINT("RX mode.state = %x\n", state);
// }
{ // TX mode
tmos_set_event( taskID , SBP_RF_PERIODIC_EVT );
}
}
/******************************** endfile @ main ******************************/