FORUM

SX1262 reduced RX sensitivity / packet reception fails

Hi

We have a problem with the SX1262 chip. Consider the following test setup: we have two receivers and one transmitter configured in SF10 LoRa mode and arrange them in such a way that the receive signal strength is around -105dBm or lower. The transmitter sends packets periodically. In the beginning, both receivers can successfully receive packets, but after some time - a few minutes to hours - one (or sometimes both) stop receiving.
Once a receiver is in this “stuck” state, it can be recovered by sending a message with a stronger signal (around -80dBm is sufficient). So it looks like the receiver sensitivity is reduced for no apparent reason.
In the “stuck” state, the receiver is still in RX mode according to SX126xGetStatus(). No interrupts are pending (RF_DIO1 is low) and no error flags are set.

After several days of debugging we came to the conclusion that it appears to be a hardware issue with the SX1262 chip.
Did anyone else experience the same issue?

It would be great if someone from Semtech could look into this…

Hi!

Can you please share the whole configuration so I can try reproduce on my bench? Basically, I need the parameters sent through SetModulationParams / SetPacketParams / SetTxParams.

Some questions:

  • Are you using “Rx continuous” mode?
  • What are the activated interrupts (Rx done, timeout, etc.)?

Thanks!

The issue occurs in RX continuous mode as well as in regular RX mode without timeout.
All interrupts are active and handled appropriately.
The settings we use:

Radio.SetRxConfig(
      MODEM_LORA,
      0,   // BW
      10,  // datarate
      1,   // coding rate
      0,   // AFC Bandwidth (FSK only, not used with SX126x)
      10,  // preamble length
      0,   // timeout
      false,  // implicit header mode
      0,      // implicit header mode length
      true,   // CRC on
      false,  // no FHSS
      0,      // FHSS period
      false,  // iqInverted
      true    // continuous RX
  );

Library function:

void RadioSetRxConfig( RadioModems_t modem, uint32_t bandwidth,
                         uint32_t datarate, uint8_t coderate,
                         uint32_t bandwidthAfc, uint16_t preambleLen,
                         uint16_t symbTimeout, bool fixLen,
                         uint8_t payloadLen,
                         bool crcOn, bool freqHopOn, uint8_t hopPeriod,
                         bool iqInverted, bool rxContinuous )
{
    RxContinuous = rxContinuous;

    if( rxContinuous == true )
    {
        symbTimeout = 0;
    }
    if( fixLen == true )
    {
        MaxPayloadLength = payloadLen;
    }
    else
    {
        MaxPayloadLength = 0xFF;
    }

    switch( modem )
    {
        case MODEM_FSK:
            SX126xSetStopRxTimerOnPreambleDetect( false );
            SX126x.ModulationParams.PacketType = PACKET_TYPE_GFSK;

            SX126x.ModulationParams.Params.Gfsk.BitRate = datarate;
            SX126x.ModulationParams.Params.Gfsk.ModulationShaping = MOD_SHAPING_G_BT_1;
            SX126x.ModulationParams.Params.Gfsk.Bandwidth = RadioGetFskBandwidthRegValue( bandwidth );

            SX126x.PacketParams.PacketType = PACKET_TYPE_GFSK;
            SX126x.PacketParams.Params.Gfsk.PreambleLength = ( preambleLen << 3 ); // convert byte into bit
            SX126x.PacketParams.Params.Gfsk.PreambleMinDetect = RADIO_PREAMBLE_DETECTOR_08_BITS;
            SX126x.PacketParams.Params.Gfsk.SyncWordLength = GfskSyncWordLength << 3; // convert byte into bit
            SX126x.PacketParams.Params.Gfsk.AddrComp = RADIO_ADDRESSCOMP_FILT_OFF;
            SX126x.PacketParams.Params.Gfsk.HeaderType = ( fixLen == true ) ? RADIO_PACKET_FIXED_LENGTH : RADIO_PACKET_VARIABLE_LENGTH;
            SX126x.PacketParams.Params.Gfsk.PayloadLength = MaxPayloadLength;
            if( crcOn == true )
            {
                SX126x.PacketParams.Params.Gfsk.CrcLength = RADIO_CRC_2_BYTES_CCIT;
            }
            else
            {
                SX126x.PacketParams.Params.Gfsk.CrcLength = RADIO_CRC_OFF;
            }
            SX126x.PacketParams.Params.Gfsk.DcFree = GfskWhitening;

            RadioStandby( );
            RadioSetModem( MODEM_FSK );
            SX126xSetModulationParams( &SX126x.ModulationParams );
            SX126xSetPacketParams( &SX126x.PacketParams );
            SX126xSetSyncWord( GfskSyncWord );
            SX126xSetWhiteningSeed( 0x01FF );

            RxTimeout = ( uint32_t )symbTimeout * 8000UL / datarate;
            break;

        case MODEM_LORA:
            SX126xSetStopRxTimerOnPreambleDetect( false );
            SX126x.ModulationParams.PacketType = PACKET_TYPE_LORA;
            SX126x.ModulationParams.Params.LoRa.SpreadingFactor = ( RadioLoRaSpreadingFactors_t )datarate;
            SX126x.ModulationParams.Params.LoRa.Bandwidth = Bandwidths[bandwidth];
            SX126x.ModulationParams.Params.LoRa.CodingRate = ( RadioLoRaCodingRates_t )coderate;

            if( ( ( bandwidth == 0 ) && ( ( datarate == 11 ) || ( datarate == 12 ) ) ) ||
                ( ( bandwidth == 1 ) && ( datarate == 12 ) ) )
            {
                SX126x.ModulationParams.Params.LoRa.LowDatarateOptimize = 0x01;
            }
            else
            {
                SX126x.ModulationParams.Params.LoRa.LowDatarateOptimize = 0x00;
            }

            SX126x.PacketParams.PacketType = PACKET_TYPE_LORA;

            // NOTE: do not increase preamble length to 12 for SF5 and SF6 if it is below 12

            SX126x.PacketParams.Params.LoRa.PreambleLength = preambleLen;

            SX126x.PacketParams.Params.LoRa.HeaderType = ( RadioLoRaPacketLengthsMode_t )fixLen;

            SX126x.PacketParams.Params.LoRa.PayloadLength = MaxPayloadLength;
            SX126x.PacketParams.Params.LoRa.CrcMode = ( RadioLoRaCrcModes_t )crcOn;
            SX126x.PacketParams.Params.LoRa.InvertIQ = ( RadioLoRaIQModes_t )iqInverted;

            RadioStandby( );
            RadioSetModem( MODEM_LORA );
            SX126xSetModulationParams( &SX126x.ModulationParams );
            SX126xSetPacketParams( &SX126x.PacketParams );
            SX126xSetLoRaSymbNumTimeout( symbTimeout );

            // WORKAROUND - Optimizing the Inverted IQ Operation, see DS_SX1261-2_V1.2 datasheet chapter 15.4
            if( SX126x.PacketParams.Params.LoRa.InvertIQ == LORA_IQ_INVERTED )
            {
                // RegIqPolaritySetup = @address 0x0736
                SX126xWriteRegister( 0x0736, SX126xReadRegister( 0x0736 ) & ~( 1 << 2 ) );
            }
            else
            {
                // RegIqPolaritySetup @address 0x0736
                SX126xWriteRegister( 0x0736, SX126xReadRegister( 0x0736 ) | ( 1 << 2 ) );
            }
            // WORKAROUND END

            // Timeout Max, Timeout handled directly in SetRx function
            RxTimeout = 0x0;

            break;
    }
}

