Nrf52840 custom firmware using BLE LR

Hello everyone,

I'm currently developing a custom firmware for the Nrf52840 usb dongle (https://www.mouser.de/new/nordic-semiconductor/nordic-nrf52840-usb-dongle).
The custom firmware is written completely from scratch in Rust, if needed I can provide all the code.

What I got working:

Board A: reads some sensor data and transmits it using Ble_1Mbit or Ble_2Mbit mode

Board B: waits for packets using Ble_1Mbit or Ble_2Mbit mode, parses the contents and outputs the sensor data over semihosting

My problem is, that I cannot seem to get the radio modes Ble_LR125Kbit or Ble_LR500Kbit working, which I would need for my project. From reading the Product Specification, the only required difference from the configuration is the PCNF0.PLEN bits, which must be set to 0b11 instead of 0b00/0b01 for Ble_1Mbit/Ble_2Mbit.

I assume there is something else I need to enable to use Ble_LR125Kbit, but I cannot seem to find out what that is, if someone could give me a hint that would be great.

For completeness the code which configures the radio registers:

        let mode = RadioMode::BleLR500Kbit;
        handle.set_mode(mode);
        handle.set_pcnf0(&RadioPcnf0Configuration {
            lengthFieldLength: RadioPcnf0LengthFieldLength::Bits8,
            s0Length: RadioPcnf0S0Length::Bits0,
            s1Length: RadioPcnf0S1Length::Bits0,
            s1Included: RadioPcnf0S1Included::Automatic,
            codeIndicatorLength: RadioPcnf0CodeIndicatorLength::L0, //no clue what this is required for. The only other mention in the documentation is the "RATEBOOST" event: "Ble_LR CI field received, receive mode is changed from Ble_LR125Kbit to Ble_LR500Kbit."
            preambleLength: mode.into(),
            lengthIncludesCrc: RadioPcnf0LengthIncludesCrc::Exclude,
            termLength: RadioPcnf0TermLength::L0, //again, no clue if this is correct.
        });
        handle.set_pcnf1(&RadioPcnf1Configuration {
            payloadMaxLength: RadioPcnf1PayloadMaxLength::Bytes255,
            staticLength: RadioPcnf1StaticLength::Bytes0,
            baseAddressLength: RadioPcnf1BaseAddressLength::Bytes4,
            endianness: RadioPcnf1Endianness::Little,
            whitening: RadioPcnf1Whitening::Disabled,
        });
        handle.set_crc_polynomial(0x98ff8c << 1); //best crc for data with length of up 4073 bits for a 3 byte crc (results in HD 5)
        handle.set_crc_cnf(&RadioCrcConfiguration {
            length: RadioCrcLength::Three, //BLE_LR only supports length 3
            skipAddress: RadioCrcSkipAddress::Skip,
        });
        // hardcoded random addresses
        handle.set_address_base0(0x2e2e86e);
        handle.set_address_base1(0xb70bcd75);
        handle.set_address_prefix0(0x8d368313);
        handle.set_address_prefix1(0x36c2c313);
        // we receive and transmit on the same address
        handle.tx_address_set(RadioLogicalAddress::LogicalAddress0);
        handle.rx_address_enable(RadioLogicalAddress::LogicalAddress0);

As stated above: the only change I need to do to this configuration to get it working is changing the mode to Ble_1Mbit or Ble_2Mbit.

Additional information:

  • I read in some other post that data whitening and CRC including address at the same time doesn't work in Ble_LR125Kbit/Ble_LR500Kbit mode, that is why data whitening is disabled.
  • I do not use any shortcuts (especially no PHYEND/START, etc)
  • The code which waits for sending packets waits for END event, but I also tried PHYEND (In case I was overwhelming the sender by starting the START task to frequently)
  • The boards are physically close together and in line of sight
  • Anything not specified in the above code sample for radio is left as is from reset (including frequency, tx power)
  • The example code doesn't specifically mention the preamble, but I triple checked that the value written to the registers had 0b11 at the correct bits
  • HXFO is enabled (otherwise BLE_1Mbit would not work)
  • I also tried turning on DCDC

Any help will be much appreciated Slight smile

Related