Version FC
Dependencies: DmTftLibrary eeprom SX1280Lib filesystem mbed
Fork of MSNV2-Terminal_V1-5 by
Lora.cpp
- Committer:
- FCH_31
- Date:
- 2018-08-22
- Revision:
- 8:cd489b7c49a0
- Child:
- 13:5414193da1de
File content as of revision 8:cd489b7c49a0:
/* * MISNet * * Lora: Radio Management * * Created on: August 17, 2018 Author: Francis CHATAIN * */ // ===================================== Includes #include "Lora.h" #include "mbed.h" #include "main.h" #include "sx1280-hal.h" // ========================================================================== DEFINE #define MODE_LORA // Lora modulation #define TX_TIMEOUT_VALUE 100 // ms Number of tick size steps for tx timeout #define RX_TIMEOUT_VALUE 100 // ms Number of tick size steps for rx timeout #define RX_TIMEOUT_TICK_SIZE RADIO_TICK_SIZE_1000_US // Size of ticks (used for Tx and Rx timeout) #define MODE_ADDR 0x8000 // ========================================================================== HW DigitalOut F_CS ( D6 ) ; // MBED description of pin DigitalOut SD_CS ( D8 ) ; // MBED description of pin DigitalOut ANT_SW ( A3 ) ; DigitalOut TxLed ( A4 ) ; DigitalOut RxLed ( A5 ) ; // ========================================================================== VARIABLES uint16_t RxIrqMask ; // Mask of IRQs to listen to in rx mode uint16_t TxIrqMask ; // Mask of IRQs to listen to in tx mode uint32_t valueTimeTx ; uint32_t valueTimeLoop ; int dataCounter = 0 ; uint8_t oldFreq ; uint8_t oldBw ; uint8_t oldPwr ; uint8_t oldSf ; uint8_t oldTimer ; // States of the application typedef enum { APP_LOWPOWER, APP_RX, APP_RX_TIMEOUT, APP_RX_ERROR, APP_TX, APP_TX_TIMEOUT, } AppStates_t ; AppStates_t AppState = APP_LOWPOWER; // Init State of the application PacketStatus_t PacketStatus ; int8_t RssiValue = 0 ; int8_t SnrValue = 0 ; ModulationParams_t modulationParams; PacketParams_t PacketParams ; // Locals parameters and status for radio API PacketStatus_t packetStatus ; // NEED TO BE OPTIMIZED, COPY OF STUCTURE ALREADY EXISTING uint32_t RF_FREQUENCY ; // HzNominal frequency RadioLoRaBandwidths_t LORA_BW ; /* 200; 400; 800; 1600 */ RadioLoRaSpreadingFactors_t LORA_SF ; /* SF5; SF6=; SF7; SF8 ; SF9; SF10; SF11 ; SF12 */ int8_t TX_OUTPUT_POWER ; /* Output power in dBm [-18..+13] dBm */ uint8_t BUFFER_SIZE_MAX ; /* Payload size max */ int16_t TIMER ; /* timer entre reemission en ms */ uint8_t BUFFER_SIZE_MIN ; /* Payload return size */ // ========================================================================== Function void initRadio () ; void setRadioTx () ; void setRadioRx () ; void watchDogRxCRNoReceived () ; Timer timerRadio ; Timeout watchDogRx ; Timeout watchDogTx ; void OnTxDone ( void ); // Function to be executed on Radio Tx Done event void OnRxDone ( void ); // Function to be executed on Radio Rx Done event void OnTxTimeout ( void ); // Function executed on Radio Tx Timeout event void OnRxTimeout ( void ); // Function executed on Radio Rx Timeout event void OnRxError ( IrqErrorCode_t ); // Function executed on Radio Rx Error event RadioCallbacks_t callbacks = { &OnTxDone, // txDone &OnRxDone, // rxDone NULL, // syncWordDone NULL, // headerDone &OnTxTimeout, // txTimeout &OnRxTimeout, // rxTimeout &OnRxError, // rxError NULL, // rangingDone NULL, // cadDone }; // mosi, miso, sclk, nss, busy , dio1 , dio2, dio3, rst , callbacks... SX1280Hal Radio ( D11 , D12 , D13 , D7 , D3 , D5 , NC , NC , A0 , &callbacks ); //=============================================================================================================================== void initLora (uint32_t rf,RadioLoRaBandwidths_t bw,RadioLoRaSpreadingFactors_t sf,int8_t pwr) //=============================================================================================================================== { // Default value initialisation printf( "*** LORA *** Lora Initialisation \r\n"); RxIrqMask = IRQ_RX_DONE | IRQ_RX_TX_TIMEOUT; // Mask of IRQs to listen to in rx mode TxIrqMask = IRQ_TX_DONE | IRQ_RX_TX_TIMEOUT; // Mask of IRQs to listen to in tx mode RF_FREQUENCY = rf ; // HzNominal frequency LORA_BW = bw ; /* 200; 400; 800; 1600 */ LORA_SF = sf ; /* SF5; SF6=; SF7; SF8 ; SF9; SF10; SF11 ; SF12 */ TX_OUTPUT_POWER = pwr ; /* Output power in dBm [-18..+13] dBm */ BUFFER_SIZE_MAX = 100 ; /* Payload size max */ BUFFER_SIZE_MIN = 8 ; /* Payload return size */ TIMER = 1000 ; /* timer entre reemission en ms */ Radio.Reset () ; Radio.Init () ; initRadio () ; Radio.SetRegulatorMode ( USE_DCDC ) ; // Can also be set in LDO mode but consume more power wait_ms ( 10 ) ; // wait for on board DC/DC start-up time TxLed = 0 ; RxLed = 0 ; } //=============================================================================================================================== void sendMessageLora () { //=============================================================================================================================== uint8_t Buffer [BUFFER_SIZE_MAX] ; // Buffer char frameMISNET [BUFFER_SIZE_MAX] ; // Misnet Frame uint8_t *pointer ; char *ptr_int ; dataCounter = dataCounter + 1 ; memset ( &Buffer , 0x00, BUFFER_SIZE_MAX ); memset ( &frameMISNET , 0x00, BUFFER_SIZE_MAX ); uint16_t clearPart = 0x0 ; uint32_t servicePayload = 0x0 ; //char serviceMessage[16] ; // TRACES uint8_t SFT = 0 ; uint8_t DFT = 0 ; uint8_t FDL = 8 ; uint8_t BL = 7 ; uint8_t DMI = 66 ; uint16_t RCA = 0xBEEF & 0x7FFF ; uint32_t MIC = 0xCAFECAFE & 0xFFFFFFFF ; clearPart = MODE_ADDR | ( ID_TERMINAL << 6 ) | ID_GATEWAY ; printf( "*** LORA *** CLEAR PART= %8X \r\n ", clearPart); servicePayload = (uint32_t)( (SFT & 0x03) << 30) | (uint32_t)( (DFT & 0x03) << 28) | (uint32_t)( (FDL & 0x3F) << 22) | (uint32_t)( (BL & 0x07) << 19) | (uint32_t)( (DMI & 0xFF) << 11) | (RCA & 0x7FF) ; //sprintf (serviceMessage, "%08X%08X", servicePayload, MIC) ; // traces //printf( "*** LORA *** SERVICE Payload = %08X \r\n ", servicePayload); //printf( "*** LORA *** SERVICE MIC = %08X \r\n ", MIC); // CLEAR PART + Indianess correction pointer = (uint8_t*) &clearPart ; for (int i = 0, j=1 ; i<2 ; i++, j--) frameMISNET[j] = pointer[i] ; // SERVICE + Indianess correction pointer = (uint8_t*) &servicePayload ; for (int i=0, j=3 ; i<4 ; i++, j--) frameMISNET[2+i] = pointer[j] ; pointer = (uint8_t*) &MIC ; for (int i=0, j=3 ; i<4 ; i++, j--) frameMISNET[6+i] = pointer[j] ; printf( "*** LORA *** START Buffer "); for (int i = 0 ; i<10 ; i++) printf ("%02X,", frameMISNET[i] ) ; printf( "\n") ; int n = sprintf (frameMISNET, "%1c%1c", ID_TERMINAL, ID_GATEWAY); pointer = (uint8_t*) &dataCounter ; for (int i = 0 ; i<4 ; i++) frameMISNET[2+i] = pointer[i] ; //(int32*)&frameMISNET[2]=(int32*)&ptr_int; // -> aton OR ntoa printf( "*** LORA *** TX SEND %05d ", dataCounter); for (int i = 0 ; i<10 ; i++) printf ("%d,", frameMISNET[i] ) ; printf( "\n") ; // Send SF, BW, COUNTER, POWER, FREQ, TIMETX, TIMELOOP, RSSIVALUE frameMISNET[6] = LORA_SF ; ptr_int = (char*) &LORA_BW ; frameMISNET[7]= ptr_int[1] ; frameMISNET[8]= ptr_int[0] ; frameMISNET[9] = TX_OUTPUT_POWER ; ptr_int = (char*) &RF_FREQUENCY ; for (int i = 0 ; i<4 ; i++) frameMISNET[10+i] = ptr_int[i] ; ptr_int = (char*) &valueTimeTx ; for (int i = 0 ; i<4 ; i++) frameMISNET[14+i] = ptr_int[i] ; //printf( "*** LORA *** TimeTx %d %d ", valueTimeTx, valueTimeLoop); //delay temps Tx ptr_int = (char*) &valueTimeLoop ; for (int i = 0 ; i<4 ; i++) frameMISNET[18+i] = ptr_int[i] ; //delay temps Loop frameMISNET[22] = RssiValue ; memcpy ( Buffer , frameMISNET , 23 ); valueTimeTx = 0 ; valueTimeLoop = 0 ; timerRadio.reset () ; // Record tile for close loop timerRadio.start () ; setRadioTx () ; TxLed = 1 ; PacketParams.Params.LoRa.PayloadLength = 23 ; Radio.SetPacketParams ( &PacketParams ) ; Radio.SendPayload ( Buffer , 23,( TickTime_t ) {RX_TIMEOUT_TICK_SIZE, TX_TIMEOUT_VALUE} ); TxLed = 0 ; //printf( "*** LORA *** ARM watchDogRxRxRxRx \r\n" ); watchDogRx.attach (&watchDogRxCRNoReceived, 1.0); // Arm watchDogRx if the response is not received in less 500 ms => force retry } //=============================================================================================================================== // Time out si pas de message de CR recu void watchDogRxCRNoReceived () { printf( "*** LORA *** watchDogRxNoReceive NO RESPONSE \r\n"); } // Force new emission //=============================================================================================================================== void initRadio () { //=============================================================================================================================== F_CS = 1 ; SD_CS = 1 ; ANT_SW = 1 ; // SET MODULATION modulationParams.PacketType = PACKET_TYPE_LORA ; modulationParams.Params.LoRa.CodingRate = LORA_CR_4_5 ; modulationParams.Params.LoRa.Bandwidth = LORA_BW_0200 ; modulationParams.Params.LoRa.SpreadingFactor = LORA_SF7 ; // SET PACKET PARAM PacketParams.PacketType = PACKET_TYPE_LORA ; PacketParams.Params.LoRa.PreambleLength = 0x08 ; PacketParams.Params.LoRa.HeaderType = LORA_PACKET_VARIABLE_LENGTH; PacketParams.Params.LoRa.PayloadLength = BUFFER_SIZE_MAX ; PacketParams.Params.LoRa.CrcMode = LORA_CRC_ON ; PacketParams.Params.LoRa.InvertIQ = LORA_IQ_INVERTED ; // RADIO Radio.SetStandby ( STDBY_RC ) ; Radio.SetPacketType ( modulationParams.PacketType ); Radio.SetModulationParams ( &modulationParams ) ; Radio.SetPacketParams ( &PacketParams ) ; Radio.SetBufferBaseAddresses ( 0x00, 0x00 ); Radio.SetTxParams ( TX_OUTPUT_POWER, RADIO_RAMP_20_US ) ; Radio.SetRx ( ( TickTime_t ) { RX_TIMEOUT_TICK_SIZE, RX_TIMEOUT_VALUE } ) ; //AppState = APP_LOWPOWER; } //=============================================================================================================================== //=============================================================================================================================== void setRadioTx () { //=============================================================================================================================== RxLed = 0 ; TxLed = 0 ; F_CS = 1 ; SD_CS = 1 ; ANT_SW = 1 ; // SET MODULATION modulationParams.PacketType = PACKET_TYPE_LORA ; modulationParams.Params.LoRa.CodingRate = LORA_CR_4_5 ; modulationParams.Params.LoRa.Bandwidth = LORA_BW ; modulationParams.Params.LoRa.SpreadingFactor = LORA_SF ; // SET PACKET PARAM PacketParams.PacketType = PACKET_TYPE_LORA ; PacketParams.Params.LoRa.PreambleLength = 0x08 ; PacketParams.Params.LoRa.HeaderType = LORA_PACKET_VARIABLE_LENGTH; PacketParams.Params.LoRa.PayloadLength = BUFFER_SIZE_MAX ; PacketParams.Params.LoRa.CrcMode = LORA_CRC_ON ; PacketParams.Params.LoRa.InvertIQ = LORA_IQ_INVERTED ; // RADIO Radio.SetStandby ( STDBY_RC ) ; Radio.SetPacketType ( modulationParams.PacketType ); Radio.SetModulationParams ( &modulationParams ) ; Radio.SetPacketParams ( &PacketParams ) ; Radio.SetRfFrequency ( RF_FREQUENCY ) ; Radio.SetBufferBaseAddresses ( 0x00, 0x00 ); Radio.SetTxParams ( TX_OUTPUT_POWER, RADIO_RAMP_20_US ) ; Radio.SetDioIrqParams ( TxIrqMask , TxIrqMask , IRQ_RADIO_NONE, IRQ_RADIO_NONE ); Radio.SetRx ( ( TickTime_t ) { RX_TIMEOUT_TICK_SIZE, RX_TIMEOUT_VALUE } ) ; //AppState = APP_LOWPOWER; } //=============================================================================================================================== void setRadioRx () { //=============================================================================================================================== RxLed = 0 ; TxLed = 0 ; // SET MODULATION modulationParams.PacketType = PACKET_TYPE_LORA ; modulationParams.Params.LoRa.CodingRate = LORA_CR_4_5 ; modulationParams.Params.LoRa.Bandwidth = LORA_BW_0200 ; modulationParams.Params.LoRa.SpreadingFactor = LORA_SF7 ; // SET PACKET PARAM PacketParams.PacketType = PACKET_TYPE_LORA ; PacketParams.Params.LoRa.PreambleLength = 0x08 ; PacketParams.Params.LoRa.HeaderType = LORA_PACKET_VARIABLE_LENGTH; PacketParams.Params.LoRa.PayloadLength = BUFFER_SIZE_MIN ; PacketParams.Params.LoRa.CrcMode = LORA_CRC_ON ; PacketParams.Params.LoRa.InvertIQ = LORA_IQ_INVERTED ; // RADIO Radio.SetStandby ( STDBY_RC ) ; Radio.SetPacketType ( modulationParams.PacketType ); Radio.SetModulationParams ( &modulationParams ) ; Radio.SetPacketParams ( &PacketParams ) ; Radio.SetRfFrequency ( RF_FREQUENCY + 440000UL) ; Radio.SetBufferBaseAddresses ( 0x00, 0x00 ); Radio.SetTxParams ( TX_OUTPUT_POWER, RADIO_RAMP_20_US ) ; Radio.SetDioIrqParams ( RxIrqMask, RxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE ) ; Radio.SetRx ( ( TickTime_t ) { RX_TIMEOUT_TICK_SIZE, RX_TIMEOUT_VALUE } ) ; //AppState = APP_LOWPOWER; } //=============================================================================================================================== // ============================================================================ RADIO CALLBACK void OnTxDone ( void ) { //============================================================================== valueTimeTx = timerRadio.read_ms () ; printf( "*** LORA *** OnTxDone \r\n" ); TxLed = 0 ; setRadioRx () ; } //============================================================================== //void OnRxDone ( void ) { AppState = APP_RX ; } //============================================================================== void OnRxDone ( void ) { //============================================================================== uint8_t Buffer1 [BUFFER_SIZE_MAX+1]; // Buffer Radio uint8_t BufferSize = BUFFER_SIZE_MAX ; // Size of the buffer RxLed = 1 ; // Show the reception printf( "*** LORA *** RX DONE \r\n" ); valueTimeLoop = timerRadio.read_ms () ; timerRadio.stop () ; watchDogRx.detach () ; //printf( "*** LORA *** DISARM watchDogRx \r\n" ); Radio.GetPacketStatus(&packetStatus) ; RssiValue = packetStatus.LoRa.RssiPkt ; memset ( &Buffer1 , 0x00, BUFFER_SIZE_MAX ); Radio.GetPayload ( Buffer1, &BufferSize, BUFFER_SIZE_MAX ); Buffer1[7] = 0 ; printf ( "*** LORA *** RX DONE => %s \r\n", Buffer1 ); wait(1) ; // flush serial // Extract value switch (Buffer1[2]) { case '1': RF_FREQUENCY = 2400000000UL ; break ; case '2': RF_FREQUENCY = 2400680000UL ; break ; case '3': RF_FREQUENCY = 2423840000UL ; break ; case '4': RF_FREQUENCY = 2424520000UL ; break ; case '5': RF_FREQUENCY = 2448840000UL ; break ; case '6': RF_FREQUENCY = 2449520000UL ; break ; case '7': RF_FREQUENCY = 2473840000UL ; break ; case '8': RF_FREQUENCY = 2474520000UL ; break ; } switch (Buffer1[3]) { case '1': LORA_BW = LORA_BW_0200 ; break ; case '2': LORA_BW = LORA_BW_0400 ; break ; case '3': LORA_BW = LORA_BW_0800 ; break ; case '4': LORA_BW = LORA_BW_1600 ; break ; } switch (Buffer1[4]) { case '1': TX_OUTPUT_POWER = -18 ; break ; case '2': TX_OUTPUT_POWER = 0 ; break ; case '3': TX_OUTPUT_POWER = 8 ; break ; case '4': TX_OUTPUT_POWER = 10 ; break ; case '5': TX_OUTPUT_POWER = 13 ; break ; } switch (Buffer1[5]) { case '1': LORA_SF = LORA_SF5 ; break ; case '2': LORA_SF = LORA_SF6 ; break ; case '3': LORA_SF = LORA_SF7 ; break ; case '4': LORA_SF = LORA_SF8 ; break ; case '5': LORA_SF = LORA_SF9 ; break ; case '6': LORA_SF = LORA_SF10 ; break ; case '7': LORA_SF = LORA_SF12 ; break ; } int OLD_TIMER = TIMER ; switch (Buffer1[6]) { case '1': TIMER = 50 ; break ; case '2': TIMER = 75 ; break ; case '3': TIMER = 125 ; break ; case '4': TIMER = 250 ; break ; case '5': TIMER = 500 ; break ; case '6': TIMER = 1000 ; break ; case '7': TIMER = 2000 ; break ; } RxLed = 0 ; if (oldFreq != Buffer1[2] || oldBw != Buffer1[3] || oldPwr != Buffer1[4] || oldSf != Buffer1[5] || oldTimer != Buffer1[6] ) { oldFreq = Buffer1[2] ; oldBw = Buffer1[3] ; oldPwr = Buffer1[4] ; oldSf = Buffer1[5] ; oldTimer = Buffer1[6] ; //printf ( "*** LORA *** Reset Radio \r\n" ); //app.updateDisplay ( LORA_SF, LORA_BW, TX_OUTPUT_POWER, BUFFER_SIZE_MAX, RF_FREQUENCY, TIMER ) ; } if (OLD_TIMER != TIMER) { //wakeUpTerminal.detach (); //wakeUpTerminal.attach (&wakeUpTerminalFunction, (float) TIMER/1000); } } //============================================================================== 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 ){ }