CDK is referencing to this board DWM3001CDK - Qorvo.
You have inside nRF52833 + dw3000.
Then you have other binaries for nordic board (nRF52832/33/40), where you would put a shield on it as done in this kit for example QM33120WDK1 - Qorvo
Looking through that package I can’t see any source code for the actual drivers, everything links to libdwt_uwb_driver-m4-hfp-6.0.14.a or libdwt_uwb_driver-m4-sfp-6.0.14.a
So how do I use these drivers if I want to use a different processor architecture?
Normally in that situation I’d say that I needed to write my own drivers based on the user manual. A perfectly reasonable requirement and the reason why user manuals tell you everything you need to know to use a part. Only the user manual says “please see API functions” for the method of how to do some things.
Quite how the API will tell me how to do this isn’t very clear since the API in in effect a black box unless I want to start disassembling the binary files. Which I’m guessing is against the terms of the license.
So how do I do this? The DW1000 I wrote my own drivers. The DW3000 I used an early decawave driver where the source was released. Right now the QM33110 looks like a non-starter since we have no way to drive the chip.
Firstly, I would like to inform you that I encountered a build failure while following the “Building” section of the “QNIA_Developer_Guide.pdf”, which was caused by the “Error starting process mergehex”. To resolve this issue, I installed the “nRF Command-Line Tools”.
May I ask which specific part of the “DWM3001CDK-QANI-FreeRTOS_full_QNI_3_0_0.hex” firmware, included in the v3.0 package, needs to be modified to enable one DWM3001CDK module to connect to two iPhones?
I got an older version with libniq-m4-hfp-0.9.9.1.a working with a custom board with a nRF5340 and Zephyr. Was some headache, because e.g. it crashed at osMutexCreate, because the Qorvo library passed a NULL pointer to it, so I had to patch the CMSIS implementation of Zephyr, and wasn’t very stable, sometimes it didn’t start. I’m currently trying to update to the latest version.
But right, it is a serious limitation to provide only binary versions of central parts of the firmware. It makes it more difficult to debug it, and limits the usable target hardware to the ARM architecture. Is there a reason why it is not distributed as source code, or is there a detailed documentation to write the driver myself? The embedded firmware part looks also very bloated and with unnecessary layers, like the libniq lib doesn’t do much except doing some variable initializations, and most of the secret implementation is in libembedded_mac_arm.
There is a user manual which in theory contains all the information required to write your own driver. It did for the DW1000, it wasn’t very clear on how some things worked but it did at least tell you what you needed to know to make things work.
However the DW3000 manual has a number of sections where it tells you to refer to the driver source code for details of how to perform an operation. The driver source code (the old version that was released before it became binary only) for those functions would change registers that weren’t listed in the manual or would set bits to values that the manual claimed were invalid.
In other words the documentation is a mess, has been for several years now and qorvo don’t seem to have any interest in fixing it.
To be honest the only reason I didn’t dismiss the DW3000 out of hand was because we already had a DW1000 product up and running. If I was starting from scratch I’d be looking very hard for an alternative part with any semblance of support.
I guess it is a regulatory problem. It is the same for Bluetooth ICs: For example the low level radio control software of nRF chips is an undocumented binary blob and the IC is only certified with the manufacturer blob. But at least they have a simple standardized way to communicate with it with HCI, and all high level commands are fully documented. If Qorvo would add a small CPU core to their chip (like licence free RISC-V), it could be much easier as well.
But looks like at least the new source code is cleaner. For example in the old code, there was a busy wait loop in waitforsysstatus, which caused Zephyr to freeze (I had to add delays). Looks like the new code uses timers and statemachines etc. instead. And maybe even the mutex and semaphore problem is fixed, so that I don’t have to maintain a Zephyr fork, we’ll see.
It’s not a regulatory radio issue, the radio isn’t sold as a certified device.
Bluetooth you purchase a module that has been certified to follow both the FCC/CE radio requirements and also certified to follow the Bluetooth protocol specification.
With the exception of the DWM1001C running PANS none of the DW1000/3000 parts are pre-certified modules. You need to perform your own FCC/CE approvals testing.
And for these UWB radios there is no fixed protocol, you can choose to follow the IEEE standard or the apple implementation, but that is up to you. And there is no certification process for these that I’m aware off.
My guess is that it’s more a IP protection move, the more you know about the internal registers the more you can guess the internal methods of operation. They have always been vague on some things like how the detection threshold is set.
Or maybe it’s just laziness, they simply can’t be bothered to fully document things.
Meanwhile I got a DWM3000EVB Evaluation Board Kit, and a nRF52840-DK. I downloaded the new software, and followed the instruction in the Quick Start Guide. I connected the shield to the DK and flashed the file nRF52840DK-QANI-FreeRTOS_full_QNI_3_0_0.hex. Then I installed the “Qorvo Nearby Interaction” iOS App. The switch on the shield is at 3V3_DCDC (couldn’t find instructions in the quick start guide to change it, so this was as delivered). After reset, the 4 LEDs blink 3 times. I can see in the iOS App the device (but sometimes it shows “unknown”). But when I click on connect, it immediately disconnects, see this video:
The problem was that the phone was in airplane mode. Bluetooth and WiFi works in airplane mode, but looks like UWB doesn’t work in this mode. An error message form the app would be nice in this case.
Meanwhile I’m nearly done with the integration of the library to Zephyr. Sometimes it needed a debugger, Ghidra disassembling, and a lot of reverse engineering work. E.g. I use WolfSSL to implement the AES functions. But somewhere inside the library there is a fira_crypto_test self test, which tests an error which results in a UWBMAC_EBADMSG error code (which is ultimately translated to EBADMSG). But WolfSSL reports this test as AES_CCM_AUTH_E. With source code would be done in a few minutes. Without needs a day playing with gdb and analyzing the disassembled code. Thanks Qorvo.