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

How to add buttonless_dfu and serial_dfu functions at the same time.

Now the code in the application part has added the buttonless_dfu function, which has also been successfully implemented. But I ’m not familiar with serial_dfu, I don’t know how to continue to add serial_dfu function. And how to achieve coexistence of ble_dfu and serial_dfu in bootload code?

Parents
  • Hi June, 

    You can have a look at this case: https://devzone.nordicsemi.com/f/nordic-q-a/35431/dfu-over-ble-and-usb

    I have an example for SDK v15.2 there. To find how to enter DFU bootloader mode from application, please study the ble_app_buttonless_dfu example. Check function enter_bootloader() and then ble_dfu_buttonless_bootloader_start_prepare(). The GPREGRET register is written before the application reset and enter bootloader. 

  • Hi Hung Bui,

    I have added the serial_dfu code with reference to this routine, and now I have a few questions:

    1、Does uart need flow control during serial dfu? I am currently turning off serial port flow control because my hardware does not have two pins for flow control

    2、In normal application operation, in addition to the buttonless method, I can also enter the upgrade mode by pressing the button. After pressing the button, I performed the following operations:

    err_code = sd_power_gpregret_clr(0, 0xffffffff);
    VERIFY_SUCCESS(err_code);
    
    err_code = sd_power_gpregret_set(0, BOOTLOADER_DFU_START);
    VERIFY_SUCCESS(err_code);
    
    // Signal that DFU mode is to be enter to the power management module
    nrf_pwr_mgmt_shutdown(NRF_PWR_MGMT_SHUTDOWN_GOTO_DFU);

    Is this correct?

    3、After entering the upgrade mode, what nrfutil command is used to upgrade the zip package into the chip?

  • By the way, I need the code to run properly at 52840dk !!!

  • Hi June, 
    I found that it was because of this definition NRF_DFU_PROTOCOL_REDUCED 1 in sdk_config.h in SDK v15.3 causing the issue. 

    Please set it to 0 if it's 1 in your sdk_config.h , after that it should work. 

    I attached here the hex file for bootloader and the Keil project in SDK v15.3 that I used. 

    It's the same private key as I sent earlier. pca10056_ble_uart_debug.zip

  • Hi Hung,

    Unfortunately, the problem still exists.

    Although I have executed MSDDisable, DFU still fails. The following is the error message, same as before:

    Traceback (most recent call last):
      File "D:\Application\Python38\Scripts\nrfutil-script.py", line 11, in <module>
        load_entry_point('nrfutil==6.0.1', 'console_scripts', 'nrfutil')()
      File "D:\Application\Python38\lib\site-packages\click-7.1.1-py3.8.egg\click\core.py", line 829, in __call__
        return self.main(*args, **kwargs)
      File "D:\Application\Python38\lib\site-packages\click-7.1.1-py3.8.egg\click\core.py", line 782, in main
        rv = self.invoke(ctx)
      File "D:\Application\Python38\lib\site-packages\click-7.1.1-py3.8.egg\click\core.py", line 1259, in invoke
        return _process_result(sub_ctx.command.invoke(sub_ctx))
      File "D:\Application\Python38\lib\site-packages\click-7.1.1-py3.8.egg\click\core.py", line 1259, in invoke
        return _process_result(sub_ctx.command.invoke(sub_ctx))
      File "D:\Application\Python38\lib\site-packages\click-7.1.1-py3.8.egg\click\core.py", line 1066, in invoke
        return ctx.invoke(self.callback, **ctx.params)
      File "D:\Application\Python38\lib\site-packages\click-7.1.1-py3.8.egg\click\core.py", line 610, in invoke
        return callback(*args, **kwargs)
      File "D:\Application\Python38\lib\site-packages\nrfutil-6.0.1-py3.8.egg\nordicsemi\__main__.py", line 1055, in serial
        do_serial(package, port, connect_delay, flow_control, packet_receipt_notification, baud_rate, serial_number, True,
      File "D:\Application\Python38\lib\site-packages\nrfutil-6.0.1-py3.8.egg\nordicsemi\__main__.py", line 970, in do_serial
        dfu.dfu_send_images()
      File "D:\Application\Python38\lib\site-packages\nrfutil-6.0.1-py3.8.egg\nordicsemi\dfu\dfu.py", line 127, in dfu_send_images
        self._dfu_send_image(self.manifest.application)
      File "D:\Application\Python38\lib\site-packages\nrfutil-6.0.1-py3.8.egg\nordicsemi\dfu\dfu.py", line 100, in _dfu_send_image
        self.dfu_transport.send_firmware(data)
      File "D:\Application\Python38\lib\site-packages\nrfutil-6.0.1-py3.8.egg\nordicsemi\dfu\dfu_transport_serial.py", line 301, in send_firmware
        response['crc'] = self.__stream_data(data=data, crc=response['crc'], offset=i)
      File "D:\Application\Python38\lib\site-packages\nrfutil-6.0.1-py3.8.egg\nordicsemi\dfu\dfu_transport_serial.py", line 474, in __stream_data
        response = self.__calculate_checksum()
      File "D:\Application\Python38\lib\site-packages\nrfutil-6.0.1-py3.8.egg\nordicsemi\dfu\dfu_transport_serial.py", line 412, in __calculate_checksum
        raise NordicSemiException('Did not receive checksum response from DFU target. '
    pc_ble_driver_py.exceptions.NordicSemiException: Did not receive checksum response from DFU target. If MSD is enabled on the target device, try to disable it ref. https://wiki.segger.com/index.php?title=J-Link-OB_SAM3U

    But at the same time SDK15.2 is normal (SDK 15.2 and SDK 15.3 are configured with 115200 baud rate and HWFC is turned on). By the way, I used your 15.3 code project to compile without any changes (just replaced the key.c that matches my environment), the problem is still not solved.

  • Please capture the RTT log as well. 

    Which baudrate did you test ? Have you tested with or without HWFC ? Could you test with very small image ? 

  • Also please try testing with my bootloader.hex file inside the .zip. 

    When you test SDK v15.3 with the stock bootloader (not the combination) do you see the same issue with "Did not receive checksum response" ? 

Reply Children
  • When you test SDK v15.3 with the stock bootloader (not the combination), everything is normal.

    In addition, I cannot use bootload.hex to test directly, because the key in the project is different from the key in my environment.

    So I replaced the key in the project with a key that matches my environment and generated hex, and tested it with this hex.

  • Hi, Hung

    Now, when the HWFC is turned on, the DFU can be normal, but once the HWFC is turned off, the DFU will fail.

    Failure information is as follows:

    Traceback (most recent call last):
      File "D:\Application\Python38\Scripts\nrfutil-script.py", line 11, in <module>
        load_entry_point('nrfutil==6.0.1', 'console_scripts', 'nrfutil')()
      File "D:\Application\Python38\lib\site-packages\click-7.1.1-py3.8.egg\click\core.py", line 829, in __call__
        return self.main(*args, **kwargs)
      File "D:\Application\Python38\lib\site-packages\click-7.1.1-py3.8.egg\click\core.py", line 782, in main
        rv = self.invoke(ctx)
      File "D:\Application\Python38\lib\site-packages\click-7.1.1-py3.8.egg\click\core.py", line 1259, in invoke
        return _process_result(sub_ctx.command.invoke(sub_ctx))
      File "D:\Application\Python38\lib\site-packages\click-7.1.1-py3.8.egg\click\core.py", line 1259, in invoke
        return _process_result(sub_ctx.command.invoke(sub_ctx))
      File "D:\Application\Python38\lib\site-packages\click-7.1.1-py3.8.egg\click\core.py", line 1066, in invoke
        return ctx.invoke(self.callback, **ctx.params)
      File "D:\Application\Python38\lib\site-packages\click-7.1.1-py3.8.egg\click\core.py", line 610, in invoke
        return callback(*args, **kwargs)
      File "D:\Application\Python38\lib\site-packages\nrfutil-6.0.1-py3.8.egg\nordicsemi\__main__.py", line 1055, in serial
        do_serial(package, port, connect_delay, flow_control, packet_receipt_notification, baud_rate, serial_number, True,
      File "D:\Application\Python38\lib\site-packages\nrfutil-6.0.1-py3.8.egg\nordicsemi\__main__.py", line 970, in do_serial
        dfu.dfu_send_images()
      File "D:\Application\Python38\lib\site-packages\nrfutil-6.0.1-py3.8.egg\nordicsemi\dfu\dfu.py", line 127, in dfu_send_images
        self._dfu_send_image(self.manifest.application)
      File "D:\Application\Python38\lib\site-packages\nrfutil-6.0.1-py3.8.egg\nordicsemi\dfu\dfu.py", line 100, in _dfu_send_image
        self.dfu_transport.send_firmware(data)
      File "D:\Application\Python38\lib\site-packages\nrfutil-6.0.1-py3.8.egg\nordicsemi\dfu\dfu_transport_serial.py", line 301, in send_firmware
        response['crc'] = self.__stream_data(data=data, crc=response['crc'], offset=i)
      File "D:\Application\Python38\lib\site-packages\nrfutil-6.0.1-py3.8.egg\nordicsemi\dfu\dfu_transport_serial.py", line 474, in __stream_data
        response = self.__calculate_checksum()
      File "D:\Application\Python38\lib\site-packages\nrfutil-6.0.1-py3.8.egg\nordicsemi\dfu\dfu_transport_serial.py", line 412, in __calculate_checksum
        raise NordicSemiException('Did not receive checksum response from DFU target. '
    pc_ble_driver_py.exceptions.NordicSemiException: Did not receive checksum response from DFU target. If MSD is enabled on the target device, try to disable it ref. https://wiki.segger.com/index.php?title=J-Link-OB_SAM3U

    The LOG during the DFU upgrade process is as follows:

    <info> nrf_dfu_serial_uart: Allocated buffer 2000B08C
    <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_PING
    <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    <debug> : Sending Response: [0x9, 0x1]
    <debug> : 
    <info> nrf_dfu_serial_uart: Allocated buffer 2000B08C
    <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_RECEIPT_NOTIF_SET
    <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    <debug> : Sending Response: [0x2, 0x1]
    <debug> : 
    <info> nrf_dfu_serial_uart: Allocated buffer 2000B08C
    <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_MTU_GET
    <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    <debug> : Sending Response: [0x7, 0x1]
    <info> nrf_dfu_serial_uart: Allocated buffer 2000B08C
    <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_SELECT (command)
    <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    <debug> : Sending Response: [0x6, 0x1]
    <debug> app: Shutting down transports (found: 2)
    <debug> nrf_dfu_ble: Shutting down BLE transport.
    <info> nrf_dfu_serial_uart: Allocated buffer 2000B08C
    <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_CREATE (command)
    <debug> app: timer_stop (0x200057D4)
    <debug> app: timer_activate (0x200057D4)
    <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    <debug> : Sending Response: [0x1, 0x1]
    <info> nrf_dfu_serial_uart: Allocated buffer 2000B110
    <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_WRITE (command)
    <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    <info> nrf_dfu_serial_uart: Allocated buffer 2000B08C
    <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_WRITE (command)
    <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    <info> nrf_dfu_serial_uart: Allocated buffer 2000B110
    <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_WRITE (command)
    <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    <info> nrf_dfu_serial_uart: Allocated buffer 2000B110
    <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_CRC_GET (command)
    <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    <debug> : Sending Response: [0x3, 0x1]
    <info> nrf_dfu_serial_uart: Allocated buffer 2000B110
    <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_EXECUTE (command)
    <debug> nrf_dfu_validation: PB: Init packet data len: 64
    <info> nrf_dfu_validation: Signature required. Checking signature.
    <info> nrf_dfu_validation: Calculating hash (len: 64)
    <info> nrf_dfu_validation: Verify signature
    <info> nrf_dfu_validation: Image verified
    <debug> app: Enter nrf_dfu_cache_prepare()
    <debug> app: required_size: 0x5788.
    <debug> app: single_bank: false.
    <debug> app: keep_app: false.
    <debug> app: keep_softdevice: true.
    <debug> app: SD_PRESENT: true.
    <debug> app: Bank contents:
    <debug> app: Bank 0 code: 0x00: Size: 0x0
    <debug> app: Bank 1 code: 0x00: Size: 0x0
    <debug> app: pass: 0.
    <debug> app: cache_address: 0x26000.
    <debug> app: cache_too_small: false.
    <debug> app: keep_firmware: false.
    <debug> app: delete_more: false.
    <debug> nrf_dfu_validation: Write address set to 0x00026000
    <debug> nrf_dfu_settings: Writing settings...
    <debug> nrf_dfu_settings: Erasing old settings at: 0x000FF000
    <debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x000FF000, len=1 pages), queue usage: 1
    <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x000FF000, src=0x2000A1F0, len=896 bytes), queue usage: 2
    <info> nrf_dfu_settings: Backing up settings page to address 0xFE000.
    <debug> nrf_dfu_settings: Writing settings...
    <debug> nrf_dfu_settings: Erasing old settings at: 0x000FE000
    <debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x000FE000, len=1 pages), queue usage: 3
    <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x000FE000, src=0x2000A570, len=896 bytes), queue usage: 4
    <debug> nrf_dfu_req_handler: Writing valid init command to flash.
    <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    <debug> : Sending Response: [0x4, 0x1]
    <debug> nrf_dfu_flash: Flash erase success: addr=0x000FF000, pending 4
    <info> nrf_dfu_serial_uart: Allocated buffer 2000B110
    <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_SELECT (data)
    <debug> nrf_dfu_req_handler: crc = 0x0, offset = 0x0, max_size = 0x1000
    <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    <debug> : Sending Response: [0x6, 0x1]
    <debug> nrf_dfu_flash: Flash write success: addr=0x000FF000, pending 3
    <info> nrf_dfu_serial_uart: Allocated buffer 2000B110
    <debug> nrf_dfu_flash: Flash erase success: addr=0x000FE000, pending 2
    <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_CREATE (data)
    <debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x00026000, len=1 pages), queue usage: 2
    <debug> nrf_dfu_req_handler: Creating object with size: 4096. Offset: 0x00000000, CRC: 0x00000000
    <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    <debug> ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ1]
    <debug> nrf_dfu_flash: Flash write success: addr=0x000FE000, pending 2
    <error> app: Received an error: 0x00000001!

  • Now I can be sure that this must not be a hardware problem, nor a problem with the nrfutil tool. I also made sure that I implemented MSDDisable. And when the HWFC is closed, the baud rate is reduced to 9600, and the DFU will fail. Then turn on HWFC, DFU can succeed again.

  • Do you have a solution to this problem? I've been knocked out by this problem...

  • Hi June, 
    I'm not sure what could be wrong here as the test here worked fine. 

    I have modified the nrf_dfu_serial_uart.c a little bit but I don't think it would help much. Please try using the file I provided here. 

    I can see in the log there is a printing of a long "ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ" could you check why ? Did you modify anything creating that ? 

    THere is an error "0x00001" that we need to investigate. 

    Please add DEBUG into the preprocessor definition in the project setting so that we can have more logging information. If there is a complain about app_error_save_and_stop() you can just change it to "while(1);"

    /**
     * Copyright (c) 2016 - 2019, Nordic Semiconductor ASA
     *
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without modification,
     * are permitted provided that the following conditions are met:
     *
     * 1. Redistributions of source code must retain the above copyright notice, this
     *    list of conditions and the following disclaimer.
     *
     * 2. Redistributions in binary form, except as embedded into a Nordic
     *    Semiconductor ASA integrated circuit in a product or a software update for
     *    such product, must reproduce the above copyright notice, this list of
     *    conditions and the following disclaimer in the documentation and/or other
     *    materials provided with the distribution.
     *
     * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
     *    contributors may be used to endorse or promote products derived from this
     *    software without specific prior written permission.
     *
     * 4. This software, with or without modification, must only be used with a
     *    Nordic Semiconductor ASA integrated circuit.
     *
     * 5. Any software provided in binary form under this license must not be reverse
     *    engineered, decompiled, modified and/or disassembled.
     *
     * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
     * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
     * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
     * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
     * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
     * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     *
     */
    
    #include "nrf_dfu_serial.h"
    
    #include <string.h>
    #include "boards.h"
    #include "app_util_platform.h"
    #include "nrf_dfu_transport.h"
    #include "nrf_dfu_req_handler.h"
    #include "slip.h"
    #include "nrf_balloc.h"
    #include "nrf_drv_uart.h"
    
    #define NRF_LOG_MODULE_NAME nrf_dfu_serial_uart
    #include "nrf_log.h"
    NRF_LOG_MODULE_REGISTER();
    
    /**@file
     *
     * @defgroup nrf_dfu_serial_uart DFU Serial UART transport
     * @ingroup  nrf_dfu
     * @brief    Device Firmware Update (DFU) transport layer using UART.
     */
     
    #define NRF_SERIAL_OPCODE_SIZE          (sizeof(uint8_t))
    #define NRF_UART_MAX_RESPONSE_SIZE_SLIP (2 * NRF_SERIAL_MAX_RESPONSE_SIZE + 1)
    #define RX_BUF_SIZE                     (64) //to get 64bytes payload
    #define OPCODE_OFFSET                   (sizeof(uint32_t) - NRF_SERIAL_OPCODE_SIZE)
    #define DATA_OFFSET                     (OPCODE_OFFSET + NRF_SERIAL_OPCODE_SIZE)
    #define UART_SLIP_MTU                   (2 * (RX_BUF_SIZE + 1) + 1)
    #define BALLOC_BUF_SIZE                 ((CEIL_DIV((RX_BUF_SIZE+OPCODE_SIZE),sizeof(uint32_t))*sizeof(uint32_t)))
    
    NRF_BALLOC_DEF(m_payload_pool, (UART_SLIP_MTU + 1), NRF_DFU_SERIAL_UART_RX_BUFFERS);
    
    static nrf_drv_uart_t m_uart =  NRF_DRV_UART_INSTANCE(0);
    static uint8_t m_rx_byte;
    
    static nrf_dfu_serial_t m_serial;
    static slip_t m_slip;
    static uint8_t m_rsp_buf[NRF_UART_MAX_RESPONSE_SIZE_SLIP];
    static bool m_active;
    
    static nrf_dfu_observer_t m_observer;
    
    static uint32_t uart_dfu_transport_init(nrf_dfu_observer_t observer);
    static uint32_t uart_dfu_transport_close(nrf_dfu_transport_t const * p_exception);
    
    DFU_TRANSPORT_REGISTER(nrf_dfu_transport_t const uart_dfu_transport) =
    {
        .init_func  = uart_dfu_transport_init,
        .close_func = uart_dfu_transport_close,
    };
    
    static void payload_free(void * p_buf)
    {
        uint8_t * p_buf_root = (uint8_t *)p_buf - DATA_OFFSET; //pointer is shifted to point to data
        nrf_balloc_free(&m_payload_pool, p_buf_root);
    }
    
    static ret_code_t rsp_send(uint8_t const * p_data, uint32_t length)
    {
        uint32_t slip_len;
        (void) slip_encode(m_rsp_buf, (uint8_t *)p_data, length, &slip_len);
    
        return nrf_drv_uart_tx(&m_uart, m_rsp_buf, slip_len);
    }
    static uint8_t close_transport_flag=1;
    static __INLINE void on_rx_complete(nrf_dfu_serial_t * p_transport, uint8_t * p_data, uint8_t len)
    {
        ret_code_t ret_code;
    
        ret_code = slip_decode_add_byte(&m_slip, p_data[0]);
        (void) nrf_drv_uart_rx(&m_uart, &m_rx_byte, 1);
    
        if (ret_code == NRF_SUCCESS)
        {
                if (close_transport_flag)
            {
                UNUSED_RETURN_VALUE(nrf_dfu_transports_close(&uart_dfu_transport));
                close_transport_flag=0;
            }
            nrf_dfu_serial_on_packet_received(p_transport,
                                             (uint8_t const *)m_slip.p_buffer,
                                             m_slip.current_index);
    
            uint8_t * p_rx_buf = nrf_balloc_alloc(&m_payload_pool);
            if (p_rx_buf == NULL)
            {
                NRF_LOG_ERROR("Failed to allocate buffer");
                return;
            }
            NRF_LOG_INFO("Allocated buffer %x", p_rx_buf);
            // reset the slip decoding
            m_slip.p_buffer      = &p_rx_buf[OPCODE_OFFSET];
            m_slip.current_index = 0;
            m_slip.state         = SLIP_STATE_DECODING;
        }
    
    }
    
    static void uart_event_handler(nrf_drv_uart_event_t * p_event, void * p_context)
    {
        switch (p_event->type)
        {
            case NRF_DRV_UART_EVT_RX_DONE:
                on_rx_complete((nrf_dfu_serial_t*)p_context,
                               p_event->data.rxtx.p_data,
                               p_event->data.rxtx.bytes);
                break;
    
            case NRF_DRV_UART_EVT_ERROR:
                APP_ERROR_HANDLER(p_event->data.error.error_mask);
                break;
    
            default:
                // No action.
                break;
        }
    }
    
    static uint32_t uart_dfu_transport_init(nrf_dfu_observer_t observer)
    {
        uint32_t err_code = NRF_SUCCESS;
    
        if (m_active)
        {
            return err_code;
        }
    
        NRF_LOG_DEBUG("serial_dfu_transport_init()");
    
        m_observer = observer;
    
        err_code = nrf_balloc_init(&m_payload_pool);
        if (err_code != NRF_SUCCESS)
        {
            return err_code;
        }
    
        uint8_t * p_rx_buf = nrf_balloc_alloc(&m_payload_pool);
    
        m_slip.p_buffer      =  &p_rx_buf[OPCODE_OFFSET];
        m_slip.current_index = 0;
        m_slip.buffer_len    = UART_SLIP_MTU;
        m_slip.state         = SLIP_STATE_DECODING;
    
        m_serial.rsp_func           = rsp_send;
        m_serial.payload_free_func  = payload_free;
        m_serial.mtu                = UART_SLIP_MTU;
        m_serial.p_rsp_buf          = &m_rsp_buf[NRF_UART_MAX_RESPONSE_SIZE_SLIP -
                                                NRF_SERIAL_MAX_RESPONSE_SIZE];
        m_serial.p_low_level_transport = &uart_dfu_transport;
    
        nrf_drv_uart_config_t uart_config = NRF_DRV_UART_DEFAULT_CONFIG;
    
        uart_config.pseltxd   = TX_PIN_NUMBER;
        uart_config.pselrxd   = RX_PIN_NUMBER;
        uart_config.pselcts   = CTS_PIN_NUMBER;
        uart_config.pselrts   = RTS_PIN_NUMBER;
        uart_config.hwfc      = NRF_DFU_SERIAL_UART_USES_HWFC ?
                                    NRF_UART_HWFC_ENABLED : NRF_UART_HWFC_DISABLED;
        uart_config.p_context = &m_serial;
    
        err_code =  nrf_drv_uart_init(&m_uart, &uart_config, uart_event_handler);
        if (err_code != NRF_SUCCESS)
        {
            NRF_LOG_ERROR("Failed initializing uart");
            return err_code;
        }
    
        err_code = nrf_drv_uart_rx(&m_uart, &m_rx_byte, 1);
        if (err_code != NRF_SUCCESS)
        {
            NRF_LOG_ERROR("Failed initializing rx");
        }
    
        NRF_LOG_DEBUG("serial_dfu_transport_init() completed");
    
        m_active = true;
    
        if (m_observer)
        {
            m_observer(NRF_DFU_EVT_TRANSPORT_ACTIVATED);
        }
    
        return err_code;
    }
    
    
    static uint32_t uart_dfu_transport_close(nrf_dfu_transport_t const * p_exception)
    {
        if ((m_active == true) && (p_exception != &uart_dfu_transport))
        {
            nrf_drv_uart_uninit(&m_uart);
            m_active = false;
        }
    
        return NRF_SUCCESS;
    }
    
    

Related