Skip to content

Lib improvements & silicon errata #51

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
maholli opened this issue Oct 31, 2020 · 6 comments
Closed

Lib improvements & silicon errata #51

maholli opened this issue Oct 31, 2020 · 6 comments

Comments

@maholli
Copy link

maholli commented Oct 31, 2020

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

@jerryneedell
Copy link
Contributor

jerryneedell commented Nov 1, 2020

@maholli Thanks for posting this. I'll give your suggestions a try.

@jerryneedell
Copy link
Contributor

jerryneedell commented Dec 22, 2020

@maholli I'm finally getting around to implementing these changes - sorry for the delay.
for the Section 2.1 changes, it looks like you have implemented it only fro the 862-1020 MHz range. Is that correct?
Since this library also serves the 433 Mhz module that alternative should also be implemented. Not a problem.
It should be simple to add that check as well. I just wanted to make sure I had not missed something.

@jerryneedell
Copy link
Contributor

also reading the errata, it looks to me like we have to be careful to set the spreading factor first, then the bandwitdth since it notes that if bit 7 of register 0x31 is changes, then registers 0x2f and 0x30 must also be reset.
Does that make sense?

@jerryneedell
Copy link
Contributor

ah -- I had that wrong -- the BW has to be set before the SF.

also -- there is a missing step in the BW setter -If the BW is not >= 500K then register 0x36 needs to be set to 0x03
Since register 0x36 is set to 0x03 by default, tis will only matter if you are changing the BW setting manually

The errata for setting but 7 of register 0x31 is confusing.
It is set to 1 by default, but should be cleared for all BW < 500K per the errata.
It will be properly set to 0 when the spreading factor is set during init.

Care must be taken if you are manually setting the BW to 500KHz since you then should also reset Bit 7 back to a 1. This can be done by setting the spreading factor any time you set the BW.

I think it might be better to set Bit 7 of Reg 0x31 as appropriate whenever the BW is set

@jerryneedell
Copy link
Contributor

@maholli Implemented via PR #57 -- take a look and comment if you have a chance.
Thank you for these updates!

@jerryneedell
Copy link
Contributor

Implemented by #57

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants