From da02cf36b7265693bef7d982c6d46b372ed53693 Mon Sep 17 00:00:00 2001 From: chen <15335560115@163.com> Date: 星期三, 21 五月 2025 18:16:14 +0800 Subject: [PATCH] 将网关读取标签配置和修改标签配置调通,但下发修改配置只能改组id其他能改但不能保存,掉电后会初始化问题未解决 --- keil/include/src/Radio/radio.c | 1159 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 1,159 insertions(+), 0 deletions(-) diff --git a/keil/include/src/Radio/radio.c b/keil/include/src/Radio/radio.c new file mode 100644 index 0000000..908a874 --- /dev/null +++ b/keil/include/src/Radio/radio.c @@ -0,0 +1,1159 @@ +/*! + * \file radio.c + * + * \brief Radio driver API definition + * + * \copyright Revised BSD License, see section \ref LICENSE. + * + * \code + * ______ _ + * / _____) _ | | + * ( (____ _____ ____ _| |_ _____ ____| |__ + * \____ \| ___ | (_ _) ___ |/ ___) _ \ + * _____) ) ____| | | || |_| ____( (___| | | | + * (______/|_____)_|_|_| \__)_____)\____)_| |_| + * (C)2013-2017 Semtech + * + * \endcode + * + * \author Miguel Luis ( Semtech ) + * + * \author Gregory Cristian ( Semtech ) + */ +// #include "stm32l0xx_hal.h" +//#include "stm32l0xx_hal_conf.h" +//#include "main.h" +#include <math.h> +#include <string.h> +#include <stdbool.h> +//#include "stm32f0xx.h" +#include "delay.h" +//#include "dw_driver.h" +//#include "gpio.h" +//#include "spi.h" +#include "radio.h" +#include "sx126x.h" +#include "sx126x-board.h" +//#include "stm32l0xx_hal_gpio.h" +#include "lora_1268.h" + +/*! + * \brief Initializes the radio + * + * \param [IN] events Structure containing the driver callback functions + */ +void RadioInit( RadioEvents_t *events ); + +/*! + * Return current radio status + * + * \param status Radio status.[RF_IDLE, RF_RX_RUNNING, RF_TX_RUNNING] + */ +RadioState_t RadioGetStatus( void ); + +/*! + * \brief Configures the radio with the given modem + * + * \param [IN] modem Modem to be used [0: FSK, 1: LoRa] + */ +void RadioSetModem( RadioModems_t modem ); + +/*! + * \brief Sets the channel frequency + * + * \param [IN] freq Channel RF frequency + */ +void RadioSetChannel( uint32_t freq ); + +/*! + * \brief Checks if the channel is free for the given time + * + * \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa] + * \param [IN] freq Channel RF frequency + * \param [IN] rssiThresh RSSI threshold + * \param [IN] maxCarrierSenseTime Max time while the RSSI is measured + * + * \retval isFree [true: Channel is free, false: Channel is not free] + */ +bool RadioIsChannelFree( RadioModems_t modem, uint32_t freq, int16_t rssiThresh, uint32_t maxCarrierSenseTime ); + +/*! + * \brief Generates a 32 bits random value based on the RSSI readings + * + * \remark This function sets the radio in LoRa modem mode and disables + * all interrupts. + * After calling this function either Radio.SetRxConfig or + * Radio.SetTxConfig functions must be called. + * + * \retval randomValue 32 bits random value + */ +uint32_t RadioRandom( void ); + +/*! + * \brief Sets the reception parameters + * + * \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa] + * \param [IN] bandwidth Sets the bandwidth + * FSK : >= 2600 and <= 250000 Hz + * LoRa: [0: 125 kHz, 1: 250 kHz, + * 2: 500 kHz, 3: Reserved] + * \param [IN] datarate Sets the Datarate + * FSK : 600..300000 bits/s + * LoRa: [6: 64, 7: 128, 8: 256, 9: 512, + * 10: 1024, 11: 2048, 12: 4096 chips] + * \param [IN] coderate Sets the coding rate (LoRa only) + * FSK : N/A ( set to 0 ) + * LoRa: [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8] + * \param [IN] bandwidthAfc Sets the AFC Bandwidth (FSK only) + * FSK : >= 2600 and <= 250000 Hz + * LoRa: N/A ( set to 0 ) + * \param [IN] preambleLen Sets the Preamble length + * FSK : Number of bytes + * LoRa: Length in symbols (the hardware adds 4 more symbols) + * \param [IN] symbTimeout Sets the RxSingle timeout value + * FSK : timeout in number of bytes + * LoRa: timeout in symbols + * \param [IN] fixLen Fixed length packets [0: variable, 1: fixed] + * \param [IN] payloadLen Sets payload length when fixed length is used + * \param [IN] crcOn Enables/Disables the CRC [0: OFF, 1: ON] + * \param [IN] FreqHopOn Enables disables the intra-packet frequency hopping + * FSK : N/A ( set to 0 ) + * LoRa: [0: OFF, 1: ON] + * \param [IN] HopPeriod Number of symbols between each hop + * FSK : N/A ( set to 0 ) + * LoRa: Number of symbols + * \param [IN] iqInverted Inverts IQ signals (LoRa only) + * FSK : N/A ( set to 0 ) + * LoRa: [0: not inverted, 1: inverted] + * \param [IN] rxContinuous Sets the reception in continuous mode + * [false: single mode, true: continuous mode] + */ +void RadioSetRxConfig( RadioModems_t modem, uint32_t bandwidth, + uint32_t datarate, uint8_t coderate, + uint32_t bandwidthAfc, uint16_t preambleLen, + uint16_t symbTimeout, bool fixLen, + uint8_t payloadLen, + bool crcOn, bool FreqHopOn, uint8_t HopPeriod, + bool iqInverted, bool rxContinuous ); + +/*! + * \brief Sets the transmission parameters + * + * \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa] + * \param [IN] power Sets the output power [dBm] + * \param [IN] fdev Sets the frequency deviation (FSK only) + * FSK : [Hz] + * LoRa: 0 + * \param [IN] bandwidth Sets the bandwidth (LoRa only) + * FSK : 0 + * LoRa: [0: 125 kHz, 1: 250 kHz, + * 2: 500 kHz, 3: Reserved] + * \param [IN] datarate Sets the Datarate + * FSK : 600..300000 bits/s + * LoRa: [6: 64, 7: 128, 8: 256, 9: 512, + * 10: 1024, 11: 2048, 12: 4096 chips] + * \param [IN] coderate Sets the coding rate (LoRa only) + * FSK : N/A ( set to 0 ) + * LoRa: [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8] + * \param [IN] preambleLen Sets the preamble length + * FSK : Number of bytes + * LoRa: Length in symbols (the hardware adds 4 more symbols) + * \param [IN] fixLen Fixed length packets [0: variable, 1: fixed] + * \param [IN] crcOn Enables disables the CRC [0: OFF, 1: ON] + * \param [IN] FreqHopOn Enables disables the intra-packet frequency hopping + * FSK : N/A ( set to 0 ) + * LoRa: [0: OFF, 1: ON] + * \param [IN] HopPeriod Number of symbols between each hop + * FSK : N/A ( set to 0 ) + * LoRa: Number of symbols + * \param [IN] iqInverted Inverts IQ signals (LoRa only) + * FSK : N/A ( set to 0 ) + * LoRa: [0: not inverted, 1: inverted] + * \param [IN] timeout Transmission timeout [ms] + */ +void RadioSetTxConfig( RadioModems_t modem, int8_t power, uint32_t fdev, + uint32_t bandwidth, uint32_t datarate, + uint8_t coderate, uint16_t preambleLen, + bool fixLen, bool crcOn, bool FreqHopOn, + uint8_t HopPeriod, bool iqInverted, uint32_t timeout ); + +/*! + * \brief Checks if the given RF frequency is supported by the hardware + * + * \param [IN] frequency RF frequency to be checked + * \retval isSupported [true: supported, false: unsupported] + */ +bool RadioCheckRfFrequency( uint32_t frequency ); + +/*! + * \brief Computes the packet time on air in ms for the given payload + * + * \Remark Can only be called once SetRxConfig or SetTxConfig have been called + * + * \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa] + * \param [IN] pktLen Packet payload length + * + * \retval airTime Computed airTime (ms) for the given packet payload length + */ +uint32_t RadioTimeOnAir( RadioModems_t modem, uint8_t pktLen ); + +/*! + * \brief Sends the buffer of size. Prepares the packet to be sent and sets + * the radio in transmission + * + * \param [IN]: buffer Buffer pointer + * \param [IN]: size Buffer size + */ +void RadioSend( uint8_t *buffer, uint8_t size ); + +/*! + * \brief Sets the radio in sleep mode + */ +void RadioSleep( void ); + +/*! + * \brief Sets the radio in standby mode + */ +void RadioStandby( void ); + +/*! + * \brief Sets the radio in reception mode for the given time + * \param [IN] timeout Reception timeout [ms] + * [0: continuous, others timeout] + */ +void RadioRx( uint32_t timeout ); + +/*! + * \brief Start a Channel Activity Detection + */ +void RadioStartCad( void ); + +/*! + * \brief Sets the radio in continuous wave transmission mode + * + * \param [IN]: freq Channel RF frequency + * \param [IN]: power Sets the output power [dBm] + * \param [IN]: time Transmission mode timeout [s] + */ +void RadioSetTxContinuousWave( uint32_t freq, int8_t power, uint16_t time ); + +/*! + * \brief Reads the current RSSI value + * + * \retval rssiValue Current RSSI value in [dBm] + */ +int16_t RadioRssi( RadioModems_t modem ); + +/*! + * \brief Writes the radio register at the specified address + * + * \param [IN]: addr Register address + * \param [IN]: data New register value + */ +void RadioWrite( uint16_t addr, uint8_t data ); + +/*! + * \brief Reads the radio register at the specified address + * + * \param [IN]: addr Register address + * \retval data Register value + */ +uint8_t RadioRead( uint16_t addr ); + +/*! + * \brief Writes multiple radio registers starting at address + * + * \param [IN] addr First Radio register address + * \param [IN] buffer Buffer containing the new register's values + * \param [IN] size Number of registers to be written + */ +void RadioWriteBuffer( uint16_t addr, uint8_t *buffer, uint8_t size ); + +/*! + * \brief Reads multiple radio registers starting at address + * + * \param [IN] addr First Radio register address + * \param [OUT] buffer Buffer where to copy the registers data + * \param [IN] size Number of registers to be read + */ +void RadioReadBuffer( uint16_t addr, uint8_t *buffer, uint8_t size ); + +/*! + * \brief Sets the maximum payload length. + * + * \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa] + * \param [IN] max Maximum payload length in bytes + */ +void RadioSetMaxPayloadLength( RadioModems_t modem, uint8_t max ); + +/*! + * \brief Sets the network to public or private. Updates the sync byte. + * + * \remark Applies to LoRa modem only + * + * \param [IN] enable if true, it enables a public network + */ +void RadioSetPublicNetwork( bool enable ); + +/*! + * \brief Gets the time required for the board plus radio to get out of sleep.[ms] + * + * \retval time Radio plus board wakeup time in ms. + */ +uint32_t RadioGetWakeupTime( void ); + +/*! + * \brief Process radio irq + */ +void RadioIrqProcess( void ); + +/*! + * \brief Sets the radio in reception mode with Max LNA gain for the given time + * \param [IN] timeout Reception timeout [ms] + * [0: continuous, others timeout] + */ +void RadioRxBoosted( uint32_t timeout ); + +/*! + * \brief Sets the Rx duty cycle management parameters + * + * \param [in] rxTime Structure describing reception timeout value + * \param [in] sleepTime Structure describing sleep timeout value + */ +void RadioSetRxDutyCycle( uint32_t rxTime, uint32_t sleepTime ); + +/*! + * Radio driver structure initialization + */ +const struct Radio_s Radio = +{ + RadioInit, + RadioGetStatus, + RadioSetModem, + RadioSetChannel, + RadioIsChannelFree, + RadioRandom, + RadioSetRxConfig, + RadioSetTxConfig, + RadioCheckRfFrequency, + RadioTimeOnAir, + RadioSend, + RadioSleep, + RadioStandby, + RadioRx, + RadioStartCad, + RadioSetTxContinuousWave, + RadioRssi, + RadioWrite, + RadioRead, + RadioWriteBuffer, + RadioReadBuffer, + RadioSetMaxPayloadLength, + RadioSetPublicNetwork, + RadioGetWakeupTime, + RadioIrqProcess, + // Available on SX126x only + RadioRxBoosted, + RadioSetRxDutyCycle +}; + +/* + * Local types definition + */ + + + /*! + * FSK bandwidth definition + */ +typedef struct +{ + uint32_t bandwidth; + uint8_t RegValue; +}FskBandwidth_t; + +/*! + * Precomputed FSK bandwidth registers values + */ +const FskBandwidth_t FskBandwidths[] = +{ + { 4800 , 0x1F }, + { 5800 , 0x17 }, + { 7300 , 0x0F }, + { 9700 , 0x1E }, + { 11700 , 0x16 }, + { 14600 , 0x0E }, + { 19500 , 0x1D }, + { 23400 , 0x15 }, + { 29300 , 0x0D }, + { 39000 , 0x1C }, + { 46900 , 0x14 }, + { 58600 , 0x0C }, + { 78200 , 0x1B }, + { 93800 , 0x13 }, + { 117300, 0x0B }, + { 156200, 0x1A }, + { 187200, 0x12 }, + { 234300, 0x0A }, + { 312000, 0x19 }, + { 373600, 0x11 }, + { 467000, 0x09 }, + { 500000, 0x00 }, // Invalid Bandwidth +}; + +const RadioLoRaBandwidths_t Bandwidths[] = { LORA_BW_125, LORA_BW_250, LORA_BW_500 }; + +// SF12 SF11 SF10 SF9 SF8 SF7 +static double RadioLoRaSymbTime[3][6] = {{ 32.768, 16.384, 8.192, 4.096, 2.048, 1.024 }, // 125 KHz + { 16.384, 8.192, 4.096, 2.048, 1.024, 0.512 }, // 250 KHz + { 8.192, 4.096, 2.048, 1.024, 0.512, 0.256 }}; // 500 KHz + +uint8_t MaxPayloadLength = 0xFF; + +uint32_t TxTimeout = 0; +uint32_t RxTimeout = 0; + +bool RxContinuous = false; + + +PacketStatus_t RadioPktStatus; +uint8_t RadioRxPayload[255]; + +bool IrqFired = false; + +/* + * SX126x DIO IRQ callback functions prototype + */ + +/*! + * \brief DIO 0 IRQ callback + */ +void RadioOnDioIrq( void ); + +/*! + * \brief Tx timeout timer callback + */ +void RadioOnTxTimeoutIrq( void ); + +/*! + * \brief Rx timeout timer callback + */ +void RadioOnRxTimeoutIrq( void ); + +/* + * Private global variables + */ + + +/*! + * Holds the current network type for the radio + */ +typedef struct +{ + bool Previous; + bool Current; +}RadioPublicNetwork_t; + +static RadioPublicNetwork_t RadioPublicNetwork = { false }; + +/*! + * Radio callbacks variable + */ +static RadioEvents_t* RadioEvents; + +/* + * Public global variables + */ + +/*! + * Radio hardware and global parameters + */ +SX126x_t SX126x; + +/*! + * Tx and Rx timers + */ +//TimerEvent_t TxTimeoutTimer; +//TimerEvent_t RxTimeoutTimer; + +/*! + * Returns the known FSK bandwidth registers value + * + * \param [IN] bandwidth Bandwidth value in Hz + * \retval regValue Bandwidth register value. + */ +static uint8_t RadioGetFskBandwidthRegValue( uint32_t bandwidth ) +{ + uint8_t i; + + if( bandwidth == 0 ) + { + return( 0x1F ); + } + + for( i = 0; i < ( sizeof( FskBandwidths ) / sizeof( FskBandwidth_t ) ) - 1; i++ ) + { + if( ( bandwidth >= FskBandwidths[i].bandwidth ) && ( bandwidth < FskBandwidths[i + 1].bandwidth ) ) + { + return FskBandwidths[i+1].RegValue; + } + } + // ERROR: Value not found + while( 1 ); +} +uint8_t buf[2]; +void RadioInit( RadioEvents_t *events ) +{ + RadioEvents = events; + + SX126xInit( RadioOnDioIrq ); + SX126xSetStandby( STDBY_RC ); + SX126xSetRegulatorMode( USE_DCDC ); +// printf("Lora_Init2\r\n"); + SX126xSetBufferBaseAddress( 0x00, 0x00 ); + +// SX126xReadCommand( RADIO_SET_BUFFERBASEADDRESS, buf, 2 ); + SX126xSetTxParams( 0, RADIO_RAMP_200_US ); + SX126xSetDioIrqParams( IRQ_RADIO_ALL, IRQ_RADIO_ALL, IRQ_RADIO_NONE, IRQ_RADIO_NONE ); + + //Initialize driver timeout timers + //TimerInit( &TxTimeoutTimer, RadioOnTxTimeoutIrq ); + //TimerInit( &RxTimeoutTimer, RadioOnRxTimeoutIrq ); + + IrqFired = false; +} + +RadioState_t RadioGetStatus( void ) +{ + switch( SX126xGetOperatingMode( ) ) + { + case MODE_TX: + return RF_TX_RUNNING; + case MODE_RX: + return RF_RX_RUNNING; + case RF_CAD: + return RF_CAD; + default: + return RF_IDLE; + } +} + +void RadioSetModem( RadioModems_t modem ) +{ + switch( modem ) + { + default: + case MODEM_FSK: + SX126xSetPacketType( PACKET_TYPE_GFSK ); + // When switching to GFSK mode the LoRa SyncWord register value is reset + // Thus, we also reset the RadioPublicNetwork variable + RadioPublicNetwork.Current = false; + break; + case MODEM_LORA: + SX126xSetPacketType( PACKET_TYPE_LORA ); + // Public/Private network register is reset when switching modems + if( RadioPublicNetwork.Current != RadioPublicNetwork.Previous ) + { + RadioPublicNetwork.Current = RadioPublicNetwork.Previous; + RadioSetPublicNetwork( RadioPublicNetwork.Current ); + } + break; + } +} + +void RadioSetChannel( uint32_t freq ) +{ + SX126xSetRfFrequency( freq ); +} + +bool RadioIsChannelFree( RadioModems_t modem, uint32_t freq, int16_t rssiThresh, uint32_t maxCarrierSenseTime ) +{ + bool status = true; + // int16_t rssi = 0; + // uint32_t carrierSenseTime = 0; + + RadioSetModem( modem ); + + RadioSetChannel( freq ); + + RadioRx( 0 ); + + HAL_Delay_nMS( 1 ); + + //carrierSenseTime = TimerGetCurrentTime( ); + + + //Perform carrier sense for maxCarrierSenseTime +// while( TimerGetElapsedTime( carrierSenseTime ) < maxCarrierSenseTime ) +// { +// rssi = RadioRssi( modem ); +// +// if( rssi > rssiThresh ) +// { +// status = false; +// break; +// } +// } + RadioSleep( ); + return status; +} + +uint32_t RadioRandom( void ) +{ + uint8_t i; + uint32_t rnd = 0; + + /* + * Radio setup for random number generation + */ + // Set LoRa modem ON + RadioSetModem( MODEM_LORA ); + + // Set radio in continuous reception + SX126xSetRx( 0 ); + + for( i = 0; i < 32; i++ ) + { + HAL_Delay_nMS( 1 ); + // Unfiltered RSSI value reading. Only takes the LSB value + rnd |= ( ( uint32_t )SX126xGetRssiInst( ) & 0x01 ) << i; + } + + RadioSleep( ); + + return rnd; +} + +void RadioSetRxConfig( RadioModems_t modem, uint32_t bandwidth, + uint32_t datarate, uint8_t coderate, + uint32_t bandwidthAfc, uint16_t preambleLen, + uint16_t symbTimeout, bool fixLen, + uint8_t payloadLen, + bool crcOn, bool freqHopOn, uint8_t hopPeriod, + bool iqInverted, bool rxContinuous ) +{ + + RxContinuous = rxContinuous; + + if( fixLen == true ) + { + MaxPayloadLength = payloadLen; + } + else + { + MaxPayloadLength = 0xFF; + } + + switch( modem ) + { + case MODEM_FSK: + SX126xSetStopRxTimerOnPreambleDetect( false ); + SX126x.ModulationParams.PacketType = PACKET_TYPE_GFSK; + + SX126x.ModulationParams.Params.Gfsk.BitRate = datarate; + SX126x.ModulationParams.Params.Gfsk.ModulationShaping = MOD_SHAPING_G_BT_1; + SX126x.ModulationParams.Params.Gfsk.Bandwidth = RadioGetFskBandwidthRegValue( bandwidth ); + + SX126x.PacketParams.PacketType = PACKET_TYPE_GFSK; + SX126x.PacketParams.Params.Gfsk.PreambleLength = ( preambleLen << 3 ); // convert byte into bit + SX126x.PacketParams.Params.Gfsk.PreambleMinDetect = RADIO_PREAMBLE_DETECTOR_08_BITS; + SX126x.PacketParams.Params.Gfsk.SyncWordLength = 3 << 3; // convert byte into bit + SX126x.PacketParams.Params.Gfsk.AddrComp = RADIO_ADDRESSCOMP_FILT_OFF; + SX126x.PacketParams.Params.Gfsk.HeaderType = ( fixLen == true ) ? RADIO_PACKET_FIXED_LENGTH : RADIO_PACKET_VARIABLE_LENGTH; + SX126x.PacketParams.Params.Gfsk.PayloadLength = MaxPayloadLength; + if( crcOn == true ) + { + SX126x.PacketParams.Params.Gfsk.CrcLength = RADIO_CRC_2_BYTES_CCIT; + } + else + { + SX126x.PacketParams.Params.Gfsk.CrcLength = RADIO_CRC_OFF; + } + SX126x.PacketParams.Params.Gfsk.DcFree = RADIO_DC_FREE_OFF; + + RadioStandby( ); + RadioSetModem( ( SX126x.ModulationParams.PacketType == PACKET_TYPE_GFSK ) ? MODEM_FSK : MODEM_LORA ); + SX126xSetModulationParams( &SX126x.ModulationParams ); + SX126xSetPacketParams( &SX126x.PacketParams ); + SX126xSetSyncWord( ( uint8_t[] ){ 0xC1, 0x94, 0xC1, 0x00, 0x00, 0x00, 0x00, 0x00 } ); + SX126xSetWhiteningSeed( 0x01FF ); + + RxTimeout = ( uint32_t )( symbTimeout * ( ( 1.0 / ( double )datarate ) * 8.0 ) * 1000 ); + break; + + case MODEM_LORA: + SX126xSetStopRxTimerOnPreambleDetect( false ); + SX126xSetLoRaSymbNumTimeout( symbTimeout ); + SX126x.ModulationParams.PacketType = PACKET_TYPE_LORA; + SX126x.ModulationParams.Params.LoRa.SpreadingFactor = ( RadioLoRaSpreadingFactors_t )datarate; + SX126x.ModulationParams.Params.LoRa.Bandwidth = Bandwidths[bandwidth]; + SX126x.ModulationParams.Params.LoRa.CodingRate = ( RadioLoRaCodingRates_t )coderate; + + if( ( ( bandwidth == 0 ) && ( ( datarate == 11 ) || ( datarate == 12 ) ) ) || + ( ( bandwidth == 1 ) && ( datarate == 12 ) ) ) + { + SX126x.ModulationParams.Params.LoRa.LowDatarateOptimize = 0x01; + } + else + { + SX126x.ModulationParams.Params.LoRa.LowDatarateOptimize = 0x00; + } + + SX126x.PacketParams.PacketType = PACKET_TYPE_LORA; + + if( ( SX126x.ModulationParams.Params.LoRa.SpreadingFactor == LORA_SF5 ) || + ( SX126x.ModulationParams.Params.LoRa.SpreadingFactor == LORA_SF6 ) ) + { + if( preambleLen < 12 ) + { + SX126x.PacketParams.Params.LoRa.PreambleLength = 12; + } + else + { + SX126x.PacketParams.Params.LoRa.PreambleLength = preambleLen; + } + } + else + { + SX126x.PacketParams.Params.LoRa.PreambleLength = preambleLen; + } + + SX126x.PacketParams.Params.LoRa.HeaderType = ( RadioLoRaPacketLengthsMode_t )fixLen; + + SX126x.PacketParams.Params.LoRa.PayloadLength = MaxPayloadLength; + SX126x.PacketParams.Params.LoRa.CrcMode = ( RadioLoRaCrcModes_t )crcOn; + SX126x.PacketParams.Params.LoRa.InvertIQ = ( RadioLoRaIQModes_t )iqInverted; + + RadioSetModem( ( SX126x.ModulationParams.PacketType == PACKET_TYPE_GFSK ) ? MODEM_FSK : MODEM_LORA ); + SX126xSetModulationParams( &SX126x.ModulationParams ); + SX126xSetPacketParams( &SX126x.PacketParams ); + + // Timeout Max, Timeout handled directly in SetRx function + RxTimeout = 0xFFFF; + + break; + } +} + +void RadioSetTxConfig( RadioModems_t modem, int8_t power, uint32_t fdev, + uint32_t bandwidth, uint32_t datarate, + uint8_t coderate, uint16_t preambleLen, + bool fixLen, bool crcOn, bool freqHopOn, + uint8_t hopPeriod, bool iqInverted, uint32_t timeout ) +{ + + switch( modem ) + { + case MODEM_FSK: + SX126x.ModulationParams.PacketType = PACKET_TYPE_GFSK; + SX126x.ModulationParams.Params.Gfsk.BitRate = datarate; + + SX126x.ModulationParams.Params.Gfsk.ModulationShaping = MOD_SHAPING_G_BT_1; + SX126x.ModulationParams.Params.Gfsk.Bandwidth = RadioGetFskBandwidthRegValue( bandwidth ); + SX126x.ModulationParams.Params.Gfsk.Fdev = fdev; + + SX126x.PacketParams.PacketType = PACKET_TYPE_GFSK; + SX126x.PacketParams.Params.Gfsk.PreambleLength = ( preambleLen << 3 ); // convert byte into bit + SX126x.PacketParams.Params.Gfsk.PreambleMinDetect = RADIO_PREAMBLE_DETECTOR_08_BITS; + SX126x.PacketParams.Params.Gfsk.SyncWordLength = 3 << 3 ; // convert byte into bit + SX126x.PacketParams.Params.Gfsk.AddrComp = RADIO_ADDRESSCOMP_FILT_OFF; + SX126x.PacketParams.Params.Gfsk.HeaderType = ( fixLen == true ) ? RADIO_PACKET_FIXED_LENGTH : RADIO_PACKET_VARIABLE_LENGTH; + + if( crcOn == true ) + { + SX126x.PacketParams.Params.Gfsk.CrcLength = RADIO_CRC_2_BYTES_CCIT; + } + else + { + SX126x.PacketParams.Params.Gfsk.CrcLength = RADIO_CRC_OFF; + } + SX126x.PacketParams.Params.Gfsk.DcFree = RADIO_DC_FREEWHITENING; + + RadioStandby( ); + RadioSetModem( ( SX126x.ModulationParams.PacketType == PACKET_TYPE_GFSK ) ? MODEM_FSK : MODEM_LORA ); + SX126xSetModulationParams( &SX126x.ModulationParams ); + SX126xSetPacketParams( &SX126x.PacketParams ); + SX126xSetSyncWord( ( uint8_t[] ){ 0xC1, 0x94, 0xC1, 0x00, 0x00, 0x00, 0x00, 0x00 } ); + SX126xSetWhiteningSeed( 0x01FF ); + break; + + case MODEM_LORA: + SX126x.ModulationParams.PacketType = PACKET_TYPE_LORA; + SX126x.ModulationParams.Params.LoRa.SpreadingFactor = ( RadioLoRaSpreadingFactors_t ) datarate; + SX126x.ModulationParams.Params.LoRa.Bandwidth = Bandwidths[bandwidth]; + SX126x.ModulationParams.Params.LoRa.CodingRate= ( RadioLoRaCodingRates_t )coderate; + + if( ( ( bandwidth == 0 ) && ( ( datarate == 11 ) || ( datarate == 12 ) ) ) || + ( ( bandwidth == 1 ) && ( datarate == 12 ) ) ) + { + SX126x.ModulationParams.Params.LoRa.LowDatarateOptimize = 0x01; + } + else + { + SX126x.ModulationParams.Params.LoRa.LowDatarateOptimize = 0x00; + } + + SX126x.PacketParams.PacketType = PACKET_TYPE_LORA; + + if( ( SX126x.ModulationParams.Params.LoRa.SpreadingFactor == LORA_SF5 ) || + ( SX126x.ModulationParams.Params.LoRa.SpreadingFactor == LORA_SF6 ) ) + { + if( preambleLen < 12 ) + { + SX126x.PacketParams.Params.LoRa.PreambleLength = 12; + } + else + { + SX126x.PacketParams.Params.LoRa.PreambleLength = preambleLen; + } + } + else + { + SX126x.PacketParams.Params.LoRa.PreambleLength = preambleLen; + } + + SX126x.PacketParams.Params.LoRa.HeaderType = ( RadioLoRaPacketLengthsMode_t )fixLen; + SX126x.PacketParams.Params.LoRa.PayloadLength = MaxPayloadLength; + SX126x.PacketParams.Params.LoRa.CrcMode = ( RadioLoRaCrcModes_t )crcOn; + SX126x.PacketParams.Params.LoRa.InvertIQ = ( RadioLoRaIQModes_t )iqInverted; + + RadioStandby( ); + RadioSetModem( ( SX126x.ModulationParams.PacketType == PACKET_TYPE_GFSK ) ? MODEM_FSK : MODEM_LORA ); + SX126xSetModulationParams( &SX126x.ModulationParams ); + SX126xSetPacketParams( &SX126x.PacketParams ); + break; + } + SX126xSetRfTxPower( power ); + TxTimeout = timeout; +} + +bool RadioCheckRfFrequency( uint32_t frequency ) +{ + return true; +} + +uint32_t RadioTimeOnAir( RadioModems_t modem, uint8_t pktLen ) +{ + uint32_t airTime = 0; + + switch( modem ) + { + case MODEM_FSK: + { + airTime = rint( ( 8 * ( SX126x.PacketParams.Params.Gfsk.PreambleLength + + ( SX126x.PacketParams.Params.Gfsk.SyncWordLength >> 3 ) + + ( ( SX126x.PacketParams.Params.Gfsk.HeaderType == RADIO_PACKET_FIXED_LENGTH ) ? 0.0 : 1.0 ) + + pktLen + + ( ( SX126x.PacketParams.Params.Gfsk.CrcLength == RADIO_CRC_2_BYTES ) ? 2.0 : 0 ) ) / + SX126x.ModulationParams.Params.Gfsk.BitRate ) * 1e3 ); + } + break; + case MODEM_LORA: + { + double ts = RadioLoRaSymbTime[SX126x.ModulationParams.Params.LoRa.Bandwidth - 4][12 - SX126x.ModulationParams.Params.LoRa.SpreadingFactor]; + // time of preamble + double tPreamble = ( SX126x.PacketParams.Params.LoRa.PreambleLength + 4.25 ) * ts; + // Symbol length of payload and time + double tmp = ceil( ( 8 * pktLen - 4 * SX126x.ModulationParams.Params.LoRa.SpreadingFactor + + 28 + 16 * SX126x.PacketParams.Params.LoRa.CrcMode - + ( ( SX126x.PacketParams.Params.LoRa.HeaderType == LORA_PACKET_FIXED_LENGTH ) ? 20 : 0 ) ) / + ( double )( 4 * ( SX126x.ModulationParams.Params.LoRa.SpreadingFactor - + ( ( SX126x.ModulationParams.Params.LoRa.LowDatarateOptimize > 0 ) ? 2 : 0 ) ) ) ) * + ( ( SX126x.ModulationParams.Params.LoRa.CodingRate % 4 ) + 4 ); + double nPayload = 8 + ( ( tmp > 0 ) ? tmp : 0 ); + double tPayload = nPayload * ts; + // Time on air + double tOnAir = tPreamble + tPayload; + // return milli seconds + airTime = floor( tOnAir + 0.999 ); + } + break; + } + return airTime; +} + +void RadioSend( uint8_t *buffer, uint8_t size ) +{ + SX126xSetDioIrqParams( IRQ_TX_DONE | IRQ_RX_TX_TIMEOUT, + IRQ_TX_DONE | IRQ_RX_TX_TIMEOUT, + IRQ_RADIO_NONE, + IRQ_RADIO_NONE ); + + if( SX126xGetPacketType( ) == PACKET_TYPE_LORA ) + { + SX126x.PacketParams.Params.LoRa.PayloadLength = size; + } + else + { + SX126x.PacketParams.Params.Gfsk.PayloadLength = size; + } + SX126xSetPacketParams( &SX126x.PacketParams ); + + SX126xSendPayload( buffer, size, 0 ); +// TimerSetValue( &TxTimeoutTimer, TxTimeout ); +// TimerStart( &TxTimeoutTimer ); +} + +void RadioSleep( void ) +{ + SleepParams_t params = { 0 }; + + params.Fields.WarmStart = 1; + SX126xSetSleep( params ); + + HAL_Delay_nMS( 2 ); +} + +void RadioStandby( void ) +{ + SX126xSetStandby( STDBY_RC ); +} + +void RadioRx( uint32_t timeout ) +{ + SX126xSetDioIrqParams( IRQ_RADIO_ALL, //IRQ_RX_DONE | IRQ_RX_TX_TIMEOUT, +// IRQ_RX_DONE|IRQ_RX_TX_TIMEOUT, + IRQ_RX_DONE| IRQ_RX_TX_TIMEOUT, + IRQ_RADIO_NONE, + IRQ_RADIO_NONE ); + + + if( RxContinuous == true ) + { + SX126xSetRx( 0xFFFFFF ); // Rx Continuous + } + else + { + SX126xSetRx( timeout << 6 ); + } +} + +void RadioRxBoosted( uint32_t timeout ) +{ + SX126xSetDioIrqParams( IRQ_RADIO_ALL, //IRQ_RX_DONE | IRQ_RX_TX_TIMEOUT, + IRQ_RADIO_ALL, //IRQ_RX_DONE | IRQ_RX_TX_TIMEOUT, + IRQ_RADIO_NONE, + IRQ_RADIO_NONE ); + + + if( RxContinuous == true ) + { + SX126xSetRxBoosted( 0xFFFFFF ); // Rx Continuous + } + else + { + SX126xSetRxBoosted( timeout << 6 ); + } +} + +void RadioSetRxDutyCycle( uint32_t rxTime, uint32_t sleepTime ) +{ + SX126xSetRxDutyCycle( rxTime, sleepTime ); +} + +void RadioStartCad( void ) +{ + SX126xSetCad( ); +} + +void RadioTx( uint32_t timeout ) +{ + SX126xSetTx( timeout << 6 ); +} + +void RadioSetTxContinuousWave( uint32_t freq, int8_t power, uint16_t time ) +{ + SX126xSetRfFrequency( freq ); + SX126xSetRfTxPower( power ); + SX126xSetTxContinuousWave( ); + +// TimerSetValue( &RxTimeoutTimer, time * 1e3 ); +// TimerStart( &RxTimeoutTimer ); +} + +int16_t RadioRssi( RadioModems_t modem ) +{ + return SX126xGetRssiInst( ); +} + +void RadioWrite( uint16_t addr, uint8_t data ) +{ + SX126xWriteRegister( addr, data ); +} + +uint8_t RadioRead( uint16_t addr ) +{ + return SX126xReadRegister( addr ); +} + +void RadioWriteBuffer( uint16_t addr, uint8_t *buffer, uint8_t size ) +{ + SX126xWriteRegisters( addr, buffer, size ); +} + +void RadioReadBuffer( uint16_t addr, uint8_t *buffer, uint8_t size ) +{ + SX126xReadRegisters( addr, buffer, size ); +} + +void RadioWriteFifo( uint8_t *buffer, uint8_t size ) +{ + SX126xWriteBuffer( 0, buffer, size ); +} + +void RadioReadFifo( uint8_t *buffer, uint8_t size ) +{ + SX126xReadBuffer( 0, buffer, size ); +} + +void RadioSetMaxPayloadLength( RadioModems_t modem, uint8_t max ) +{ + if( modem == MODEM_LORA ) + { + SX126x.PacketParams.Params.LoRa.PayloadLength = MaxPayloadLength = max; + SX126xSetPacketParams( &SX126x.PacketParams ); + } + else + { + if( SX126x.PacketParams.Params.Gfsk.HeaderType == RADIO_PACKET_VARIABLE_LENGTH ) + { + SX126x.PacketParams.Params.Gfsk.PayloadLength = MaxPayloadLength = max; + SX126xSetPacketParams( &SX126x.PacketParams ); + } + } +} + +void RadioSetPublicNetwork( bool enable ) +{ + RadioPublicNetwork.Current = RadioPublicNetwork.Previous = enable; + + RadioSetModem( MODEM_LORA ); + if( enable == true ) + { + // Change LoRa modem SyncWord + SX126xWriteRegister( REG_LR_SYNCWORD, ( LORA_MAC_PUBLIC_SYNCWORD >> 8 ) & 0xFF ); + SX126xWriteRegister( REG_LR_SYNCWORD + 1, LORA_MAC_PUBLIC_SYNCWORD & 0xFF ); + } + else + { + // Change LoRa modem SyncWord + SX126xWriteRegister( REG_LR_SYNCWORD, ( LORA_MAC_PRIVATE_SYNCWORD >> 8 ) & 0xFF ); + SX126xWriteRegister( REG_LR_SYNCWORD + 1, LORA_MAC_PRIVATE_SYNCWORD & 0xFF ); + } +} + +uint32_t RadioGetWakeupTime( void ) +{ + return( RADIO_TCXO_SETUP_TIME + RADIO_WAKEUP_TIME ); +} + +void RadioOnTxTimeoutIrq( void ) +{ + if( ( RadioEvents != NULL ) && ( RadioEvents->TxTimeout != NULL ) ) + { + RadioEvents->TxTimeout( ); + } +} + +void RadioOnRxTimeoutIrq( void ) +{ + if( ( RadioEvents != NULL ) && ( RadioEvents->RxTimeout != NULL ) ) + { + RadioEvents->RxTimeout( ); + } +} + +void RadioOnDioIrq( void ) +{ + IrqFired = true; +} + +void RadioIrqProcess( void ) +{ + // if( IrqFired == true ) + if(gpio_pin_get_val(LORA_IRQ)) + { + IrqFired = false; + + uint16_t irqRegs = SX126xGetIrqStatus( ); + SX126xClearIrqStatus( IRQ_RADIO_ALL ); + + if( ( irqRegs & IRQ_TX_DONE ) == IRQ_TX_DONE ) + { + + if( ( RadioEvents != NULL ) && ( RadioEvents->TxDone != NULL ) ) + { + RadioEvents->TxDone( ); + } + } + + if( ( irqRegs & IRQ_RX_DONE ) == IRQ_RX_DONE ) + { + uint8_t size; + + SX126xGetPayload( RadioRxPayload, &size , 255 ); + SX126xGetPacketStatus( &RadioPktStatus ); + if( ( RadioEvents != NULL ) && ( RadioEvents->RxDone != NULL ) ) + { + RadioEvents->RxDone( RadioRxPayload, size, RadioPktStatus.Params.LoRa.RssiPkt, RadioPktStatus.Params.LoRa.SnrPkt ); + } + } + + if( ( irqRegs & IRQ_CRC_ERROR ) == IRQ_CRC_ERROR ) + { + if( ( RadioEvents != NULL ) && ( RadioEvents->RxError ) ) + { + RadioEvents->RxError( ); + } + } + + if( ( irqRegs & IRQ_CAD_DONE ) == IRQ_CAD_DONE ) + { + if( ( RadioEvents != NULL ) && ( RadioEvents->CadDone != NULL ) ) + { + RadioEvents->CadDone( ( ( irqRegs & IRQ_CAD_ACTIVITY_DETECTED ) == IRQ_CAD_ACTIVITY_DETECTED ) ); + } + } + + if( ( irqRegs & IRQ_RX_TX_TIMEOUT ) == IRQ_RX_TX_TIMEOUT ) + { + if( SX126xGetOperatingMode( ) == MODE_TX ) + { + if( ( RadioEvents != NULL ) && ( RadioEvents->TxTimeout != NULL ) ) + { + RadioEvents->TxTimeout( ); + } + } + else if( SX126xGetOperatingMode( ) == MODE_RX ) + { + + if( ( RadioEvents != NULL ) && ( RadioEvents->RxTimeout != NULL ) ) + { + RadioEvents->RxTimeout( ); + } + } + } + + if( ( irqRegs & IRQ_PREAMBLE_DETECTED ) == IRQ_PREAMBLE_DETECTED ) + { + //__NOP( ); + } + + if( ( irqRegs & IRQ_SYNCWORD_VALID ) == IRQ_SYNCWORD_VALID ) + { + //__NOP( ); + } + + if( ( irqRegs & IRQ_HEADER_VALID ) == IRQ_HEADER_VALID ) + { + //__NOP( ); + } + + if( ( irqRegs & IRQ_HEADER_ERROR ) == IRQ_HEADER_ERROR ) + { + if( ( RadioEvents != NULL ) && ( RadioEvents->RxTimeout != NULL ) ) + { + RadioEvents->RxTimeout( ); + } + } + } +} -- Gitblit v1.9.3