Version FC
Dependencies: DmTftLibrary eeprom SX1280Lib filesystem mbed
Fork of MSNV2-Terminal_V1-5 by
Diff: Loracpp.txt
- Revision:
- 41:5a436163dddf
- Parent:
- 13:5414193da1de
diff -r 14a8da4108d5 -r 5a436163dddf Loracpp.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Loracpp.txt Mon Oct 22 09:37:50 2018 +0000 @@ -0,0 +1,463 @@ +/* + * 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 = 5 ; /* 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.Crc = 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.Crc = 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 ; + + 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_MIN ; + PacketParams.Params.LoRa.Crc = 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.SetDioIrqParams ( RxIrqMask, RxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE ) ; + Radio.SetRx ( ( TickTime_t ) { RX_TIMEOUT_TICK_SIZE, 0x00000000 } ) ; +// Radio.SetRx ( ( TickTime_t ) { RX_TIMEOUT_TICK_SIZE, RX_TIMEOUT_VALUE } ) ; +} +//=============================================================================================================================== + + + + +// ============================================================================ 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 ); + + RxLed = 0 ; // Show the reception + + 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 ){ } + +