This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

No trigger interface found when performing serial DFU with FTDI USB->UART converter

Hello,

I have successfully integrated the UART secure_bootloader from SDK 17 with my project. In the field, firmware updates will have to be performed using the FT2232H. I have no choice in this. I started out just testing the example on the nRF52840 DK, using the onboard JLink as the USB->Uart converter. That worked. Now I am using a bus pirate with an FT232 to perform DFU on a particle boron. I got that working as well, with one hitch.

The device will successfully update, but it takes about 10 seconds to do so and I see the following output:

nrfutil dfu serial -pkg _build/app_dfu_package.zip -p /dev/ttyUSB0 -fc 0
  [------------------------------------]    0%2021-09-15 12:25:09,369 No trigger interface found for device with serial number: AB0KOIJS, Product ID: 0x6001 and Vendor ID: 0x403

  [####################################]  100%
Device programmed.

I have looked in dfu_trigger.py in the pc-nrfutil Github repository and seen that this is a "no_trigger_exception". Specifically, it is being raised because the expression "if dfu_iface is None" is evaluating to True. In my log file I can see that nrfutil is spending 5 seconds waiting for my device to be in bootloader mode even though it is already in bootloader mode. Then it eventually works anyways.

What can I do to make nrfutil work with my FTDI device and would this speed up DFU? I am happy it's working in spite of this but I would like it to be faster so that I can set the DFU timeout lower. Can I add the VID/PID of my FTDI device so that it will be properly recognized? Thank you.

Parents
  • nrfutil -v -v -v -o log.log dfu serial -pkg _build/app_dfu_package.zip -p /dev/ttyUSB0 -fc 0
    2021-09-15 14:22:52,786 Using board at serial port: /dev/ttyUSB0
    2021-09-15 14:22:52,787 Sending Application image.
    2021-09-15 14:22:56,382 No trigger interface found for device with serial number: AB0KOIJS, Product ID: 0x6001 and Vendor ID: 0x403
    
    2021-09-15 14:22:56,382 Serial: Waiting 500 ms for device to enter bootloader 1/10 time
    2021-09-15 14:22:56,904 Serial: Waiting 500 ms for device to enter bootloader 2/10 time
    2021-09-15 14:22:57,415 Serial: Waiting 500 ms for device to enter bootloader 3/10 time
    2021-09-15 14:22:57,926 Serial: Waiting 500 ms for device to enter bootloader 4/10 time
    2021-09-15 14:22:58,437 Serial: Waiting 500 ms for device to enter bootloader 5/10 time
    2021-09-15 14:22:58,957 Serial: Waiting 500 ms for device to enter bootloader 6/10 time
    2021-09-15 14:22:59,479 Serial: Waiting 500 ms for device to enter bootloader 7/10 time
    2021-09-15 14:23:00,000 Serial: Waiting 500 ms for device to enter bootloader 8/10 time
    2021-09-15 14:23:00,511 Serial: Waiting 500 ms for device to enter bootloader 9/10 time
    2021-09-15 14:23:01,021 Serial: Waiting 500 ms for device to enter bootloader 10/10 time
    2021-09-15 14:23:01,532 Serial: Device is either not in bootloader mode, or using an unsupported bootloader.
    2021-09-15 14:23:01,619 Serial: Set Packet Receipt Notification 0
    2021-09-15 14:23:01,651 Sending init packet...
    2021-09-15 14:23:01,651 Serial: Selecting Object: type:1
    2021-09-15 14:23:01,667 Serial: Object selected:  max_size:512 offset:0 crc:0
    2021-09-15 14:23:01,683 Serial: Streaming Data: len:139 offset:0 crc:0x00000000
    2021-09-15 14:23:01,922 Sending firmware file...
    2021-09-15 14:23:01,923 Serial: Selecting Object: type:2
    2021-09-15 14:23:01,938 Serial: Object selected:  max_size:4096 offset:0 crc:0
    2021-09-15 14:23:02,034 Serial: Streaming Data: len:3896 offset:0 crc:0x00000000
    2021-09-15 14:23:02,434 Image sent in 0.783496618270874s
    Device programmed.
    

    ^^^ this is the log file

  • Hi,

    The trigger interface is only for USB DFU. You write that you use a FTDI, so in this case you are using UART DFU, and not a USB DFU bootloader, right? There is no trigger interface for that. You need to either enter DFU mode via button press or something else, or some other application specific method.

  • Yes, I am using UART DFU. The device is already in DFU mode when I issue the command from nrfutil. So why does nrfutil have this behavior when the device is already in DFU mode?

    Edit: Since I have posted this I have learned about the DFU trigger library provided in the SDK. Please correct me if I am wrong, but it looks like this library is only for USB and not for UART?

    I have written my application code such that when it receives the byte "0xAA" from its UART port, it will do this:

    NRF_POWER->GPREGRET = BOOTLOADER_DFU_GPREGRET_MASK | BOOTLOADER_DFU_START_BIT_MASK; 
    NVIC_SystemReset();
    This will successfully cause the device to boot into the bootloader on reset rather than the application code. However, it appears that rather than recognizing that the device is already in bootloader mode and flashing it, nrfutil is trying to put the device in bootloader mode, which is wasting time.

    Any advice on how to fix this would be much appreciated

Reply
  • Yes, I am using UART DFU. The device is already in DFU mode when I issue the command from nrfutil. So why does nrfutil have this behavior when the device is already in DFU mode?

    Edit: Since I have posted this I have learned about the DFU trigger library provided in the SDK. Please correct me if I am wrong, but it looks like this library is only for USB and not for UART?

    I have written my application code such that when it receives the byte "0xAA" from its UART port, it will do this:

    NRF_POWER->GPREGRET = BOOTLOADER_DFU_GPREGRET_MASK | BOOTLOADER_DFU_START_BIT_MASK; 
    NVIC_SystemReset();
    This will successfully cause the device to boot into the bootloader on reset rather than the application code. However, it appears that rather than recognizing that the device is already in bootloader mode and flashing it, nrfutil is trying to put the device in bootloader mode, which is wasting time.

    Any advice on how to fix this would be much appreciated

Children
  • Hi,

    cwmoreiras said:
    Edit: Since I have posted this I have learned about the DFU trigger library provided in the SDK. Please correct me if I am wrong, but it looks like this library is only for USB and not for UART?

    That is correct. It is not used for UART DFU.

    cwmoreiras said:
    nrfutil is trying to put the device in bootloader mode, which is wasting time.

    That is odd as this is not possible for UART DFU. I did not come across this before, but it seems the nrfutil serial DFU implementation make some assumptions it should not. It does not differentiate between UART and USB with regard to triggering the bootloader mode if it seems the device is not in bootloader mode, and the decision is made in a too simple way. You can see it checks if the device is in bootloader mode or not on line 320 in dfu_transport_serial.py, and based on that it either continues with DFU or tries to trigger DFU mode. The function __is_device_in_bootloader_mode() is too simple, and I suggest you modify it to work around this problem. For instance, remove the whole mechanism by making it always return True. I will make a internal bug report about this.

    cwmoreiras said:
    Any advice on how to fix this would be much appreciated

    As you write that the device is in DFU mode this should work with the changes above. If not, have you verified that the UART communication is working? That should be the first step now.  Have you configured the bootloader to use the correct pins for UART, flow control disabled also on the bootloader as you disable it in your nrfutil call, the correct baud rate etc? And can you check the UART lines with a logic analyzer to see the communication?

    (Also, it is generally a good idea to use flow control if possible, but that should not be relevant at this point)

  • Commenting out the body of function __is_device_in_bootloader_mode() and having it return True worked like a charm. Thank you for your help!

Related