This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

How to upgrade my nrf52810 over I2C (or UART) by using a nrf52832 as a bridge

Hello,

In our product we have the following hardware configuration that implies two MCUs :

- a nrF52832 with BLE capability and running as an I2C master

- a nrf52810 runing as an I2C slave (without any BLE connection possibility)

I can upgrade the nrf52832 without any issue by using DFU and nRF Toolbox app but my question was about upgrading the nRF52810. In that case, the nRF52832 will acte as a bridge and it will transfer data over I2C (or UART if i reconfigure the pin, i didn't decide yet) to the nRF52810 DFU.

I know i will need to rewrite my own DFU for the nRF52810 but what i'm missing is the entry point. For the nRF52832, i can use nRF-Toolbox from my phone but which tool can i use for the nRF52810 ?

The BLE from my nRF52832 is the only interface to upgrade both CPU.

Is there someone that has already accomplished this ?

Best regards,

Aurélien

Parents
  • Hi,

    Nordic does not provide anything that will give you this out of the box, so you would have to write something yourself, probably utilizing parts of the existing DFU solution.

    One possible way of doing it could be like this:

    • nRF52810 runs a serial bootloader form the SDK (we provide a UART transport layer which could be used, alternatively you would have to make a TWI transport)
    • The nRF52832 has a DFU master implementation. This is not something we provide for the nRF, so you would have to implement that yourself.
    • DFU master (phone) does a normal DFU upgrade via BLE of the nRF52832.
      • This firmware includes the firmware destined for the nRF52810. (If flash space on the 832 is a limiting factor, this could be a temporary firmware that has reduced functionality in order to hold the upgrade image of the 810 and DFU master implementation.)
    • The nRF52832 upgrades the nRF52810 via serial interface (UART or TWI) by acting as a DFU master.
    • (If a temporary firmware was used on the nRF52832, then it is updated again with the firmware it should normally have when not updating the 810).

    Update: You can find some unofficial serial DFU master implementations here.

    Einar

  • Hi Einar,


    Thank you very much for the answer and i'm sorry for the late reply.
    Indeed, what you propose is a kind of what i want excepted i wasn't thinking about storing the 810 binary onto the flash of the 832 but actually it is not a big deal. At first, i was thinking to just hook "upgrade" function on the 832 and then, directly transfer data on the serial port. Tell me if i'm wrong, but the upgrade protocole, whether is be uart or BLE, is the same, right ?
    I will take a look at the link you attached since i really need to find a solution to upgrade my 810 since we are deploying a batch of 200 devices for testing purpose in the coming month.

    Regards,

    Aurélien

  • Hi Aurélien,

    Aurele said:
    At first, i was thinking to just hook "upgrade" function on the 832 and then, directly transfer data on the serial port.

    Ah, I see. I did not think of that, but I suppose it should be possible to make that work.

    Aurele said:
    but the upgrade protocole, whether is be uart or BLE, is the same, right ?

    Yes, that is correct. The DFU protocol itself is the same regardless of which transport layer you use.

    Br,

    Einar

  • Hi Einar,

    I ll try this and let you know if i'm facing issues Slight smile

    Regards,

    Aurélie

  • Actually, firstly i tried to update my nrf52810 directly by using a FTDI from my labtop, just to validate this part. Then i will switch on nrf52832 to implement the full part, nrf52810 + nrf52832

    But on the nrf52810, i'm facing an issue : 

    <info> nrf_dfu_serial_uart: Allocated buffer 20000AF0
    <info> nrf_dfu_req_handler: Handle NRF_DFU_OP_RECEIPT_NOTIF_SET
    <info> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    <info> nrf_dfu_serial_uart: Allocated buffer 20000AF0
    <info> nrf_dfu_req_handler: Handle NRF_DFU_OP_MTU_GET
    <info> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    <error> nrf_dfu_serial: Failed to send data over serial interface!
    

    on the laptop i'm seeing this when i try to upgrade by using nrfutil : 

    > nrfutil dfu usb-serial -pkg consumer_aux_app_1_0_0.zip -p /dev/ttyUSB0 -b 9600
    2020-08-19 18:55:15,059 No trigger interface found for device with serial number: A50285BI, Product ID: 0x6001 and Vendor ID: 0x403
    
    
    Traceback (most recent call last):
      File "/usr/local/bin/nrfutil", line 33, in <module>
        sys.exit(load_entry_point('nrfutil==6.1.0', 'console_scripts', 'nrfutil')())
      File "/home/aurelien/.local/lib/python3.6/site-packages/click/core.py", line 764, in __call__
        return self.main(*args, **kwargs)
      File "/home/aurelien/.local/lib/python3.6/site-packages/click/core.py", line 717, in main
        rv = self.invoke(ctx)
      File "/home/aurelien/.local/lib/python3.6/site-packages/click/core.py", line 1137, in invoke
        return _process_result(sub_ctx.command.invoke(sub_ctx))
      File "/home/aurelien/.local/lib/python3.6/site-packages/click/core.py", line 1137, in invoke
        return _process_result(sub_ctx.command.invoke(sub_ctx))
      File "/home/aurelien/.local/lib/python3.6/site-packages/click/core.py", line 956, in invoke
        return ctx.invoke(self.callback, **ctx.params)
      File "/home/aurelien/.local/lib/python3.6/site-packages/click/core.py", line 555, in invoke
        return callback(*args, **kwargs)
      File "/home/aurelien/.local/lib/python3.6/site-packages/nordicsemi/__main__.py", line 1015, in usb_serial
        timeout)
      File "/home/aurelien/.local/lib/python3.6/site-packages/nordicsemi/__main__.py", line 970, in do_serial
        dfu.dfu_send_images()
      File "/home/aurelien/.local/lib/python3.6/site-packages/nordicsemi/dfu/dfu.py", line 127, in dfu_send_images
        self._dfu_send_image(self.manifest.application)
      File "/home/aurelien/.local/lib/python3.6/site-packages/nordicsemi/dfu/dfu.py", line 88, in _dfu_send_image
        self.dfu_transport.open()
      File "/home/aurelien/.local/lib/python3.6/site-packages/nordicsemi/dfu/dfu_transport_serial.py", line 217, in open
        self.__get_mtu()
      File "/home/aurelien/.local/lib/python3.6/site-packages/nordicsemi/dfu/dfu_transport_serial.py", line 366, in __get_mtu
        self.mtu = struct.unpack('<H', bytearray(response))[0]
    TypeError: 'NoneType' object is not iterable
    ^C
    

    i'm working at 9600 baud without flow control (at least deactivated on the nrf52810 for sure and i think it is deactivated on nrfutil too)

    Do you have any idea why the upgrade is failing ?

    Best regards,

    Aurélien

