#include "sx1281_driver.h"

#include <string.h>
#include "stdio.h"
#include "device/sx1281_driver/radio.h"
#include "usart.h"
#include "bsp/uart.h"
#include "device/sx1281_driver/sx1281_header.h"
#include "device/sx1281_driver/sx1281.h"
#include "device/device.h"

/* --------------SX1281 Work mode------------- */
#define SX1281_INTERRUP_MODE   /* 中断模式 */
// #define SX1281_POLLING_MODE /* 轮询模式 */ 
/* ------------SX1281 Work mode end----------- */



#if defined(SX1281_INTERRUP_MODE) && defined(SX1281_POLLING_MODE)
#error "Both SX1281_INTERRUP_MODE and SX1281_POLLING_MODE are defined. Only one can be defined."
#elif !defined(SX1281_INTERRUP_MODE) && !defined(SX1281_POLLING_MODE)
#error "Neither SX1281_INTERRUP_MODE nor SX1281_POLLING_MODE is defined. One of them must be defined."
#endif


/*!
 * \brief Used to display firmware version UART flow
 */
#define FIRMWARE_VERSION    ( ( char* )"Firmware Version: 170919A" )

/*!
 * \brief Number of tick size steps for tx timeout
 */
#define TX_TIMEOUT_VALUE                            2000 // ms

/*!
 * \brief Number of tick size steps for rx timeout
 */
#define RX_TIMEOUT_VALUE                            2000 // ms

/*!
 * \brief Size of ticks (used for Tx and Rx timeout)
 */
#define RX_TIMEOUT_TICK_SIZE                        RADIO_TICK_SIZE_1000_US

/**-------------------------radio params----------------------------------**/
typedef struct {
  RadioGfskBleBitrates_t       BitrateBandwidth;  //!< The bandwidth and bit-rate values for BLE and GFSK modulations
  RadioGfskBleModIndexes_t     ModulationIndex;   //!< The coding rate for BLE and GFSK modulations
  RadioModShapings_t           ModulationShaping; //!< The modulation shaping for BLE and GFSK modulations
}SX1281_BLEConfig_t;

typedef struct
{
  RadioLoRaSpreadingFactors_t  SpreadingFactor;   //!< Spreading Factor for the LORA modulation
  RadioLoRaBandwidths_t        Bandwidth;         //!< Bandwidth for the LORA modulation
  RadioLoRaCodingRates_t       CodingRate;        //!< Coding rate for the LORA modulation
}SX1281_LORAConfig_t;

typedef struct {
  RadioGfskBleBitrates_t    BitrateBandwidth;  //!< The bandwidth and bit-rate values for BLE and GFSK modulations
  RadioGfskBleModIndexes_t  ModulationIndex;   //!< The coding rate for BLE and GFSK modulations
  RadioModShapings_t        ModulationShaping; //!< The modulation shaping for BLE and GFSK modulations
}SX1281_GFSKConfig_t;

typedef struct
{
  RadioFlrcBitrates_t          BitrateBandwidth;  //!< The bandwidth and bit-rate values for FLRC modulation
  RadioFlrcCodingRates_t       CodingRate;        //!< The coding rate for FLRC modulation
  RadioModShapings_t           ModulationShaping; //!< The modulation shaping for FLRC modulation
}SX1281_FLRCConfig_t;

const SX1281_BLEConfig_t bleConfigList[RF_BAUDRATE_BLE_NUM] = 
{
    {
    .BitrateBandwidth = GFS_BLE_BR_0_250_BW_0_6,  // 250 Kbps, 0.6 MHz
    .ModulationIndex = GFS_BLE_MOD_IND_0_50,      // 调制指数 0.5
    .ModulationShaping = RADIO_MOD_SHAPING_BT_0_5 // 调制整形 BT = 0.5
    },
    {
    .BitrateBandwidth = GFS_BLE_BR_0_500_BW_1_2,  // 500 Kbps, 1.2 MHz
    .ModulationIndex = GFS_BLE_MOD_IND_0_50,      // 调制指数 0.5
    .ModulationShaping = RADIO_MOD_SHAPING_BT_0_5 // 调制整形 BT = 0.5
    },
    {
    .BitrateBandwidth = GFS_BLE_BR_1_000_BW_2_4,  // 1 Mbps, 2.4 MHz
    .ModulationIndex = GFS_BLE_MOD_IND_0_50,      // 调制指数 0.5
    .ModulationShaping = RADIO_MOD_SHAPING_BT_0_5 // 调制整形 BT = 0.5
    },
};

