SPI Radio Register Dump

Could anyone provide a dump of the SPI bus/written register values into the radio?

It’s really hard to trace from code what actually goes out onto wire.

Any radio/region would do.

I’m working on a minimal repeater node from scratch.

Surely registers would really depend on the exact Radio chipset used. Each device has has its own register map.

Not sure if it helps, but I figured out the settings to use to match LongFast on EU_868, here:

THis is for the RadioHead library (which is what the Ardiuno heltec lora v3 device driver uses) for SX1262

I have also figured it out for Micropython

I’ve been able to send & receive Meshtastic packets (but not decode the protobufs/encrypted payloads)
… but working on it for my own repeater (not released the code yet!). THis is actully for the RFM95W module, which is a wrapper for the SX1276
… a repeater doesnt technically need to decode protobufs

So can’t help with the exact register maps, but can with the settings to drive the libraries (which ahve already figured the gritty details of SPI registers)

I guess you seen it, but this was very useful

(particularly the SyncWord bit! Easy to overlook that)

And of course

1 Like

A ‘register dump’ is easy enough on a SX127X, basic SPI reads.

However, whilst you could work out stuff like LoRa modem settings a register dump wont tell you whats happening at Meshtastic level in that how its setup or handles packets in the RX and TX side.

Quite so.

Whilst its clearly stated in the SX127X datasheet what each of the registers means and does, the SX126X interface is quite different. The SX126X does have registers, but the data sheet only lists a handfull, configuration of the SX126X is done via API commands, not register writes.

I know that, but if I see which registers are written then I could look for equivalent on other radios.

Currently my issue is that I set bw,cr,freq but not receiving anything.
Also preamble length is inconsistent, code says 12, meshtastic doc says 16.

setCRC(16) doesn’t seem to match any registers.

But if anyone has a debugger attached it would be easy to stop at writeReg function.

I’ve got it working with Preamble of 16.

As noted the syncword was the major stumbling block I had. SyncWord is not well documented in most libraries I’ve used. But do need to Ox2B for it work.

Just have to enable CRC - a boolean on RadioHead, and uLora Libraries, didn’t give it any value.

Edit. just found here: Heltec_ESP32/src/radio/radio.c at master · HelTecAutomation/Heltec_ESP32 · GitHub

if( crcOn == true )
{
SX126x.PacketParams.Params.Gfsk.CrcLength = RADIO_CRC_2_BYTES_CCIT;
}
else
{
SX126x.PacketParams.Params.Gfsk.CrcLength = RADIO_CRC_OFF;
}

So enabling CRC uses defined ‘RADIO_CRC_2_BYTES_CCIT’ and
RADIO_CRC_2_BYTES_CCIT = 0xF2,

dont know of that tells you anything!

Syncwords are not well documented by Semtech, there was a time (circa 2020) when an application note was promised by them, but I dont recall seeing it.

Changing the syncword away from the two defaults, 0x12 and 0x34 can cause issues.

Away from the two ‘defaults’ the syncwords can be leaky, not work, not be compatible between SX127x and Sx126x or result in reduced sensitivity.

Its a single bit of register 0x1E on SX127x and on SX126x its byte 4 of the setpacketparams command.

Which LoRa device are you using ?

I’m trying to get the frequency right first

I receive signals centered around 869.5Mhz (the weak ones) from my town,
even though spec says 869.525
and official Holtec doesn’t even seem to be symmetrical to that (strong one).
So which one should I aim for from the 3 frequencies?

My target radio is RFM95 module.

The frequency of the SX127x is in registers 0x06,0x07,0x08.

That gives you a 6 digit HEX number, convert to decimal, multiply that by 61.03515625 to get the frequency Hz set.

SDRs I have used dont tend to be very accurate frequency wise.

Ok I think I got all the registers, I get RXDONE irq when nearby Heltec transmits,

but for some reason LORARegIrqFlags is always 0x70, meaning CRC Error bit is always set. I clear irqs after each RXDONE. What can cause CRC error even with strong signal?

