Files
HBshuiwuConcentrator/APP/PHY.c
2025-12-15 16:07:49 +08:00

417 lines
12 KiB
C

#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