const SX1281_LORAConfig_t loraConfigList[RF_BAUDRATE_LORA_NUM] = 
{
    {//216.264204545455bps,SF=12,BW=203kHz,CR=7
    .SpreadingFactor = LORA_SF12,        
    .Bandwidth = LORA_BW_0200,               
    .CodingRate = LORA_CR_LI_4_7,            
    },
    {//991.2109375bps,SF=10,BW=203kHz,CR=4
    .SpreadingFactor = LORA_SF10,        
    .Bandwidth = LORA_BW_0200,               
    .CodingRate = LORA_CR_4_8,            
    },
    {//4987.44419642857bps,SF=11,BW=1625kHz,CR=3
    .SpreadingFactor = LORA_SF11,        
    .Bandwidth = LORA_BW_1600,               
    .CodingRate = LORA_CR_4_7,            
    },
    {//10150bps,SF=8,BW=812kHz,CR=6
    .SpreadingFactor = LORA_SF8,        
    .Bandwidth = LORA_BW_0800,               
    .CodingRate = LORA_CR_LI_4_6,            
    },
    {//20300bps,SF=8,BW=812kHz,CR=1
    .SpreadingFactor = LORA_SF8,        
    .Bandwidth = LORA_BW_0800,               
    .CodingRate = LORA_CR_4_5,            
    },
    {//60900bps,SF=6,BW=812kHz,CR=1
    .SpreadingFactor = LORA_SF6,                                                                                
    .Bandwidth = LORA_BW_0800,               
    .CodingRate = LORA_CR_4_5,            
    },
    {//126953.125bps,SF=5,BW=1625kHz,CR=4
    .SpreadingFactor = LORA_SF5,        
    .Bandwidth = LORA_BW_1600,               
    .CodingRate = LORA_CR_4_8,            
    },
    {//203125bps,SF=5,BW=1625kHz,CR=1
    .SpreadingFactor = LORA_SF5,        
    .Bandwidth = LORA_BW_1600,               
    .CodingRate = LORA_CR_4_5,            
    },
};

const SX1281_GFSKConfig_t gfskConfigList[RF_BAUDRATE_GFSK_NUM] = 
{
    {
        .BitrateBandwidth = GFS_BLE_BR_0_125_BW_0_3,  // 125 Kbps, 0.3 MHz
        .ModulationIndex = GFS_BLE_MOD_IND_0_50,      // 调制指数 0.5
        .ModulationShaping = RADIO_MOD_SHAPING_BT_0_5 // 调制整形 BT = 0.5
    },
    {
        .BitrateBandwidth = GFS_BLE_BR_0_250_BW_0_6,  // 250 Kbps, 0.6 MHz
        .ModulationIndex = GFS_BLE_MOD_IND_0_50,      // 调制指数 0.5
        .ModulationShaping = RADIO_MOD_SHAPING_BT_0_5 // 调制整形 BT = 0.5
    },
    {
        .BitrateBandwidth = GFS_BLE_BR_0_500_BW_1_2,  // 500 Kbps, 1.2 MHz
        .ModulationIndex = GFS_BLE_MOD_IND_0_50,      // 调制指数 0.5
        .ModulationShaping = RADIO_MOD_SHAPING_BT_0_5 // 调制整形 BT = 0.5
    },
    {
        .BitrateBandwidth = GFS_BLE_BR_1_000_BW_2_4,  // 1 Mbps, 2.4 MHz
        .ModulationIndex = GFS_BLE_MOD_IND_0_50,      // 调制指数 0.5
        .ModulationShaping = RADIO_MOD_SHAPING_BT_0_5 // 调制整形 BT = 0.5
    }
};

const SX1281_FLRCConfig_t flrcConfigList[RF_BAUDRATE_FLRC_NUM] = 
{
    {//0.26Mbps
        .BitrateBandwidth       =FLRC_BR_0_260_BW_0_3,
        .CodingRate             =FLRC_CR_1_2, 
        .ModulationShaping      =RADIO_MOD_SHAPING_BT_1_0,
    },
    {//0.52Mbps
        .BitrateBandwidth       =FLRC_BR_0_520_BW_0_6,
        .CodingRate             =FLRC_CR_1_2, 
        .ModulationShaping      =RADIO_MOD_SHAPING_BT_1_0,
    },
    {//0.52Mbps
        .BitrateBandwidth       =FLRC_BR_1_040_BW_1_2,
        .CodingRate             =FLRC_CR_1_2, 
        .ModulationShaping      =RADIO_MOD_SHAPING_BT_1_0,
    },
    {//1.04Mbps
        .BitrateBandwidth       =FLRC_BR_1_040_BW_1_2,
        .CodingRate             =FLRC_CR_1_0, 
        .ModulationShaping      =RADIO_MOD_SHAPING_BT_1_0,
    },
};

/*!
 * \brief Defines the states of the application
 */
typedef enum
{
    APP_LOWPOWER,
    APP_RX,
    APP_RX_TIMEOUT,
    APP_RX_ERROR,
    APP_TX,
    APP_TX_TIMEOUT,
}AppStates_t;

/*!
 * \brief Function to be executed on Radio Tx Done event
 */
void OnTxDone( void );

/*!
 * \brief Function to be executed on Radio Rx Done event
 */
void OnRxDone( void );

/*!
 * \brief Function executed on Radio Tx Timeout event
 */
void OnTxTimeout( void );