_setOPmodeLora(OPMODE_SLEEP);
_setOPmodeLora(OPMODE_STANDBY);
wrReg(LORARegSyncWord, 0x2B);
wrReg(LORARegFifoAddrPtr, 0u);
wrReg(RegFrfMsb, (tUI8) (Frf >> (8u * 2u)));
wrReg(RegFrfMid, (tUI8) (Frf >> (8u * 1u)));
wrReg(RegFrfLsb, (tUI8) (Frf >> (8u * 0u)));
/* using Explicit Header mode! */
wrReg(LORARegModemConfig1, (c->bw << 4u) | ((c->cr + 1u) << 1u));
ASSERT((c->sf >= 7u) && (c->sf <= 12u)); 
wrReg(LORARegModemConfig2, c->sf << 4u); 
wrReg(LORARegModemConfig3, SX1276_MC3_AGCAUTO | SX1276_MC3_LOW_DATA_RATE_OPTIMIZE); 
wrReg(LORARegPreambleLsb, 16);
wrReg(LORARegDetectOptimize, (0xC0u << 3) | 0x03u); /* improve RX noise rejection, clear bit7 */
wrReg(RegLna, 0x23u); /* boost RX gain */

is there an option to print register writes on meshtastic fw?

That can happen if there is a missmatch in the low datarate optimisation settings, both TX and RX need to use the same setting.

One of the details of syncwords I recall was to not use nibbles that are greater than 0x7

Works ok after I removed every errata fixes/improvements.

Still getting 30% crc errors.

Weirdly when Holtec receives destAddress FFFF FFFF on app Debug log then it broadcasts it, which I read as FFFF FF00 after CRC is valid, not sure why.

Stop and think.

If the CRC is valid, then the data received into the packet buffer is almost certainly correct.

The CRC is a 16 bit number so whilst it is possible that the packet data is corrupt and the CRC (sent at the end of the packet) is also corrupt and the corruption matches what are the chances of that ?

That’s why I’m asking, becauses FFFF FF00 doesn’t seem to be documented.

it may help if you post the full packet header (16 bytes)
also, on a functioning meshtastic node attach to the serial port and look at the chatter, there’s a lot of information printed, including from/to/id/length info when a packet is received, that may help you compare should/got…
BTW, I found the CubeCellRepeater code very helpful 'cause it extracts the Meshtastic magic settings into a file or two: GitHub - tuxphone/CubeCellRepeater: Small repeater node for the meshtastic project. it may help you if you freq is off resulting in the 30% CRC error…

Well I’m down to the bare minimum config and still getting crc errors, so the issue might be incompatibility between modules, or Meshtastic using extra settings.
Frequency should be ok within ±62Khz based on datasheet.

It’s funny there are so many users but no one can debug the firmware, that’s why I started on STM32.

1 Like

Not sure I understand… I’m using stm32wle5. I enabled a #define in RadioLib which prints out the SPI transactions. That gave me the commands it sends to the radio on a WSL, which uses an sx1262. I also looked at the CubeCellRepeater code, and of course the Meshtastic source. I had no issues getting the stm32wle5 to talk to a Meshtastic node and it’s all programmed down to the registers, i.e., zero external libs. So far I’m at ~14kB of code and ~1KB RAM for a basic repeater that doesn’t decrypt/decode packets. (TX queue and seen-packet-ID-list being separate. I’m not seeing any CRC errors.

You say that no-one can debug the firmware, but I’m not sure what someone would debug here? Which code would they debug?

I doubt it.

The only caveat to that is that the modules base frequencies need to be within 25% of the bandwidth in use.

But easy to test the modules with LoRa point to point library examples to see if you get the same issues with those particular modules and LoRa settings.

Would you have a copy of what register configs you found in sx1262?

Do you also see destination address of FFFF FF00 coming in?

The way I count crc errors:

if RXDONE
   if CRCERR
      cntCRC++
  else
      cntRx++
      proc()