Reply
  • Actually, firstly i tried to update my nrf52810 directly by using a FTDI from my labtop, just to validate this part. Then i will switch on nrf52832 to implement the full part, nrf52810 + nrf52832

    But on the nrf52810, i'm facing an issue : 

    <info> nrf_dfu_serial_uart: Allocated buffer 20000AF0
    <info> nrf_dfu_req_handler: Handle NRF_DFU_OP_RECEIPT_NOTIF_SET
    <info> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    <info> nrf_dfu_serial_uart: Allocated buffer 20000AF0
    <info> nrf_dfu_req_handler: Handle NRF_DFU_OP_MTU_GET
    <info> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    <error> nrf_dfu_serial: Failed to send data over serial interface!
    

    on the laptop i'm seeing this when i try to upgrade by using nrfutil : 

    > nrfutil dfu usb-serial -pkg consumer_aux_app_1_0_0.zip -p /dev/ttyUSB0 -b 9600
    2020-08-19 18:55:15,059 No trigger interface found for device with serial number: A50285BI, Product ID: 0x6001 and Vendor ID: 0x403
    
    
    Traceback (most recent call last):
      File "/usr/local/bin/nrfutil", line 33, in <module>
        sys.exit(load_entry_point('nrfutil==6.1.0', 'console_scripts', 'nrfutil')())
      File "/home/aurelien/.local/lib/python3.6/site-packages/click/core.py", line 764, in __call__
        return self.main(*args, **kwargs)
      File "/home/aurelien/.local/lib/python3.6/site-packages/click/core.py", line 717, in main
        rv = self.invoke(ctx)
      File "/home/aurelien/.local/lib/python3.6/site-packages/click/core.py", line 1137, in invoke
        return _process_result(sub_ctx.command.invoke(sub_ctx))
      File "/home/aurelien/.local/lib/python3.6/site-packages/click/core.py", line 1137, in invoke
        return _process_result(sub_ctx.command.invoke(sub_ctx))
      File "/home/aurelien/.local/lib/python3.6/site-packages/click/core.py", line 956, in invoke
        return ctx.invoke(self.callback, **ctx.params)
      File "/home/aurelien/.local/lib/python3.6/site-packages/click/core.py", line 555, in invoke
        return callback(*args, **kwargs)
      File "/home/aurelien/.local/lib/python3.6/site-packages/nordicsemi/__main__.py", line 1015, in usb_serial
        timeout)
      File "/home/aurelien/.local/lib/python3.6/site-packages/nordicsemi/__main__.py", line 970, in do_serial
        dfu.dfu_send_images()
      File "/home/aurelien/.local/lib/python3.6/site-packages/nordicsemi/dfu/dfu.py", line 127, in dfu_send_images
        self._dfu_send_image(self.manifest.application)
      File "/home/aurelien/.local/lib/python3.6/site-packages/nordicsemi/dfu/dfu.py", line 88, in _dfu_send_image
        self.dfu_transport.open()
      File "/home/aurelien/.local/lib/python3.6/site-packages/nordicsemi/dfu/dfu_transport_serial.py", line 217, in open
        self.__get_mtu()
      File "/home/aurelien/.local/lib/python3.6/site-packages/nordicsemi/dfu/dfu_transport_serial.py", line 366, in __get_mtu
        self.mtu = struct.unpack('<H', bytearray(response))[0]
    TypeError: 'NoneType' object is not iterable
    ^C
    

    i'm working at 9600 baud without flow control (at least deactivated on the nrf52810 for sure and i think it is deactivated on nrfutil too)

    Do you have any idea why the upgrade is failing ?

    Best regards,

    Aurélien

Children
  • Finally, i just needed to add the fc option (-fc 0) to disable the flow control on laptop side and the upgrade is working now with an external serial port ! ;)

    Now, i come back on the nrf52832 side in order to finalysed the upgrade !

  • Sounds good! Thank you for sharing the good news Slight smile

  • Hi Einar

    I succeeded to start the transfer from my BLE device through the nrf52832 until the nrf52810 but i'm stuck with the first write function.

    Here is my logs : 

    <info> nrf_dfu_settings: Backing up settings page to address 0x7E000.
    <info> app: No firmware to activate.
    <info> app: Boot validation failed. No valid app to boot.
    <info> nrf_bootloader_wdt: WDT is not enabled
    <info> app: Entering DFU mode.
    <info> nrf_dfu_req_handler: ==> nrf_dfu_req_handler_req_process
    <info> nrf_dfu_req_handler: NRF_DFU_OBJ_TYPE_COMMAND
    <info> nrf_dfu_req_handler: NRF_DFU_OP_OBJECT_SELECT
    <info> app: TX_DONE
    <info> app: RX_DONE 60
    <info> app: RX_DONE 06
    <info> app: RX_DONE 01
    <info> app: RX_DONE 00
    <info> app: RX_DONE 02
    <info> app: RX_DONE 00
    <info> app: RX_DONE 00
    <info> app: RX_DONE 8D
    <info> app: RX_DONE 00
    <info> app: RX_DONE 00
    <info> app: RX_DONE 00
    <info> app: RX_DONE 82
    <info> app: RX_DONE 9A
    <info> app: RX_DONE 88
    <info> app: RX_DONE 18
    <info> app: RX_DONE C0
    <info> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    <info> nrf_dfu_req_handler: ==> nrf_dfu_req_handler_req_process
    <info> app: TX_DONE
    <info> app: RX_DONE 60
    <info> app: RX_DONE 02
    <info> app: RX_DONE 01
    <info> app: RX_DONE C0
    <info> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    <info> nrf_dfu_req_handler: ==> nrf_dfu_req_handler_req_process
    <info> nrf_dfu_req_handler: NRF_DFU_OBJ_TYPE_COMMAND
    <info> nrf_dfu_req_handler: NRF_DFU_OP_OBJECT_CREATE 8D
    <info> app: TX_DONE
    <info> app: RX_DONE 60
    <info> app: RX_DONE 01
    <info> app: RX_DONE 01
    <info> app: RX_DONE C0
    <info> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    <info> nrf_dfu_req_handler: ==> nrf_dfu_req_handler_req_process
    <info> nrf_dfu_req_handler: NRF_DFU_OBJ_TYPE_COMMAND
    <info> nrf_dfu_req_handler: NRF_DFU_OP_OBJECT_WRITE 141
    <info> app: Data : 79 536936188 62
    <info> app: TX_DONE
    <info> app: Data : 17 536936188 62
    <info> app: TX_DONE
    <info> app: Data : 0 536936188 62
    <info> app: TX_DONE
    <info> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    <info> nrf_dfu_req_handler: ==> nrf_dfu_req_handler_req_process
    <info> nrf_dfu_req_handler: NRF_DFU_OBJ_TYPE_COMMAND
    <info> nrf_dfu_req_handler: NRF_DFU_OP_CRC_GET
    <info> app: TX_DONE
    <info> app: RX_DONE 60
    <info> app: RX_DONE 03
    <info> app: RX_DONE 01
    <info> app: RX_DONE 8D
    <info> app: RX_DONE 00
    <info> app: RX_DONE 00
    <info> app: RX_DONE 00
    <info> app: RX_DONE 82
    <info> app: RX_DONE 9A
    <info> app: RX_DONE 88
    <info> app: RX_DONE 18
    <info> app: RX_DONE C0
    <info> nrf_dfu_req_handler: Request handling complete. Result: 0x1

    Indeed, there is a get from the phone that is transfered to nrf52810. In the response, the offset seems to be OK but the phone stops the transfer and says : DFU INVALID RESPONSE !

    The error code : 0x01 indicates a success

    The offset : 0x8D is exactly the size of the write.

    Here is the hook function in nrf_dfu_req_handler : 

            case NRF_DFU_OP_OBJECT_CREATE:
            {
                NRF_LOG_INFO("NRF_DFU_OP_OBJECT_CREATE %x",p_req->create.object_size);
    #ifndef MAIN_DFU
                on_cmd_obj_create_request(p_req, p_res);
    #else
                uart_send_object_create_packet(p_req->create.object_type,p_req->create.object_size,(uint8_t*)p_res);
    #endif
            } break;
    
            case NRF_DFU_OP_CRC_GET:
            {
                NRF_LOG_INFO("NRF_DFU_OP_CRC_GET");
    #ifndef MAIN_DFU
                on_cmd_obj_crc_request(p_req, p_res);
    #else
                uart_send_crc_get_packet((uint8_t*)p_res);
    #endif
            } break;
    
            case NRF_DFU_OP_OBJECT_WRITE:
            {
                NRF_LOG_INFO("NRF_DFU_OP_OBJECT_WRITE %d",p_req->write.len);
    #ifndef MAIN_DFU
                on_cmd_obj_write_request(p_req, p_res);
    #else
                uart_send_object_write_packet((uint8_t*)p_req->write.p_data,p_req->write.len,(uint8_t*)p_res);
    #endif
            } break;

    Do you have an idea of the issue ?
    Regards,

  • Hi,

    I do not see any indication of what actually went wrong. Can you upload a detailed log from the DFU master (Phone or nRFConnect for desktop)?

  • Hi

    Here is what i get from nrfconnect on my desktop : 

    It seems that the CRC is wrong.

    Why do i receive 141 bytes as size for the write ? It is not word align ? Moreover i was thinking about slip encode/decode but i don't it is slip

Related