/*!
 * \brief Function executed on Radio Rx Timeout event
 */
void OnRxTimeout( void );

/*!
 * \brief Function executed on Radio Rx Error event
 */
void OnRxError( IrqErrorCode_t );

/*!
 * \brief All the callbacks are stored in a structure
 */
RadioCallbacks_t Callbacks =
{
    &OnTxDone,        // txDone
    &OnRxDone,        // rxDone
    NULL,             // syncWordDone
    NULL,             // headerDone
    &OnTxTimeout,     // txTimeout
    &OnRxTimeout,     // rxTimeout
    &OnRxError,       // rxError
    NULL,             // cadDone
};

/*!
 * \brief Mask of IRQs to listen to in rx mode
 */
uint16_t RxIrqMask = IRQ_RX_DONE | IRQ_RX_TX_TIMEOUT;

/*!
 * \brief Mask of IRQs to listen to in tx mode
 */
uint16_t TxIrqMask = IRQ_TX_DONE | IRQ_RX_TX_TIMEOUT;

/*!
 * \brief The State of the application
 */
SX1281_States_t sx1281_state = LOWPOWER;


/*!
 * \brief In case of BLE, the payload must contain the header
 */
typedef union
{
    struct BleAdvHeaderField_s
    {
        uint8_t pduType: 4;
        uint8_t rfu1:2;
        uint8_t txAddr:1;
        uint8_t rxAddr:1;
        uint8_t length:6;
        uint8_t rfu2:2;
    } Fields;
    uint8_t Serial[ 2 ];
}BleAdvHeaders_t;
BleAdvHeaders_t ble_header_adv;


