Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

nrfx confusion and the state of documentation and examples

I had my first encounter with Nordic chips a couple of years ago. To evaluate the devices, I used an nRF52832 to implement a small helper project. I was very impressed: it took me no more than 2 hours to get from zero to working code that interfaced with SPI, performed various other I/O and, most importantly, did BLE. FreeRTOS was also supported, and there were good examples.

After poor experiences with other vendors' software support, I decided Nordic is the way to go.

Fast forward to last week. I have a number of projects where I need BLE-capable MCUs. I still remembered my excellent experience with Nordic. But this time things were different. Let's quickly retrace my steps:

I go to the web page, click around, stumble onto "nRF Connect SDK", download the installer, installer starts downloading python and a ton of other dependencies, I run away screaming.

I read deeper between the lines and it seems that nRF5 SDK actually isn't obsolete. I think. The site isn't entirely clear on the future of nRF5 SDK. So, I download the nRF5 SDK.

I try to find an introductory overview of how to use peripheral drivers. Can't find anything of the kind. The "infocenter" with its auto-extracted API documentation is next to useless: there are very few overview articles, the rest is auto-generated from header files. Well I can read header files myself. What I need is introductions and overviews, articles that explain HOW and WHY.

Well, I need to use I2C. How difficult could that be? So I start looking for I2C, it's nowhere to be found. Googling tells me that I'm looking for "TWI". Ok. I find "TWI master" in "Drivers descriptions" and read the (rare) overview. I learn about `nrf_drv_twi_init()`. Things look good.

