Version FC
Dependencies: DmTftLibrary eeprom SX1280Lib filesystem mbed
Fork of MSNV2-Terminal_V1-5 by
Diff: Radio.cpp
- Revision:
- 41:5a436163dddf
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Radio.cpp Mon Oct 22 09:37:50 2018 +0000 @@ -0,0 +1,436 @@ +/* + * MISNet + * + * TERMINAL Radio module + * + * Created on: September 19, 2018 Author: Francis CHATAIN + * + */ + +// ================================================================= INCLUDES + +#include "mbed.h" +#include "main.h" +#include "Radio.h" +#include "sx1280-hal.h" +#include <string.h> + + +// ================================================================= VARIABLE & DEFINE + +extern "C"{ + int _getpid () { return -1;} + int _kill (int pid, int sig) { return -1; } + extern int _write () ; //{return -1;} +} + +//DigitalOut ledReceive (PA_8) ; +//DigitalOut ledSend (PB_13) ; +DigitalOut ledReceive (A5) ; +DigitalOut ledSend (A4) ; + + +/****************************************************************************** + * Declaration of RADIO variables and function + *****************************************************************************/ + +// FEM TxEN:PB3 RxEN:PB9 +//DigitalOut femTx (PB_3); +//DigitalOut femRx (PB_9); + +#define BUFFER_SIZE 100 +uint8_t BufferSize = BUFFER_SIZE; +uint8_t Buffer[BUFFER_SIZE]; + +int8_t RssiValue = 0 ; +int8_t SnrValue = 0 ; + +typedef enum { APP_IDLE=0, APP_LOWPOWER, APP_RX, APP_RX_TIMEOUT, APP_RX_ERROR, APP_TX, APP_TX_TIMEOUT,} AppStates_t; +AppStates_t AppState = APP_LOWPOWER ; + +ModulationParams_t ModulationParams ; +ModulationParams_t ModulationParamsEmitter ; +ModulationParams_t ModulationParamsReceiver; + +PacketParams_t PacketParamsReceiver ; +PacketStatus_t PacketStatusReceiver ; + +PacketParams_t PacketParamsEmitter ; + + +// Radio Callback event +void OnTxDone (void) { AppState = APP_TX ; } +void OnRxDone (void) { AppState = APP_RX ; } +void OnTxTimeout (void) { AppState = APP_TX_TIMEOUT ; } +void OnRxTimeout (void) { AppState = APP_RX_TIMEOUT ; } +void OnRxError (IrqErrorCode_t errorCode) { AppState = APP_RX_ERROR ; } +void OnRangingDone (IrqRangingCode_t val) { } +void OnCadDone (bool channelActivityDetected){} + +RadioCallbacks_t callbacks ={ + &OnTxDone , &OnRxDone , // tx / rx Done + NULL , NULL , // syncWordDone headerDone + &OnTxTimeout , &OnRxTimeout , // txTimeout rxTimeout + &OnRxError , // rxError + NULL , NULL , // rangingDone / cadDone +}; + +// Timeout callback +#define TX_TIMEOUT_VALUE 100 // ms +#define RX_TIMEOUT_VALUE 0x00000000 // or 100 (ms) +#define RX_TIMEOUT_TICK_SIZE RADIO_TICK_SIZE_1000_US + +uint16_t RxIrqMask = IRQ_RX_DONE | IRQ_RX_TX_TIMEOUT ; +uint16_t TxIrqMask = IRQ_TX_DONE | IRQ_RX_TX_TIMEOUT ; + + +int8_t rssi=0, snr=0; + +// SX1280 MOSI:PA7 MISO:PA6 CLK:PA5 CS:PA4 BSY:PB7 DIO1:PB6 DIO2:PB5 DIO3:PB4 RST:PB8 +// SX1280Hal Radio (PA_7, PA_6, PA_5, PA_4, PB_7, PB_6, PB_5, PB_4, PB_8, &callbacks);//mosi miso clk cs bsy dio1 dio2 dio3 rst [DONGLE] +SX1280Hal Radio ( D11 , D12 , D13 , D7 , D3 , D5 , NC , NC , A0 , &callbacks ); // [NUCLEO] + +//Radio Factory Parameter Sender and Receiver only diff the Central Frequency emetter are shited by 800 Mhz +uint8_t _modulation = PACKET_TYPE_LORA; +int _spreadingFactor = 2 ; +int _bandWidth = 1 ; +int _codingRate = 0 ; +unsigned long _frequencySend = 2400000000UL ; +unsigned long _frequencyReceive = 2400000000UL ; +int _outputPower = 13 ; // -18 to +13 dBm +int _size = 10 ; + +int _iq = 1 ; +int _crc = 0 ; +uint8_t _ar[] = { 0xDD, 0xA0, 0x96, 0x69, 0xDD } ; // only used in GENERIC and BLE mode +uint8_t _crcSeedLocal[3] = { 0x00, 0x45, 0x67 } ; // only used in GFSK, FLRC + + +// Futur use with FLRC modulation +//int _mode = 4 ; +//int _modeShape = 1 ; +//int _modeIndex = 2 ; +//int _whitening = 1 ; +//int _bitrateBandwidth = 12 ; + +// ============================================================================================ Declaration Internal function + +RadioLoRaCodingRates_t returnCrLORA (int index) ; +RadioLoRaSpreadingFactors_t returnSfLORA (int index) ; +RadioLoRaBandwidths_t returnBwLORA (int index) ; + +void setFemTxRx (bool tx) ; // only if FEM HW + +/* Evolution FLRC + * RadioCrcTypes_t returnCrcLen (int index) ; + * RadioFlrcBitrates_t returnBrbwFLRC (int index) ; + * RadioFlrcCodingRates_t returnCrFLRC (int index) ; + * RadioModShapings_t returnMs (int index) ; + */ + +// ============================================================================================ EXTERNAL FUNCTION + + +// ============================================================================================ Radio Self Test + +bool radioSelfTest (uint16_t *rev) { + Radio.Init(); + *rev = Radio.GetFirmwareVersion () ; + // printf("*** RAD_ *** Selftest : Firmware R%u\r\n", rev); + wait(0.2); + //printf((rev==0xffff?"Self test FAIL\r\n":"Self test PASS\r\n")); + if (*rev==0xffff) return false ; + else return true ; +} + +// ============================================================================================ Radio Initialisation + + +void radioInitReceiver (RadioParameter radioParameter ) { + _modulation = radioParameter.modulation ; + _spreadingFactor = radioParameter.spreadingFactor ; + _bandWidth = radioParameter.bandWidth ; + _codingRate = radioParameter.codingRate ; + _frequencyReceive = radioParameter.frequency ; + + if( _modulation == PACKET_TYPE_LORA ) { + ModulationParamsReceiver.PacketType = PACKET_TYPE_LORA; + ModulationParamsReceiver.Params.LoRa.SpreadingFactor = returnSfLORA (_spreadingFactor) ; + ModulationParamsReceiver.Params.LoRa.Bandwidth = returnBwLORA (_bandWidth) ; + ModulationParamsReceiver.Params.LoRa.CodingRate = returnCrLORA (_codingRate) ; + PacketParamsReceiver.PacketType = PACKET_TYPE_LORA; + PacketParamsReceiver.Params.LoRa.PreambleLength = 0x08; + PacketParamsReceiver.Params.LoRa.HeaderType = LORA_PACKET_VARIABLE_LENGTH; + PacketParamsReceiver.Params.LoRa.PayloadLength = 7 ; + PacketParamsReceiver.Params.LoRa.Crc = _crc==1?LORA_CRC_ON:LORA_CRC_OFF; + PacketParamsReceiver.Params.LoRa.InvertIQ = _iq==1?LORA_IQ_INVERTED:LORA_IQ_NORMAL; + //Eeprom.EepromData.DemoSettings.PayloadLength = PacketParams.Params.LoRa.PayloadLength; + } +} + +void radioInitEmitter (RadioParameter radioParameter ) { + _modulation = radioParameter.modulation ; + _spreadingFactor = radioParameter.spreadingFactor ; + _bandWidth = radioParameter.bandWidth ; + _codingRate = radioParameter.codingRate ; + _size = radioParameter.size ; + _frequencySend = radioParameter.frequency ; + + if( _modulation == PACKET_TYPE_LORA ) { + ModulationParamsEmitter.PacketType = PACKET_TYPE_LORA ; + ModulationParamsEmitter.Params.LoRa.SpreadingFactor = returnSfLORA (_spreadingFactor) ; + ModulationParamsEmitter.Params.LoRa.Bandwidth = returnBwLORA (_bandWidth) ; + ModulationParamsEmitter.Params.LoRa.CodingRate = returnCrLORA (_codingRate) ; + PacketParamsEmitter.PacketType = PACKET_TYPE_LORA ; + PacketParamsEmitter.Params.LoRa.PreambleLength = 0x08 ; + PacketParamsEmitter.Params.LoRa.HeaderType = LORA_PACKET_VARIABLE_LENGTH ; + PacketParamsEmitter.Params.LoRa.PayloadLength = _size ; + PacketParamsEmitter.Params.LoRa.Crc = _crc==1?LORA_CRC_ON:LORA_CRC_OFF ; + PacketParamsEmitter.Params.LoRa.InvertIQ = _iq==1?LORA_IQ_INVERTED:LORA_IQ_NORMAL; + //Eeprom.EepromData.DemoSettings.PayloadLength = PacketParams.Params.LoRa.PayloadLength; + } +} + + +void radioInitRadio () { + Radio.SetStandby ( STDBY_RC ) ; + Radio.SetCrcSeed ( _crcSeedLocal ) ; + Radio.SetCrcPolynomial ( 0x0123 ) ; + Radio.SetPollingMode ( ) ; + Radio.SetBufferBaseAddresses ( 0x00, 0x00 ) ; + Radio.SetSyncWord ( 1, _ar ) ; +} + +void radioStartReceive (RadioParameter radioParameter) { + _frequencyReceive = radioParameter.frequency ; + _outputPower = radioParameter.outputPower ; + +// setFemTxRx (0) ; + ledSend = 0 ; + ledReceive = 0 ; + + Radio.SetPacketType ( ModulationParamsReceiver.PacketType ) ; + Radio.SetModulationParams ( &ModulationParamsReceiver ) ; + Radio.SetPacketParams ( &PacketParamsReceiver ) ; + Radio.SetRfFrequency ( _frequencyReceive ) ; + Radio.SetDioIrqParams ( RxIrqMask, RxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE ) ; + Radio.SetRx ( ( TickTime_t ) { RX_TIMEOUT_TICK_SIZE, RX_TIMEOUT_VALUE } ) ; + + AppState = APP_LOWPOWER ; + memset ( &Buffer , 0x00, BufferSize ) ; +} + + +void radioSend (RadioParameter radioParameter, uint8_t *frame, uint8_t len) { + _frequencySend = radioParameter.frequency ; + _outputPower = radioParameter.outputPower ; + + ledSend = 1 ; + ledReceive = 0 ; +// setFemTxRx(1); + + Radio.SetPacketType ( ModulationParamsEmitter.PacketType ) ; + Radio.SetModulationParams ( &ModulationParamsEmitter ) ; + Radio.SetPacketParams ( &PacketParamsEmitter ) ; + Radio.SetRfFrequency ( _frequencySend ) ; + Radio.SetTxParams ( _outputPower, RADIO_RAMP_20_US ) ; + Radio.SetDioIrqParams ( TxIrqMask, TxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE ); + Radio.SendPayload ( frame, len, ( TickTime_t ){ RX_TIMEOUT_TICK_SIZE, TX_TIMEOUT_VALUE } ); +} + +// ============================================================================================ Radio Handler +bool radioHandler(uint8_t *frame, uint8_t *len, int8_t *rssi, int8_t *snr){ + + bool event = false ; + Radio.ProcessIrqs(); + switch( AppState ) { + case APP_RX: + printf ("*** RADIO *** radioHandler APP RX \r\n"); + AppState = APP_LOWPOWER; + memset ( &Buffer , 0, BUFFER_SIZE ) ; + ledReceive = !ledReceive; + Radio.GetPayload( Buffer, len, BUFFER_SIZE ); + //cdc2->printf ("APP-RX Buffer = %s\r\n", Buffer); + //showRssiSnr () ; + Radio.GetPacketStatus(&PacketStatusReceiver); + *rssi = PacketStatusReceiver.LoRa.RssiPkt; + *snr = PacketStatusReceiver.LoRa.SnrPkt; + memcpy (frame, Buffer, *len) ; + event = true ; + //printBytes (Buffer, 30) ; + setFemTxRx(0); + Radio.SetDioIrqParams( RxIrqMask, RxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE ); + Radio.SetRx( ( TickTime_t ) { RX_TIMEOUT_TICK_SIZE, RX_TIMEOUT_VALUE } ); + ledReceive = !ledReceive; + break; + + case APP_TX: + printf ("*** RADIO *** radioHandler APP TX \r\n"); + AppState = APP_LOWPOWER; + //cdc2->printf ("APP-TX \r\n"); + setFemTxRx(0); // if fem + Radio.SetPacketType ( ModulationParamsReceiver.PacketType ) ; + Radio.SetModulationParams ( &ModulationParamsReceiver ) ; + Radio.SetPacketParams ( &PacketParamsReceiver ) ; + Radio.SetRfFrequency ( _frequencyReceive ) ; + + Radio.SetDioIrqParams( RxIrqMask, RxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE ); + Radio.SetRx( ( TickTime_t ) { RX_TIMEOUT_TICK_SIZE, RX_TIMEOUT_VALUE } ); + ledSend = 0 ; + break; + + case APP_RX_TIMEOUT: + printf ("*** RADIO *** radioHandler APP RX Timeout \r\n"); + AppState = APP_LOWPOWER; + setFemTxRx(0); + Radio.SetDioIrqParams( RxIrqMask, RxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE ); + Radio.SetRx( ( TickTime_t ) { RX_TIMEOUT_TICK_SIZE, RX_TIMEOUT_VALUE } ); + break; + + case APP_RX_ERROR: + AppState = APP_LOWPOWER; + break; + + case APP_TX_TIMEOUT: + printf ("*** RADIO *** radioHandler APP TX Timeout \r\n"); + AppState = APP_LOWPOWER; + //cdc2->printf ("APP-TX \r\n"); + setFemTxRx(0); + Radio.SetPacketType ( ModulationParamsReceiver.PacketType ) ; + Radio.SetModulationParams ( &ModulationParamsReceiver ) ; + Radio.SetPacketParams ( &PacketParamsReceiver ) ; + Radio.SetRfFrequency ( _frequencyReceive ) ; + + Radio.SetDioIrqParams( RxIrqMask, RxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE ); + Radio.SetRx( ( TickTime_t ) { RX_TIMEOUT_TICK_SIZE, RX_TIMEOUT_VALUE } ); + ledSend = 0 ; + break; + + case APP_LOWPOWER: + break; + + default: + // Set low power + break; + } + return event ; +} + + + + +// ====================================================================================================== INTERNAL FUNCTION + +RadioLoRaCodingRates_t returnCrLORA (int index) { + // coding rate for LoRa + switch(index){ + case 0: return LORA_CR_4_5; + case 1: return LORA_CR_4_6; + case 2: return LORA_CR_4_7; + case 3: return LORA_CR_4_8; + case 4: return LORA_CR_LI_4_5; + case 5: return LORA_CR_LI_4_6; + case 6: return LORA_CR_LI_4_7; + default : return LORA_CR_4_5; + } +} + + +// SF for LoRa +RadioLoRaSpreadingFactors_t returnSfLORA(int index) { + switch(index){ + case 0: return LORA_SF5 ; + case 1: return LORA_SF6 ; + case 2: return LORA_SF7 ; + case 3: return LORA_SF8 ; + case 4: return LORA_SF9 ; + case 5: return LORA_SF10; + case 6: return LORA_SF11; + case 7: return LORA_SF12; + default : return LORA_SF7 ; + } +} +RadioModShapings_t returnMs(int index){ + // shaping for FLRC GFSK and BLE + switch(index){ + case 0: return RADIO_MOD_SHAPING_BT_OFF ; + case 1: return RADIO_MOD_SHAPING_BT_1_0 ; + case 2: return RADIO_MOD_SHAPING_BT_0_5 ; + default : return RADIO_MOD_SHAPING_BT_1_0 ; + } +} +RadioLoRaBandwidths_t returnBwLORA(int index){ + // bandwidth for LoRa + switch(index){ + case 0: return LORA_BW_0200 ; + case 1: return LORA_BW_0400 ; + case 2: return LORA_BW_0800 ; + case 3: return LORA_BW_1600 ; + default : return LORA_BW_1600 ; + } +} + + +void setFemTxRx(bool tx) { + /* Hoel module + if (tx) { femTx=1 ; femRx=0 ; } + else { femRx=1 ; femTx=0 ; } + */ +} + + +/* Futur Use + * + * else if( _modulation == PACKET_TYPE_FLRC ) { + ModulationParams.PacketType = PACKET_TYPE_FLRC; + ModulationParams.Params.Flrc.BitrateBandwidth = returnBrbwFLRC (_bitrateBandwidth);// FLRC_BR_0_260_BW_0_3; + ModulationParams.Params.Flrc.CodingRate = returnCrFLRC (codingRate);//FLRC_CR_1_2; + ModulationParams.Params.Flrc.ModulationShaping = returnMs (_modeShape);//RADIO_MOD_SHAPING_BT_1_0; + PacketParams.PacketType = PACKET_TYPE_FLRC; + PacketParams.Params.Flrc.PreambleLength = PREAMBLE_LENGTH_32_BITS; + PacketParams.Params.Flrc.SyncWordLength = FLRC_SYNCWORD_LENGTH_4_BYTE; + PacketParams.Params.Flrc.SyncWordMatch = RADIO_RX_MATCH_SYNCWORD_1; + PacketParams.Params.Flrc.HeaderType = RADIO_PACKET_VARIABLE_LENGTH; + PacketParams.Params.Flrc.PayloadLength = 32 ; + PacketParams.Params.Flrc.CrcLength = RADIO_CRC_3_BYTES; + PacketParams.Params.Flrc.Whitening = _whitening==1?RADIO_WHITENING_ON:RADIO_WHITENING_OFF;//RADIO_WHITENING_OFF; + //Eeprom.EepromData.DemoSettings.PayloadLength = PacketParams.Params.Flrc.PayloadLength; + } + * + * + * + *RadioFlrcBitrates_t returnBrbwFLRC(int index){ + // bitrate and bandwidth for FLRC + switch(index){ + case 0: return FLRC_BR_1_300_BW_1_2; + case 1: return FLRC_BR_1_040_BW_1_2; + case 2: return FLRC_BR_0_650_BW_0_6; + case 3: return FLRC_BR_0_520_BW_0_6; + case 4: return FLRC_BR_0_325_BW_0_3; + case 5: return FLRC_BR_0_260_BW_0_3; + default : return FLRC_BR_1_300_BW_1_2; + } +} +RadioFlrcCodingRates_t returnCrFLRC(int index){ + switch(index){ + case 0: return FLRC_CR_1_2; + case 1: return FLRC_CR_3_4; + case 2: return FLRC_CR_3_4; + default : return FLRC_CR_1_2; + } +} + +RadioCrcTypes_t returnCrcLen(int index){ + // CRC length for GFSK and FLRC + switch(index){ + case 0: return RADIO_CRC_OFF; + case 1: return RADIO_CRC_1_BYTES; + case 2: return RADIO_CRC_2_BYTES; + case 3: return RADIO_CRC_3_BYTES; + default : return RADIO_CRC_OFF; + } +} + * + * + * + */