int8_t SX1281_Init(SX1281_t *radio, SX1281_Params_t *param,SX1281_RadioMode_t mode) {
  if (radio==NULL) {
    return DEVICE_ERR;
  }
  radio->param=param;

  radio->param->radioMode = mode;
  
  SX1281_BSPInit() ;
  HAL_Delay( 500 );/* let DC/DC power ramp up */   
  Radio.Init( &Callbacks );
  
//  memset( &radio->rxBuffer, 0x00, BufferSize );
  
  #ifdef SX1281_VIEW
  printf( "\r\n" );
  printf( "============================================================\r\n" );
  printf( "              SX1281 Radio Initialization\r\n" );
  printf( "============================================================\r\n" );
  printf( "  Application Version : %s\r\n", FIRMWARE_VERSION );
  printf( "  Firmware Version    : 0x%04X\r\n", Radio.GetFirmwareVersion( ) );
  printf( "============================================================\r\n" );
  #endif //SX1281_VIEW

  /* Use the modulation and packet parameters from config (either from flash or defaults).
     This preserves user customizations and avoids overwriting detailed parameters. */
  
  /* 根据模式选择属性 */
  switch (mode) {
    case RADIOMODE_BLE:
        #ifdef SX1281_VIEW
        printf( "\r\n[*] Radio Mode: BLE (Bluetooth Low Energy)\r\n" );
        #endif //SX1281_VIEW
        radio->param->modulationParams.PacketType = PACKET_TYPE_BLE;
        radio->param->packetParams.PacketType = PACKET_TYPE_BLE;
      break;
    case RADIOMODE_LORA:
        #ifdef SX1281_VIEW
        printf( "\r\n[*] Radio Mode: LORA (Long Range)\r\n" );
        #endif //SX1281_VIEW
        radio->param->modulationParams.PacketType = PACKET_TYPE_LORA;
        radio->param->packetParams.PacketType = PACKET_TYPE_LORA;
      break;
    case RADIOMODE_GFSK:
        #ifdef SX1281_VIEW
        printf( "\r\n[*] Radio Mode: GFSK (Gaussian FSK)\r\n" );
        #endif //SX1281_VIEW
        radio->param->modulationParams.PacketType = PACKET_TYPE_GFSK;
        radio->param->packetParams.PacketType = PACKET_TYPE_GFSK;
      break;
    case RADIOMODE_FLRC:
        #ifdef SX1281_VIEW
        printf( "\r\n[*] Radio Mode: FLRC (Fast Long Range Communication)\r\n" );
        #endif //SX1281_VIEW
        radio->param->modulationParams.PacketType = PACKET_TYPE_FLRC;
        radio->param->packetParams.PacketType = PACKET_TYPE_FLRC;
      break;
    default:
        return DEVICE_ERR;
  }
  /* 设置属性 */
  Radio.SetStandby( STDBY_RC );
  Radio.SetPacketType( radio->param->modulationParams.PacketType );//包类型
  Radio.SetModulationParams( &radio->param->modulationParams );//调制属性
  Radio.SetPacketParams( &radio->param->packetParams );//包属性
  Radio.SetRfFrequency( radio->param->rfFrequency );//设置射频工作中心频率
  Radio.SetBufferBaseAddresses( 0x00, 0x00 );//缓冲区起始地址
  Radio.SetTxParams( radio->param->txOutputPower, radio->param->rampTime);//发送属性
  
  // 设置同步字 - 必须在SetPacketType之后设置
  if (radio->param->radioMode==RADIOMODE_GFSK) {
    Radio.SetSyncWord(1, radio->param->syncWord.gfsk.first); // 设置第一个同步字
    Radio.SetSyncWord(2, radio->param->syncWord.gfsk.second); // 设置第二个同步字
    Radio.SetSyncWord(3, radio->param->syncWord.gfsk.third); // 设置第三个同步字
  }
  if (radio->param->radioMode==RADIOMODE_FLRC) {
    Radio.SetSyncWord(1, radio->param->syncWord.flrc.first); // 设置第一个同步字
    Radio.SetSyncWord(2, radio->param->syncWord.flrc.second); // 设置第二个同步字
    Radio.SetSyncWord(3, radio->param->syncWord.flrc.third); // 设置第三个同步字
  }

  #ifdef SX1281_INTERRUP_MODE
  /* 中断模式 */
  Radio.SetInterruptMode(); 
  #endif
  #ifdef SX1281_POLLING_MODE
  /* 轮询模式 */
  Radio.SetPollingMode();
  #endif

  #ifdef SX1281_VIEW
  printf( "\r\n" );
  printf( "------------------------------------------------------------\r\n" );
  printf( "                  Configuration Summary\r\n" );
  printf( "------------------------------------------------------------\r\n" );
  printf( "  RF Frequency    : %llu Hz (%.1f MHz)\r\n", 
          (unsigned long long)radio->param->rfFrequency, radio->param->rfFrequency/1000000.0f );
  printf( "  TX Power        : %d dBm\r\n", 
          radio->param->txOutputPower );
  printf( "  Buffer Size     : %d bytes\r\n", 
          BUFFER_SIZE );
  
  /* Print modulation-specific parameters */
  if (radio->param->radioMode == RADIOMODE_LORA) {
    printf( "  LoRa SF         : %d\r\n", radio->param->modulationParams.Params.LoRa.SpreadingFactor );
    printf( "  LoRa BW         : %d\r\n", radio->param->modulationParams.Params.LoRa.Bandwidth );
    printf( "  LoRa CR         : %d\r\n", radio->param->modulationParams.Params.LoRa.CodingRate );
    printf( "  Preamble Len    : %d\r\n", radio->param->packetParams.Params.LoRa.PreambleLength );
    printf( "  Payload Len     : %d\r\n", radio->param->packetParams.Params.LoRa.PayloadLength );
  } else if (radio->param->radioMode == RADIOMODE_FLRC) {
    printf( "  FLRC BitRate/BW : %d\r\n", radio->param->modulationParams.Params.Flrc.BitrateBandwidth );
    printf( "  FLRC CR         : %d\r\n", radio->param->modulationParams.Params.Flrc.CodingRate );
    printf( "  Preamble Len    : %d\r\n", radio->param->packetParams.Params.Flrc.PreambleLength );
    printf( "  Payload Len     : %d\r\n", radio->param->packetParams.Params.Flrc.PayloadLength );
  }
  
  #ifdef SX1281_INTERRUP_MODE
  printf( "  Mode            : INTERRUPT\r\n" );
  #endif
  #ifdef SX1281_POLLING_MODE
  printf( "  Mode            : POLLING\r\n" );
  #endif
  printf( "------------------------------------------------------------\r\n" );
  printf( "\r\n[*] SX1281 Initialization Complete!\r\n\r\n" );
  #endif //SX1281_VIEW

  /* 还没搞懂这里是干啥的 */
  // if (radio->param->radioMode==RADIOMODE_BLE) {
  //   // only used in GENERIC and BLE mode
  //   Radio.SetSyncWord( 1, ( uint8_t[] ){ 0xDD, 0xA0, 0x96, 0x69, 0xDD } );
  //   Radio.WriteRegister(0x9c7, 0x55 );
  //   Radio.WriteRegister(0x9c8, 0x55 );
  //   Radio.WriteRegister(0x9c9, 0x55 );
  //   //Radio.WriteRegister( 0x9c5, 0x33 );
  //   Radio.SetBleAdvertizerAccessAddress( );
  //   Radio.SetWhiteningSeed( 0x33 );
  //   ble_header_adv.Fields.length =  2;
  //   ble_header_adv.Fields.pduType = 2;
  // }
  return DEVICE_OK;
}

int8_t SX1281_SetRFFrequency(SX1281_t *radio, uint32_t frequency) {
  if (radio==NULL) {
    return DEVICE_ERR;
  }
  Radio.SetStandby( STDBY_RC );
  Radio.SetPacketType( radio->param->modulationParams.PacketType );

  radio->param->rfFrequency=frequency;
  Radio.SetRfFrequency( radio->param->rfFrequency );//设置射频工作中心频率
  return DEVICE_OK;
}


