/// <summary> /// Get the RSSI correction constant. /// </summary> /// <returns></returns> private int GetRssiCorrection() { // Page 87 in Semtech SX1276 datasheet. return(RegisterManager.Read <CommonRegisterOpMode>().LowFrequencyModeOn == CommonRegisterOpMode.LowFrequencyModeOnEnum.HighFrequencyMode ? -157 : -164); }
private void Dio0Pin_ValueChanged(GpioPin sender, GpioPinValueChangedEventArgs args) { if (args.Edge != GpioPinEdge.RisingEdge) { return; } LoraRegisterIrqFlags.FlagsEnum irqFlags = RegisterManager.Read <LoraRegisterIrqFlags>().Flags; if (irqFlags.HasFlag(LoraRegisterIrqFlags.FlagsEnum.TxDone)) { TransmittedOkCount++; _transmissionCompletedEventSlim.Set(); } if (irqFlags.HasFlag(LoraRegisterIrqFlags.FlagsEnum.RxDone)) { ReceivedMessage message = GetReceivedMessage(); OnMessageReceived?.Invoke(this, new ReceivedMessageEventArgs(message)); } // Clear all IRQ flags RegisterManager.Write(new LoraRegisterIrqFlags(0xFF)); }
private ReceivedMessage GetReceivedMessage() { DateTime timestamp = DateTime.UtcNow; LoraRegisterIrqFlags.FlagsEnum irqFlags = RegisterManager.Read <LoraRegisterIrqFlags>().Flags; bool timeout; if (irqFlags.HasFlag(LoraRegisterIrqFlags.FlagsEnum.RxTimeout)) { timeout = true; ReceivedTimeoutCount++; } else { timeout = false; } bool crcOk; if (irqFlags.HasFlag(LoraRegisterIrqFlags.FlagsEnum.PayloadCrcError)) { crcOk = false; ReceivedBadCrcCount++; } else { crcOk = true; } if (!timeout && crcOk) { ReceivedOkCount++; } lock (_registerFifoLock) { // Get the FIFO-address of the last received packet byte currentFifoAddr = RegisterManager.Read <LoraRegisterFifoRxCurrentAddr>().Addr; // Go to that address RegisterManager.Write(new LoraRegisterFifoAddrPtr(currentFifoAddr)); // Get the number of received bytes byte receivedCount = RegisterManager.Read <LoraRegisterRxNbBytes>().FifoRxBytesNb; // Prepare a buffer to copy to from the FIFO queue var buffer = new byte[receivedCount]; // Copy from the FIFO queue for (int i = 0; i < receivedCount; i++) { buffer[i] = RegisterManager.Read <CommonRegisterFifo>().Value; } // Get the RSSI correction value int rssiCorrection = GetRssiCorrection(); // Get the adjusted RSSI value int rssi = RegisterManager.Read <LoraRegisterRssiValue>().Rssi + rssiCorrection; // Get the adjusted RSSI value of the packet int pktRssi = RegisterManager.Read <LoraRegisterPktRssiValue>().PacketRssi + rssiCorrection; // Get the packet signal-to-noise ratio float pktSnr = (float)Math.Round(RegisterManager.Read <LoraRegisterPktSnrValue>().PacketSnr / 4d, 1); #if DEBUG Debug.WriteLine($"Packet RSSI: {pktRssi}, RSSI: {rssi}, SNR: {pktSnr}, Length: {buffer.Length}"); #endif return(new ReceivedMessage(buffer, rssi, pktRssi, pktSnr, crcOk, timeout, timestamp)); } }
protected override async Task Init() { Pins.Reset.Write(GpioPinValue.Low); await Task.Delay(10); Pins.Reset.Write(GpioPinValue.High); await Task.Delay(10); CommonRegisterVersion version = RegisterManager.Read <CommonRegisterVersion>(); if (version.Value == 0x12) { Debug.WriteLine("SX1276/77/78/79 detected, starting."); } else { throw new Exception("Unrecognized transceiver."); } RegisterManager.Write(new CommonRegisterOpMode( CommonRegisterOpMode.LongRangeModeEnum.LoRaMode, CommonRegisterOpMode.AccessSharedRegEnum.AccessLoRaRegisterPage, CommonRegisterOpMode.LowFrequencyModeOnEnum.HighFrequencyMode, CommonRegisterOpMode.DeviceModeEnum.Sleep)); uint frf = (uint)(((ulong)Settings.Frequency << 19) / 32000000); RegisterManager.Write(new CommonRegisterFrf(frf)); RegisterManager.Write(new LoraRegisterSyncWord(Settings.LoraSyncWord.Value)); RegisterManager.Write(new LoraRegisterModemConfig1( ConvertBandWidth(Settings.BandWidth), ConvertCodingRate(Settings.CodingRate), LoraRegisterModemConfig1.HeaderModeEnum.ExplicitHeaderMode)); RegisterManager.Write(new LoraRegisterModemConfig2( ConvertSpreadingFactor(Settings.SpreadingFactor), LoraRegisterModemConfig2.TxModeEnum.NormalMode, Settings.CrcEnabled ? LoraRegisterModemConfig2.RxPayloadCrcEnum.CrcEnabled : LoraRegisterModemConfig2.RxPayloadCrcEnum.CrcDisabled, Settings.SymbolTimeout)); RegisterManager.Write(new LoraRegisterModemConfig3( Settings.EnableLowDataRateOptimize ? LoraRegisterModemConfig3.LowDataRateOptimizeEnum.Enabled : LoraRegisterModemConfig3.LowDataRateOptimizeEnum.Disabled, LoraRegisterModemConfig3.AgcAutoEnum.Enabled)); RegisterManager.Write(new LoraRegisterMaxPayloadLength(0x80)); RegisterManager.Write(new LoraRegisterPayloadLength(0x40)); RegisterManager.Write(new LoraRegisterHopPeriod(0xFF)); RegisterManager.Write(new LoraRegisterFifoRxBaseAddr(0x00)); RegisterManager.Write(new LoraRegisterFifoTxBaseAddr(0x80)); byte fifoRxBaseAddr = RegisterManager.Read <LoraRegisterFifoRxBaseAddr>().FifoRxBaseAddr; RegisterManager.Write(new LoraRegisterFifoAddrPtr(fifoRxBaseAddr)); RegisterManager.Write(new CommonRegisterLna( CommonRegisterLna.LnaGainEnum.G1Max, CommonRegisterLna.LnaBoostLfEnum.DefaultLnaCurrent, CommonRegisterLna.LnaBoostHfEnum.BoostOn)); RegisterManager.Write(new CommonRegisterOpMode( CommonRegisterOpMode.LongRangeModeEnum.LoRaMode, CommonRegisterOpMode.AccessSharedRegEnum.AccessLoRaRegisterPage, CommonRegisterOpMode.LowFrequencyModeOnEnum.HighFrequencyMode, CommonRegisterOpMode.DeviceModeEnum.ReceiveContinuous)); }