@ mantoine
did you have time to look into this?

Sorry for the delay.

Few questions:

  • Can you please define periodically?
  • Are both receivers stuck at the same time?
  • Do you see the issue after a specific number of sent packets?
  • The periodicity doesn’t really matter. In our tests we usually use a random delay of 5 to 60s between two packets.
  • Yes, we have indeed observed that both receivers often get stuck at the very same time (but it is not always the case).
  • No, there is no clear correlation to the number of sent/received packets (it can happen after a couple packets or only after hundreds of packets).

Any update on this?

I am still not able to reproduce the issue you see - keep on trying.

Few more questions:

  • Are you using a TCXO or a XTAL for the SX1262?
  • On the Tx side, what is the preamble length?
  • On the Tx side, what is the payload length?
  • What is the LoRa syncword (private / public)?
  • Do you perform your test in conducted or radiated mode?

Thanks for the reply. I assume you placed the transmitter and receiver far apart such that the RSSI is worse than -105dBm, otherwise the issue will no appear.

We are using the XTAL.
Preamble length is the same on the TX side as on the receiver side (10).
We chose the payload length randomly in our experiments, so anything from I think 4 to 64 bytes.
LoRa syncword is “private”.
We use a real transmitter and receiver and place them 50m apart, indoors (if that’s what you are asking in the last question).

I had a very similar problem on the SX1276 in GFSK mode. It is not the same chip or mode, but this sounds like exactly the sort of behavior I had. In my case the issue comes about if the device starts receiving another packet, with another sync word. My workaround was to constantly monitor the flags on the Lora module to determine when a preamble was detected, but a sync match was not, ( you have to give enough time for it to receive the sync word after the preamble detection bit becomes true). If a valid sync word is not received after a short time I reset the gfsk receiver. This solved the problem for me on the SX1276.

My theory about what is happening is that the AGC gain gets fixed by the first preamble that it receives. It should, but appears not to, allow the gain to adjust when the packet with the wrong sync word is received. So if there is a source of packets with another sync word that has a very high signal strength, it will not receive any packet with a significantly lower signal strength as the AGC gain will be set so low that the receiver will never pick up much weaker packets. This may well not be the correct reason for this behavior as other issues could result in the same behavior, but this seemed most likely to me.