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.