• @Einzenheim

    to get started take a look at the API programming guide at https://www.decawave.com/dwm1001/api/

    As a first API call I would implement the 5.3.17 dwm_ver_get - This API function obtains the firmware version of the module. (about p. 61)

    Logically, it looks simple:

    • you write two (2) bytes 0x15 0x00 as (TLV) request
    • you read fifteen (15) bytes 0x40 0x01 0x00 0x50 ... as (TLV) response
    • you interpret the read bytes by splitting them up and creating a response object. You have to plan for an OK-object - a version object - when error comes back with 0x00, an NOT_OK-object - an error object - when error comes back with something else than 0x00. (Pseudo code below uses for latter also the version object - with integrated error info.)

    Physically, a bit more goes on then just straight reading the response (all reads and writes via SPI) - see 3.2.2 SPI Scheme: normal TLV communication and 3.2.3 SPI Example: normal TLV communication / Figure 4 SPI example: normal TLV communication (about pages 18 + 19).

    1. you write two (2) bytes 0x15 0x00 as request
    2. you read - deferred with a timeout of, for example, 10ms (>1ms) - two (2) bytes as communication control bytes about the response the device has ready for you to read:
      • byte 0: a packet_size byte (SIZE)
      • byte 1: a packet_count byte (NUM)
    3. you interpret - byte 0 - the packet_size byte (SIZE):
      • if it is ===0, then you go back to step 2.
      • if it is >0, then you continue with step 4.
    4. you read packet_count packages of packet_size bytes each - deferred as well - into and compose a single response.
    5. you interpret the response string according the TLV description (by passing it to a class constructor and getting a nice object back)

    PS: Above pseudo code is for single package responses - which all but 2 are.

    For the coding try not to do the "delay"-approach that is usually done in Arduino context. Use the event driven approach with setTimeout( function(...) {...}, 10);. In - still - pseudo code this looks about like:

    // some declaration and setup stuff about the SPI to communicate with
    function DwmVersion(response) { // define version object constructor
      this.error = ... // unpack the error from response[..] ...(Uint8Array)
      if (this.error) { // keep going
        // do something more about error interpretation, for example
        // this.errorMessage = ...
      } else { // ...happy path... set errorMessage to "" so you can...
        this.errorMessage = ""; // just check for ! errorMessage in callback
        // this.fwMajor = ... // firmware major version
        // this.fwMinor = ... // firmware minor version
        // ...for all what is in the response definition
    DwmVersion.prototype.toString() {
      return  ( "DMW1001C Version: "
      //     +  (this.error)
      //           ? "Error "+this.error+" - "+this.errorMessage
      //           :  ""+this.fwMajor+"."+this.fwMinor+...
    function readResponseChunk(callback,responseClazz­,response,size,count) {
      // var chunk = read(size bytes)
      // response.append(chunck);
      if (count > 1) {
                  ,callback,responseClazz,response,size,co­unt - 1);
      } else {
        var responseObject = new responseClazz(response);
    function readSizeAndCount(callback,responseClazz)­ {
      // var controlResponse = read(2 bytes) sizeCountBytes (2) ...(Uint8Array)
      // var size = ...something of controlResponse[..] (unsigned int)
      if (size === 0) {
      } else {
        // var count = ...something of controlResponse[..] (unsigned int)
        // var response = ... (Uint8Array)
    function getVer(callback) {
      // sendRequestBytes...
    function onInt() {
       // reset if implemented  and needeed
       getVer(function(versionObject) { console.log(versionObject); });
    setTimeout(onInit,999); // while deving; remove before upload for save()

    There is a more efficient way to communicate using a data ready pin driving an interrupt (watched by Espruino), but we keep that for a later point in time of implementation.

    Wiring all up could be worth another post... should though be obvious... (when using a Puck.js, you are safe when powering both devices from same 3..3.6V source (not a CR3025... it is too weak for driving the - 160mA - power hungry DMW1001C... Working with a Pico gets you faster round trips - since the upload goes wired in big chunks rather than 20 bytes at a time over BLE).

    Should you get into trouble, you may need to implement 5.3.16 dwm_reset - This API function reboots the module (about p. 60), and fire that API call first before dwm_ver_get .

    For convenience and preserve integrity of this post I attach the version 2.2 of the DWM1001 Firmware API Guide guide as current at this time (check back on regular base for updates of the API guide).

    3 Attachments


Avatar for allObjects @allObjects started