diff --git a/main/hal.cpp b/main/hal.cpp index dc6d0d3..0c86886 100644 --- a/main/hal.cpp +++ b/main/hal.cpp @@ -279,6 +279,9 @@ GPIO HELTEC TTGO JACEK M5_JACEK T-Beam T-Beamv10 Foll #ifdef WITH_TBEAM_V10 #define PIN_RFM_RST GPIO_NUM_23 // Reset 23 #define PIN_RFM_IRQ GPIO_NUM_26 // packet done on receive or transmit +#ifdef WITH_SX1262 +#define PIN_RFM_BUSY GPIO_NUM_32 // for the T-Beam with SX1262 +#endif #define PIN_RFM_SS GPIO_NUM_18 // SPI chip-select #define PIN_RFM_SCK GPIO_NUM_5 // SPI clock #define PIN_RFM_MISO GPIO_NUM_19 // SPI MISO @@ -910,7 +913,7 @@ void RFM_RESET_SetInput (void) { gpio_set_direction(PIN_RFM_RST, GPIO_M void RFM_RESET_SetOutput (void) { gpio_set_direction(PIN_RFM_RST, GPIO_MODE_OUTPUT); } void RFM_RESET_SetLevel (uint8_t High) { gpio_set_level(PIN_RFM_RST, High&1); } -#ifdef WITH_RFM95 // for RFM95 reset is low-active +#if defined(WITH_RFM95) || defined(WITH_SX1272) || defined(WITH_SX1262) // for RFM95 reset is low-active void RFM_RESET(uint8_t On) { if(On&1) { RFM_RESET_SetOutput(); RFM_RESET_SetLevel(0); } else RFM_RESET_SetInput(); } #endif @@ -925,7 +928,10 @@ void RFM_RESET(uint8_t On) { } 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); } - +#ifdef WITH_SX1262 +void RFM_Busy_SetInput(void) { gpio_set_direction(PIN_RFM_BUSY, GPIO_MODE_INPUT); } +bool RFM_Busy_isOn(void) { return gpio_get_level(PIN_RFM_BUSY); } +#endif void RFM_Delay(int ms) { vTaskDelay(ms); } static spi_device_handle_t RFM_SPI; @@ -1864,6 +1870,9 @@ void IO_Configuration(void) #endif RFM_IRQ_SetInput(); +#ifdef WITH_SX1262 + RFM_Busy_SetInput(); +#endif RFM_RESET_SetOutput(); RFM_RESET(0); diff --git a/main/hal.h b/main/hal.h index da57d97..8c0d0da 100644 --- a/main/hal.h +++ b/main/hal.h @@ -96,6 +96,10 @@ void RFM_TransferBlock(uint8_t *Data, uint8_t Len); void RFM_RESET(uint8_t On); // RF module reset bool RFM_IRQ_isOn(void); // query the IRQ state void RFM_Delay(int ms); // [ms] idle delay +#ifdef WITH_SX1262 +void RFM_Busy_SetInput(void); +bool RFM_Busy_isOn(void); +#endif #ifdef WITH_OLED int OLED_DisplayON(uint8_t ON, uint8_t DispIdx=0); // when OFF then low-power mode diff --git a/main/nmea.h b/main/nmea.h index 72f33be..ff603b2 100644 --- a/main/nmea.h +++ b/main/nmea.h @@ -199,7 +199,7 @@ inline uint8_t NMEA_AppendCheckCRNL(char *NMEA, uint8_t Len) { return NMEA_Appen if(Data[4]!='X') return 0; return Data[5]=='T'; } - uint8_t isP(void) const + uint8_t isP(void) const // Private thus specific to the euqipment { return Data[1]=='P'; } uint8_t isPOGN(void) const // OGN dedicated NMEA sentence @@ -220,6 +220,13 @@ inline uint8_t NMEA_AppendCheckCRNL(char *NMEA, uint8_t Len) { return NMEA_Appen { if(!isPOGN()) return 0; return Data[5]=='S'; } + uint8_t isPGRMZ(void) // barometric pressure report + { if(!isP()) return 0; + if(Data[2]!='G') return 0; + if(Data[3]!='R') return 0; + if(Data[4]!='M') return 0; + return Data[5]=='Z'; } + uint8_t isPOGNL(void) // log file list request { if(!isPOGN()) return 0; return Data[5]=='L'; } diff --git a/main/ogn.h b/main/ogn.h index 98f417b..ab9831a 100644 --- a/main/ogn.h +++ b/main/ogn.h @@ -472,7 +472,7 @@ template Len+=Format_SignDec(Out+Len, -(int16_t)RxRSSI/2); Out[Len++]='d'; Out[Len++]='B'; Out[Len++]='m'; Out[Len++]=' '; Len+=Format_UnsDec(Out+Len, (uint16_t)Packet.Position.Time, 2); - Out[Len++]=' '; + Out[Len++]='s'; Out[Len++]=' '; Len+=Format_Latitude(Out+Len, Packet.DecodeLatitude()); Out[Len++]=' '; Len+=Format_Longitude(Out+Len, Packet.DecodeLongitude()); @@ -482,6 +482,9 @@ template Len+=Format_UnsDec(Out+Len, Packet.DecodeSpeed(), 2, 1); Out[Len++]='m'; Out[Len++]='/'; Out[Len++]='s'; Out[Len++]=' '; Len+=Format_SignDec(Out+Len, Packet.DecodeClimbRate(), 2, 1); Out[Len++]='m'; Out[Len++]='/'; Out[Len++]='s'; + Out[Len++]=' '; + Out[Len++]='r'; + Len+=Format_Hex(Out+Len, Rank); Out[Len++]='\n'; Out[Len]=0; return Len; } @@ -984,6 +987,8 @@ class GPS_Position: public GPS_Time Out[Len++]='/'; Len+=Format_SignDec(Out+Len, GeoidSeparation, 4, 1); Out[Len++]='m'; Out[Len++]=' '; Len+=Format_UnsDec(Out+Len, Speed, 2, 1); Out[Len++]='m'; Out[Len++]='/'; Out[Len++]='s'; Out[Len++]=' '; Len+=Format_UnsDec(Out+Len, Heading, 4, 1); Out[Len++]='d'; Out[Len++]='e'; Out[Len++]='g'; + Out[Len++]=' '; Len+=Format_SignDec(Out+Len, ClimbRate, 2, 1); Out[Len++]='m'; Out[Len++]='/'; Out[Len++]='s'; + Out[Len++]=' '; Len+=Format_SignDec(Out+Len, TurnRate, 2, 1); Out[Len++]='d'; Out[Len++]='e'; Out[Len++]='g'; Out[Len++]='/'; Out[Len++]='s'; if(hasBaro) { Out[Len++]=' '; Len+=Format_SignDec(Out+Len, Temperature, 2, 1); Out[Len++]='C'; Out[Len++]=' '; Len+=Format_UnsDec(Out+Len, Pressure/4 ); Out[Len++]='P'; Out[Len++]='a'; @@ -1030,12 +1035,13 @@ class GPS_Position: public GPS_Time return 1; } int8_t ReadNMEA(NMEA_RxMsg &RxMsg) - { if(RxMsg.isGPGGA()) return ReadGGA(RxMsg); - if(RxMsg.isGNGGA()) return ReadGGA(RxMsg); - if(RxMsg.isGPRMC()) return ReadRMC(RxMsg); - if(RxMsg.isGNRMC()) return ReadRMC(RxMsg); - if(RxMsg.isGPGSA()) return ReadGSA(RxMsg); - if(RxMsg.isGNGSA()) return ReadGSA(RxMsg); + { // if(RxMsg.isGPGGA()) return ReadGGA(RxMsg); + if(RxMsg.isGxGGA()) return ReadGGA(RxMsg); + // if(RxMsg.isGPRMC()) return ReadRMC(RxMsg); + if(RxMsg.isGxRMC()) return ReadRMC(RxMsg); + // if(RxMsg.isGPGSA()) return ReadGSA(RxMsg); + if(RxMsg.isGxGSA()) return ReadGSA(RxMsg); + if(RxMsg.isPGRMZ()) return ReadPGRMZ(RxMsg); // (pressure) altitude // if(RxMsg.isGxGSV()) return ReadGSV(RxMsg); return 0; } @@ -1047,6 +1053,17 @@ class GPS_Position: public GPS_Time // Err=ReadGSV(NMEA); if(Err!=(-1)) return Err; return 0; } + int8_t ReadPGRMZ(NMEA_RxMsg &RxMsg) + { if(RxMsg.Parms<3) return -2; + int8_t Ret=Read_Float1(StdAltitude, (const char *)(RxMsg.ParmPtr(0))); + if(Ret<=0) return -1; + char Unit=RxMsg.ParmPtr(1)[0]; + hasBaro=1; Pressure=0; Temperature=0; + if(Unit=='m' || Unit=='M') return 1; + if(Unit!='f' && Unit!='F') return -1; + StdAltitude = (StdAltitude*312+512)>>10; + return 1; } + int8_t ReadGGA(NMEA_RxMsg &RxMsg) { if(RxMsg.Parms<14) return -2; // no less than 14 paramaters hasGPS = ReadTime((const char *)RxMsg.ParmPtr(0))>0; // read time and check if same as the RMC says diff --git a/main/ogn1.h b/main/ogn1.h index 0ea2109..28b38db 100644 --- a/main/ogn1.h +++ b/main/ogn1.h @@ -317,10 +317,12 @@ class OGN1_Packet // Packet structure for the OGN tracker Len+=Format_UnsDec(JSON+Len, DecodeHeading(), 2, 1); Len+=Format_String(JSON+Len, ",\"speed_mps\":"); Len+=Format_UnsDec(JSON+Len, DecodeSpeed(), 2, 1); - Len+=Format_String(JSON+Len, ",\"climb_mps\":"); - Len+=Format_SignDec(JSON+Len, DecodeClimbRate(), 2, 1, 1); - Len+=Format_String(JSON+Len, ",\"turn_dps\":"); - Len+=Format_SignDec(JSON+Len, DecodeTurnRate(), 2, 1, 1); + if(hasClimbRate()) + { Len+=Format_String(JSON+Len, ",\"climb_mps\":"); + Len+=Format_SignDec(JSON+Len, DecodeClimbRate(), 2, 1, 1); } + if(hasTurnRate()) + { Len+=Format_String(JSON+Len, ",\"turn_dps\":"); + Len+=Format_SignDec(JSON+Len, DecodeTurnRate(), 2, 1, 1); } Len+=Format_String(JSON+Len, ",\"DOP\":"); Len+=Format_UnsDec(JSON+Len, 10+DecodeDOP(), 2, 1); } if(!Header.Encrypted && Header.NonPos) // non-encrypted status and info @@ -746,7 +748,7 @@ class OGN1_Packet // Packet structure for the OGN tracker { return (uint16_t)Position.Heading<<6; } void clrTurnRate(void) { Position.TurnRate=0x80; } // mark turn-rate as absent - bool hasTurnRate(void) const { return Position.TurnRate==0x80; } + bool hasTurnRate(void) const { return Position.TurnRate!=0x80; } void EncodeTurnRate(int16_t Turn) // [0.1 deg/sec] { Position.TurnRate = EncodeSR2V5(Turn); } @@ -755,7 +757,7 @@ class OGN1_Packet // Packet structure for the OGN tracker { return DecodeSR2V5(Position.TurnRate); } void clrClimbRate(void) { Position.ClimbRate=0x100; } // mark climb rate as absent - bool hasClimbRate(void) const { return Position.ClimbRate==0x100; } + bool hasClimbRate(void) const { return Position.ClimbRate!=0x100; } void EncodeClimbRate(int16_t Climb) { Position.ClimbRate = EncodeSR2V6(Climb); } diff --git a/main/paw.h b/main/paw.h index 2908591..f84982e 100644 --- a/main/paw.h +++ b/main/paw.h @@ -88,13 +88,12 @@ class PAW_Packet { OGN=1; // extended data flag AddrType = Packet.Header.AddrType; // [2-bit] Relay = Packet.Header.Relay; // relay flag - // Time = Packet.Position.Time; // [sec] + Time = Packet.Position.Time; // [sec] int32_t ClimbRate = Packet.DecodeClimbRate(); // [0.1m/s] ClimbRate = (ClimbRate*315+512)>>10; // [64fpm] if(ClimbRate>127) ClimbRate=127; else if(ClimbRate<(-127)) ClimbRate=(-127); - Climb = ClimbRate; - } + Climb = ClimbRate; } SeqMsg = 0; setCRC(); return 1; } diff --git a/main/rf.cpp b/main/rf.cpp index e7c5098..b10f3c9 100644 --- a/main/rf.cpp +++ b/main/rf.cpp @@ -91,7 +91,7 @@ static uint8_t ReceivePacket(void) // see if a pack // PktData.Print(); // for debug RF_RxFIFO.Write(); // complete the write to the receiver FIFO - // TRX.WriteMode(RFM69_OPMODE_RX); // back to receive (but we already have AutoRxRestart) + // TRX.setModeRX(); // back to receive (but we already have AutoRxRestart) return 1; } // return: 1 packet we have received static uint32_t ReceiveUntil(TickType_t End) @@ -125,28 +125,25 @@ static uint8_t Transmit(uint8_t TxChan, const uint8_t *PacketByte, uint8_t Thres #ifdef WITH_LED_TX LED_TX_Flash(20); #endif - TRX.WriteMode(RF_OPMODE_STANDBY); // switch to standby + TRX.setModeStandby(); // switch to standby // vTaskPrioritySet(0, tskIDLE_PRIORITY+2); vTaskDelay(1); SetTxChannel(TxChan); TRX.ClearIrqFlags(); - TRX.WritePacketOGN(PacketByte); // write packet into FIFO - TRX.WriteMode(RF_OPMODE_TRANSMITTER); // transmit - vTaskDelay(5); // wait 5ms + TRX.WritePacketOGN(PacketByte); // write packet into FIFO + TRX.setModeTX(); // transmit + vTaskDelay(5); // wait 5ms (about the OGN packet time) uint8_t Break=0; for(uint16_t Wait=400; Wait; Wait--) // wait for transmission to end - { // if(!TRX.DIO0_isOn()) break; - // uint8_t Mode=TRX.ReadMode(); - uint16_t Flags=TRX.ReadIrqFlags(); - // if(Mode!=RF_OPMODE_TRANSMITTER) break; + { uint16_t Flags=TRX.ReadIrqFlags(); if(Flags&RF_IRQ_PacketSent) Break++; if(Break>=2) break; } - TRX.WriteMode(RF_OPMODE_STANDBY); // switch to standy + TRX.setModeStandby(); // switch to standy // vTaskPrioritySet(0, tskIDLE_PRIORITY+2); SetRxChannel(); - TRX.WriteMode(RF_OPMODE_RECEIVER); // back to receive mode + TRX.setModeRX(); // back to receive mode return 1; } // make a time-slot: listen for packets and transmit given PacketByte$ static void TimeSlot(uint8_t TxChan, uint32_t SlotLen, const uint8_t *PacketByte, uint8_t Rx_RSSI, uint8_t MaxWait=8, uint32_t TxTime=0) @@ -172,7 +169,7 @@ static void SetFreqPlanWAN(void) // set the LoRaWAN TRX.setFrequencyCorrection(Parameters.RFchipFreqCorr); } static uint8_t StartRFchip(void) -{ TRX.WriteMode(RF_OPMODE_STANDBY); +{ TRX.setModeStandby(); vTaskDelay(1); TRX.RESET(1); // RESET active vTaskDelay(1); // wait 10ms @@ -188,7 +185,7 @@ static uint8_t StartRFchip(void) // TRX.WriteDefaultReg(); // #endif TRX.OGN_Configure(0, OGN_SYNC); // setup RF chip parameters and set to channel #0 - TRX.WriteMode(RF_OPMODE_STANDBY); // set RF chip mode to STANDBY + TRX.setModeStandby(); // set RF chip mode to STANDBY uint8_t Version = TRX.ReadVersion(); #ifdef DEBUG_PRINT xSemaphoreTake(CONS_Mutex, portMAX_DELAY); @@ -232,7 +229,10 @@ extern "C" TRX.Deselect = RFM_Deselect; // [call] TRX.TransferByte = RFM_TransferByte; // [call] #endif - TRX.DIO0_isOn = RFM_IRQ_isOn; // [call] read IRQrfm_reset + TRX.DIO0_isOn = RFM_IRQ_isOn; // [call] read IRQ +#ifdef WITH_SX1262 + TRX.Busy_isOn = RFM_Busy_isOn; // [call] read Busy +#endif TRX.Delay_ms = RFM_Delay; // [call] delay by N miliseconds TRX.RESET = RFM_RESET; // [call] chip reset control @@ -261,7 +261,7 @@ extern "C" RX_Channel = RF_FreqPlan.getChannel(TimeSync_Time(), 0, 1); // set initial RX channel SetRxChannel(); - TRX.WriteMode(RF_OPMODE_RECEIVER); + TRX.setModeRX(); RX_RSSI.Set(2*112); @@ -293,14 +293,14 @@ extern "C" if(WANrx) // if reception expected from WAN { int RxLen=0; - TRX.WriteMode(RF_OPMODE_STANDBY); // TRX to standby + TRX.setModeStandby(); // TRX to standby TRX.setLoRa(); // switch to LoRa mode (through sleep) - TRX.WriteMode(RF_OPMODE_LORA_STANDBY); // TRX in standby + TRX.setModeLoRaStandby(); // 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 + TRX.setModeLoRaRXsingle(); // wait for a single packet int Wait=WAN_RespLeft+100; // 100ms timeout after the expected reception for( ; Wait>0; Wait--) { vTaskDelay(1); @@ -323,7 +323,7 @@ extern "C" SetFreqPlanOGN(); // OGN frequency plan TRX.OGN_Configure(0, OGN_SYNC); // OGN config SetRxChannel(); - TRX.WriteMode(RF_OPMODE_RECEIVER); // switch to receive mode + TRX.setModeRX(); // switch to receive mode WANdev.WriteToNVS(); // store new WAN state in flash if(RxLen>0) // if Downlink data received { xSemaphoreTake(CONS_Mutex, portMAX_DELAY); @@ -353,14 +353,14 @@ extern "C" } #endif - TRX.WriteMode(RF_OPMODE_STANDBY); // switch to standy + TRX.setModeStandby(); // switch to standy vTaskDelay(1); if(PowerMode==0) - { TRX.WriteMode(RF_OPMODE_SLEEP); + { TRX.setModeSleep(); while(PowerMode==0) vTaskDelay(1); - TRX.WriteMode(RF_OPMODE_STANDBY); + TRX.setModeStandby(); vTaskDelay(1); } SetFreqPlanOGN(); @@ -388,7 +388,7 @@ extern "C" RX_Channel = TxChan; SetRxChannel(); // here we can read the chip temperature - TRX.WriteMode(RF_OPMODE_RECEIVER); // switch to receive mode + TRX.setModeRX(); // switch to receive mode vTaskDelay(1); uint32_t RxRssiSum=0; uint16_t RxRssiCount=0; // measure the average RSSI for the upper frequency @@ -404,7 +404,7 @@ extern "C" } while(TimeSync_msTime()<350); // keep going until 400 ms after PPS RX_RSSI.Process(RxRssiSum/RxRssiCount); // [-0.5dBm] average noise on channel - TX_Credit+=1000; if(TX_Credit>3600000) TX_Credit=3600000; // [ms] count the transmission credit + TX_Credit+=10; if(TX_Credit>3600000) TX_Credit=3600000; // [ms] count the transmission credit XorShift32(RX_Random); uint32_t TxTime = (RX_Random&0x3F)+1; TxTime*=6; TxTime+=50; // random transmission time: (1..64)*6+50 [ms] @@ -423,7 +423,7 @@ extern "C" } TimeSlot(TxChan, 800-TimeSync_msTime(), TxPktData0, TRX.averRSSI, 0, TxTime); // run a Time-Slot till 0.800sec - TRX.WriteMode(RF_OPMODE_STANDBY); // switch to receive mode + TRX.setModeStandby(); TxChan = RF_FreqPlan.getChannel(RF_SlotTime, 1, 1); // transmit channel RX_Channel = TxChan; @@ -434,13 +434,13 @@ extern "C" TRX.FNT_Configure(); // configure for FANET // TRX.setChannel(0); // configure for FANET TRX.WriteTxPower(Parameters.TxPower); // transmission power - TRX.WriteMode(RF_OPMODE_LORA_RX_CONT); // continous receiver mode + TRX.setModeLoRaRXcont(); // continous receiver mode vTaskDelay(2); for(uint8_t Wait=50; Wait; Wait--) // { vTaskDelay(1); // every milisecond uint8_t Stat = TRX.ReadByte(REG_LORA_MODEM_STATUS); // receiver status if((Stat&0x0B)==0) break; } // 0:signal-det, 1:signal-sync, 3:header-valid - TRX.WriteMode(RF_OPMODE_LORA_STANDBY); + TRX.setModeLoRaStandby(); TRX.FNT_SendPacket(FNTpkt->Byte, FNTpkt->Len); // transmit the FANET packet FNT_TxFIFO.Read(); // remove the last packet from the queue /* @@ -462,16 +462,16 @@ extern "C" */ vTaskDelay(8); for( uint8_t Wait=50; Wait; Wait--) - { vTaskDelay(1); - uint8_t Mode=TRX.ReadMode(); - if(Mode!=RF_OPMODE_LORA_TX) break; } + { vTaskDelay(1); if(!TRX.isModeLoRaTX()) brek; } + // uint8_t Mode=TRX.ReadMode(); + // if(Mode!=RF_OPMODE_LORA_TX) break; } TRX.setFSK(); TRX.OGN_Configure(0, OGN_SYNC); } #endif SetRxChannel(); - TRX.WriteMode(RF_OPMODE_RECEIVER); // switch to receive mode + TRX.setModeRX(); // switch to receive mode XorShift32(RX_Random); TxTime = (RX_Random&0x3F)+1; TxTime*=6; // [ms] (1..64)*6 = 6..384ms @@ -500,20 +500,20 @@ extern "C" TxPkt.Dewhiten(); XorShift32(RX_Random); if(PAWtxBackOff==0 && !TxPkt.Header.Relay && Packet.Copy(TxPkt) && TxPkt.Position.Time<60) - { TRX.WriteMode(RF_OPMODE_STANDBY); + { TRX.setModeStandby(); TRX.PAW_Configure(PAW_SYNC); TRX.WriteTxPower(Parameters.TxPower+6); vTaskDelay(RX_Random&0x3F); TRX.ClearIrqFlags(); TRX.WritePacketPAW(Packet.Byte, 24); - TRX.WriteMode(RF_OPMODE_TRANSMITTER); - vTaskDelay(8); // wait 5ms + TRX.setModeTX(); + vTaskDelay(8); // wait 8ms (about the PAW packet time) uint8_t Break=0; for(uint16_t Wait=400; Wait; Wait--) // wait for transmission to end { uint16_t Flags=TRX.ReadIrqFlags(); if(Flags&RF_IRQ_PacketSent) Break++; if(Break>=2) break; } - TRX.WriteMode(RF_OPMODE_STANDBY); + TRX.setModeStandby(); TRX.OGN_Configure(0, OGN_SYNC); PAWtxBackOff = 2+(RX_Random%5); XorShift32(RX_Random); TX_Credit-=8; } @@ -523,9 +523,9 @@ extern "C" #ifdef WITH_LORAWAN if(WANtx) - { TRX.WriteMode(RF_OPMODE_STANDBY); // TRX to standby + { TRX.setModeStandby(); // TRX to standby TRX.setLoRa(); // switch to LoRa mode (through sleep) - TRX.WriteMode(RF_OPMODE_LORA_STANDBY); // TRX in standby + TRX.setModeLoRaStandby(); // TRX in standby SetFreqPlanWAN(); // WAN frequency plan TRX.WAN_Configure(); // LoRa for WAN config. XorShift32(RX_Random); // random @@ -557,9 +557,9 @@ extern "C" 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; } + { 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: 5sec after the end of Join-Request packet xSemaphoreTake(CONS_Mutex, portMAX_DELAY); Format_UnsDec(CONS_UART_Write, xTaskGetTickCount(), 4, 3); @@ -572,7 +572,7 @@ extern "C" SetFreqPlanOGN(); // OGN frequency plan TRX.OGN_Configure(0, OGN_SYNC); // OGN config SetRxChannel(); - TRX.WriteMode(RF_OPMODE_RECEIVER); // switch to receive mode + TRX.setModeRX(); // switch to receive mode } #endif diff --git a/main/rfm.h b/main/rfm.h index 6ca43a9..381b348 100644 --- a/main/rfm.h +++ b/main/rfm.h @@ -191,19 +191,29 @@ class RFM_FSK_RxPktData // OGN packet received by the RF chip #endif // of WITH_RFM69 #ifdef WITH_RFM95 - #include "sx1276.h" - -#define RF_IRQ_PreambleDetect 0x0200 // - +#define RF_IRQ_PreambleDetect 0x0200 // #endif // of WITH_RFM95 +#ifdef WITH_SX1262 +#include "sx1262.h" + +#define RF_IRQ_PacketSent 0x0001 // packet transmission was completed +#define RF_IRQ_PayloadReady 0x0002 // +#define RF_IRQ_PreambleDetect 0x0004 // +#define RF_IRQ_SyncAddrMatch 0x0008 // +#define RF_IRQ_CrcErr 0x0040 // +#define RF_IRQ_Timeout 0x0200 // + +#endif + +#if defined(WITH_RFM69) || defined(WITH_RFM95) || defined(WITH_SX1272) // bits in IrqFlags1 and IrfFlags2 #define RF_IRQ_ModeReady 0x8000 // mode change done (between some modes) -#define RF_IRQ_RxReady 0x4000 -#define RF_IRQ_TxReady 0x2000 // +#define RF_IRQ_RxReady 0x4000 // receiver ready +#define RF_IRQ_TxReady 0x2000 // transmitter ready #define RF_IRQ_PllLock 0x1000 // -#define RF_IRQ_Rssi 0x0800 +#define RF_IRQ_Rssi 0x0800 // #define RF_IRQ_Timeout 0x0400 #define RF_IRQ_PreambleDetect 0x0200 #define RF_IRQ_SyncAddrMatch 0x0100 @@ -217,6 +227,8 @@ class RFM_FSK_RxPktData // OGN packet received by the RF chip #define RF_IRQ_CrcOk 0x0002 #define RF_IRQ_LowBat 0x0001 +#endif + #include "manchester.h" class RFM_TRX @@ -237,6 +249,37 @@ class RFM_TRX // printf("Block_Write( [0x%02X, .. ], %d, 0x%02X) .. [0x%02X, 0x%02X, ...]\n", Data[0], Len, Addr, Block_Buffer[0], Block_Buffer[1]); (*TransferBlock) (Block_Buffer, Len+1); return Block_Buffer+1; } + +#ifdef WITH_SX1262 + uint8_t *Cmd_Write(uint8_t Cmd, const uint8_t *Data, uint8_t Len) // command code, Data[Len] + { return Block_Write(Data, Len, Cmd); } + + uint8_t *Cmd_Read(uint8_t Cmd, uint8_t Len) + { Block_Buffer[0] = Cmd; memset(Block_Buffer+1, 0, Len+1); + (*TransferBlock) (Block_Buffer, Len+2); + return Block_Buffer+2; } + + uint8_t *Regs_Write(uint16_t Addr, const uint8_t *Data, uint8_t Len) // register-write code, 2-byte Address, Data[Len] + { Block_Buffer[0] = CMD_WRITEREGISTER; Block_Buffer[1] = Addr>>8; Block_Buffer[2] = Addr; memcpy(Block_Buffer+3, Data, Len); + (*TransferBlock) (Block_Buffer, Len+3); + return Block_Buffer+3; } + + uint8_t *Regs_Read(uint16_t Addr, const uint8_t *Data, uint8_t Len) // register-read code, 2-byte Address, zero, Data[Len] + { Block_Buffer[0] = CMD_READREGISTER; Block_Buffer[1] = Addr>>8; Block_Buffer[2] = Addr; memset(Block_Buffer+3, 0, Len+1); + (*TransferBlock) (Block_Buffer, Len+4); + return Block_Buffer+4; } + + uint8_t *Buff_Write(uint8_t Ofs, const uint8_t *Data, uint8_t Len) // buffer-write code, 1-byte offset, Data[Len] + { Block_Buffer[0] = CMD_WRITEBUFFER; Block_Buffer[1] = Ofs; memcpy(Block_Buffer+2, Data, Len); + (*TransferBlock) (Block_Buffer, Len+2); + return Block_Buffer+2; } + + uint8_t *Buff_Read(uint8_t Ofs, uint8_t Len) // buffer-read code, 1-byte offset, zero, Data[Len] + { Block_Buffer[0] = CMD_READBUFFER; Block_Buffer[1] = Ofs; memset(Block_Buffer+2, 0, Len+1); + (*TransferBlock) (Block_Buffer, Len+3); + return Block_Buffer+3; } +#endif + #else // SPI transfers as single bytes, explicit control of the SPI-select void (*Select)(void); // activate SPI select void (*Deselect)(void); // desactivate SPI select @@ -245,14 +288,18 @@ class RFM_TRX void (*Delay_ms)(int ms); bool (*DIO0_isOn)(void); // read DIO0 = packet is ready +#ifdef WITH_SX1262 + bool (*Busy_isOn)(void); // +#endif // bool (*DIO4_isOn)(void); void (*RESET)(uint8_t On); // activate or desactivate the RF chip reset bool readIRQ(void) { return (*DIO0_isOn)(); } - +#ifdef WITH_SX1262 + bool readBusy(void) { return (*Busy_isOn)(); } +#endif // 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 -// int32_t FrequencyCorrection; // [32MHz/2^19/2^8] frequency correction (due to Xtal offset) uint32_t ChannelSpacing; // [32MHz/2^19/2^8] spacing between channels int16_t FreqCorr; // [0.1ppm] int16_t Channel; // [ integer] channel being used @@ -262,6 +309,7 @@ class RFM_TRX uint8_t averRSSI; // [-0.5dB] uint8_t dummy; +/* #ifdef WITH_RFM95 void WriteDefaultReg(void) { const uint8_t Default[64] = { 0x00, 0x01, 0x1A, 0x0B, 0x00, 0x52, 0xE4, 0xC0, 0x00, 0x0F, 0x19, 0x2B, 0x20, 0x08, 0x02, 0x0A, @@ -283,27 +331,27 @@ class RFM_TRX WriteByte(0xDB, 0x64); } #endif +*/ static uint32_t calcSynthFrequency(uint32_t Frequency) { return (((uint64_t)Frequency<<16)+7812)/15625; } public: - void setBaseFrequency(uint32_t Frequency=868200000) { BaseFrequency=calcSynthFrequency(Frequency); } // [Hz] - void setChannelSpacing(uint32_t Spacing= 200000) { ChannelSpacing=calcSynthFrequency(Spacing); } // [Hz] + void setBaseFrequency(uint32_t Frequency=868200000) { BaseFrequency=calcSynthFrequency(Frequency); } // [Hz] => [synth] + void setChannelSpacing(uint32_t Spacing= 200000) { ChannelSpacing=calcSynthFrequency(Spacing); } // [Hz] => [synth] void setFrequencyCorrection(int16_t ppmFreqCorr=0) { FreqCorr = ppmFreqCorr; } // [0.1ppm] -// void setFrequencyCorrection(int32_t Correction=0) -// { if(Correction<0) FrequencyCorrection = -calcSynthFrequency(-Correction); -// else FrequencyCorrection = calcSynthFrequency( Correction); } - void setFrequency(uint32_t Freq) // [Hz] - { Freq = calcSynthFrequency(Freq); - int32_t Corr = ((int64_t)Freq*FreqCorr+5000000)/10000000; - Freq+=Corr; WriteFreq((Freq+128)>>8); } - void setChannel(int16_t newChannel) + void setFrequency(uint32_t Freq) // [Hz] set for given frequency + { Freq = calcSynthFrequency(Freq); // [32MHz/2^27] + int32_t Corr = ((int64_t)Freq*FreqCorr+5000000)/10000000; // [32MHz/2^27] + Freq+=Corr; WriteFreq(Freq); } // [32MHz/2^27] write into the RF chip + + void setChannel(int16_t newChannel) // set for given channel { Channel=newChannel; - uint32_t Freq = BaseFrequency+ChannelSpacing*Channel; - int32_t Corr = ((int64_t)Freq*FreqCorr+5000000)/10000000; - Freq += Corr; - WriteFreq((Freq+128)>>8); } + uint32_t Freq = BaseFrequency+ChannelSpacing*Channel; // [32MHz/2^27] + int32_t Corr = ((int64_t)Freq*FreqCorr+5000000)/10000000; // [32MHz/2^27] + Freq += Corr; // [32MHz/2^27] + WriteFreq(Freq); } // [32MHz/2^27] write into the RF chip + uint8_t getChannel(void) const { return Channel; } #ifdef USE_BLOCK_SPI @@ -331,8 +379,11 @@ class RFM_TRX void WriteBytes(const uint8_t *Data, uint8_t Len, uint8_t Addr=0) { Block_Write(Data, Len, Addr); } - void WriteFreq(uint32_t Freq) // [32MHz/2^19] Set center frequency in units of RFM69 synth. +#if defined(WITH_RFM95) || defined(WITH_SX1272) || defined(WITH_RFM69) + void WriteFreq(uint32_t Freq) // [32MHz/2^27] Set center frequency in units of RFM69 synth. { const uint8_t Addr = REG_FRFMSB; + Freq = (Freq+128)>>8; // [32MHz/2^19] + // printf("RFM::WriteFreq(%06X)\n", Freq); uint8_t Buff[4]; Buff[0] = Freq>>16; Buff[1] = Freq>> 8; @@ -343,11 +394,35 @@ class RFM_TRX uint32_t ReadFreq(uint8_t Addr=REG_FRFMSB) { uint8_t *Data = Block_Read(3, Addr); uint32_t Freq=Data[0]; Freq<<=8; Freq|=Data[1]; Freq<<=8; Freq|=Data[2]; - return Freq; } + return Freq; } // [32MHz/2^19] void WriteFIFO(const uint8_t *Data, uint8_t Len) { Block_Write(Data, Len, REG_FIFO); } + uint8_t *ReadFIFO(uint8_t Len) + { return Block_Read(Len, REG_FIFO); } +#endif + +#ifdef WITH_SX1262 + void WriteFreq(uint32_t Freq) // [32MHz/2^27] Set center frequency + { uint8_t Buff[4]; + Freq = (Freq+2)>>2; // [32MHz/2^25] + Buff[0] = Freq>>24; + Buff[1] = Freq>>16; + Buff[2] = Freq>> 8; + Buff[3] = Freq ; + Cmd_Write(CMD_SETRFFREQUENCY, Buff, 4); } + + void WriteFIFO(const uint8_t *Data, uint8_t Len) + { const uint8_t BaseOfs[2] = { 0x80, 0x00 }; // TX, RX offsets in the 256-byte buffer + Cmd_Write(CMD_SETBUFFERBASEADDRESS, BaseOfs, 2); + Buff_Write(BaseOfs[0], Data, Len); } + + uint8_t *ReadFIFO(uint8_t Len) + { uint8_t *BuffStat = Cmd_Read(CMD_GETRXBUFFERSTATUS, 2); // length, offset + return Buff_Read(BuffStat[1], BuffStat[0]); } +#endif + void WritePacketOGN(const uint8_t *Data, uint8_t Len=26) // write the packet data (26 bytes) { uint8_t Packet[2*Len]; uint8_t PktIdx=0; @@ -356,7 +431,7 @@ class RFM_TRX Packet[PktIdx++]=ManchesterEncode[Byte>>4]; // software manchester encode every byte Packet[PktIdx++]=ManchesterEncode[Byte&0x0F]; } - Block_Write(Packet, 2*Len, REG_FIFO); } + WriteFIFO(Packet, 2*Len); } void WritePacketPAW(const uint8_t *Data, uint8_t Len=24) { uint8_t Packet[Len+1]; @@ -364,13 +439,10 @@ class RFM_TRX { Packet[Idx] = Data[Idx]; } PAW_Packet::Whiten(Packet, Len); Packet[Len] = PAW_Packet::CRC8(Packet, Len); - Block_Write(Packet, Len+1, REG_FIFO); } + WriteFIFO(Packet, Len+1); } - uint8_t *ReadFIFO(uint8_t Len) - { return Block_Read(Len, REG_FIFO); } - - void ReadPacketOGN(uint8_t *Data, uint8_t *Err, uint8_t Len=26) // read packet data from FIFO - { uint8_t *Packet = Block_Read(2*Len, REG_FIFO); // read 2x26 bytes from the RF chip RxFIFO + void ReadPacketOGN(uint8_t *Data, uint8_t *Err, uint8_t Len=26) // read packet data from FIFO + { uint8_t *Packet = ReadFIFO(2*Len); // read 2x26 bytes from the RF chip RxFIFO uint8_t PktIdx=0; for(uint8_t Idx=0; Idx>8; // [32MHz/2^19] Select(); TransferByte(Addr | 0x80); uint32_t Old = TransferByte(Freq>>16); Old = (Old<<8) | TransferByte(Freq>>8); Old = (Old<<8) | TransferByte(Freq); // actual change in the frequency happens only when the LSB is written Deselect(); - return Old; } // return the previously set frequency + return Old<<8; } // return the previously set frequency void WriteFIFO(const uint8_t *Data, uint8_t Len) { const uint8_t Addr=REG_FIFO; // write to FIFO @@ -493,7 +566,6 @@ class RFM_TRX // ^ 8 or 9 ? #endif -// #ifdef WITH_RFM95 #if defined(WITH_RFM95) || defined(WITH_SX1272) void FSK_WriteSYNC(uint8_t WriteSize, uint8_t SyncTol, const uint8_t *SyncData) { if(SyncTol>7) SyncTol=7; @@ -504,6 +576,20 @@ class RFM_TRX // ^ 8 or 9 ? #endif +#ifdef WITH_SX1262 + void WriteTxPower(int8_t TxPower) { } + void WriteTxPowerMin(void) { WriteTxPower(0); } + void FSK_WriteSYNC(uint8_t WriteSize, uint8_t SyncTol, const uint8_t *SyncData) { } + void OGN_Configure(int16_t Channel, const uint8_t *Sync) { } + void ClearIrqFlags(uint16_t Mask=0xFFFF) { uint8_t Data[2]; Data[0]=Mask>>8; Data[1]=Mask; Cmd_Write(CMD_CLEARIRQSTATUS, Data, 2); } + uint16_t ReadIrqFlags(void) { uint8_t *Stat=Cmd_Read(CMD_GETIRQSTATUS, 2); return 0x0000; } + void setModeSleep(void) { uint8_t Config[3] = { 0,0,0 }; Cmd_Write(CMD_SETSLEEP, Config, 3); } + void setModeStandby(void) { uint8_t Config[1] = { 1 }; Cmd_Write(CMD_SETSTANDBY, Config, 1); } + void setModeTX(uint32_t Timeout=0) { uint8_t T[3]; T[0]=Timeout>>16; T[1]=Timeout>>8; T[2]=Timeout; Cmd_Write(CMD_SETTX, T, 3); } + void setModeRX(uint32_t Timeout=0) { uint8_t T[3]; T[0]=Timeout>>16; T[1]=Timeout>>8; T[2]=Timeout; Cmd_Write(CMD_SETRX, T, 3); } +#endif + +#if defined(WITH_RFM95) || defined(WITH_SX1272) || defined(WITH_RFM69) void WriteMode(uint8_t Mode=RF_OPMODE_STANDBY) { WriteByte(Mode, REG_OPMODE); } // SLEEP/STDBY/FSYNTH/TX/RX uint8_t ReadMode (void) { return ReadByte(REG_OPMODE); } uint8_t ModeReady(void) { return ReadByte(REG_IRQFLAGS1)&0x80; } @@ -512,6 +598,18 @@ class RFM_TRX void ClearIrqFlags(void) { WriteWord(RF_IRQ_FifoOverrun | RF_IRQ_Rssi | RF_IRQ_PreambleDetect | RF_IRQ_SyncAddrMatch, REG_IRQFLAGS1); } + void setModeSleep(void) { WriteMode(RF_OPMODE_SLEEP); } // FSK sleep + void setModeStandby(void) { WriteMode(RF_OPMODE_STANDBY); } // FSK standby + void setModeTX(void) { WriteMode(RF_OPMODE_TRANSMITTER); } // FSK transmit + void setModeRX(void) { WriteMode(RF_OPMODE_RECEIVER); } // FSK receive +#if defined(WITH_RFM95) || defined(WITH_SX1272) + void setModeLoRaStandby(void) { WriteMode(RF_OPMODE_LORA_STANDBY); } // LoRa standby + void setModeLoRaRXcont(void) { WriteMode(RF_OPMODE_LORA_RX_CONT); } // Lora continues recieve + void setModeLoRaRXsingle(void) { WriteMode(RF_OPMODE_LORA_RX_SINGLE); } // LoRa single receive + bool isModeLoRaTX(void) { return ReadMode()==RF_OPMODE_LORA_TX; } // LoRa still transmitting ? +#endif +#endif + #ifdef WITH_RFM69 void WriteTxPower_W(int8_t TxPower=10) // [dBm] for RFM69W: -18..+13dBm { if(TxPower<(-18)) TxPower=(-18); // check limits @@ -545,7 +643,7 @@ class RFM_TRX void WriteTxPowerMin(void) { WriteTxPower_W(-18); } // set minimal Tx power and setup for reception - int OGN_Configure(int16_t Channel, const uint8_t *Sync) + void OGN_Configure(int16_t Channel, const uint8_t *Sync) { WriteMode(RF_OPMODE_STANDBY); // mode = STDBY ClearIrqFlags(); WriteByte( 0x02, REG_DATAMODUL); // [0x00] Packet mode, FSK, 0x02: BT=0.5, 0x01: BT=1.0, 0x03: BT=0.3 @@ -570,8 +668,14 @@ class RFM_TRX WriteByte( 0x30, REG_TESTDAGC); // [0x30] 0x20 when AfcLowBetaOn, 0x30 otherwise-> page 25 WriteByte( 0x00, REG_AFCFEI); // [0x00] AfcAutoOn=0, AfcAutoclearOn=0 WriteByte( 0x00, REG_AFCCTRL); // [0x00] 0x20 = AfcLowBetaOn=1 -> page 64 -> page 33 - WriteByte( +10, REG_TESTAFC); // [0x00] [488Hz] if AfcLowBetaOn - return 0; } + WriteByte( +10, REG_TESTAFC); } // [0x00] [488Hz] if AfcLowBetaOn +#endif + + +#ifdef WITH_SX1262 + void setModulation(uint8_t Mode=0) { Cmd_Write(CMD_SETPACKETTYPE, &Mode, 1); } + void setLoRa(void) { setModulation(0x01); } // switch to FSK + void setFSK(void) { setModulation(0x00); } // switch to LoRa #endif // #ifdef WITH_RFM95 @@ -602,15 +706,13 @@ class RFM_TRX void WriteTxPowerMin(void) { WriteTxPower(0); } - int setLoRa(void) // switch to LoRa: has to go througth the SLEEP mode + void setLoRa(void) // switch to LoRa: has to go througth the SLEEP mode { WriteMode(RF_OPMODE_LORA_SLEEP); - WriteMode(RF_OPMODE_LORA_SLEEP); - return 0; } + WriteMode(RF_OPMODE_LORA_SLEEP); } - int setFSK(void) // switch to FSK: has to go through the SLEEP mode + void setFSK(void) // switch to FSK: has to go through the SLEEP mode { WriteMode(RF_OPMODE_SLEEP); - WriteMode(RF_OPMODE_SLEEP); - return 0; } + WriteMode(RF_OPMODE_SLEEP); } int LoRa_Configure(RFM_LoRa_Config CFG, uint8_t MaxSize=64) { WriteByte(0x00, REG_LORA_HOPPING_PERIOD); // disable fast-hopping @@ -642,7 +744,7 @@ class RFM_TRX RFM_LoRa_Config CFG = RFM_FNTcfg; CFG.CR=CR; return LoRa_Configure(CFG, FANET_Packet::MaxBytes); } - int WAN_Configure(uint8_t CR=1) // configure for FANET/LoRa + int WAN_Configure(uint8_t CR=1) // configure for LoRaWAN { WriteTxPower(0); RFM_LoRa_Config CFG = RFM_WANcfg; CFG.CR=CR; return LoRa_Configure(CFG, 40); } @@ -747,7 +849,7 @@ class RFM_TRX return 0; } - int OGN_Configure(int16_t Channel, const uint8_t *Sync) + void OGN_Configure(int16_t Channel, const uint8_t *Sync) { // WriteMode(RF_OPMODE_STANDBY); // mode: STDBY, modulation: FSK, no LoRa // usleep(1000); WriteTxPower(0); @@ -770,9 +872,7 @@ class RFM_TRX WriteByte( 0x49, REG_PARAMP); // BT=0.5 shaping, 40us ramp up/down WriteByte( 0x0E, REG_RXCONFIG); // => p.90 (or 0x8E ?) WriteByte( 0x07, REG_RSSICONFIG); // 256 samples for RSSI, no offset, => p.90,82 - WriteByte( 0x20, REG_LNA); // max. LNA gain, => p.89 - - return 0; } + WriteByte( 0x20, REG_LNA); } // max. LNA gain, => p.89 uint8_t ReadLowBat(void) { return ReadByte(REG_LOWBAT ); } @@ -813,32 +913,28 @@ class RFM_TRX Format_Hex(CONS_UART_Write, ReadByte(REG_PACONFIG)); Format_String(CONS_UART_Write, "\n"); } -#endif +#endif // WITH_RFM95 - uint8_t ReadVersion(void) { chipVer=ReadByte(REG_VERSION); return chipVer; } // 0x24 for RFM69 or 0x12 for RFM95 +#if defined(WITH_RFM95) || defined(WITH_SX1272) || defined(WITH_RFM69) + uint8_t ReadVersion(void) { chipVer=ReadByte(REG_VERSION); return chipVer; } // 0x24 for RFM69 or 0x12 for RFM95 + uint8_t ReadRSSI(void) { return ReadByte(REG_RSSIVALUE); } // read value: RSS = -Value/2 +#endif +#ifdef WITH_SX1262 + uint8_t ReadVersion(void) { return 0x12; } + uint8_t ReadRSSI(void) { uint8_t *RSSI=Cmd_Read(CMD_GETRSSIINST, 1); return RSSI[0]; } +#endif #ifdef WITH_RFM69 void TriggerRSSI(void) { WriteByte(0x01, REG_RSSICONFIG); } // trigger measurement uint8_t ReadyRSSI(void) { return ReadByte(REG_RSSICONFIG) & 0x02; } // ready ? -#endif - uint8_t ReadRSSI(void) { return ReadByte(REG_RSSIVALUE); } // read value: RSS = -Value/2 - -#ifdef WITH_RFM69 void TriggerTemp(void) { WriteByte(0x08, REG_TEMP1); } // trigger measurement uint8_t RunningTemp(void) { return ReadByte(REG_TEMP1) & 0x04; } // still running ? int8_t ReadTemp(void) { chipTemp=165-ReadByte(REG_TEMP2); return chipTemp; } // [deg] #endif + #if defined(WITH_RFM95) || defined(WITH_SX1272) int8_t ReadTemp(void) { chipTemp = 15-ReadByte(REG_TEMP); return chipTemp; } // [degC] #endif -/* - void Dump(uint8_t EndAddr=0x20) - { printf("RFM_TRX[] ="); - for(uint8_t Addr=1; Addr<=EndAddr; Addr++) - { printf(" %02X", ReadByte(Addr)); } - printf("\n"); - } -*/ } ; #endif // __RFM_H__ diff --git a/main/sens.cpp b/main/sens.cpp index 8e80712..a0b6d7d 100644 --- a/main/sens.cpp +++ b/main/sens.cpp @@ -272,9 +272,10 @@ static void ProcBaro(void) Len=0; // start preparing the PGRMZ NMEA sentence Len+=Format_String(Line+Len, "$PGRMZ,"); - Len+=Format_SignDec(Line+Len, StdAltitude, 2, 1); // [m] standard altitude (calc. from pressure) + int32_t StdFeet=(StdAltitude*3360+512)>>10; + Len+=Format_SignDec(Line+Len, StdFeet/10, 1, 0, 1); // [feet] standard altitude (calc. from pressure) Line[Len++]=','; - Len+=Format_String(Line+Len, "m,"); // normally f for feet, but metres and m works with XcSoar + Len+=Format_String(Line+Len, "f,"); // normally f for feet, but metres and m works with XcSoar Len+=Format_String(Line+Len, "3"); // 1 no fix, 2 - 2D, 3 - 3D; assume 3D for now Len+=NMEA_AppendCheckCRNL(Line, Len); if(Parameters.Verbose) diff --git a/main/sx1262.h b/main/sx1262.h new file mode 100644 index 0000000..27b4d99 --- /dev/null +++ b/main/sx1262.h @@ -0,0 +1,72 @@ +#define CMD_SETSLEEP 0x84 // [1] set sleep +#define CMD_SETSTANDBY 0x80 // [1] set standby +#define CMD_SETFS 0xC1 // [0] test mode: set synthesis +#define CMD_SETTX 0x83 // [3] set transmitter mode, timeout [15.625us] ? +#define CMD_SETRX 0x82 // [3] set receive mode, timeout +#define CMD_STOPTIMERONPREAMBLE 0x9F // [1] +#define CMD_SETRXDUTYCYCLE 0x94 // [6] sleep/receive cycle to save power +#define CMD_SETCAD 0xC5 // [0] +#define CMD_SETTXCONTINUOUSWAVE 0xD1 // [1] test mode: continues wave +#define CMD_SETTXINFINITEPREAMBLE 0xD2 // [1] test mode: continues preamble +#define CMD_SETREGULATORMODE 0x96 // [1] +#define CMD_CALIBRATE 0x89 // [1] +#define CMD_CALIBRATEIMAGE 0x98 // [2] +#define CMD_SETPACONFIG 0x95 // [4] PA control: duty +#define CMD_SETRXTXFALLBACKMODE 0x93 // [1] + +#define CMD_WRITEREGISTER 0x0D // write one or more registers +#define CMD_READREGISTER 0x1D // read one or more registers +#define CMD_WRITEBUFFER 0x0E // write the packet +#define CMD_READBUFFER 0x1E // read the packet + +#define CMD_SETDIOIRQPARAMS 0x08 // [8] IRQ enable and masks for DIO1/2/3 outputs +#define CMD_GETIRQSTATUS 0x12 // [stat+2] get IRQ flags +#define CMD_CLEARIRQSTATUS 0x02 // [2] clear IRQ flags according to given mask +#define CMD_SETDIO2ASRFSWITCHCTRL 0x9D // [1] Use DIO2 as the RF switch control +#define CMD_SETDIO3ASTCXOCTRL 0x97 // [4] Use DIO3 as TCXO control: voltage, delay + +#define CMD_SETRFFREQUENCY 0x86 // [4] frequency [Fxtal/2^25] +#define CMD_SETPACKETTYPE 0x8A // [1] 0x00=GFSK, 0x01=LoRa (must be the first vonfiguration command) +#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 +#define CMD_SETPACKETPARAMS 0x8C // [9] +#define CMD_SETCADPARAMS 0x88 // [8] depends on the protocol +#define CMD_SETBUFFERBASEADDRESS 0x8F // [2] Tx-base address, Rx-base address +#define CMD_SETLORASYMBNUMTIMEOUT 0xA0 // [1] timeout [symbols] + +#define CMD_GETSTATUS 0xC0 +#define CMD_GETRSSIINST 0x15 // [stat+1] RX-RSSI at this moment +#define CMD_GETRXBUFFERSTATUS 0x13 // [stat+2] RX-packet: length, buffer pointer +#define CMD_GETPACKETSTATUS 0x14 // [stat+3] RX-packet: RSSI/SNR +#define CMD_GETDEVICEERRORS 0x17 +#define CMD_CLEARDEVICEERRORS 0x07 +#define CMD_GETSTATS 0x10 // [stat+6] RX-statistics: packets, errors +#define CMD_RESETSTATS 0x00 // [stat+6] RX-statistics reset + +#define REG_WHITENINGMSB 0x06B8 +#define REG_WHITENINGLSB 0x06B9 +#define REG_CRCINITVALMSB 0x06BC +#define REG_CRCINITVALLSB 0x06BD +#define REG_CRCPOLYVALMSB 0x06BE +#define REG_CRCPOLYVALLSB 0x06BF +#define REG_SYNCWORD0 0x06C0 +#define REG_SYNCWORD1 0x06C1 +#define REG_SYNCWORD2 0x06C2 +#define REG_SYNCWORD3 0x06C3 +#define REG_SYNCWORD4 0x06C4 +#define REG_SYNCWORD5 0x06C5 +#define REG_SYNCWORD6 0x06C6 +#define REG_SYNCWORD7 0x06C7 +#define REG_NODEADDRESS 0x06CD +#define REG_BROADCASTADDR 0x06CE +#define REG_LORASYNCWORDMSB 0x0740 +#define REG_LORASYNCWORDLSB 0x0741 +#define REG_RANDOMNUMBERGEN0 0x0819 +#define REG_RANDOMNUMBERGEN1 0x081A +#define REG_RANDOMNUMBERGEN2 0x081B +#define REG_RANDOMNUMBERGEN3 0x081C +#define REG_RXGAIN 0x08AC +#define REG_OCPCONFIG 0x08E7 +#define REG_XTATRIM 0x0911 +#define REG_XTBTRIM 0x0912