Beispiel #1
0
 /// <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);
 }
Beispiel #2
0
        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));
        }
Beispiel #3
0
        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));
        }