adafruit / circuitpython

CircuitPython - a Python implementation for teaching coding with microcontrollers
https://circuitpython.org
MIT License
3.97k stars 1.16k forks source link

NRF52840 Enhanced ShockBurst Support #1258

Open tannewt opened 5 years ago

tannewt commented 5 years ago

Nordic's legacy protocol support that is commonly used with the inexpensive modules of the same name. The nRF52840 can also speak the same protocol.

uhrheber commented 5 years ago

This protocol is named "Enhanced ShockBurst": http://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.sdk5.v15.2.0%2Fesb_users_guide.html&cp=4_0_0_5_1

saspa commented 5 years ago

Is there any way that I can help out in implementing this? I'm interested in using the ESB on the NRF52840 for a low latency HID project (BLE is capped at 7.5ms latency). I was looking at the Nordic's ESB protocol docs/examples and was hoping if I could implement it for circuitpython since @dhalbert seems to be busy implementing more important features 👍 . I own a NRF52840DK and the NRF52840 dongle if that is helpful at all.

tannewt commented 5 years ago

@saspa We'd love your help! How can we help you get started on it?

saspa commented 5 years ago

Maybe you could link me to some examples of how to port the nrf code into python? I was looking at https://circuitpython.readthedocs.io/en/latest/docs/common_hal.html and https://circuitpython.readthedocs.io/en/latest/docs/design_guide.html

Sorry I'm new to circuitpython but I have some basic knowledge in C and Python.

tannewt commented 5 years ago

Sure! The Discord #circuitpython channel is a good place to get real-time help as well.

I'd suggest by starting with the API portion first. Posting a set of example code here is a good way to brainstorm it.

Once you have an idea then you can create the Python -> C translation in ports/nrf/bindings (like this). I'd suggest copying an existing module that's similar to what you want. Then you can add the C implementation into ports/nrf/common-hal. (Look there for existing examples too.)

Does that help? I can give better answers to specific questions.

Thanks for taking this on!

uhrheber commented 5 years ago

No offence, by why does it have to be Discord? Did anybody ever read their terms of use? You grant them the right to record and use your uploaded content as they please. At the same time, they deny every liability. According to this, they could take what you said or wrote, translate it to another language, publish it elsewhere, and you'd still be reliable for it. Thanks, but no thanks. I'll stay with irc.

tannewt commented 5 years ago

@uhrheber We use it because its way easier than the alternatives. For those who don't want to use it then communicating on GitHub issues is totally fine.

C47D commented 5 years ago

Does this still need help to be implemented?

I checked the Nordic documentation about ESB and maybe the API on circuitpython should be similar, i don't own any Nordic kits but i would like to help.

-carlos

tannewt commented 5 years ago

Yup! Getting dev board for the nRF52840 is the best way to start. It includes debugging onboard which makes it easier. If you need links to it let me know and I can help.

C47D commented 5 years ago

Actually i had tried to get a Nordic board in previous years and never been able to do so because of it's wireless communications ihave to fill some forms, i will try to get familiar with modules development and then get the nRF52840 board.

tannewt commented 5 years ago

@C47D Your help would be welcome on SAMD work too if those are easier to find for you.

2bndy5 commented 4 years ago

I have a Particle Argon coming in the mail because this idea is just too appealing and seems quite doable (given my experience with the nRF24L01). I found some examples in the NRF5 SDK, and it also contains a components\proprietary_rf\esb folder for implementing the Enhanced ShockBurst (ESB) protocol. I'm still pouring through the CircuitPython ports/nrf source, so I'll likely have questions about how to use the ESB files as their licensing disclaimer seems to allow it for nrf ICs. I'm still delving into the nrfx submodule extracted from the SDK to determine what dependencies need to be included for the ESB files to compile.

There are some quirks noted in the SDK about the addresses assigned to payloads. Also looks like the nRF52840 has a couple extra pipes to play with, although that would really only benefit simultaneous reception from multiple transmitters (AKA "multiceiver" mode in the nRF24L01 datasheet).

PS. My C++ may be rusty and I've never written a python lib in C... yet.

jerryneedell commented 4 years ago

@2bndy5 Just curious why you chose an Argon - Are you planning to use the ESP32 co-processor on the Argon as well? Would you be able to work just as well with the Feather nRF52840 express (out of stock) or the Particle Xenon?

2bndy5 commented 4 years ago

Thought I'd try something new and it was the right price. About 2 clicks after the purchase I found out the esp32 as a co-processor is limited by AT command transports on the Argon... I do plan on exploring the esp32 as a co-processor, but maybe I'll just get the breakout board. I'm currently stopping the order, and going to try changing it to the xenon (kinda regret not settling for that in the first place). The NFC feature on the Particle Xenon/Argon could be fun. Correct me if I'm wrong, but I don't think the Feather express has NFC.

jerryneedell commented 4 years ago

That was my concern -- the limits of the AT command set on the Argon -- I just verified that the Xenon works fine with an Airlift Featherwing and Airlift Breakout.

as to NFC -- there is some discussion of it on the guide for the feather nrf52840 express, I have not tried it. dee the Pin D2/NFC2 secition https://learn.adafruit.com/introducing-the-adafruit-nrf52840-feather/pinouts

2bndy5 commented 4 years ago

An Update:

