Skip to content

Lib improvements & silicon errata  #51

Closed
@maholli

Description

@maholli

Having taken the CircuitPython_RFM9x lib and heavily modifying it for my own applications, there are some general register settings that could be implemented to improve performance as well as some SX1276/7/8/9 errata that may want to be included.

General Performance Improvements

Many of these are not present in the HopeRF datasheet (but ARE described in the SX1276/7/8/9 datasheet). My testing with HopeRF RFM98PW modules has convinced me these specific semtech registers DO make a difference.

  1. Enabling automatic gain control has improved my LoRa Rx packet RSSI sensitivity in all situations I've encountered. I just created another registerbits instance: auto_agc = _RegisterBits(_RH_RF95_REG_26_MODEM_CONFIG3, offset=2, bits=1) and set it True during init. See register 0x26 in either HopeRF or Semtech datasheet.
  2. In it's current state, I'm unable to this library for low data rate operation in standard (benchtop) testing conditions. This can be remedied by setting bit 3 of register 0x26. Semtech calls it "Low Data Rate Optimization" but HopeRF calls this bit "MobileNode." See semtech datasheet for more detail.
  3. (for high frequency modules) setting LnaBoostHF (register 0x0C bits 0,1) to 0b11

Addressing Errata

Semtech has an: errata doc for the SX1276/7/8/9. For all my modules, the silicon version matches that which is specified in the beginning of the errata (0x12), and implementing the following fixes DID make a difference in performance.

  1. Section 2.1 Sensitivity Optimization with a 500 kHz Bandwidth -- which can be just an easy check & write in during the signal_bandwidth setter.
  2. Section 2.3 Receiver Spurious Reception of a LoRa Signal -- a handful of different configuration cases will need to be accounted for, but I saw improved rejection for the bandwidths I'm utilizing.
    My hacky implementation look like this:
    @signal_bandwidth.setter
    def signal_bandwidth(self, val):
        # Set signal bandwidth (set to 125000 to match RadioHead Bw125).
        for bw_id, cutoff in enumerate(self.bw_bins):
            if val <= cutoff:
                break
        else:
            bw_id = 9
        self._write_u8(
            _RH_RF95_REG_1D_MODEM_CONFIG1,
            (self._read_u8(_RH_RF95_REG_1D_MODEM_CONFIG1) & 0x0F) | (bw_id << 4))
        if val >= 500000:
            # see Semtech SX1276 errata note 2.1
            self._write_u8(0x36,0x02)
            self._write_u8(0x3a,0x64)
        else:
            if val == 7800:
                self._write_u8(0x2F,0x48)
            elif val >= 62500:
                # see Semtech SX1276 errata note 2.3
                self._write_u8(0x2F,0x40)
            else:
                self._write_u8(0x2F,0x44)
            self._write_u8(0x30,0)
    @spreading_factor.setter
    def spreading_factor(self, val):
        # Set spreading factor (set to 7 to match RadioHead Sf128).
        val = min(max(val, 6), 12)
        self._write_u8(_RH_RF95_DETECTION_OPTIMIZE, 0xC5 if val == 6 else 0xC3)

        if self.signal_bandwidth >= 5000000:
            self._write_u8(_RH_RF95_DETECTION_OPTIMIZE, 0xC5 if val == 6 else 0xC3)
        else:
            # see Semtech SX1276 errata note 2.3
            self._write_u8(_RH_RF95_DETECTION_OPTIMIZE, 0x45 if val == 6 else 0x43)

        self._write_u8(_RH_RF95_DETECTION_THRESHOLD, 0x0C if val == 6 else 0x0A)
        self._write_u8(
            _RH_RF95_REG_1E_MODEM_CONFIG2,
            (
                (self._read_u8(_RH_RF95_REG_1E_MODEM_CONFIG2) & 0x0F)
                | ((val << 4) & 0xF0)
            ),
        )

I'm filing an issue rather than a PR since I don't have the time to implement and test atm 😇
EDIT: @jerryneedell this will likely remedy the "garbage" packets you were investigating last year

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions