From a46dab7ab313ab58a22227a4fca9e97ed6b6325a Mon Sep 17 00:00:00 2001 From: Pawel Jalocha Date: Sun, 24 Jan 2021 03:38:29 +0000 Subject: [PATCH] Prepare for sx1262 RF chip, but still long way to go --- main/hal.cpp | 11 ++++++- main/hal.h | 4 +++ main/nmea.h | 9 +++++- main/ogn.h | 31 ++++++++++++++----- main/ogn1.h | 14 +++++---- main/paw.h | 5 ++-- main/rf.cpp | 82 +++++++++++++++++++++++++-------------------------- main/rfm.h | 66 +++++++++++++++++++++++++++++++++++++---- main/sx1262.h | 74 ++++++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 231 insertions(+), 65 deletions(-) create mode 100644 main/sx1262.h diff --git a/main/hal.cpp b/main/hal.cpp index dc6d0d3..39a3dd6 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 @@ -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..e52937c 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..9dca10e 100644 --- a/main/rfm.h +++ b/main/rfm.h @@ -191,13 +191,13 @@ 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" +#endif // bits in IrqFlags1 and IrfFlags2 #define RF_IRQ_ModeReady 0x8000 // mode change done (between some modes) #define RF_IRQ_RxReady 0x4000 @@ -237,6 +237,32 @@ 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 *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; Block_Buffer[2] = 0; memcpy(Block_Buffer+4, Data, Len); + (*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-byt 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, const uint8_t *Data, uint8_t Len) // buffer-read code, 1-byt offset, zero, Data[Len] + { Block_Buffer[0] = CMD_READBUFFER; Block_Buffer[1] = Ofs; Block_Buffer[2] = 0; memcpy(Block_Buffer+3, Data, Len); + (*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,11 +271,16 @@ 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) @@ -262,6 +293,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,9 +315,15 @@ class RFM_TRX WriteByte(0xDB, 0x64); } #endif +*/ static uint32_t calcSynthFrequency(uint32_t Frequency) { return (((uint64_t)Frequency<<16)+7812)/15625; } + // static uint32_t calcSynthFrequency(uint32_t Frequency) + // { uint32_t Synth = (((uint64_t)Frequency<<16)+7812)/15625; + // printf("RFM::calcSynthFrequency(%d) = > %08X\n", Frequency, Synth); + // return Synth; } + public: void setBaseFrequency(uint32_t Frequency=868200000) { BaseFrequency=calcSynthFrequency(Frequency); } // [Hz] void setChannelSpacing(uint32_t Spacing= 200000) { ChannelSpacing=calcSynthFrequency(Spacing); } // [Hz] @@ -331,8 +369,14 @@ class RFM_TRX void WriteBytes(const uint8_t *Data, uint8_t Len, uint8_t Addr=0) { Block_Write(Data, Len, Addr); } +// #ifdef WITH_SX1262 +// void WriteCmd(uint8_t Cmd, uint8_t *Data, uint8_t Len) +// { Block_Write(Data, Len, Cmd); } +// #endif + void WriteFreq(uint32_t Freq) // [32MHz/2^19] Set center frequency in units of RFM69 synth. { const uint8_t Addr = REG_FRFMSB; + // printf("RFM::WriteFreq(%06X)\n", Freq); uint8_t Buff[4]; Buff[0] = Freq>>16; Buff[1] = Freq>> 8; @@ -493,7 +537,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; @@ -512,6 +555,17 @@ 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 + #ifdef WITH_RFM69 void WriteTxPower_W(int8_t TxPower=10) // [dBm] for RFM69W: -18..+13dBm { if(TxPower<(-18)) TxPower=(-18); // check limits diff --git a/main/sx1262.h b/main/sx1262.h new file mode 100644 index 0000000..67a74e7 --- /dev/null +++ b/main/sx1262.h @@ -0,0 +1,74 @@ +#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 + +