/////蓝牙还没研究明白
void SetBLEAdvertisingPacket(SX1281_t *radio, uint8_t *data, uint8_t length) {
    // if (radio->param->radioMode != RADIOMODE_BLE) {
    //     printf("Error: Not in BLE mode\n");
    //     return;
    // }
    
    // // 检查数据长度是否符合BLE规范
    // if (length > 37) { // BLE广告PDU最大有效载荷为37字节
    //     printf("Error: BLE advertising data too long: %d bytes (max 37)\n", length);
    //     return;
    // }
    
    // // 根据BLE规范构建PDU报头
    // uint8_t pduHeader[2] = {0};
    
    // // 第一字节: PDU类型(4位) + RFU(2位) + TxAdd(1位) + RxAdd(1位)
    // // ADV_IND类型 = 0x0, TxAdd=1(随机地址), RxAdd=0
    // pduHeader[0] = (0x0 << 4) | (0x0 << 2) | (0x1 << 1) | (0x0 << 0);
    
    // // 第二字节: 长度(6位) + RFU(2位)
    // // 长度不包括报头本身，只包括有效载荷
    // pduHeader[1] = (length & 0x3F) | (0x0 << 6);
    
    // printf("PDU Header: 0x%02X 0x%02X\n", pduHeader[0], pduHeader[1]);
    // printf("Payload length: %d\n", length);
    
    // // 组合完整的PDU: 报头(2字节) + 有效载荷
    // uint8_t completePdu[2 + length];
    // completePdu[0] = pduHeader[0];
    // completePdu[1] = pduHeader[1];
    // memcpy(&completePdu[2], data, length);
    
    // // 设置BLE模式
    // Radio.SetStandby(STDBY_RC);
    // Radio.SetPacketType(PACKET_TYPE_BLE);
    
    // // 设置调制参数
    // ModulationParams_t modulationParams;
    // modulationParams.PacketType = PACKET_TYPE_BLE;
    // modulationParams.Params.Ble.BitrateBandwidth = GFS_BLE_BR_1_000_BW_1_2;
    // modulationParams.Params.Ble.ModulationIndex = GFS_BLE_MOD_IND_0_50;
    // modulationParams.Params.Ble.ModulationShaping = RADIO_MOD_SHAPING_BT_0_5;
    // Radio.SetModulationParams(&modulationParams);
    
    // // 设置包参数 - BLE模式下没有PayloadLength字段
    // PacketParams_t packetParams;
    // packetParams.PacketType = PACKET_TYPE_BLE;
    // packetParams.Params.Ble.BlePacketType = BLE_EYELONG_1_0;
    // packetParams.Params.Ble.ConnectionState = BLE_ADVERTISER;
    // packetParams.Params.Ble.CrcField = BLE_CRC_3B;
    // packetParams.Params.Ble.Whitening = RADIO_WHITENING_ON;
    // Radio.SetPacketParams(&packetParams);
    
    // // 设置频率 - BLE广告信道38: 2426000000 Hz
    // Radio.SetRfFrequency(radio->param->rfFrequency);
    
    // // 设置BLE特定参数
    // Radio.SetSyncWord(1, (uint8_t[]){0xDD, 0xA0, 0x96, 0x69, 0xDD});
    // Radio.SetBleAdvertizerAccessAddress();
    // Radio.SetWhiteningSeed(0x33);
    
    // // 写入寄存器配置
    // Radio.WriteRegister(0x9C7, 0x55);
    // Radio.WriteRegister(0x9C8, 0x55);
    // Radio.WriteRegister(0x9C9, 0x55);
    
    // // 设置中断参数并发送完整的PDU
    // uint16_t TxIrqMask = IRQ_TX_DONE | IRQ_RX_TX_TIMEOUT;
    // Radio.SetDioIrqParams(TxIrqMask, TxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE);
    
    // // 发送完整的PDU（报头+有效载荷）
    // Radio.SendPayload(completePdu, length + 2, (TickTime_t){RX_TIMEOUT_TICK_SIZE, TX_TIMEOUT_VALUE});
    
    // printf("BLE Advertising packet sent, total PDU length: %d\n", length + 2);
}


int8_t SX1281_SetRXSingle(SX1281_t *radio) {
  radio->appMode=APPMODE_RXSINGLE;
  radio->param->RadioRole=RadioRoleRX;
  Radio.SetDioIrqParams( RxIrqMask, RxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE );
  Radio.SetRx( ( TickTime_t ) { RX_TIMEOUT_TICK_SIZE, RX_TIMEOUT_VALUE } );
  return DEVICE_OK;
}

int8_t SX1281_SetRXSuccessive(SX1281_t *radio) {
  radio->appMode=APPMODE_RXSUCCESSIVE;
  radio->param->RadioRole=RadioRoleRX;
  Radio.SetDioIrqParams( RxIrqMask, RxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE );
  Radio.SetRx( ( TickTime_t ) { RX_TIMEOUT_TICK_SIZE, 0xFFFF } );
  return DEVICE_OK;
}

