#include "PHY.h" #include "uart.h" # extern st_RF_LoRa_DypeDef g_RF_LoRa; extern SemaphoreHandle_t port_radio_Semaphore; static QueueHandle_t radioQueue; static TimerHandle_t radio_tx_handle; static int8_t RxPacketSnr; static double RxPacketRssiValue; #define RADIO_TX_TIMEOUT 2000/portTICK_RATE_MS u32 period = 1500; void radio_tx_timeout_callback(TimerHandle_t xTimer) { hal_InitRF(); SX1276LoRa_Receive_Packet(0, false); printf("RF tx timeout\r\n"); } void read_radio_rssi(void) { RxPacketSnr = getPacketSnr(); RxPacketRssiValue = get_RxPacketRssi(RxPacketSnr); printf("RSSI = %.2f, SNR = %d\r\n",RxPacketRssiValue, RxPacketSnr); } /***************************************************************************** * Function : get_radio_bufPtr * Description : none * Input : void * Output : None * Return : u8 * Others : * Record * 1.Date : 20170419 * Author : barry * Modification: Created function *****************************************************************************/ u8 * get_RF_bufPtr(void) { return g_RF_LoRa.rf_DataBuffer; } /***************************************************************************** * Function : get_radio_bufLen * Description : none * Input : void * Output : None * Return : * Others : * Record * 1.Date : 20170419 * Author : barry * Modification: Created function *****************************************************************************/ u8 get_RF_bufLen(void) { return g_RF_LoRa.rf_RxPacketSize; } /***************************************************************************** * Function : SX1276LoRa_NormalTx * Description : none * Input : u8 chl u8 *PBuffer u8 length * Output : None * Return : * Others : * Record * 1.Date : 20170419 * Author : barry * Modification: Created function *****************************************************************************/ void SX1276LoRa_NormalTx(u8 chl, u8 *PBuffer,u8 length) { SX1276LoRa_Send_Packet(chl, false, PBuffer,length); } /***************************************************************************** * Function : SX1276LoRa_WokeUpTx * Description : none * Input : u8 chl u8 *PBuffer u8 length * Output : None * Return : * Others : * Record * 1.Date : 20170419 * Author : barry * Modification: Created function *****************************************************************************/ void SX1276LoRa_WokeUpTx(u8 chl, u8 *PBuffer,u8 length) { SX1276LoRa_Send_Packet(chl, true, PBuffer,length); } /***************************************************************************** * Function : radio_idle * Description : none * Input : void * Output : None * Return : * Others : * Record * 1.Date : 20170306 * Author : barry * Modification: Created function *****************************************************************************/ bool radio_idle(void) { #ifdef USE_LORA_MODE if ( (g_RF_LoRa.rf_state != RFLR_STATE_TX_RUNNING) && (g_RF_LoRa.rf_state != RFLR_STATE_RX_RECEIVEING)) #else if ( (g_fsk.states != RF_STATE_TX_RUNNING) && (g_fsk.states != RF_STATE_RX_SYNC) && (g_fsk.states != RF_STATE_RX_RUNNING)) #endif { return true; } else { return false; } } /***************************************************************************** * Function : mac_data_req * Description : none * Input : u8 *buf u8 length u32 timeout * Output : None * Return : * Others : * Record * 1.Date : 20170419 * Author : barry * Modification: Created function *****************************************************************************/ void mac_data_req(u8 *buf, u8 length) { if (radio_idle()) { SX1276LoRa_WokeUpTx(0 , buf, length); xTimerReset(radio_tx_handle, 0); } else { printf("radio busy\r\n"); } } /***************************************************************************** * Function : vtask_mac_data_process * Description : none * Input : void *ptr * Output : None * Return : * Others : * Record * 1.Date : 20170419 * Author : barry * Modification: Created function *****************************************************************************/ void vtask_mac_data_process(void *ptr) { u16 flag; radioQueue = xQueueCreate(1, 2); u32 radio_rx_timeout = 4000/portTICK_RATE_MS; radio_tx_handle = xTimerCreate( "radio tx timer", RADIO_TX_TIMEOUT, pdFALSE, 0, radio_tx_timeout_callback); Lora_lowPower_Init(period); hal_InitRF(); SX1276LoRa_Receive_Packet(0, false); for (;;) { flag = 0; if (xQueueReceive(radioQueue, &flag, DELAY_HOUR_TIME) == pdPASS) { if (flag == RF_VALID_HEAD) { printf("valid head\r\n"); if (xQueueReceive(radioQueue, &flag, radio_rx_timeout) == pdPASS) { printf("RSSI = %.2f, SNR = %d\r\n",RxPacketRssiValue, RxPacketSnr); if (flag == RF_RX_SUCCESS) { printf("RF Rx:"); printf_buf(g_RF_LoRa.rf_DataBuffer, g_RF_LoRa.rf_RxPacketSize); xSemaphoreGive(port_radio_Semaphore); } else if (flag == RF_RX_FAILED) { printf("crc err\r\n"); } else { printf("RF RX timeout\r\n"); } } SX1276LoRa_Receive_Packet(0, false); } else if ( (flag == RF_RX_SUCCESS) || (flag == RF_RX_FAILED) || (flag == RF_TX_SUCCESS) ) { if (flag == RF_TX_SUCCESS) { xTimerStop(radio_tx_handle,100); printf("tx done\r\n"); } else if (flag == RF_RX_SUCCESS) { printf("RF Rx:"); printf_buf(g_RF_LoRa.rf_DataBuffer, g_RF_LoRa.rf_RxPacketSize); xSemaphoreGive(port_radio_Semaphore); } else { printf("rx crc err\r\n"); } SX1276LoRa_Receive_Packet(0, false); } } else { //此处可以做成绝对复位射频功能 hal_InitRF(); SX1276LoRa_Receive_Packet(0, false); printf("reset RF\r\n"); } } } /***************************************************************************** * Function : get_lora_status * Description : none * Input : ST_irqFlag irq_flag * Output : None * Return : * Others : * Record * 1.Date : 20170418 * Author : barry * Modification: Created function *****************************************************************************/ u8 get_lora_status(ST_irqFlag irq_flag) { u8 rf_status = RF_ERR; u8 cur_chl; if ( (irq_flag.RxDone == 1) || (irq_flag.TxDone == 1) || (irq_flag.CadDone == 1) || (irq_flag.RxTimeout == 1)) { hal_DIOx_ITConfig(all,DISABLE); hal_sRF_ClearAllRF_IT(); SX1276Write( REG_LR_IRQFLAGS, 0xFF); } if (irq_flag.RxDone == 1) { SX1276LoRaSetOpMode( RFLR_OPMODE_STANDBY); RxPacketSnr = getPacketSnr(); RxPacketRssiValue = get_RxPacketRssi(RxPacketSnr); if (irq_flag.PayloadCrcError == 0) { g_RF_LoRa.rf_state = RFLR_STATE_RX_DONE; receiveRxData(g_RF_LoRa.rf_DataBuffer, &g_RF_LoRa.rf_RxPacketSize); rf_status = RF_RX_SUCCESS; } else { g_RF_LoRa.rf_state = RFLR_STATE_RX_ERR; rf_status = RF_RX_FAILED; } } else if (irq_flag.TxDone == 1) { switch_Rx(); g_RF_LoRa.rf_state = RFLR_STATE_TX_DONE; rf_status = RF_TX_SUCCESS; } else if (irq_flag.ValidHeader == 1) { hal_DIOx_ITConfig(3,DISABLE); // SX1276Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_VALIDHEADER); if (g_RF_LoRa.rf_state == RFLR_STATE_RX_RUNNING) { g_RF_LoRa.rf_state = RFLR_STATE_RX_RECEIVEING; } rf_status = RF_VALID_HEAD; } else if (irq_flag.CadDone == 1) { if (irq_flag.CadDetected == 1) { rf_status = RF_CAD_DETECT; } else { //SX1276StartSleep(); } } else if (irq_flag.RxTimeout == 1) { rf_status = RF_PREAMBLE_TIMEOUT; } else if (irq_flag.FhssChangeChannel == 1) { /* 此处表明在单次接收时是先收到头再跳频,在连续接收模式下是先跳频再收到头,需要验证 */ /* 在接收模式下,谁先发生就算接收开始了,并不是接收到头才算接收开始, 也可以处理为接收到头算接收开始,连续模式下可能头也是跳频发送的*/ /* 统一为接收到头才算接收开始 */ SX1276Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL ); SX1276Read( REG_LR_HOPCHANNEL, &cur_chl); set_hop_Channel(cur_chl); } return rf_status; } #ifdef USE_LORA_MODE /***************************************************************************** Prototype : EXTI4_15_IRQHandler Description : EXTI11 for valid header Input : void Output : None Return Value : Date : 2014/3/15 Author : Barry *****************************************************************************/ void EXTI15_10_IRQHandler(void) { BaseType_t pxHigherPriorityTaskWoken = pdFALSE; ST_irqFlag irq_flag; u16 rf_flag; bool need_radio_process = FALSE; /* tx done, rx done, cad done */ if(EXTI_GetITStatus(DIO0_IRQ) != RESET) { need_radio_process = TRUE; EXTI_ClearITPendingBit(DIO0_IRQ); } else if (EXTI_GetITStatus(DIO1_IRQ) != RESET) /* Rx timeOut */ { need_radio_process = TRUE; EXTI_ClearITPendingBit(DIO1_IRQ); } if ( need_radio_process == TRUE) { SX1276Read( REG_LR_IRQFLAGS, (u8*)&irq_flag); rf_flag = get_lora_status(irq_flag); if (rf_flag != 0) { xQueueSendToBackFromISR( radioQueue, &rf_flag, &pxHigherPriorityTaskWoken); portYIELD_FROM_ISR( pxHigherPriorityTaskWoken ); } } } /***************************************************************************** * Function : EXTI0_IRQHandler * Description : none * Input : void * Output : None * Return : * Others : * Record * 1.Date : 20170419 * Author : barry * Modification: Created function *****************************************************************************/ void EXTI0_IRQHandler(void) { BaseType_t pxHigherPriorityTaskWoken = pdFALSE; ST_irqFlag irq_flag; u16 rf_flag; bool need_radio_process = FALSE; if (EXTI_GetITStatus(DIO3_IRQ) != RESET) { need_radio_process= TRUE; EXTI_ClearITPendingBit(DIO3_IRQ); } if ( need_radio_process == TRUE) { SX1276Read( REG_LR_IRQFLAGS, (u8*)&irq_flag); rf_flag = get_lora_status(irq_flag); if (rf_flag != 0) { xQueueSendToBackFromISR( radioQueue, &rf_flag, &pxHigherPriorityTaskWoken); portYIELD_FROM_ISR( pxHigherPriorityTaskWoken ); } } } #endif