diff --git a/main/ctrl.cpp b/main/ctrl.cpp index 7e14067..0b05094 100644 --- a/main/ctrl.cpp +++ b/main/ctrl.cpp @@ -250,7 +250,7 @@ static void ProcessCtrlC(void) // print system Parameters.Write(CONS_UART_Write); // write the parameters to the console // Parameters.WriteFile(stdout); // write the parameters to the stdout - Format_String(CONS_UART_Write, "Batt: "); + Format_String(CONS_UART_Write, "Batt:"); Format_UnsDec(CONS_UART_Write, (10*BatteryVoltage+128)>>8, 5, 4); Format_String(CONS_UART_Write, "V "); Format_SignDec(CONS_UART_Write, (600*BatteryVoltageRate+128)>>8, 3, 1); @@ -269,13 +269,13 @@ static void ProcessCtrlC(void) // print system Format_UnsDec(CONS_UART_Write, Batt, 4, 3); Format_String(CONS_UART_Write, "V "); Format_UnsDec(CONS_UART_Write, InpCurr, 4, 3); - Format_String(CONS_UART_Write, "/"); + Format_String(CONS_UART_Write, "-"); Format_UnsDec(CONS_UART_Write, OutCurr, 4, 3); Format_String(CONS_UART_Write, "A USB:"); Format_UnsDec(CONS_UART_Write, Vbus, 4, 3); Format_String(CONS_UART_Write, "V "); Format_UnsDec(CONS_UART_Write, VbusCurr, 4, 3); - Format_String(CONS_UART_Write, "A Charge:"); + Format_String(CONS_UART_Write, "A CC:"); Format_UnsDec(CONS_UART_Write, ((InpCharge<<12)+562)/1125, 2, 1); Format_String(CONS_UART_Write, "-"); Format_UnsDec(CONS_UART_Write, ((OutCharge<<12)+562)/1125, 2, 1); diff --git a/main/disp_oled.cpp b/main/disp_oled.cpp index 1bc3279..ec333d4 100644 --- a/main/disp_oled.cpp +++ b/main/disp_oled.cpp @@ -292,6 +292,9 @@ void OLED_DrawRF(u8g2_t *OLED, GPS_Position *GPS) // RF #ifdef WITH_RFM95 Len+=Format_String(Line+Len, "RFM95"); #endif +#ifdef WITH_SX1262 + Len+=Format_String(Line+Len, "SX1262"); +#endif #ifdef WITH_SX1272 Len+=Format_String(Line+Len, "SX1272"); #endif @@ -666,6 +669,9 @@ void OLED_DrawSystem(u8g2_t *OLED, GPS_Position *GPS) #ifdef WITH_RFM95 Len+=Format_String(Line+Len, "RFM95 v"); #endif +#ifdef WITH_SX1262 + Len+=Format_String(Line+Len, "SX1262 v"); +#endif #ifdef WITH_SX1272 Len+=Format_String(Line+Len, "SX1272 v"); #endif diff --git a/main/hal.cpp b/main/hal.cpp index 096b117..aa2a782 100644 --- a/main/hal.cpp +++ b/main/hal.cpp @@ -1467,6 +1467,7 @@ void vApplicationTickHook(void) // RTOS timer tick hook // AXP192 #ifdef WITH_AXP +// SemaphoreHandle_t AXP_Mutex; AXP192 AXP; #endif diff --git a/main/hal.h b/main/hal.h index baa3893..e2153d8 100644 --- a/main/hal.h +++ b/main/hal.h @@ -223,6 +223,7 @@ extern BQ24295 BQ; #ifdef WITH_AXP #include "axp192.h" +// extern SemaphoreHandle_t AXP_Mutex; extern AXP192 AXP; #endif diff --git a/main/lorawan.h b/main/lorawan.h index 207a824..a546e81 100644 --- a/main/lorawan.h +++ b/main/lorawan.h @@ -55,7 +55,7 @@ class LoRaWANnode bool SaveReq:1; // Request to save the node state } ; } ; - uint8_t Spare; // 112 bytes up to this point + uint8_t RxSilent; // count non-receptions <- 112 bytes up to (and including) this point uint32_t LastSaved; // [sec] when saved to EEPROM or other permament storage uint8_t Dummy[8]; // just to fill up the space, could be used later uint32_t CRC32; // 128 bytes up to here: fits into 1kbit EEPROM @@ -72,7 +72,7 @@ class LoRaWANnode void Reset(void) { State=0; DevNonce=0; JoinNonce=0; - LastTx=0; TxCount=0; LastRx=0; RxCount=0; Flags=0; LastSaved=0; + LastTx=0; TxCount=0; LastRx=0; RxCount=0; RxSilent=0; Flags=0; LastSaved=0; setCRC(); } void Reset(uint64_t MAC, uint8_t *AppKey=0) @@ -82,7 +82,7 @@ class LoRaWANnode Reset(); } // reset to not-joined state void Disconnect(void) - { State=0; } + { State=0; RxSilent=0; } uint32_t calcCRC(void) const { uint32_t Sum=0x87654321; // start the sum with some magic diff --git a/main/main.cpp b/main/main.cpp index 9ea1fde..9e76b00 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -48,6 +48,9 @@ void app_main(void) CONS_UART_Init(); CONS_Mutex = xSemaphoreCreateMutex(); // semaphore for sharing the writing to the console I2C_Mutex = xSemaphoreCreateMutex(); // semaphore for sharing the I2C bus +#ifdef WITH_AXP + // AXP_Mutex = xSemaphoreCreateMutex(); // semaphore for sharing the AXP power controller +#endif NVS_Init(); // initialize Non-Volatile-Storage in Flash and read the tracker parameters @@ -79,7 +82,7 @@ void app_main(void) { WANdev.Reset(getUniqueID(), Parameters.AppKey); // then reset LoRaWAN to this key WANdev.WriteToNVS(); } // and save LoRaWAN config. to NVS Parameters.clrAppKey(); } - WANdev.Disconnect(); // restart with network join-request/accept at each restart + // WANdev.Disconnect(); // restart with network join-request/accept at each restart #endif CONS_UART_SetBaudrate(Parameters.CONbaud); diff --git a/main/ogn1.h b/main/ogn1.h index 592f382..5592ff8 100644 --- a/main/ogn1.h +++ b/main/ogn1.h @@ -184,14 +184,17 @@ class OGN1_Packet // Packet structure for the OGN tracker Out[Len++]='/'; Out[Len++]='0'+Status.FixQuality; Out[Len++]='/'; Len+=Format_UnsDec(Out+Len, Status.SatSNR+8); Out[Len++]='d'; Out[Len++]='B'; Out[Len++]=' '; Len+=Format_SignDec(Out+Len, DecodeAltitude(), 1, 0, 1); Out[Len++]='m'; - Out[Len++]=' '; Len+=Format_UnsDec(Out+Len, (((uint32_t)Status.Pressure<<3)+5)/10, 2, 1); Out[Len++]='h'; Out[Len++]='P'; Out[Len++]='a'; - Out[Len++]=' '; Len+=Format_SignDec(Out+Len, DecodeTemperature(), 2, 1); Out[Len++]='d'; Out[Len++]='e'; Out[Len++]='g'; Out[Len++]='C'; - Out[Len++]=' '; Len+=Format_SignDec(Out+Len, DecodeHumidity(), 2, 1); Out[Len++]='%'; + if(Status.Pressure>0) + { Out[Len++]=' '; Len+=Format_UnsDec(Out+Len, (((uint32_t)Status.Pressure<<3)+5)/10, 2, 1); Out[Len++]='h'; Out[Len++]='P'; Out[Len++]='a'; } + if(hasTemperature()) + { Out[Len++]=' '; Len+=Format_SignDec(Out+Len, DecodeTemperature(), 2, 1); Out[Len++]='d'; Out[Len++]='e'; Out[Len++]='g'; Out[Len++]='C'; } + if(hasHumidity()) + { Out[Len++]=' '; Len+=Format_SignDec(Out+Len, DecodeHumidity(), 2, 1); Out[Len++]='%'; } Out[Len++]=' '; Len+=Format_SignDec(Out+Len, ((uint32_t)DecodeVoltage()*100+32)>>6, 3, 2); Out[Len++]='V'; Out[Len++]=' '; Len+=Format_UnsDec(Out+Len, Status.TxPower+4); Out[Len++]='/'; Out[Len++]='-'; Len+=Format_UnsDec(Out+Len, 5*Status.RadioNoise, 2, 1); Out[Len++]='d'; Out[Len++]='B'; Out[Len++]='m'; Out[Len++]=' '; Len+=Format_UnsDec(Out+Len, (1<0) + { Out[Len++]=' '; Len+=Format_UnsDec(Out+Len, (((uint32_t)Status.Pressure<<3)+5)/10, 2, 1); Out[Len++]='h'; Out[Len++]='P'; Out[Len++]='a'; } + if(hasTemperature()) + { Out[Len++]=' '; Len+=Format_SignDec(Out+Len, DecodeTemperature(), 2, 1); Out[Len++]='d'; Out[Len++]='e'; Out[Len++]='g'; Out[Len++]='C'; } + if(hasHumidity()) + { Out[Len++]=' '; Len+=Format_SignDec(Out+Len, DecodeHumidity(), 2, 1); Out[Len++]='%'; } + Out[Len++]=' '; Len+=Format_SignDec(Out+Len, ((uint32_t)DecodeVoltage()*100+32)>>6, 3, 2); Out[Len++]='V'; + Out[Len++]=' '; Len+=Format_UnsDec(Out+Len, Status.TxPower+4); + Out[Len++]='/'; Out[Len++]='-'; Len+=Format_UnsDec(Out+Len, 5*Status.RadioNoise, 2, 1); Out[Len++]='d'; Out[Len++]='B'; Out[Len++]='m'; + Out[Len++]=' '; Len+=Format_UnsDec(Out+Len, (1<>8; } // remove the sync '$' // void setAddress(uint32_t Addr) { Address = (Addr<<8) | 0x24; } // set new address and set the '$' sync char - int Copy(const OGN1_Packet &Packet, bool Ext=0) + int Copy(const OGN1_Packet &Packet /* , bool Ext=0 */ ) // convert from an OGN packet { Clear(); Address = Packet.Header.Address; // [24-bit] if(Packet.Header.NonPos) return 0; // encode only position packets @@ -84,6 +86,7 @@ class PAW_Packet Speed = (398*(int32_t)Packet.DecodeSpeed()+1024)>>11; // [0.1m/s] => [kts] Latitude = 0.0001f/60*Packet.DecodeLatitude(); // [deg] Longitude = 0.0001f/60*Packet.DecodeLongitude(); // [deg] +/* if(Ext) { OGN=1; // extended data flag AddrType = Packet.Header.AddrType; // [2-bit] @@ -94,10 +97,11 @@ class PAW_Packet if(ClimbRate>127) ClimbRate=127; else if(ClimbRate<(-127)) ClimbRate=(-127); Climb = ClimbRate; } +*/ SeqMsg = 0; setCRC(); return 1; } - int WriteJSON(char *JSON) const + int WriteStxJSON(char *JSON) const { int Len=0; Len+=Format_String(JSON+Len, "\"addr\":\""); Len+=Format_Hex(JSON+Len, (uint8_t) (Address>>16)); @@ -121,7 +125,7 @@ class PAW_Packet // Len+=Format_SignDec(JSON+Len, RxTime, 4, 3, 1); Len+=sprintf(JSON+Len, ",\"lat_deg\":%8.7f,\"lon_deg\":%8.7f,\"alt_msl_m\":%d", Latitude, Longitude, Altitude); Len+=sprintf(JSON+Len, ",\"track_deg\":%d,\"speed_mps\":%3.1f", Heading, 0.514*Speed); - if(OGN) Len+=sprintf(JSON+Len, ",\"climb_mps\":%3.1f", 0.32512*Climb); + // if(OGN) Len+=sprintf(JSON+Len, ",\"climb_mps\":%3.1f", 0.32512*Climb); return Len; } uint8_t Dump(char *Out) @@ -136,7 +140,8 @@ class PAW_Packet TypeByte, Address, Latitude, Longitude, Altitude, Heading, Speed, Seq, Msg[0], Msg[1], Msg[2]); for(int Idx=0; Idx<3; Idx++) { printf("%c", Msg[Idx]<' '?'.':Msg[Idx]); } - printf("\n"); } + // printf(" %c%c%c\n", Relay?'R':'_', OGN?'O':'_', '0'+AddrType); + printf(" %04X %04X\n", HeadWord, SpeedWord); } uint8_t Read(const char *Inp) // read packet from a hex dump { uint8_t Len; @@ -201,9 +206,9 @@ class PAW_Packet } ; -class PAW_RxPacket // Received PilotAware packet +class PAW_RxPacket: public PAW_Packet // Received PilotAware packet { public: - PAW_Packet Packet; + // PAW_Packet Packet; // uint8_t CRC; // [] external CRC (we assume it is correct) uint8_t CSNR; // [0.5dB] carrier Signal-to-Noise Ratio uint8_t SNR; // [0.25dB] @@ -214,14 +219,18 @@ class PAW_RxPacket // Received PilotAware packet public: void Print(void) { printf("PAW: %d.%03ds: %02X:%06X [%+09.5f, %+010.5f]deg %4dm, %03ddeg %3dkt #%02X %3.1f/%3.1fdB %+4.1fkHz\n", - Time, nsTime/1000000, Packet.TypeByte, Packet.Address, Packet.Latitude, Packet.Longitude, Packet.Altitude, Packet.Heading, Packet.Speed, - Packet.Seq, 0.25*SNR, 0.5*CSNR, 0.01*FreqOfs); } + Time, nsTime/1000000, TypeByte, Address, Latitude, Longitude, Altitude, Heading, Speed, + Seq, 0.25*SNR, 0.5*CSNR, 0.01*FreqOfs); } - int WriteJSON(char *JSON) const - { int Len = Packet.WriteJSON(JSON); + uint32_t getSlotTime(void) const + { if(nsTime>=300000000) return Time; + return Time-1; } + + int WriteStxJSON(char *JSON) const + { int Len = PAW_Packet::WriteStxJSON(JSON); uint32_t PosTime=Time; if(nsTime<300000000) PosTime--; - if(Packet.OGN) - { } + // if(OGN) + // { } Len+=Format_String(JSON+Len, ",\"time\":"); Len+=Format_UnsDec(JSON+Len, PosTime); int64_t RxTime=(int64_t)Time-PosTime; RxTime*=1000; RxTime+=nsTime/1000000; diff --git a/main/proc.cpp b/main/proc.cpp index 982b673..a0f8382 100644 --- a/main/proc.cpp +++ b/main/proc.cpp @@ -251,7 +251,11 @@ static void ReadStatus(OGN_Packet &Packet) #endif #endif +#ifdef WITH_SX1262 + if(Packet.Status.Pressure==0) Packet.clrTemperature(); +#else if(Packet.Status.Pressure==0) Packet.EncodeTemperature(TRX.chipTemp*10); // [0.1degC] +#endif Packet.Status.RadioNoise = TRX.averRSSI; // [-0.5dBm] write radio noise to the status packet uint8_t TxPower = Parameters.TxPower-4; diff --git a/main/rf.cpp b/main/rf.cpp index 7846799..1ac8847 100644 --- a/main/rf.cpp +++ b/main/rf.cpp @@ -456,16 +456,21 @@ extern "C" { TRX.LoRa_ReceivePacket(WAN_RxPacket); xSemaphoreTake(CONS_Mutex, portMAX_DELAY); Format_UnsDec(CONS_UART_Write, xTaskGetTickCount(), 4, 3); - Format_String(CONS_UART_Write, "s LoRaWAN Rx: "); + Format_String(CONS_UART_Write, "s LoRaWAN Rx["); + CONS_UART_Write('0'+WANdev.State); + Format_String(CONS_UART_Write, "]: "); Format_UnsDec(CONS_UART_Write, (uint16_t)WAN_RxPacket.Len); Format_String(CONS_UART_Write, "B/"); - Format_UnsDec(CONS_UART_Write, (unsigned)Wait); + Format_UnsDec(CONS_UART_Write, (unsigned)Wait); // amount of timeout left Format_String(CONS_UART_Write, "ms\n"); xSemaphoreGive(CONS_Mutex); if(WANdev.State==1) WANdev.procJoinAccept(WAN_RxPacket); // if join-request state then expect a join-accept packet else if(WANdev.State==3) RxLen=WANdev.procRxData(WAN_RxPacket); // if data send then respect ACK and/or downlink data packet + WANdev.RxSilent=0; } - else WANdev.State--; // if no packet received then retreat the State + else // if no packet received then retreat the State + { WANdev.State--; + WANdev.RxSilent++; if(WANdev.RxSilent>30) WANdev.Disconnect(); } // count silence when reception expected, if too many then disconnect TRX.setFSK(); // back to FSK SetFreqPlanOGN(); // OGN frequency plan TRX.OGN_Configure(0, OGN_SYNC); // OGN config @@ -545,7 +550,7 @@ extern "C" RX_Channel = TxChan; SetRxChannel(); TRX.setModeRX(); // switch to receive mode - TRX.ClearIrqFlags(); // here we can read the chip temperature + TRX.ClearIrqFlags(); // here we can read the chip temperature vTaskDelay(1); uint32_t RxRssiSum=0; uint16_t RxRssiCount=0; // measure the average RSSI for the upper frequency @@ -657,11 +662,11 @@ extern "C" OGN1_Packet TxPkt = TxPkt0->Packet; TxPkt.Dewhiten(); // de-whiten the OGN packet so it can be converted to PAW format XorShift32(RX_Random); // convert PAW to OGN - if(PAWtxBackOff==0 && Parameters.TxPower!=(-32) && !TxPkt.Header.Relay && Packet.Copy(TxPkt) && TxPkt.Position.Time<60) - { TRX.setModeStandby(); + if(PAWtxBackOff==0 && Parameters.TxPower!=(-32) && TxPkt.Header.NonPos==0 && !TxPkt.Header.Relay && Packet.Copy(TxPkt) && TxPkt.Position.Time<60) + { TRX.setModeStandby(); // TRX.PAW_Configure(PAW_SYNC); - TRX.WriteTxPower(Parameters.TxPower+6); - vTaskDelay(RX_Random&0x3F); + TRX.WriteTxPower(Parameters.TxPower+6); // + vTaskDelay(RX_Random&0x3F); // TRX.ClearIrqFlags(); TRX.PAW_WritePacket(Packet.Byte, 24); // TRX.setModeTX(); // @@ -722,16 +727,21 @@ extern "C" } if(RespDelay) { vTaskDelay(8); - for( uint8_t Wait=100; Wait; Wait--) // wait for the end of transmission + uint8_t Wait = 100; // [ms] + for( ; Wait; Wait--) // wait for the end of transmission { vTaskDelay(1); if(!TRX.isModeLoRaTX()) break; } // uint8_t Mode=TRX.ReadMode(); // if(Mode!=RF_OPMODE_LORA_TX) break; } WAN_RespTick=xTaskGetTickCount()+RespDelay; // when to expect the response after the end of transmitted packet xSemaphoreTake(CONS_Mutex, portMAX_DELAY); Format_UnsDec(CONS_UART_Write, xTaskGetTickCount(), 4, 3); - Format_String(CONS_UART_Write, "s LoRaWAN Tx: "); - Format_UnsDec(CONS_UART_Write, (unsigned)TxPktLen); - Format_String(CONS_UART_Write, "B\n"); + Format_String(CONS_UART_Write, "s LoRaWAN Tx["); + CONS_UART_Write('0'+WANdev.State); + Format_String(CONS_UART_Write, "]: "); + Format_UnsDec(CONS_UART_Write, (unsigned)TxPktLen); // packet size + Format_String(CONS_UART_Write, "B/"); + Format_UnsDec(CONS_UART_Write, (unsigned)Wait); // amount of timeout left + Format_String(CONS_UART_Write, "ms\n"); xSemaphoreGive(CONS_Mutex); } TRX.setFSK(); // back to FSK diff --git a/main/sx1262.h b/main/sx1262.h index 3f4c17c..bf9f9fc 100644 --- a/main/sx1262.h +++ b/main/sx1262.h @@ -27,11 +27,11 @@ #define CMD_SETRFFREQUENCY 0x86 // [4] frequency [Fxtal/2^25] #define CMD_SETPACKETTYPE 0x8A // [1] 0x00=GFSK, 0x01=LoRa (must be the first configuration command) -#define CMD_GETPACKETTYPE 0x11 +#define CMD_GETPACKETTYPE 0x11 // [ ] #define CMD_SETTXPARAMS 0x8E // [2] TxPower: -17..+14 or -9..+22 [dBm] depending on PA config RampTime: 0..7: 10,20,40,80,200,800,1700,3400us #define CMD_SETMODULATIONPARAMS 0x8B // [8] depends on the protocol: FSK or LoRa #define CMD_SETPACKETPARAMS 0x8C // [9] -#define CMD_SETCADPARAMS 0x88 +#define CMD_SETCADPARAMS 0x88 // [ ] #define CMD_SETBUFFERBASEADDRESS 0x8F // [2] Tx-base address, Rx-base address #define CMD_SETLORASYMBNUMTIMEOUT 0xA0 // [1] timeout [symbols] @@ -69,7 +69,7 @@ #define REG_RANDOMNUMBERGEN2 0x081B #define REG_RANDOMNUMBERGEN3 0x081C #define REG_RXGAIN 0x08AC -#define REG_OCPCONFIG 0x08E7 +#define REG_OCPCONFIG 0x08E7 // max. PA current ? #define REG_XTATRIM 0x0911 #define REG_XTBTRIM 0x0912