int8_t SX1281_SetTX (SX1281_t *radio,uint8_t *data,uint8_t datalength) {
  radio->appMode=APPMODE_TX;
  radio->param->RadioRole=RadioRoleTX;
  Radio.SetDioIrqParams( TxIrqMask, TxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE );
  Radio.SendPayload(data,datalength, ( TickTime_t ){ RX_TIMEOUT_TICK_SIZE, TX_TIMEOUT_VALUE });
  return DEVICE_OK;
}


int8_t SX1281_SetMode(SX1281_t *radio, SX1281_RadioMode_t mode) {
  if (radio==NULL) {
    return DEVICE_ERR;
  }
  Radio.SetStandby( STDBY_RC );
  Radio.SetPacketType( radio->param->modulationParams.PacketType );
  radio->param->radioMode = mode;
  switch (radio->param->radioMode) {
    case RADIOMODE_BLE:
      radio->param->modulationParams.PacketType = PACKET_TYPE_BLE;
      radio->param->packetParams.PacketType = PACKET_TYPE_BLE;
      Radio.SetPacketType( radio->param->modulationParams.PacketType );
      Radio.SetModulationParams( &radio->param->modulationParams );
      Radio.SetPacketParams( &radio->param->packetParams );
      break;
    case RADIOMODE_LORA:
      radio->param->modulationParams.PacketType = PACKET_TYPE_LORA;
      radio->param->packetParams.PacketType = PACKET_TYPE_LORA;
      Radio.SetPacketType( radio->param->modulationParams.PacketType );
      Radio.SetModulationParams( &radio->param->modulationParams );
      Radio.SetPacketParams( &radio->param->packetParams );
      break;
    case RADIOMODE_GFSK:
      radio->param->modulationParams.PacketType = PACKET_TYPE_GFSK;
      radio->param->packetParams.PacketType = PACKET_TYPE_LORA;
      Radio.SetPacketType( radio->param->modulationParams.PacketType );
      Radio.SetModulationParams( &radio->param->modulationParams );
      Radio.SetPacketParams( &radio->param->packetParams );
      break;
    case RADIOMODE_FLRC:
      radio->param->modulationParams.PacketType = PACKET_TYPE_FLRC;
      radio->param->packetParams.PacketType = PACKET_TYPE_LORA;
      Radio.SetPacketType( radio->param->modulationParams.PacketType );
      Radio.SetModulationParams( &radio->param->modulationParams );
      Radio.SetPacketParams( &radio->param->packetParams );
      break;
    default:
      return DEVICE_ERR;
  }

  return DEVICE_OK;
}

int8_t SX1281_SetBLEBaudrate(SX1281_t *radio, SX1281_BLEBaudrate_t baudrate) {
  if (radio==NULL) {
    return DEVICE_ERR;
  }
  radio->param->baudrate.ble=baudrate;
  Radio.SetStandby( STDBY_RC );

  /* Only apply preset if not USER_CUSTOM, otherwise preserve user's detailed parameters */
  if (baudrate != RF_BAUDRATE_BLE_USER_CUSTOM && baudrate < RF_BAUDRATE_BLE_USER_CUSTOM) {
    radio->param->modulationParams.Params.Ble.BitrateBandwidth 
    = bleConfigList[radio->param->baudrate.ble].BitrateBandwidth;
    radio->param->modulationParams.Params.Ble.ModulationIndex  
    = bleConfigList[radio->param->baudrate.ble].ModulationIndex;
    radio->param->modulationParams.Params.Ble.ModulationShaping 
    = bleConfigList[radio->param->baudrate.ble].ModulationShaping;
  }
  
  Radio.SetPacketType( radio->param->modulationParams.PacketType );
  Radio.SetModulationParams( &radio->param->modulationParams );

  return DEVICE_OK;
}

int8_t SX1281_SetLORABaudrate(SX1281_t *radio, SX1281_LORABaudrate_t baudrate) {
  if (radio==NULL) {
    return DEVICE_ERR;
  }
  radio->param->baudrate.lora=baudrate;
  Radio.SetStandby( STDBY_RC );

  radio->param->modulationParams.Params.LoRa.SpreadingFactor  
  = loraConfigList[radio->param->baudrate.lora].SpreadingFactor;
  radio->param->modulationParams.Params.LoRa.Bandwidth  
  = loraConfigList[radio->param->baudrate.lora].Bandwidth;
  radio->param->modulationParams.Params.LoRa.CodingRate
  = loraConfigList[radio->param->baudrate.lora].CodingRate;
  
  Radio.SetPacketType( radio->param->modulationParams.PacketType );
  Radio.SetModulationParams( &radio->param->modulationParams );

  return DEVICE_OK;
}