After an hour or two wasted on Segger Embedded Studio licensing (what's an "ethernet address" these days? my computer has 11 of those) I give up and go back to Makefiles and gcc.

I start going through `sdk_config.h` and… what is this "nrfx" business? Why are some drivers "legacy"? Will they be obsoleted soon? It seems I shouldn't be using "legacy" drivers when writing new code. So, I guess `nrf_drv_twi_*` is out. So why does the API documentation point me to this "legacy" driver?

Then I discover that I can also get to TWI drivers through "nRF52832 Drivers" and that shows me different information. It shows four options, where only one seems right (TWI driver), and that lands me in an `nrfx` API. With no overview.

Hey, nothing could be easier, right? After all, Nordic's own "Introduction to Nordic nRF5 SDK and Softdevice" article says "Many developers asked, “where I can get the documentation of SoC peripheral driver APIs” Because they need to follow the documents to develop applications. In Nordic, we not only provide the documentation but also the examples. We recommend reading the example code directly, which is more efficient."

As it turns out, none of the examples use `nrfx_twi`. They all use the "legacy" API.

Right now, I am getting seriously confused. I discovered TWI, TWIM, TWIS, `NRFX_TWI`, and `NRFX_TWIM`. I am banging my head against the wall trying to enable the right SDK options. I have no idea what needs to be enabled. And if I try to enable `NRFX_TWI`, and `NRFX_TWIM`, my code doesn't compile unless I also set `TWI_ENABLED` to 1 (?).

It seems I am not the only one confused, see for example [https://devzone.nordicsemi.com/f/nordic-q-a/34317/undefined-reference-to-nrfx\_twi\_tx] or [https://devzone.nordicsemi.com/f/nordic-q-a/44628/confusing-about-nrfx-how-should-i-use-it-without-legacy-with-old-and-do-i-need-it] — there are a number of those over the years.

I am fighting with defines and adding #error directives to driver sources to check what *actually* gets compiled.

The documentation is insufficient. For example, how do I discover what `nrfx_twi_evt_handler_t` function is supposed to do? The function prototype isn't enough.

More importantly, what is this whole "nrfx" business? On one hand, I am being scared away from "legacy" drivers. On the other hand, it seems the migration has been going on for years now, is not finished, and Nordic hasn't even bothered to update the examples!

Dear Nordic, we don't use your chips because of your low, low prices. We use them, because they let us get things done, quickly and reliably, software being the largest factor. And software is not just code. It's your documentation, examples, overview and introductory material. It's the developer experience, because not everyone is a full-time Nordic developer, we have to juggle many projects and responsibilities. We don't have time for messy and incomplete solutions.

I am making the effort and spending the time to write this, because I suspect Nordic doesn't realize that there is a problem. So, in different terms: 3 years ago, I would have picked a Nordic chip for any BLE project, immediately, *because of the software experience*. Today, I am installing SDKs from Silicon Labs and checking out their Blue Gecko line. I wouldn't even have looked closer at those chips if not for the current experience with Nordic's software.

One of the biggest issues with silicon vendors these days is software support. What we get is bloated Eclipse clones with "custom" functionality, unfinished SDKs, auto-generated API documentation, and a couple of half-assed application notes. Even worse, we get a "strategy change" every couple of years or so, where the vendor decides to use some New Thing, never completes the migration, and keeps dragging us along. I had this happen with Freescale/NXP Kinetis (their various SDK approaches over the years, KDS and then MCUxpresso) and the result is that I'm not using any complex Kinetis chips anymore. I can't keep up with their strategy shifts.

What vendors fail to understand is that times have changed and these days it's often a single person doing all the hardware and software development. On many architectures.

Here's what I would do *right now*, if I were Nordic:

  • Write a clear and understandable document about the whole nrfx thing. No, "Migration guide for nrfx drivers" is not enough. BE CLEAR whether I am expected to use nrf or nrfx going forward. Use specific timeframes ("nrf will only be supported until 2021"). Do not use the word "legacy" unless you mean "deprecated". And don't use weasel language like "For new applications, consider to use the new nrfx API" — that's just skirting responsibility. Tell us what you will support and what we should use.
  • As Yoda said, either do or do not. Either move to nrfx, or stick with the old APIs, but don't get stuck inbetween.
  • (I can't believe I have to say this) For every peripheral driver, review API documentation and update it for nrfx.
  • Hire an intern and have him/her convert the examples to nrfx. Don't let him/her talk to any of you! Don't answer any questions! The point is to do this based on available code and documentation. Note where he/she gets stuck and improve those areas of documentation.
  • Write a series of introductory/overview articles. I don't mean step-by-step tutorials, but rather articles for experienced developers, with tradeoffs and guiding principles. I can look at a code example to see what to do step-by-step, but I still want to know what my event handler will receive, what is the expected behavior, which functions can be called from interrupts, how they will interact with an RTOS and a SoftDevice, etc. Should I use the TWI or TWIM driver? At which point does DMA make a difference? If you don't know what to write about, hire an experienced embedded developer that hasn't used Nordic chips, have him/her write an application, and he/she will tell you what is missing.
Parents
  • I think some of your input have been taken into account in the latest nRF5 SDK:
    https://infocenter.nordicsemi.com/topic/sdk_nrf5_v17.0.2/nrfx_migration_user_guide.html

    "The migration process is not required and often results in exactly the same functionality. Consider migration only if you want to take advantage of the new features offered by nrfx."

    In terms of DMA or not to DMA; I would consider using DMA for all transactions where you don't need or want to analyze data during the transaction.

    More examples, tutorials and blog posts on best practices is good input, and something that I hope we can improve on.

  • Kenneth — I did read that page, and it didn't clarify much for me. The next paragraph after the one you quoted says:

    "If you want to continue using the nrf_drv drivers, no changes are required. You can use the drivers as before, but without taking advantage of any new functionalities introduced to the nrfx drivers."

    But I do want the "new functionalities"! (I think) — I am now beginning development of code that I will need to extend and maintain for years. As I have to go through a learning curve anyway, I'd much rather do it for the Officially Strategically Future-Proof API. And that web page does not clarify which API it is.

    Looking at the TWI driver, it seems for example that the nrfx one has a function that can recover a stalled bus, and the "legacy" one does not.

    I wanted to quickly check that, but I can't even find the right place in the documentation: going into "Software Development Kit > nRF5 SDK v17.0.2 > Hardware Drivers > Drivers descriptions" and choosing "TWI master" lands me in a page which describes the "legacy" nrf_drv API. To confuse things even more, this page also says:

    "The driver layer provides APIs on a higher level than the HAL. See the API documentation for the TWI driver - legacy layer for details."

    So, which layer is the "legacy" layer again?

    If you search the forums, you will find many posts from users confused about nrfx. Some of the posts are from more than two years ago, and the confusion still remains.

  • Not sure I have a good answer for you here, but nrfx was introduced (or a requirement if you like) when Nordic started supporting zephyr RTOS. In the process it was decided that our nrf drivers should use the nrfx hardware abstraction layer also, and the drivers from that point have been described as legacy. That is though misleading, since the drivers in many cases can provide a slightly higher abstraction layer (that at least in some case) may be easier to work with, also there is no problem to continue to use the drivers in any way. There is no plans to obsolete or deprecate them from what I know, but if you are planning to transition to zephyr RTOS (part of the nRF Connect SDK) then the legacy drivers you are familiar from the nRF5 SDK is not availble there (instead there are many other libraries that can be used if you don't want to use the nrfx directly).

    Best regards,
    Kenneth

  • Kenneth — if describing the drivers as "legacy" is misleading, then I would suggest not doing it.

    Thanks for the explanation, but I'm not sure if you realize how unclear it all sounds to people from the outside. I now understand *why* Nordic did the whole nrfx thing, but I still do not understand what the path forward is for me.

    Zephyr scares me with its complexity. I will have to use it one day because of the nRF9160, but I'm holding off for as long as I can.

    What I think vendors do not understand is that for us, designers and developers, "transitions" and "migrations" are the worst things ever. Taking the example of Freescale/NXP, their Kinetis software was going through "transitions" all the time, and the transitions were never "done", they just overlapped. From a developer point of view, the software was always either "legacy/obsolete" or "being transitioned", with the documentation never being up to date. And projects had a roughly two-year lifetime.

    Now I'm looking at Nordic and I'm beginning to see the same thing: an incomplete nrf_drv -> nrfx "transition" (which isn't really a transition, except the old drivers are "legacy" and you should use the new ones, except you don't have to, but only the new drivers have new features, etc). And on top of that there is the nRF5 SDK -> nRF Connect "transition" (sure, you can use the "old" SDK, but Zephyr is the way forward, but the old SDK is supported, but new features… etc). This creates confusion, uncertainty and doubt.

    I think my "here's what I would do right now if I were Nordic" points still stand (*especially* the first four!).

    Also, you wrote "good input, and something that I hope we can improve on" — so, has any specific action been taken? Is there somebody tasked today with fixing the documentation? Writing nrfx examples? I'm asking, because I'm looking through these forums, and I see posts from TWO YEARS ago about insufficient nrfx examples and nrfx confusion. If nothing has been done so far, it doesn't bode well for the future.

Reply
  • Kenneth — if describing the drivers as "legacy" is misleading, then I would suggest not doing it.

    Thanks for the explanation, but I'm not sure if you realize how unclear it all sounds to people from the outside. I now understand *why* Nordic did the whole nrfx thing, but I still do not understand what the path forward is for me.

    Zephyr scares me with its complexity. I will have to use it one day because of the nRF9160, but I'm holding off for as long as I can.

    What I think vendors do not understand is that for us, designers and developers, "transitions" and "migrations" are the worst things ever. Taking the example of Freescale/NXP, their Kinetis software was going through "transitions" all the time, and the transitions were never "done", they just overlapped. From a developer point of view, the software was always either "legacy/obsolete" or "being transitioned", with the documentation never being up to date. And projects had a roughly two-year lifetime.

    Now I'm looking at Nordic and I'm beginning to see the same thing: an incomplete nrf_drv -> nrfx "transition" (which isn't really a transition, except the old drivers are "legacy" and you should use the new ones, except you don't have to, but only the new drivers have new features, etc). And on top of that there is the nRF5 SDK -> nRF Connect "transition" (sure, you can use the "old" SDK, but Zephyr is the way forward, but the old SDK is supported, but new features… etc). This creates confusion, uncertainty and doubt.

    I think my "here's what I would do right now if I were Nordic" points still stand (*especially* the first four!).

    Also, you wrote "good input, and something that I hope we can improve on" — so, has any specific action been taken? Is there somebody tasked today with fixing the documentation? Writing nrfx examples? I'm asking, because I'm looking through these forums, and I see posts from TWO YEARS ago about insufficient nrfx examples and nrfx confusion. If nothing has been done so far, it doesn't bode well for the future.

Children
Related