I've been trying to hunt down where the BLE libraries schedule a timeslot using the SoftDevice's Timeslots API on the nRF52840... Still haven't found it, but I'm thinking this concurrent multi-protocol idea isn't very feasible since

  1. The BLE stack has to be disabled when the radio is being used for a different protocol. I think the same applies to the ESB protocol. Also, I'm not sure if BLE configuration needs to be reloaded when its scheduled timeslot is executed.
  2. Timeslots API can pose additional problems for concurrent multi-protocol usage. ie ESB transmissions amidst being received when timeslot expires will be discarded (although there does seem to be an option to request a timeslot extension).

Am I Overthinking This?

It would be easier if I could treat the protocol being used as a singleton (only BLE is used or only ESB is used). This doesn't mean I'm giving up, I'm just having trouble reading the Circuitpython source code in regards to the SoftDevice implementation. I think I'll push forward with a custom build for the nRF52840 dongle (super cheap) that only employs the ESB protocol (and disallows BLE).

PS I've been thinking of adding something similar to Nordic's ESB protocol API (that uses an external nRF24L01 module) to the Circuitpython firmware because C++ takes up less memory, and as it turns out my Circuitpython-nRF24l01 library is too big for the M0. Thoughts?

tannewt commented 4 years ago

Am I Overthinking This?

It would be easier if I could treat the protocol being used as a singleton (only BLE is used or only ESB is used). This doesn't mean I'm giving up, I'm just having trouble reading the Circuitpython source code in regards to the SoftDevice implementation. I think I'll push forward with a custom build for the nRF52840 dongle (super cheap) that only employs the ESB protocol (and disallows BLE).

A custom build is probably easiest. Right now we only enable the soft device when import _bleio is done but I want to have it on in the future for file transfers.

PS I've been thinking of adding something similar to Nordic's ESB protocol API (that uses an external nRF24L01 module) to the Circuitpython firmware because C++ takes up less memory, and as it turns out my Circuitpython-nRF24l01 library is too big for the M0. Thoughts?

You could do it as a custom build but we don't have the space for any more modules into the M0 build. We could update to newer MicroPython to get loadable native modules but that is a huge undertaking.

2bndy5 commented 4 years ago

That explains why all I could find is the sd_enable() call in adapter.c which is called from _bleio's init.c; thanks for the help there. I didn't know that the softdevice could also help with file transfers. Are you referring to the flash memory API and/or the Interrupt model and processor availability (I don't see an open issue for this feature)?

I had to recommend using Arduino IDE for employing the nRF24L01 on the M0. Looks like I'll have to double down on that advice. Thanks again.

tannewt commented 4 years ago

That explains why all I could find is the sd_enable() call in adapter.c which is called from _bleio's init.c; thanks for the help there. I didn't know that the softdevice could also help with file transfers. Are you referring to the flash memory API and/or the Interrupt model and processor availability (I don't see an open issue for this feature)?

Nope, I intend on enabling file transfers over bluetooth at some point so that folks can edit code from their mobile devices. When I do that, I'll want it started after-boot.py like USB.

I had to recommend using Arduino IDE for employing the nRF24L01 on the M0. Looks like I'll have to double down on that advice. Thanks again.

Arduino is a good tool too. :-)

2bndy5 commented 4 years ago

Interesting. I've been anxiously awaiting the introduction of BLE audio profiles. It would seem Nordic semi is too.

auxym commented 2 years ago

Hi, I see mentioned in this thread that BLE has a lower bound of 7.5 ms latency. Does anyone have any idea what the latency of ESB would be using nrf52840s? We are looking into the use of these modules for robotics applications where latency is critical but throughput not that much (and power is relatively irrelevant).

2bndy5 commented 2 years ago

I haven't been getting around to solving this... But my guess would be much less than 7.5 ms. A single successful transmission normally takes a little over 500 us (depending on what you have the auto-retry feature's delay value set to - 500 us is the datasheet's recommendation).

If auto-ack feature is off (not recommended), then it would be more like 200 us. Note that turning off auto-ack is really only for OTA backward compatibility with Nordic Semi's older ShockBurst protocol (only used by deprecated nRF24*** radios or some horrible nRF24L01 clones).

BLE is a very bloated protocol.

mrfibreoptic commented 1 year ago

Is there any way that I can help out in implementing this? I'm interested in using the ESB on the NRF52840 for a low latency HID project (BLE is capped at 7.5ms latency). I was looking at the Nordic's ESB protocol docs/examples and was hoping if I could implement it for circuitpython since @dhalbert seems to be busy implementing more important features 👍 . I own a NRF52840DK and the NRF52840 dongle if that is helpful at all.

Hi, have you gotten anywhere with this? I have a project I would like to implement this into

2bndy5 commented 1 year ago

No, not in CirPy. We (me and TMRh20) made some progress as an Arduino Lib (C++). Checkout nrf_to_nrf. We also added support in the network layers' v2.0 (RF24Network and RF24Mesh) for the nrf_to_nrf lib. But that nrf_to_nrf lib is still in its infancy - no TX FIFO implemented and no interrupt support (both of which would depend on the RTOS used).


It turns out that the ESB protocol implemented in the nRF Connect SDK (& nRF5 SDK) cannot behave identically to the ESB protocol implemented in the nRF24L01 chips. For example, dynamic payloads are not pipe specific in the nRF SDKs but are in the nRF24L. Note that some differences are born from hardware limitations of the nRF5x chips, not software limitations. The SDKs could be improved about ACK packets that don't have payloads attached, but that may incur a significant refactor of the ESB module.

Basically, OTA compatibility between nRF5x \<--> nRF24L is slightly compromised.