int8_t SX1281_SetGFSKBaudrate(SX1281_t *radio, SX1281_GFKSBaudrate_t baudrate) {
  if (radio==NULL) {
    return DEVICE_ERR;
  }
  radio->param->baudrate.gfks=baudrate;
  Radio.SetStandby( STDBY_RC );

  /* Only apply preset if not USER_CUSTOM, otherwise preserve user's detailed parameters */
  if (baudrate != RF_BAUDRATE_GFSK_USER_CUSTOM && baudrate < RF_BAUDRATE_GFSK_USER_CUSTOM) {
    radio->param->modulationParams.Params.Gfsk.BitrateBandwidth  
    = gfskConfigList[radio->param->baudrate.gfks].BitrateBandwidth;
    radio->param->modulationParams.Params.Gfsk.ModulationIndex  
    = gfskConfigList[radio->param->baudrate.gfks].ModulationIndex;
    radio->param->modulationParams.Params.Gfsk.ModulationShaping  
    = gfskConfigList[radio->param->baudrate.gfks].ModulationShaping;
  }
  
  Radio.SetPacketType( radio->param->modulationParams.PacketType );
  Radio.SetModulationParams( &radio->param->modulationParams );

  return DEVICE_OK;
}

int8_t SX1281_SetFLRCBaudrate(SX1281_t *radio, SX1281_FLRCBaudrate_t baudrate) {
  if (radio==NULL) {
    return DEVICE_ERR;
  }
  radio->param->baudrate.flrc=baudrate;
  Radio.SetStandby( STDBY_RC );

  /* Only apply preset if not USER_CUSTOM, otherwise preserve user's detailed parameters */
  if (baudrate != RF_BAUDRATE_FLRC_USER_CUSTOM && baudrate < RF_BAUDRATE_FLRC_USER_CUSTOM) {
    radio->param->modulationParams.Params.Flrc.BitrateBandwidth  
    = flrcConfigList[radio->param->baudrate.flrc].BitrateBandwidth;
    radio->param->modulationParams.Params.Flrc.CodingRate  
    = flrcConfigList[radio->param->baudrate.flrc].CodingRate;
    radio->param->modulationParams.Params.Flrc.ModulationShaping  
    = flrcConfigList[radio->param->baudrate.flrc].ModulationShaping;
  }
  
  Radio.SetPacketType( radio->param->modulationParams.PacketType );
  Radio.SetModulationParams( &radio->param->modulationParams );

  return DEVICE_OK;
}

int8_t SX1281_SetPayloadLength(SX1281_t *radio, uint8_t length) {
  if (radio==NULL) {
    return DEVICE_ERR;
  }
  if (length<0|length>255) {
    return DEVICE_ERR;
  }
  Radio.SetStandby( STDBY_RC );
  switch (radio->param->packetParams.PacketType) {
    case PACKET_TYPE_BLE:
    //蓝牙待更新
      break;
    case PACKET_TYPE_GFSK:  
    case PACKET_TYPE_LORA:
    case PACKET_TYPE_FLRC:
      radio->param->packetParams.Params.Flrc.PayloadLength=length;
      radio->param->packetParams.Params.Gfsk.PayloadLength=length;
      radio->param->packetParams.Params.LoRa.PayloadLength=length;
      Radio.SetPacketParams( &radio->param->packetParams );
      break;
    case PACKET_TYPE_RANGING:
    case PACKET_TYPE_NONE:
      break;
  }
  return DEVICE_OK;
}

/**
 * @brief 退出射频进入休眠
 * 
 */
int8_t SX1281_SetSleep(SX1281_t *radio) {
    if (radio == 0)
    {
        return DEVICE_ERR;
    }

    // SleepParams_t SleepParams;
    // SleepParams.DataBufferRetention = 1;
    // SleepParams.DataRamRetention = 1;
    // SleepParams.InstructionRamRetention = 1;
    // SleepParams.WakeUpRTC = 0;
    // // Radio.SetSleep( SleepParams );
    // Radio.SetStandby( STDBY_RC );
	return DEVICE_OK;
}

int8_t SX1281_GetState(SX1281_t *radio) {
  if (radio==NULL) {
    return DEVICE_ERR;
  }
  radio->appState=sx1281_state;
  return DEVICE_OK;
}

int8_t SX1281_Running(SX1281_t *radio) {
  SX1281ProcessIrqs();
  SX1281_GetState(radio);
//	HAL_Delay(5);
	return DEVICE_OK;
}

