/** ************************************************************************ * @file main.c * @brief Example for RF tx function. * @version V0.6 * @date 2024-11-20 * @author Panchip Team * Copyright (C) 2024 Panchip Technology Corp. All rights reserved. **************************************************************************** */ #include #include "stdlib.h" #include #include #include "gpio.h" #include "rcc.h" #include "rf.h" #include "uart.h" #include "timer.h" #include "log.h" #ifndef IS_CLIENT_BOARD #define IS_CLIENT_BOARD 0 #endif #if IS_CLIENT_BOARD #define USER_KEY_PIN GPIO_P32 #define USER_KEY_PIN_BIT P3_2 #define USER_KEY_PIN_MUX GPIO_P32_MUX_IO #else #define USER_KEY_PIN GPIO_P33 #define USER_KEY_PIN_BIT P3_3 #define USER_KEY_PIN_MUX GPIO_P33_MUX_IO #endif #define RF_ADRESS_SIZE 5 #define RF_TX_BUF_SIZE 64 // The length of PAYLOAD/ACK PAYLOAD to be sent each time #define RF_RX_BUF_SIZE 64 // Receive payload length is set by RF_SetRxPayloadLen RF_ITStatus_t rf_status; typedef struct { /* radio param */ u16 channel; // 2400~2480 RF_TxPower_t txPower; // 0dbm~13dbm RF_DataRate_t rate; // 1Mbps, 2Mbps and 250Kbps /* radio config */ RF_ChipMode_t ChipMode; // 297L、BLE and 24L01 RF_WorkMode_t WorkMode; // normal mode and enhance mode bool EnAPL; // ack payload enable or disable only used in enhancde mode bool EnDPL; // dynamic payload enable or disable only used in enhancde mode bool EnTxNoAck; // tx noack enable or disable only used in normal mode bool EnWhite; // whiten enable or disable RF_Crc_t crc; u8 AddrWidth; u8 TRxAddr[RF_ADRESS_SIZE]; u16 RxTimeoutUs; // RF Wait for ack timeout time in enhance mode or receive a packet with timeout in normal mode u16 TxSetupTimeUs; // RF tx setup time, the time from the end of the last bit of received packet to the start of the first bit of the ack packet u8 TxBuf[RF_TX_BUF_SIZE]; u8 RxBuf[RF_RX_BUF_SIZE]; u8 TxLen; u8 RxLen; } RFConfig_t; RFConfig_t xdata gRfConfig = { /*.Channel = */ 2418, /*.TxPower = */ 7, /*.DataRate = */ RF_DR_1Mbps, /*.ChipMode = */ RF_CHIPMODE_BLE, /*.WorkMode = */ RF_WORKMODE_NORMAL, /*.EnAPL = */ ENABLE, /*.EnDPL = */ ENABLE, /*.EnTxNoAck = */ DISABLE, /*.EnWhite = */ ENABLE, /*.Crc = */ RF_CRC_2BYTE, /*.AddrWidth = */ RF_ADRESS_SIZE, /*.TRxAddr = */ {0x10, 0x22, 0x55, 0x0F, 0x71}, // If you want to test multi-pipe0, you can use this address // /*.TRxAddr = */ {0x11, 0x22, 0x55, 0x0F, 0x71}, // If you want to test multi-pipe1, you can use this address // /*.TRxAddr = */ {0x12, 0x22, 0x55, 0x0F, 0x71}, // If you want to test multi-pipe2, you can use this address // /*.TRxAddr = */ {0x13, 0x22, 0x55, 0x0F, 0x71}, // If you want to test multi-pipe3, you can use this address // /*.TRxAddr = */ {0x14, 0x22, 0x55, 0x0F, 0x71}, // If you want to test multi-pipe4, you can use this address // /*.TRxAddr = */ {0x15, 0x22, 0x55, 0x0F, 0x71}, // If you want to test multi-pipe5, you can use this address /*.RxTimeoutUs = */ 1000, /*.TxSetupTimeUs = */ 200, /*.TxBuf = */ {0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 0x55,0x55,0x55,0x55}, /*.RxBuf = */ {0}, /*.TxLen = */ 0, /*.RxLen = */ 0, }; u16 xdata Timer2IntCnt = 0; // The interrupt period of timer2's setting is about 50ms void APP_UartInit(void) { RCC_PeriphClockCmd(RCC_PERIPH_UART, ENABLE); RCC_PeriphClockCmd(RCC_PERIPH_PORT, ENABLE); RCC_PeriphClockCmd(RCC_PERIPH_TIMER1, ENABLE); /** Initialize uart params(if baudrate is 115200, timer1 will be used by uart) */ GPIO_Init(GPIO_P31, GPIO_P31_MUX_TXD0, GPIO_MODE_OUTPUT_PP, GPIO_NOPULL); UART_Init(LENGTH_8, DISABLE_RX, DISABLE_PAR, BAUD_115200); } void APP_Timer2Init(void) { RCC_PeriphClockCmd(RCC_PERIPH_TIMER2, ENABLE); TIM_TimeBaseInit(TIMER2, TIM2_Mode0_16BitAutoReload, TIM_CLK_DIV_12T, 0xFACB); TIM_EnableIRQ(TIMER2); /**< Enable timer0 interrupt */ TIM_Cmd(TIMER2, ENABLE); /**< Start timer0 */ } void APP_RfInit(RFConfig_t *pCfg) { RCC_PeriphClockCmd(RCC_PERIPH_RF, ENABLE); RF_Init(); RF_CarrierOffset(0x00); RF_SetChipMode(pCfg->ChipMode); RF_SetDataRate(pCfg->rate); RF_SetChannel(pCfg->channel-2400); RF_SetCrc(pCfg->crc); RF_SetTxPower(pCfg->txPower); RF_SetFifoLenType(RF_FIFOLEN_TYPE_64); RF_SetTxAddr(pCfg->TRxAddr, pCfg->AddrWidth); RF_SetRxAddr(RF_PIPE0, pCfg->TRxAddr, pCfg->AddrWidth); RF_SetRxPayloadLen(RF_PIPE0, sizeof(gRfConfig.RxBuf)); RF_SetWorkMode(pCfg->WorkMode); /* RF tx setup time: 112us is minimum value */ RF_SetTxSetupTime(pCfg->TxSetupTimeUs); if(pCfg->WorkMode == RF_WORKMODE_ENHANCE) { RF_SetTRxAckTimeout(pCfg->RxTimeoutUs); RF_SetAutoRetrans(250, 3); // 250us delay, 3 times retransmit RF_SetNoAck(pCfg->EnTxNoAck); RF_SetAckPayload(pCfg->EnAPL); RF_EnableDynamicPayload(RF_PIPE0, pCfg->EnDPL); } else { RF_SetAutoRetrans(250, 0); // You must disable the auto retransmit function, when chip is in normal mode RF_SetNoAck(ENABLE); // You must enable the Tx noack bit, when chip is in normal mode RF_SetAckPayload(DISABLE); RF_EnableDynamicPayload(RF_PIPE0, DISABLE); } RF_ITConfig(RF_ITCONF_TX|RF_ITCONF_RX|RF_ITCONF_TX_MAX, ENABLE); RF_EnableIRQ(); } void DelayMs(u16 Ms) { u16 i, j; for (i = 0; i < Ms; i++) { for (j = 0; j < 1000; j++) { ; _nop_(); } } } static unsigned char key_flag = 0; unsigned char key_scan(void) { uint8_t P10Sta; if (USER_KEY_PIN_BIT) { P10Sta = 1; } else { P10Sta = 0; } // printf("USER_KEY_PIN_BIT=[%bu]\r\n", P10Sta); if(P10Sta==0) { if (key_flag== 0) { DelayMs(300); if(P10Sta==0) { key_flag = 1; } } } else { if(P10Sta) { if(key_flag==1) { DelayMs(300); if(P10Sta) { if(key_flag==1) { key_flag=0; return 1; } key_flag=0; } } } } return 0; } int main(void) { uint8_t txrx_done = 0; uint8_t mode = 250; uint8_t mode_set = 0; uint8_t rf_ch = 2; uint8_t get_rand_num = 0; uint8_t autoMode = 0; int sendPacketCount = 0; /** System clock initialize */ RCC_SysClkInit(); DelayMs(1000); APP_UartInit(); APP_Timer2Init(); APP_RfInit(&gRfConfig); RF_EnterTxMode(); GPIO_Init(USER_KEY_PIN, USER_KEY_PIN_MUX, GPIO_MODE_INPUT, GPIO_PULLUP); EA = 1; printf("RF Tx Test.\r\n"); while (1) { // static u8 Count = 0; if (rf_status) { switch (rf_status) { case RF_IT_TX_RX_DONE: printf("Tx&Rx done.\n"); break; case RF_IT_TX_DONE: // printf("Tx done.\n"); txrx_done = 1; break; case RF_IT_RX_DONE: // printf("Rx done.\n"); break; case RF_IT_TX_MAX_RT: printf("Tx fail.\n"); break; default: break; } rf_status = RF_IT_NONE; } if(key_scan()) { txrx_done = 1; mode_set = 1; mode++; if(mode>=9)mode = 0; printf("mode=[%bu]\r\n", mode); } switch(mode) { case 0: if(mode_set) { mode_set = 0; txrx_done = 1; RF_Deinit(); APP_RfInit(&gRfConfig); RF_SetChannel(02); RF_EnterTxMode(); } if (txrx_done) { txrx_done = 0; // DelayMs(50); RF_FlushTxFifo(); if(gRfConfig.EnTxNoAck) { RF_WriteTxPayloadByXDATA(rf_tx_noack, gRfConfig.TxBuf, sizeof(gRfConfig.TxBuf)); } else { RF_WriteTxPayloadByXDATA(rf_tx, gRfConfig.TxBuf, sizeof(gRfConfig.TxBuf)); } // printf("TxLen[%bu]:\n", sizeof(gRfConfig.TxBuf)); // panlog_hexdump(16, gRfConfig.TxBuf, sizeof(gRfConfig.TxBuf)); } break; case 1: if(mode_set) { mode_set = 0; txrx_done = 1; RF_SetChannel(40); } if (txrx_done) { txrx_done = 0; // DelayMs(50); RF_FlushTxFifo(); RF_WriteTxPayloadByXDATA(rf_tx_noack, gRfConfig.TxBuf, sizeof(gRfConfig.TxBuf)); // printf("start to send data\r\n"); } break; case 2: if(mode_set) { mode_set = 0; txrx_done = 1; RF_SetChannel(80); } if (txrx_done) { txrx_done = 0; // DelayMs(50); RF_FlushTxFifo(); RF_WriteTxPayloadByXDATA(rf_tx_noack, gRfConfig.TxBuf, sizeof(gRfConfig.TxBuf)); // printf("start to send data\r\n"); } break; case 3: if(mode_set) { mode_set = 0; RF_SetChannel(2); RF_EnterRxMode(); printf("RF_EnterRxMode\r\n"); } break; case 4: if(mode_set) { mode_set = 0; txrx_done=0; RF_Deinit(); APP_RfInit(&gRfConfig); RF_SetChannel(2); RF_EnterTxMode(); // DelayMs(50); RF_Carrier(); } break; case 5: if(mode_set) { mode_set = 0; RF_SetChannel(40); } break; case 6: if(mode_set) { mode_set = 0; RF_SetChannel(80); } break; case 7: if(mode_set) { mode_set = 0; RF_Deinit(); APP_RfInit(&gRfConfig); RF_EnterTxMode(); txrx_done=1; sendPacketCount = 0; } if (sendPacketCount >= 300) { sendPacketCount = 0; // flag_200ms = 0; get_rand_num = rand()%41; rf_ch = get_rand_num*2; if(rf_ch>80)rf_ch=80; RF_SetChannel(rf_ch); printf("rand_num=[%bu]\r\n", rf_ch); } if (txrx_done) { sendPacketCount++; txrx_done=0; RF_FlushTxFifo(); RF_WriteTxPayloadByXDATA(rf_tx_noack, gRfConfig.TxBuf, sizeof(gRfConfig.TxBuf)); } break; case 8: if(mode_set) { mode_set = 0; rf_ch = 0; txrx_done=1; sendPacketCount = 0; } if (sendPacketCount >= 300) { sendPacketCount = 0; txrx_done=0; rf_ch+=2; if(rf_ch>80)rf_ch=2; RF_SetChannel(rf_ch); printf("rf_ch=[%bu]\r\n", rf_ch); } if (txrx_done) { txrx_done=0; sendPacketCount++; RF_FlushTxFifo(); RF_WriteTxPayloadByXDATA(rf_tx_noack, gRfConfig.TxBuf, sizeof(gRfConfig.TxBuf)); } break; } // if(Timer2IntCnt >= 500) // { // Timer2IntCnt = 0; // memset(gRfConfig.TxBuf, Count++, sizeof(gRfConfig.TxBuf)); // RF_FlushTxFifo(); // if(gRfConfig.EnTxNoAck) // { // RF_WriteTxPayloadByXDATA(rf_tx_noack, gRfConfig.TxBuf, sizeof(gRfConfig.TxBuf)); // } // else // { // RF_WriteTxPayloadByXDATA(rf_tx, gRfConfig.TxBuf, sizeof(gRfConfig.TxBuf)); // } // printf("TxLen[%bu]:\n", sizeof(gRfConfig.TxBuf)); // panlog_hexdump(16, gRfConfig.TxBuf, sizeof(gRfConfig.TxBuf)); // } // if(gRfConfig.RxLen > 0) // { // printf("RxLen[%bu]:\n", gRfConfig.RxLen); // panlog_hexdump(16, gRfConfig.RxBuf, gRfConfig.RxLen); // gRfConfig.RxLen = 0; // } } } /** * @brief * @param None * @retval None */ void RF_InterruptHandler(void) interrupt RF_COM3_VECTOR { rf_status = RF_GetIRQFlags(); switch (rf_status) { case RF_IT_TX_RX_DONE: if(gRfConfig.EnAPL != RF_APL_DISABLE) { gRfConfig.RxLen = RF_ReadRxPayloadByXDATA(gRfConfig.RxBuf, sizeof(gRfConfig.RxBuf)); } //printf("Tx&Rx done.\n"); break; case RF_IT_TX_DONE: //printf("Tx done.\n"); break; case RF_IT_RX_DONE: //printf("Rx done.\n"); break; case RF_IT_TX_MAX_RT: //printf("Tx fail.\n"); break; default: break; } RF_FlushRxFifo(); RF_ClearIRQFlags(); } void TIMER2_InterruptHandler(void) interrupt TIMER2_VECTOR { /* mode1:Tmax = (0x10000)*(1/(16M/div_12)) = 49.152ms */ /* Clear timer2 global interrupt falg */ TF2 = 0; Timer2IntCnt++; }