kopia lustrzana https://github.com/pjalocha/esp32-ogn-tracker
LoRaWAN code can join and send positions, proof of concept, far from stable
rodzic
38d8ecaf22
commit
e9caf1f353
|
@ -42,6 +42,10 @@
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Computes the LoRaMAC frame MIC field
|
* Computes the LoRaMAC frame MIC field
|
||||||
*
|
*
|
||||||
|
@ -124,4 +128,8 @@ void LoRaMacBeaconComputePingOffset( uint64_t beaconTime, uint32_t address, uint
|
||||||
|
|
||||||
/*! \} defgroup LORAMAC */
|
/*! \} defgroup LORAMAC */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} // extern "C"
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // __LORAMAC_CRYPTO_H__
|
#endif // __LORAMAC_CRYPTO_H__
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
#include "disp_lcd.h"
|
#include "disp_lcd.h"
|
||||||
|
|
||||||
#ifdef WITH_U8G2_OLED
|
#ifdef WITH_U8G2_OLED
|
||||||
const uint8_t DISP_Pages = 11;
|
const uint8_t DISP_Pages = 12;
|
||||||
static uint8_t DISP_Page = 0;
|
static uint8_t DISP_Page = 0;
|
||||||
#endif
|
#endif
|
||||||
#if defined(WITH_ST7789) || defined(WITH_ILI9341)
|
#if defined(WITH_ST7789) || defined(WITH_ILI9341)
|
||||||
|
@ -191,7 +191,8 @@ void vTaskDISP(void* pvParameters)
|
||||||
case 7: OLED_DrawRelay (&U8G2_OLED, GPS); break;
|
case 7: OLED_DrawRelay (&U8G2_OLED, GPS); break;
|
||||||
case 8: OLED_DrawLookout (&U8G2_OLED, GPS); break;
|
case 8: OLED_DrawLookout (&U8G2_OLED, GPS); break;
|
||||||
case 9: OLED_DrawTrafWarn (&U8G2_OLED, GPS); break;
|
case 9: OLED_DrawTrafWarn (&U8G2_OLED, GPS); break;
|
||||||
case 10: OLED_DrawLoRaWAN (&U8G2_OLED, GPS); break;
|
case 10: OLED_DrawFlight (&U8G2_OLED, GPS); break;
|
||||||
|
case 11: OLED_DrawLoRaWAN (&U8G2_OLED, GPS); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//if ( DISP_Page != 6 )
|
//if ( DISP_Page != 6 )
|
||||||
|
|
|
@ -815,6 +815,12 @@ void OLED_DrawAltitudeAndSpeed(u8g2_t *OLED, GPS_Position *GPS)
|
||||||
u8g2_DrawXBM(OLED, 118, 47, kmh_width, kmh_height, kmh_bits);
|
u8g2_DrawXBM(OLED, 118, 47, kmh_width, kmh_height, kmh_bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OLED_DrawFlight(u8g2_t *OLED, GPS_Position *GPS) // draw flight status page
|
||||||
|
{ u8g2_SetFont(OLED, u8g2_font_7x13_tf);
|
||||||
|
u8g2_DrawStr(OLED, 0, 28, "Flight");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void OLED_DrawLoRaWAN(u8g2_t *OLED, GPS_Position *GPS) // draw LoRaWAN status page
|
void OLED_DrawLoRaWAN(u8g2_t *OLED, GPS_Position *GPS) // draw LoRaWAN status page
|
||||||
{
|
{
|
||||||
u8g2_SetFont(OLED, u8g2_font_7x13_tf);
|
u8g2_SetFont(OLED, u8g2_font_7x13_tf);
|
||||||
|
@ -822,13 +828,25 @@ void OLED_DrawLoRaWAN(u8g2_t *OLED, GPS_Position *GPS) // draw LoRaWAN status pa
|
||||||
u8g2_DrawStr(OLED, 0, 28, "LoRaWAN: -OFF-");
|
u8g2_DrawStr(OLED, 0, 28, "LoRaWAN: -OFF-");
|
||||||
#endif
|
#endif
|
||||||
#ifdef WITH_LORAWAN
|
#ifdef WITH_LORAWAN
|
||||||
const char *StateName[3] = { "Idle", "Join-Req", "Joined" } ;
|
const char *StateName[4] = { "Not-Joined", "Join-Req", "+Joined+", "PktSend" } ;
|
||||||
int Len=Format_String(Line, "LoRaWAN: ");
|
int Len=Format_String(Line, "LoRaWAN: ");
|
||||||
if(WANdev.State<=2) Len+=Format_String(Line+Len, StateName[WANdev.State]);
|
if(WANdev.State<=3) Len+=Format_String(Line+Len, StateName[WANdev.State]);
|
||||||
else Len+=Format_Hex(Line+Len, WANdev.State);
|
else Len+=Format_Hex(Line+Len, WANdev.State);
|
||||||
Line[Len]=0;
|
Line[Len]=0;
|
||||||
u8g2_DrawStr(OLED, 0, 24, Line);
|
u8g2_DrawStr(OLED, 0, 24, Line);
|
||||||
|
Len =Format_String(Line , "Up: "); Len+=Format_Hex(Line+Len, (uint16_t)WANdev.UpCount);
|
||||||
|
Len+=Format_String(Line+Len, " Dn: "); Len+=Format_Hex(Line+Len, (uint16_t)WANdev.DnCount);
|
||||||
|
Line[Len]=0;
|
||||||
|
u8g2_DrawStr(OLED, 0, 36, Line);
|
||||||
|
// if(WANdev.State>=2) { }
|
||||||
|
/*
|
||||||
|
Len=0;
|
||||||
|
for(int Idx=0; Idx<16; Idx++)
|
||||||
|
{ Len+=Format_Hex(Line+Len, WANdev.AppKey[Idx]); }
|
||||||
|
Line[Len]=0;
|
||||||
|
u8g2_SetFont(OLED, u8g2_font_5x8_tr);
|
||||||
|
u8g2_DrawStr(OLED, 0, 48, Line);
|
||||||
|
*/
|
||||||
#endif // WITH_LORAWAN
|
#endif // WITH_LORAWAN
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,5 +23,6 @@ void OLED_DrawStatusBar(u8g2_t *OLED, GPS_Position *GPS=0);
|
||||||
void OLED_DrawSystem (u8g2_t *OLED, GPS_Position *GPS=0);
|
void OLED_DrawSystem (u8g2_t *OLED, GPS_Position *GPS=0);
|
||||||
void OLED_DrawID (u8g2_t *OLED, GPS_Position *GPS=0);
|
void OLED_DrawID (u8g2_t *OLED, GPS_Position *GPS=0);
|
||||||
void OLED_DrawAltitudeAndSpeed(u8g2_t *OLED, GPS_Position *GPS=0);
|
void OLED_DrawAltitudeAndSpeed(u8g2_t *OLED, GPS_Position *GPS=0);
|
||||||
|
void OLED_DrawFlight (u8g2_t *OLED, GPS_Position *GPS=0);
|
||||||
void OLED_DrawLoRaWAN (u8g2_t *OLED, GPS_Position *GPS=0);
|
void OLED_DrawLoRaWAN (u8g2_t *OLED, GPS_Position *GPS=0);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -33,11 +33,14 @@ uint8_t Format_String(char *Out, const char *String, uint8_t MinLen, uint8_t Max
|
||||||
uint8_t Format_UnsDec (char *Out, uint32_t Value, uint8_t MinDigits=1, uint8_t DecPoint=0);
|
uint8_t Format_UnsDec (char *Out, uint32_t Value, uint8_t MinDigits=1, uint8_t DecPoint=0);
|
||||||
uint8_t Format_SignDec(char *Out, int32_t Value, uint8_t MinDigits=1, uint8_t DecPoint=0, uint8_t NoPlus=0);
|
uint8_t Format_SignDec(char *Out, int32_t Value, uint8_t MinDigits=1, uint8_t DecPoint=0, uint8_t NoPlus=0);
|
||||||
|
|
||||||
uint8_t Format_Hex( char *Output, uint8_t Byte );
|
uint8_t Format_Hex(char *Output, uint8_t Byte );
|
||||||
uint8_t Format_Hex( char *Output, uint16_t Word );
|
uint8_t Format_Hex(char *Output, uint16_t Word );
|
||||||
uint8_t Format_Hex( char *Output, uint32_t Word );
|
uint8_t Format_Hex(char *Output, uint32_t Word );
|
||||||
uint8_t Format_Hex( char *Output, uint32_t Word, uint8_t Digits);
|
uint8_t Format_Hex(char *Output, uint32_t Word, uint8_t Digits);
|
||||||
uint8_t Format_Hex( char *Output, uint64_t Word );
|
uint8_t Format_Hex(char *Output, uint64_t Word );
|
||||||
|
|
||||||
|
// uint8_t Format_Hex(char *Output, const uint8_t *Bytes, uint8_t Len );
|
||||||
|
|
||||||
// uint8_t Format_Hex( char *Output, uint64_t Word, uint8_t Digits);
|
// uint8_t Format_Hex( char *Output, uint64_t Word, uint8_t Digits);
|
||||||
|
|
||||||
template <class Type>
|
template <class Type>
|
||||||
|
|
|
@ -919,6 +919,8 @@ void RFM_RESET(uint8_t On) { }
|
||||||
void RFM_IRQ_SetInput(void) { gpio_set_direction(PIN_RFM_IRQ, GPIO_MODE_INPUT); }
|
void RFM_IRQ_SetInput(void) { gpio_set_direction(PIN_RFM_IRQ, GPIO_MODE_INPUT); }
|
||||||
bool RFM_IRQ_isOn(void) { return gpio_get_level(PIN_RFM_IRQ); }
|
bool RFM_IRQ_isOn(void) { return gpio_get_level(PIN_RFM_IRQ); }
|
||||||
|
|
||||||
|
void RFM_Delay(int ms) { vTaskDelay(ms); }
|
||||||
|
|
||||||
static spi_device_handle_t RFM_SPI;
|
static spi_device_handle_t RFM_SPI;
|
||||||
|
|
||||||
void RFM_TransferBlock(uint8_t *Data, uint8_t Len)
|
void RFM_TransferBlock(uint8_t *Data, uint8_t Len)
|
||||||
|
|
|
@ -94,6 +94,7 @@ void AERO_UART_SetBaudrate(int BaudRate);
|
||||||
void RFM_TransferBlock(uint8_t *Data, uint8_t Len);
|
void RFM_TransferBlock(uint8_t *Data, uint8_t Len);
|
||||||
void RFM_RESET(uint8_t On); // RF module reset
|
void RFM_RESET(uint8_t On); // RF module reset
|
||||||
bool RFM_IRQ_isOn(void); // query the IRQ state
|
bool RFM_IRQ_isOn(void); // query the IRQ state
|
||||||
|
void RFM_Delay(int ms); // [ms] idle delay
|
||||||
|
|
||||||
#ifdef WITH_OLED
|
#ifdef WITH_OLED
|
||||||
int OLED_DisplayON(uint8_t ON, uint8_t DispIdx=0); // when OFF then low-power mode
|
int OLED_DisplayON(uint8_t ON, uint8_t DispIdx=0); // when OFF then low-power mode
|
||||||
|
|
|
@ -25,7 +25,7 @@ class LoRaWANnode
|
||||||
uint32_t DevAddr; // from Join-Accept: Device Address
|
uint32_t DevAddr; // from Join-Accept: Device Address
|
||||||
uint8_t DLsetting; // from Join-Accept: DownLink configuration: OptNeg | RX1DRoffset | RX2 data rate
|
uint8_t DLsetting; // from Join-Accept: DownLink configuration: OptNeg | RX1DRoffset | RX2 data rate
|
||||||
uint8_t RxDelay; // from Join-Accept:
|
uint8_t RxDelay; // from Join-Accept:
|
||||||
uint8_t State; // 0:disconencted, 1:join-request sent, 2:join-accept received
|
uint8_t State; // 0:disconencted, 1:join-request sent, 2:join-accept received, 3:uplink-packet sent
|
||||||
uint8_t Chan; // [0..7] Current channel being used
|
uint8_t Chan; // [0..7] Current channel being used
|
||||||
uint32_t UpCount; // [seq] Uplink frame counter: reset when joining the network
|
uint32_t UpCount; // [seq] Uplink frame counter: reset when joining the network
|
||||||
uint32_t DnCount; // [seq] Downlink frame counter: reset when joining the network
|
uint32_t DnCount; // [seq] Downlink frame counter: reset when joining the network
|
||||||
|
@ -105,9 +105,10 @@ class LoRaWANnode
|
||||||
|
|
||||||
int getJoinRequest(uint8_t *Req)
|
int getJoinRequest(uint8_t *Req)
|
||||||
{ Req[0] = 0x00; // MHDR, Join-Request: 000 000 00
|
{ Req[0] = 0x00; // MHDR, Join-Request: 000 000 00
|
||||||
memcpy(Req+1, &AppEUI, 8); //
|
memcpy(Req+1, &AppEUI, 8); // AppEUI
|
||||||
memcpy(Req+9, &DevEUI, 8);
|
memcpy(Req+9, &DevEUI, 8); // DevEUI
|
||||||
Req[17] = DevNonce;
|
DevNonce++; // increment DevNonce for a new request
|
||||||
|
Req[17] = DevNonce; // DevNonce
|
||||||
Req[18] = DevNonce>>8;
|
Req[18] = DevNonce>>8;
|
||||||
uint32_t MIC=0;
|
uint32_t MIC=0;
|
||||||
LoRaMacJoinComputeMic(Req, 19, AppKey, &MIC); // compute MIC
|
LoRaMacJoinComputeMic(Req, 19, AppKey, &MIC); // compute MIC
|
||||||
|
@ -123,7 +124,7 @@ class LoRaWANnode
|
||||||
RxRSSI = RxPacket.RSSI;
|
RxRSSI = RxPacket.RSSI;
|
||||||
return Ret; }
|
return Ret; }
|
||||||
|
|
||||||
int procJoinAccept(const uint8_t *PktData, int PktLen)
|
int procJoinAccept(const uint8_t *PktData, int PktLen) // process Join-Accept packet (5sec after Join-Request)
|
||||||
{ if(PktLen<13) return -1;
|
{ if(PktLen<13) return -1;
|
||||||
uint8_t Type = PktData[0]>>5; if(Type!=1) return -1;
|
uint8_t Type = PktData[0]>>5; if(Type!=1) return -1;
|
||||||
Packet[0] = PktData[0];
|
Packet[0] = PktData[0];
|
||||||
|
@ -137,7 +138,7 @@ class LoRaWANnode
|
||||||
DevAddr = readInt<uint32_t>(Packet+7, 4);
|
DevAddr = readInt<uint32_t>(Packet+7, 4);
|
||||||
DLsetting = Packet[11];
|
DLsetting = Packet[11];
|
||||||
RxDelay = Packet[12];
|
RxDelay = Packet[12];
|
||||||
State = 2; // State = accepted on network
|
State = 2; // State = accepted on network
|
||||||
UpCount = 0;
|
UpCount = 0;
|
||||||
DnCount = 0;
|
DnCount = 0;
|
||||||
#ifdef WITH_PRINTF
|
#ifdef WITH_PRINTF
|
||||||
|
@ -151,23 +152,21 @@ class LoRaWANnode
|
||||||
return 0; }
|
return 0; }
|
||||||
|
|
||||||
int getDataPacket(uint8_t *Packet, const uint8_t *Data, int DataLen, uint8_t Port=1, bool Confirm=0)
|
int getDataPacket(uint8_t *Packet, const uint8_t *Data, int DataLen, uint8_t Port=1, bool Confirm=0)
|
||||||
{ uint8_t Type = Confirm?0x04:0x02;
|
{ if(State<2) return 0; // not joined to the network yet
|
||||||
|
uint8_t Type = Confirm?0x04:0x02; // request confirmation or not ?
|
||||||
int PktLen=0;
|
int PktLen=0;
|
||||||
Packet[PktLen++] = Type<<5; // packet-type
|
Packet[PktLen++] = Type<<5; // packet-type
|
||||||
PktLen+=writeInt(Packet+PktLen, DevAddr, 4); // Device Address
|
PktLen+=writeInt(Packet+PktLen, DevAddr, 4); // Device Address
|
||||||
uint8_t Ctrl=0;
|
uint8_t Ctrl=0; // Frame Control
|
||||||
if(TxACK) { Ctrl|=0x20; TxACK=0; }
|
if(TxACK) { Ctrl|=0x20; TxACK=0; } // if there is ACK to be transmitted
|
||||||
Packet[PktLen++] = Ctrl; // Frame Control: ADR | ADR-ACK-Req | ACK | ClassB | FOptsLen[4]
|
Packet[PktLen++] = Ctrl; // Frame Control: ADR | ADR-ACK-Req | ACK | ClassB | FOptsLen[4]
|
||||||
PktLen+=writeInt(Packet+PktLen, UpCount, 2); // uplink frame counter
|
PktLen+=writeInt(Packet+PktLen, UpCount, 2); // uplink frame counter
|
||||||
Packet[PktLen++] = Port; // port
|
Packet[PktLen++] = Port; // port
|
||||||
LoRaMacPayloadEncrypt(Data, DataLen, AppSesKey, DevAddr, 0, UpCount, Packet+PktLen); PktLen+=DataLen; // copy+encrypt user data
|
LoRaMacPayloadEncrypt(Data, DataLen, AppSesKey, DevAddr, 0, UpCount, Packet+PktLen); PktLen+=DataLen; // copy+encrypt user data
|
||||||
uint32_t MIC=0;
|
uint32_t MIC=0;
|
||||||
LoRaMacComputeMic(Packet, PktLen, NetSesKey, DevAddr, 0x00, UpCount, &MIC); // calc. MIC
|
LoRaMacComputeMic(Packet, PktLen, NetSesKey, DevAddr, 0x00, UpCount, &MIC); // calc. MIC
|
||||||
// uint8_t MIC2[4];
|
|
||||||
// Tiny.Calculate_MIC(Packet, MIC2, PktLen, UpCount, 0x00);
|
|
||||||
// printf("Data packet MIC: %08X <=> %02X%02X%02X%02X\n", MIC, MIC2[3], MIC2[2], MIC2[1], MIC2[0]);
|
|
||||||
memcpy(Packet+PktLen, &MIC, 4); PktLen+=4; // append MIC
|
memcpy(Packet+PktLen, &MIC, 4); PktLen+=4; // append MIC
|
||||||
UpCount++; return PktLen; }
|
UpCount++; State=3; return PktLen; } // return the packet size
|
||||||
|
|
||||||
int getDataPacket(uint8_t **Pkt, const uint8_t *Data, int DataLen, uint8_t Port=1, bool Confirm=0)
|
int getDataPacket(uint8_t **Pkt, const uint8_t *Data, int DataLen, uint8_t Port=1, bool Confirm=0)
|
||||||
{ int Len=getDataPacket(Packet, Data, DataLen, Port, Confirm); *Pkt = Packet; return Len; }
|
{ int Len=getDataPacket(Packet, Data, DataLen, Port, Confirm); *Pkt = Packet; return Len; }
|
||||||
|
@ -185,17 +184,11 @@ class LoRaWANnode
|
||||||
if(Addr!=DevAddr) return 0;
|
if(Addr!=DevAddr) return 0;
|
||||||
uint8_t Ctrl = PktData[5]; // Frame control: ADR | RFU | ACK | FPending | FOptLen[4]
|
uint8_t Ctrl = PktData[5]; // Frame control: ADR | RFU | ACK | FPending | FOptLen[4]
|
||||||
uint32_t Count=readInt<uint32_t>(PktData+6, 2);
|
uint32_t Count=readInt<uint32_t>(PktData+6, 2);
|
||||||
// Count |= DnCount&0xFFFF0000;
|
|
||||||
int16_t CountDiff = Count-DnCount; //
|
int16_t CountDiff = Count-DnCount; //
|
||||||
if(CountDiff<=0) return -1; // attempt to reuse the counter: drop this packet
|
if(CountDiff<=0) return -1; // attempt to reuse the counter: drop this packet
|
||||||
// if(Diff<=(-0x4000)) Count+=0x10000;
|
|
||||||
// else if(Diff>0x4000) Count-=0x10000;
|
|
||||||
// printf("RxData: %08X\n", Count);
|
|
||||||
uint32_t MIC=0;
|
uint32_t MIC=0;
|
||||||
LoRaMacComputeMic(PktData, PktLen-4, NetSesKey, Addr, 0x01, Count, &MIC);
|
LoRaMacComputeMic(PktData, PktLen-4, NetSesKey, Addr, 0x01, Count, &MIC);
|
||||||
// printf("RxData: %08X\n", MIC);
|
|
||||||
if(memcmp(PktData+PktLen-4, &MIC, 4)) return -1; // give up if MIC does not match
|
if(memcmp(PktData+PktLen-4, &MIC, 4)) return -1; // give up if MIC does not match
|
||||||
// if(Count==DnCount) return 0;
|
|
||||||
uint8_t DataOfs = 8 + (Ctrl&0x0F); // where the port byte should be
|
uint8_t DataOfs = 8 + (Ctrl&0x0F); // where the port byte should be
|
||||||
uint8_t DataLen = PktLen-DataOfs-4; // number of bytes of the user data field
|
uint8_t DataLen = PktLen-DataOfs-4; // number of bytes of the user data field
|
||||||
if(DataLen) // if non-zero
|
if(DataLen) // if non-zero
|
||||||
|
@ -211,6 +204,7 @@ class LoRaWANnode
|
||||||
if(Ctrl&0x40) RxACK=1; // we got ACK to our ACK request
|
if(Ctrl&0x40) RxACK=1; // we got ACK to our ACK request
|
||||||
if(Type==5) TxACK=1; // if ACK requested
|
if(Type==5) TxACK=1; // if ACK requested
|
||||||
RxPend = Ctrl&0x10; // is there more data pending to be received on next round ?
|
RxPend = Ctrl&0x10; // is there more data pending to be received on next round ?
|
||||||
|
State=2;
|
||||||
return DataLen; }
|
return DataLen; }
|
||||||
|
|
||||||
#ifdef WITH_ESP32
|
#ifdef WITH_ESP32
|
||||||
|
|
|
@ -46,12 +46,6 @@ void app_main(void)
|
||||||
Parameters.setDefault(getUniqueAddress()); // set default parameter values
|
Parameters.setDefault(getUniqueAddress()); // set default parameter values
|
||||||
if(Parameters.ReadFromNVS()!=ESP_OK) // try to get parameters from NVS
|
if(Parameters.ReadFromNVS()!=ESP_OK) // try to get parameters from NVS
|
||||||
{ Parameters.WriteToNVS(); } // if did not work: try to save (default) parameters to NVS
|
{ Parameters.WriteToNVS(); } // if did not work: try to save (default) parameters to NVS
|
||||||
#ifdef WITH_LORAWAN
|
|
||||||
WANdev.Reset(getUniqueID(), Parameters.AppKey);
|
|
||||||
if(WANdev.ReadFromNVS()!=ESP_OK)
|
|
||||||
{ WANdev.WriteToNVS(); }
|
|
||||||
if(memcpy(WANdev.AppKey, Parameters.AppKey, 16)) WANdev.Reset(getUniqueID(), Parameters.AppKey);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef WITH_SPIFFS
|
#ifdef WITH_SPIFFS
|
||||||
SPIFFS_Register(); // initialize the file system in the Flash
|
SPIFFS_Register(); // initialize the file system in the Flash
|
||||||
|
@ -68,6 +62,14 @@ void app_main(void)
|
||||||
// #endif
|
// #endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef WITH_LORAWAN
|
||||||
|
WANdev.Reset(getUniqueID(), Parameters.AppKey); // set default LoRaWAN config.
|
||||||
|
if(WANdev.ReadFromNVS()!=ESP_OK) // if can't read the LoRaWAN setup from NVS
|
||||||
|
{ WANdev.WriteToNVS(); } // then store the default
|
||||||
|
// if(memcmp(WANdev.AppKey, Parameters.AppKey, 16)) // if LoRaWAN key different from the one in Parameters
|
||||||
|
// { WANdev.Reset(getUniqueID(), Parameters.AppKey); // then reset LoRaWAN to this key
|
||||||
|
// WANdev.WriteToNVS(); } // and save LoRaWAN config. to NVS
|
||||||
|
#endif
|
||||||
|
|
||||||
CONS_UART_SetBaudrate(Parameters.CONbaud);
|
CONS_UART_SetBaudrate(Parameters.CONbaud);
|
||||||
|
|
||||||
|
@ -92,7 +94,7 @@ void app_main(void)
|
||||||
xTaskCreate(vTaskLOG , "LOG", 4096, 0, tskIDLE_PRIORITY+1, 0);
|
xTaskCreate(vTaskLOG , "LOG", 4096, 0, tskIDLE_PRIORITY+1, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
xTaskCreate(vTaskRF, "RF", 2048, 0, tskIDLE_PRIORITY+4, 0);
|
xTaskCreate(vTaskRF, "RF", 2048, 0, tskIDLE_PRIORITY+5, 0);
|
||||||
xTaskCreate(vTaskPROC, "PROC", 2048, 0, tskIDLE_PRIORITY+3, 0);
|
xTaskCreate(vTaskPROC, "PROC", 2048, 0, tskIDLE_PRIORITY+3, 0);
|
||||||
|
|
||||||
xTaskCreate(vTaskGPS, "GPS", 2048, 0, tskIDLE_PRIORITY+4, 0);
|
xTaskCreate(vTaskGPS, "GPS", 2048, 0, tskIDLE_PRIORITY+4, 0);
|
||||||
|
@ -107,7 +109,7 @@ void app_main(void)
|
||||||
xTaskCreate(vTaskKNOB, "KNOB", 2048, 0, tskIDLE_PRIORITY+3, 0);
|
xTaskCreate(vTaskKNOB, "KNOB", 2048, 0, tskIDLE_PRIORITY+3, 0);
|
||||||
#endif
|
#endif
|
||||||
#ifdef WITH_AERO
|
#ifdef WITH_AERO
|
||||||
xTaskCreate(vTaskAERO, "AERO", 2048, 0, tskIDLE_PRIORITY+4, 0);
|
xTaskCreate(vTaskAERO, "AERO", 2048, 0, tskIDLE_PRIORITY+3, 0);
|
||||||
#endif
|
#endif
|
||||||
#ifdef WITH_WIFI
|
#ifdef WITH_WIFI
|
||||||
xTaskCreate(vTaskWIFI, "WIFI", 4096, 0, tskIDLE_PRIORITY+2, 0);
|
xTaskCreate(vTaskWIFI, "WIFI", 4096, 0, tskIDLE_PRIORITY+2, 0);
|
||||||
|
|
|
@ -518,11 +518,12 @@ class FlashParameters
|
||||||
Verbose=Mode; return 1; }
|
Verbose=Mode; return 1; }
|
||||||
#ifdef WITH_LORAWAN
|
#ifdef WITH_LORAWAN
|
||||||
if(strcmp(Name, "AppKey")==0)
|
if(strcmp(Name, "AppKey")==0)
|
||||||
{ for( uint8_t Idx=0; Idx<16; Idx++)
|
{ for(uint8_t Idx=0; Idx<16; Idx++)
|
||||||
{ uint8_t Byte;
|
{ uint8_t Byte;
|
||||||
uint8_t Len=Read_Hex(Byte, Value);
|
uint8_t Len=Read_Hex(Byte, Value);
|
||||||
if(Len!=2) break;
|
if(Len!=2) break;
|
||||||
AppKey[Idx]=Byte; }
|
AppKey[Idx]=Byte;
|
||||||
|
Value+=2; }
|
||||||
return 1; }
|
return 1; }
|
||||||
#endif
|
#endif
|
||||||
#ifdef WITH_ENCRYPT
|
#ifdef WITH_ENCRYPT
|
||||||
|
|
168
main/rf.cpp
168
main/rf.cpp
|
@ -159,11 +159,15 @@ static void TimeSlot(uint8_t TxChan, uint32_t SlotLen, const uint8_t *PacketByte
|
||||||
ReceiveUntil(End); // listen till the end of the time-slot
|
ReceiveUntil(End); // listen till the end of the time-slot
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SetFreqPlan(void) // set the RF TRX according to the selected frequency hopping plan
|
static void SetFreqPlanOGN(void) // set the RF TRX according to the selected frequency hopping plan
|
||||||
{ TRX.setBaseFrequency(RF_FreqPlan.BaseFreq); // set the base frequency (recalculate to RFM69 internal synth. units)
|
{ TRX.setBaseFrequency(RF_FreqPlan.BaseFreq); // set the base frequency (recalculate to RFM69 internal synth. units)
|
||||||
TRX.setChannelSpacing(RF_FreqPlan.ChanSepar); // set the channel separation
|
TRX.setChannelSpacing(RF_FreqPlan.ChanSepar); // set the channel separation
|
||||||
TRX.setFrequencyCorrection(Parameters.RFchipFreqCorr); // set the fine correction (to counter the Xtal error)
|
TRX.setFrequencyCorrection(Parameters.RFchipFreqCorr); } // set the fine correction (to counter the Xtal error)
|
||||||
}
|
|
||||||
|
static void SetFreqPlanWAN(void) // set the LoRaWAN EU frequency plan: 8 LoRa channels
|
||||||
|
{ TRX.setBaseFrequency(867100000);
|
||||||
|
TRX.setChannelSpacing( 200000);
|
||||||
|
TRX.setFrequencyCorrection(Parameters.RFchipFreqCorr); }
|
||||||
|
|
||||||
static uint8_t StartRFchip(void)
|
static uint8_t StartRFchip(void)
|
||||||
{ TRX.WriteMode(RF_OPMODE_STANDBY);
|
{ TRX.WriteMode(RF_OPMODE_STANDBY);
|
||||||
|
@ -172,7 +176,7 @@ static uint8_t StartRFchip(void)
|
||||||
vTaskDelay(1); // wait 10ms
|
vTaskDelay(1); // wait 10ms
|
||||||
TRX.RESET(0); // RESET released
|
TRX.RESET(0); // RESET released
|
||||||
vTaskDelay(5); // wait 10ms
|
vTaskDelay(5); // wait 10ms
|
||||||
SetFreqPlan(); // set TRX base frequency and channel separation after the frequency hopping plan
|
SetFreqPlanOGN(); // set TRX base frequency and channel separation after the frequency hopping plan
|
||||||
#ifdef DEBUG_PRINT
|
#ifdef DEBUG_PRINT
|
||||||
xSemaphoreTake(CONS_Mutex, portMAX_DELAY);
|
xSemaphoreTake(CONS_Mutex, portMAX_DELAY);
|
||||||
TRX.PrintReg(CONS_UART_Write);
|
TRX.PrintReg(CONS_UART_Write);
|
||||||
|
@ -200,6 +204,11 @@ static uint8_t StartRFchip(void)
|
||||||
#endif
|
#endif
|
||||||
return Version; } // read the RF chip version and return it
|
return Version; } // read the RF chip version and return it
|
||||||
|
|
||||||
|
static TickType_t WAN_RespTick = xTaskGetTickCount(); // when to expect the WAN response
|
||||||
|
static RFM_LoRa_RxPacket WAN_RxPacket; // packet received from WAN
|
||||||
|
// static WAN_Setup()
|
||||||
|
// static WAN_Back()
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
void vTaskRF(void* pvParameters)
|
void vTaskRF(void* pvParameters)
|
||||||
{
|
{
|
||||||
|
@ -213,12 +222,13 @@ extern "C"
|
||||||
#ifdef USE_BLOCK_SPI
|
#ifdef USE_BLOCK_SPI
|
||||||
TRX.TransferBlock = RFM_TransferBlock;
|
TRX.TransferBlock = RFM_TransferBlock;
|
||||||
#else
|
#else
|
||||||
TRX.Select = RFM_Select;
|
TRX.Select = RFM_Select; // [call]
|
||||||
TRX.Deselect = RFM_Deselect;
|
TRX.Deselect = RFM_Deselect; // [call]
|
||||||
TRX.TransferByte = RFM_TransferByte;
|
TRX.TransferByte = RFM_TransferByte; // [call]
|
||||||
#endif
|
#endif
|
||||||
TRX.DIO0_isOn = RFM_IRQ_isOn;
|
TRX.DIO0_isOn = RFM_IRQ_isOn; // [call] read IRQrfm_reset
|
||||||
TRX.RESET = RFM_RESET;
|
TRX.Delay_ms = RFM_Delay; // [call] delay by N miliseconds
|
||||||
|
TRX.RESET = RFM_RESET; // [call] chip reset control
|
||||||
|
|
||||||
RF_FreqPlan.setPlan(Parameters.FreqPlan); // 1 = Europe/Africa, 2 = USA/CA, 3 = Australia and South America
|
RF_FreqPlan.setPlan(Parameters.FreqPlan); // 1 = Europe/Africa, 2 = USA/CA, 3 = Australia and South America
|
||||||
|
|
||||||
|
@ -256,18 +266,73 @@ extern "C"
|
||||||
// RF_Print();
|
// RF_Print();
|
||||||
// #endif
|
// #endif
|
||||||
|
|
||||||
uint32_t RxRssiSum=0; uint16_t RxRssiCount=0; // measure the average RSSI for lower frequency
|
#ifdef WITH_LORAWAN
|
||||||
do
|
bool WANrx=0;
|
||||||
{ ReceivePacket(); // keep checking for received packets
|
int WAN_RespLeft = WAN_RespTick-xTaskGetTickCount();
|
||||||
|
if(WANdev.State==1 || WANdev.State==3)
|
||||||
|
{ if(WAN_RespLeft<=5) WANdev.State--;
|
||||||
|
else if(WAN_RespLeft<200) { WANrx=1; }
|
||||||
|
xSemaphoreTake(CONS_Mutex, portMAX_DELAY);
|
||||||
|
Format_String(CONS_UART_Write, "LoRaWAN Rx: ");
|
||||||
|
Format_SignDec(CONS_UART_Write, WAN_RespLeft);
|
||||||
|
Format_String(CONS_UART_Write, "ms ");
|
||||||
|
Format_UnsDec(CONS_UART_Write, xTaskGetTickCount());
|
||||||
|
Format_String(CONS_UART_Write, "ms\n");
|
||||||
|
xSemaphoreGive(CONS_Mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(WANrx)
|
||||||
|
{ TRX.WriteMode(RF_OPMODE_STANDBY); // TRX to standby
|
||||||
|
TRX.setLoRa(); // switch to LoRa mode (through sleep)
|
||||||
|
TRX.WriteMode(RF_OPMODE_LORA_STANDBY); // TRX in standby
|
||||||
|
SetFreqPlanWAN(); // WAN frequency plan
|
||||||
|
TRX.WAN_Configure(); // LoRa for WAN config.
|
||||||
|
TRX.setChannel(WANdev.Chan); // set the channel
|
||||||
|
TRX.LoRa_InvertIQ(1); TRX.LoRa_setCRC(0); TRX.LoRa_setIRQ(0); // setup for WAN RX
|
||||||
|
TRX.WriteMode(RF_OPMODE_LORA_RX_SINGLE); // wait for a single packet
|
||||||
|
int Wait=WAN_RespLeft+100;
|
||||||
|
for( ; Wait>0; Wait--)
|
||||||
|
{ vTaskDelay(1);
|
||||||
|
if(TRX.readIRQ()) break; }
|
||||||
|
if(Wait)
|
||||||
|
{ TRX.LoRa_ReceivePacket(WAN_RxPacket);
|
||||||
|
xSemaphoreTake(CONS_Mutex, portMAX_DELAY);
|
||||||
|
Format_String(CONS_UART_Write, "LoRaWAN Rx: ");
|
||||||
|
Format_UnsDec(CONS_UART_Write, (uint16_t)WAN_RxPacket.Len);
|
||||||
|
Format_String(CONS_UART_Write, "B/");
|
||||||
|
Format_UnsDec(CONS_UART_Write, (unsigned)Wait);
|
||||||
|
Format_String(CONS_UART_Write, "ms ");
|
||||||
|
Format_UnsDec(CONS_UART_Write, xTaskGetTickCount());
|
||||||
|
Format_String(CONS_UART_Write, "ms\n");
|
||||||
|
xSemaphoreGive(CONS_Mutex);
|
||||||
|
if(WANdev.State==1) WANdev.procJoinAccept(WAN_RxPacket);
|
||||||
|
else if(WANdev.State==3) WANdev.procRxData(WAN_RxPacket);
|
||||||
|
}
|
||||||
|
else WANdev.State--;
|
||||||
|
WANdev.WriteToNVS();
|
||||||
|
TRX.setFSK(); // back to FSK
|
||||||
|
SetFreqPlanOGN(); // OGN frequency plan
|
||||||
|
TRX.OGN_Configure(0, OGN_SYNC); // OGN config
|
||||||
|
SetRxChannel();
|
||||||
|
TRX.WriteMode(RF_OPMODE_RECEIVER); // switch to receive mode
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#else
|
||||||
|
// if(TimeSync_msTime()<260);
|
||||||
|
{ uint32_t RxRssiSum=0; uint16_t RxRssiCount=0; // measure the average RSSI for lower frequency
|
||||||
|
do
|
||||||
|
{ ReceivePacket(); // keep checking for received packets
|
||||||
#ifdef WITH_RFM69
|
#ifdef WITH_RFM69
|
||||||
TRX.TriggerRSSI();
|
TRX.TriggerRSSI();
|
||||||
|
#endif
|
||||||
|
vTaskDelay(1);
|
||||||
|
uint8_t RxRSSI=TRX.ReadRSSI(); // measure the channel noise level
|
||||||
|
RX_Random = (RX_Random<<1) | (RxRSSI&1);
|
||||||
|
RxRssiSum+=RxRSSI; RxRssiCount++;
|
||||||
|
} while(TimeSync_msTime()<270); // until 300ms from the PPS
|
||||||
|
RX_RSSI.Process(RxRssiSum/RxRssiCount); // [-0.5dBm] average noise on channel
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
vTaskDelay(1);
|
|
||||||
uint8_t RxRSSI=TRX.ReadRSSI(); // measure the channel noise level
|
|
||||||
RX_Random = (RX_Random<<1) | (RxRSSI&1);
|
|
||||||
RxRssiSum+=RxRSSI; RxRssiCount++;
|
|
||||||
} while(TimeSync_msTime()<270); // until 300ms from the PPS
|
|
||||||
RX_RSSI.Process(RxRssiSum/RxRssiCount); // [-0.5dBm] average noise on channel
|
|
||||||
|
|
||||||
TRX.WriteMode(RF_OPMODE_STANDBY); // switch to standy
|
TRX.WriteMode(RF_OPMODE_STANDBY); // switch to standy
|
||||||
vTaskDelay(1);
|
vTaskDelay(1);
|
||||||
|
@ -279,7 +344,7 @@ extern "C"
|
||||||
TRX.WriteMode(RF_OPMODE_STANDBY);
|
TRX.WriteMode(RF_OPMODE_STANDBY);
|
||||||
vTaskDelay(1); }
|
vTaskDelay(1); }
|
||||||
|
|
||||||
SetFreqPlan();
|
SetFreqPlanOGN();
|
||||||
|
|
||||||
TRX.averRSSI=RX_RSSI.getOutput();
|
TRX.averRSSI=RX_RSSI.getOutput();
|
||||||
|
|
||||||
|
@ -307,7 +372,7 @@ extern "C"
|
||||||
TRX.WriteMode(RF_OPMODE_RECEIVER); // switch to receive mode
|
TRX.WriteMode(RF_OPMODE_RECEIVER); // switch to receive mode
|
||||||
vTaskDelay(1);
|
vTaskDelay(1);
|
||||||
|
|
||||||
RxRssiSum=0; RxRssiCount=0; // measure the average RSSI for the upper frequency
|
uint32_t RxRssiSum=0; uint16_t RxRssiCount=0; // measure the average RSSI for the upper frequency
|
||||||
do
|
do
|
||||||
{ ReceivePacket(); // check for packets being received ?
|
{ ReceivePacket(); // check for packets being received ?
|
||||||
#ifdef WITH_RFM69
|
#ifdef WITH_RFM69
|
||||||
|
@ -349,6 +414,7 @@ extern "C"
|
||||||
{ TRX.setLoRa(); // switch TRX to LoRa
|
{ TRX.setLoRa(); // switch TRX to LoRa
|
||||||
TRX.FNT_Configure();
|
TRX.FNT_Configure();
|
||||||
// TRX.setChannel(0); // configure for FANET
|
// TRX.setChannel(0); // configure for FANET
|
||||||
|
TRX.WriteTxPower(Parameters.getTxPower());
|
||||||
TRX.WriteMode(RF_OPMODE_LORA_RX_CONT);
|
TRX.WriteMode(RF_OPMODE_LORA_RX_CONT);
|
||||||
vTaskDelay(2);
|
vTaskDelay(2);
|
||||||
for(uint8_t Wait=50; Wait; Wait--)
|
for(uint8_t Wait=50; Wait; Wait--)
|
||||||
|
@ -389,9 +455,65 @@ extern "C"
|
||||||
TRX.WriteMode(RF_OPMODE_RECEIVER); // switch to receive mode
|
TRX.WriteMode(RF_OPMODE_RECEIVER); // switch to receive mode
|
||||||
|
|
||||||
XorShift32(RX_Random);
|
XorShift32(RX_Random);
|
||||||
TxTime = (RX_Random&0x3F)+1; TxTime*=6;
|
TxTime = (RX_Random&0x3F)+1; TxTime*=6; // [ms] (1..64)*6 = 6..384ms
|
||||||
|
#ifdef WITH_LORAWAN
|
||||||
|
bool WANtx = 0; // decide if send Join-Request
|
||||||
|
uint16_t SlotEnd = 1240;
|
||||||
|
if(WANdev.State==0 || WANdev.State==2)
|
||||||
|
{ XorShift32(RX_Random); if((RX_Random&0x3F)==0x20) WANtx=1; SlotEnd=1200; }
|
||||||
|
TimeSlot(TxChan, SlotEnd-TimeSync_msTime(), TxPktData1, TRX.averRSSI, 0, TxTime);
|
||||||
|
#else
|
||||||
TimeSlot(TxChan, 1250-TimeSync_msTime(), TxPktData1, TRX.averRSSI, 0, TxTime);
|
TimeSlot(TxChan, 1250-TimeSync_msTime(), TxPktData1, TRX.averRSSI, 0, TxTime);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef WITH_LORAWAN
|
||||||
|
if(WANtx)
|
||||||
|
{ TRX.WriteMode(RF_OPMODE_STANDBY); // TRX to standby
|
||||||
|
TRX.setLoRa(); // switch to LoRa mode (through sleep)
|
||||||
|
TRX.WriteMode(RF_OPMODE_LORA_STANDBY); // TRX in standby
|
||||||
|
SetFreqPlanWAN(); // WAN frequency plan
|
||||||
|
TRX.WAN_Configure(); // LoRa for WAN config.
|
||||||
|
XorShift32(RX_Random); // random
|
||||||
|
WANdev.Chan = RX_Random&7; // choose random channel
|
||||||
|
TRX.setChannel(WANdev.Chan); // set the channel
|
||||||
|
TRX.LoRa_InvertIQ(0); TRX.LoRa_setCRC(1); // setup for WAN TX
|
||||||
|
TRX.WriteTxPower(Parameters.getTxPower()); // transmit power
|
||||||
|
int RespDelay=0;
|
||||||
|
int TxPktLen=0;
|
||||||
|
if(WANdev.State==0)
|
||||||
|
{ uint8_t *TxPacket; int TxPktLen=WANdev.getJoinRequest(&TxPacket); // produce Join-Request packet
|
||||||
|
TRX.LoRa_SendPacket(TxPacket, TxPktLen); RespDelay=5000; // transmit join-request packet
|
||||||
|
} else if(WANdev.State==2)
|
||||||
|
{ const uint8_t *PktData=TxPktData0;
|
||||||
|
if(PktData==0) PktData=TxPktData1;
|
||||||
|
if(PktData)
|
||||||
|
{ ((OGN1_Packet *)PktData)->Dewhiten();
|
||||||
|
uint8_t *TxPacket;
|
||||||
|
TxPktLen=WANdev.getDataPacket(&TxPacket, PktData, 20, 1, ((RX_Random>>16)&0xF)==0x8 );
|
||||||
|
TRX.LoRa_SendPacket(TxPacket, TxPktLen); RespDelay=1000; }
|
||||||
|
}
|
||||||
|
if(RespDelay)
|
||||||
|
{ vTaskDelay(8);
|
||||||
|
for( uint8_t Wait=100; Wait; Wait--) // wait for the end of transmission
|
||||||
|
{ vTaskDelay(1);
|
||||||
|
uint8_t Mode=TRX.ReadMode();
|
||||||
|
if(Mode!=RF_OPMODE_LORA_TX) break; }
|
||||||
|
WAN_RespTick=xTaskGetTickCount()+RespDelay; // when to expect the response: 5sec after the end of Join-Request packet
|
||||||
|
xSemaphoreTake(CONS_Mutex, portMAX_DELAY);
|
||||||
|
Format_String(CONS_UART_Write, "LoRaWAN Tx: ");
|
||||||
|
Format_UnsDec(CONS_UART_Write, (unsigned)TxPktLen);
|
||||||
|
Format_String(CONS_UART_Write, "B ");
|
||||||
|
Format_UnsDec(CONS_UART_Write, xTaskGetTickCount());
|
||||||
|
Format_String(CONS_UART_Write, "ms\n");
|
||||||
|
xSemaphoreGive(CONS_Mutex);
|
||||||
|
}
|
||||||
|
TRX.setFSK(); // back to FSK
|
||||||
|
SetFreqPlanOGN(); // OGN frequency plan
|
||||||
|
TRX.OGN_Configure(0, OGN_SYNC); // OGN config
|
||||||
|
SetRxChannel();
|
||||||
|
TRX.WriteMode(RF_OPMODE_RECEIVER); // switch to receive mode
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if(TxPkt0) RF_TxFIFO.Read();
|
if(TxPkt0) RF_TxFIFO.Read();
|
||||||
if(TxPkt1) RF_TxFIFO.Read();
|
if(TxPkt1) RF_TxFIFO.Read();
|
||||||
|
|
10
main/rfm.h
10
main/rfm.h
|
@ -47,6 +47,7 @@ class RFM_LoRa_Config
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
const RFM_LoRa_Config RFM_FNTcfg { 0xF1587190 } ; // LoRa seting for FANET
|
const RFM_LoRa_Config RFM_FNTcfg { 0xF1587190 } ; // LoRa seting for FANET
|
||||||
|
const RFM_LoRa_Config RFM_WANcfg { 0x34877190 } ; // LoRa WAN setting for TX
|
||||||
|
|
||||||
class RFM_LoRa_RxPacket
|
class RFM_LoRa_RxPacket
|
||||||
{ public:
|
{ public:
|
||||||
|
@ -246,6 +247,8 @@ class RFM_TRX
|
||||||
// bool (*DIO4_isOn)(void);
|
// bool (*DIO4_isOn)(void);
|
||||||
void (*RESET)(uint8_t On); // activate or desactivate the RF chip reset
|
void (*RESET)(uint8_t On); // activate or desactivate the RF chip reset
|
||||||
|
|
||||||
|
bool readIRQ(void) { return (*DIO0_isOn)(); }
|
||||||
|
|
||||||
// the following are in units of the synthesizer with 8 extra bits of precision
|
// the following are in units of the synthesizer with 8 extra bits of precision
|
||||||
uint32_t BaseFrequency; // [32MHz/2^19/2^8] base frequency = channel #0
|
uint32_t BaseFrequency; // [32MHz/2^19/2^8] base frequency = channel #0
|
||||||
// int32_t FrequencyCorrection; // [32MHz/2^19/2^8] frequency correction (due to Xtal offset)
|
// int32_t FrequencyCorrection; // [32MHz/2^19/2^8] frequency correction (due to Xtal offset)
|
||||||
|
@ -613,6 +616,11 @@ class RFM_TRX
|
||||||
RFM_LoRa_Config CFG = RFM_FNTcfg; CFG.CR=CR;
|
RFM_LoRa_Config CFG = RFM_FNTcfg; CFG.CR=CR;
|
||||||
return LoRa_Configure(CFG, FANET_Packet::MaxBytes); }
|
return LoRa_Configure(CFG, FANET_Packet::MaxBytes); }
|
||||||
|
|
||||||
|
int WAN_Configure(uint8_t CR=1) // configure for FANET/LoRa
|
||||||
|
{ WriteTxPower(0);
|
||||||
|
RFM_LoRa_Config CFG = RFM_WANcfg; CFG.CR=CR;
|
||||||
|
return LoRa_Configure(CFG, 40); }
|
||||||
|
|
||||||
void LoRa_setIRQ(uint8_t Mode=0) // 0:on RX, 1:on TX, 2: on CAD
|
void LoRa_setIRQ(uint8_t Mode=0) // 0:on RX, 1:on TX, 2: on CAD
|
||||||
{ WriteByte(Mode<<6, REG_DIOMAPPING1); }
|
{ WriteByte(Mode<<6, REG_DIOMAPPING1); }
|
||||||
|
|
||||||
|
@ -662,7 +670,7 @@ class RFM_TRX
|
||||||
Packet.FreqOfs = (FreqOfs*1718+0x8000)>>16; // [10Hz]
|
Packet.FreqOfs = (FreqOfs*1718+0x8000)>>16; // [10Hz]
|
||||||
Packet.BitErr = 0;
|
Packet.BitErr = 0;
|
||||||
Packet.CodeErr = 0;
|
Packet.CodeErr = 0;
|
||||||
int Len=LoRa_ReceivePacket(Packet.Byte, Packet.MaxBytes);
|
int Len=LoRa_ReceivePacket(Packet.Byte, Packet.MaxBytes); // read packet data
|
||||||
// printf("ReceivePacketFNT() => %d %02X %3.1fdB %+ddBm 0x%08X=%+6.3fkHz, %02X%02X%02X%02X\n",
|
// printf("ReceivePacketFNT() => %d %02X %3.1fdB %+ddBm 0x%08X=%+6.3fkHz, %02X%02X%02X%02X\n",
|
||||||
// Packet.Len, Stat, 0.25*Packet.SNR, Packet.RSSI, FreqOfs, 0.5*0x1000000/32e9*FreqOfs,
|
// Packet.Len, Stat, 0.25*Packet.SNR, Packet.RSSI, FreqOfs, 0.5*0x1000000/32e9*FreqOfs,
|
||||||
// Packet.Byte[0], Packet.Byte[1], Packet.Byte[2], Packet.Byte[3]);
|
// Packet.Byte[0], Packet.Byte[1], Packet.Byte[2], Packet.Byte[3]);
|
||||||
|
|
Ładowanie…
Reference in New Issue