/* Callback function  -------------------------------------------------------- */
__attribute__((weak)) int8_t SX1281_Callback(SX1281_States_t source) {
  switch (source) {
    case RX_DONE:
        #ifdef SX1281_VIEW
        /* 打印状态 */
        printf( "\r\n[RX] >>> Packet Received <<<\r\n" );
        #endif
        /* 从缓冲区拿数据 */
        uint8_t radioRXSize = 0;
        uint8_t radioRXBuffer[BUFFER_SIZE]={0};
        Radio.GetPayload( radioRXBuffer, &radioRXSize, BUFFER_SIZE);
        radioRXBuffer[radioRXSize+1] = 0;
        #ifdef SX1281_VIEW
        printf( "[RX] Size: %d bytes\r\n", radioRXSize );
        #endif
        /* 重启接收 */
        //Radio.SetRx( ( TickTime_t ) { RX_TIMEOUT_TICK_SIZE, RX_TIMEOUT_VALUE } );
      break;

    case RX_TIMEOUT:
        #ifdef SX1281_VIEW
        /* 打印状态 */
        printf( "\r\n[RX] ... Timeout (Restarting RX)\r\n" );
        #endif
        //Radio.SetRx( ( TickTime_t ) { RX_TIMEOUT_TICK_SIZE, RX_TIMEOUT_VALUE } );
        Radio.SetRx( ( TickTime_t ) { RX_TIMEOUT_TICK_SIZE, 0xFFFF } );
      break;

    case RX_ERROR:
        #ifdef SX1281_VIEW
        /* 打印状态 */
        printf( "\r\n[RX] !!! ERROR - Reception Failed !!!\r\n" );
        #endif
//        SX1281_SetRXSuccessive(&radio);
      break;

    case TX_DONE:
        #ifdef SX1281_VIEW
        /* 打印状态 */
        printf( "\r\n[TX] <<< Packet Sent Successfully >>>\r\n" );
        #endif  
//        SX1281_SetTX(&radio,(uint8_t*)"hello",  5);
      break;

    case TX_TIMEOUT:
        #ifdef SX1281_VIEW
        /* 打印状态 */
        printf( "\r\n[TX] !!! TIMEOUT - Transmission Failed !!!\r\n" );
        #endif
//        SX1281_SetTX(&radio,(uint8_t*)"hello",  5);
        
      break;

    case LORA_CAD_DONE:
        #ifdef SX1281_VIEW
        /* 打印状态 */
        printf( "\r\n[CAD] Channel Activity Detected\r\n" );
        #endif
      break;
    default:
      break;
  }
  return 0;  
}

void OnTxDone( void ) {
  #ifdef SX1281_VIEW
  printf("[TX] TX_DONE\r\n");
  #endif
  sx1281_state = TX_DONE;
  SX1281_Callback(sx1281_state);
}

void OnRxDone( void ) {
  sx1281_state = RX_DONE;
  SX1281_Callback(sx1281_state);
}

void OnTxTimeout( void ) {
  #ifdef SX1281_VIEW
  printf("[TX] TX_TIMEOUT!\r\n");
  #endif
  sx1281_state = TX_TIMEOUT;
  SX1281_Callback(sx1281_state);
}

void OnRxTimeout( void ) {
  sx1281_state = RX_TIMEOUT;
  SX1281_Callback(sx1281_state);
}

void OnRxError( IrqErrorCode_t errorCode ) {
  sx1281_state = RX_ERROR;
  SX1281_Callback(sx1281_state);
}

void OnCadDone( bool channelActivityDetected ) {
  sx1281_state = LORA_CAD_DONE;
  SX1281_Callback(sx1281_state);
}

/* Direct modulation parameter setting functions */
int8_t SX1281_SetBLEModulationParams(SX1281_t *radio, RadioGfskBleBitrates_t bitrateBandwidth, 
                                     RadioGfskBleModIndexes_t modulationIndex, 
                                     RadioModShapings_t modulationShaping) {
  if (radio == NULL) {
    return DEVICE_ERR;
  }
  
  /* Switch to USER_CUSTOM mode to indicate user-defined parameters */
  radio->param->baudrate.ble = RF_BAUDRATE_BLE_USER_CUSTOM;
  
  /* Set the detailed parameters */
  radio->param->modulationParams.Params.Ble.BitrateBandwidth = bitrateBandwidth;
  radio->param->modulationParams.Params.Ble.ModulationIndex = modulationIndex;
  radio->param->modulationParams.Params.Ble.ModulationShaping = modulationShaping;
  
  /* Apply to hardware */
  Radio.SetStandby(STDBY_RC);
  Radio.SetPacketType(radio->param->modulationParams.PacketType);
  Radio.SetModulationParams(&radio->param->modulationParams);
  
  return DEVICE_OK;
}

int8_t SX1281_SetGFSKModulationParams(SX1281_t *radio, RadioGfskBleBitrates_t bitrateBandwidth, 
                                      RadioGfskBleModIndexes_t modulationIndex, 
                                      RadioModShapings_t modulationShaping) {
  if (radio == NULL) {
    return DEVICE_ERR;
  }
  
  /* Switch to USER_CUSTOM mode to indicate user-defined parameters */
  radio->param->baudrate.gfks = RF_BAUDRATE_GFSK_USER_CUSTOM;
  
  /* Set the detailed parameters */
  radio->param->modulationParams.Params.Gfsk.BitrateBandwidth = bitrateBandwidth;
  radio->param->modulationParams.Params.Gfsk.ModulationIndex = modulationIndex;
  radio->param->modulationParams.Params.Gfsk.ModulationShaping = modulationShaping;
  
  /* Apply to hardware */
  Radio.SetStandby(STDBY_RC);
  Radio.SetPacketType(radio->param->modulationParams.PacketType);
  Radio.SetModulationParams(&radio->param->modulationParams);
  
  return DEVICE_OK;
}

