Trigger library does not work

After a painful sequence here

https://devzone.nordicsemi.com/f/nordic-q-a/80283/how-to-use-the-trigger-library-to-program-the-nrf52840-dongle

I managed to merge the projects and insert all those c-files and h-files and tried to match all the correct items in the sdk_config.h file (perhaps the hardest part) into the project to support the single function added to my project nrf_dfu_trigger_usb_init().

It finally built with no undefined references and I was able to use nRF Connect to install SoftDevice and my trigger-usb loaded application onto the dongle. Though the application worked fine, nRF Connect gave the message

Nordic DFU Trigger Interface was not found. Please physically reset the device.

I have no idea how to test this and why it should fail. Since there is not much I have to do with respect to writing code (add one h-file and one init method), if you can get all the dependencies right so the project builds, what could go wrong? The only thing I can think of is the sdk_config.h file. There are all kinds of things in there mostly undocumented and I have no idea what they do.

Since my original project did not use USB in any way, I assumed the share option would be off. The example project \examples\connectivity\ble_connectivity\pca10059\ser_s140_usb_hci had it set to shared, but I do not know what it is sharing it with.

Has anyone ever gotten this to work with their BTLE-SoftDevice application?

In the connectivity sdk_config.h file the following items are enabled:

sdk_config.h(151) : #define BLE_DTM_ENABLED 1
sdk_config.h(209) : #define NRFX_CLOCK_ENABLED 1
sdk_config.h(294) : #define NRFX_POWER_ENABLED 1
sdk_config.h(334) : #define NRFX_PRS_ENABLED 1
sdk_config.h(368) : #define NRFX_PRS_BOX_4_ENABLED 1
sdk_config.h(428) : #define NRFX_SYSTICK_ENABLED 1
sdk_config.h(434) : #define NRFX_UARTE_ENABLED 1
sdk_config.h(560) : #define NRFX_UART_ENABLED 1
sdk_config.h(681) : #define NRFX_USBD_ENABLED 1
sdk_config.h(746) : #define NRF_CLOCK_ENABLED 1
sdk_config.h(789) : #define POWER_ENABLED 1
sdk_config.h(832) : #define SYSTICK_ENABLED 1
sdk_config.h(838) : #define UART_ENABLED 1
sdk_config.h(915) : #define UART0_ENABLED 1
sdk_config.h(938) : #define USBD_ENABLED 1
sdk_config.h(1001) : #define APP_SCHEDULER_ENABLED 1
sdk_config.h(1022) : #define APP_TIMER_ENABLED 1
sdk_config.h(1117) : #define APP_USBD_ENABLED 1
sdk_config.h(1388) : #define APP_USBD_NRF_DFU_TRIGGER_ENABLED 1
sdk_config.h(1395) : #define CRC16_ENABLED 1
sdk_config.h(1401) : #define NRF_BALLOC_ENABLED 1
sdk_config.h(1458) : #define NRF_MEMOBJ_ENABLED 1
sdk_config.h(1464) : #define NRF_QUEUE_ENABLED 1
sdk_config.h(1479) : #define NRF_SECTION_ITER_ENABLED 1
sdk_config.h(1486) : #define NRF_SORTLIST_ENABLED 1
sdk_config.h(1493) : #define NRF_STRERROR_ENABLED 1
sdk_config.h(1503) : #define APP_USBD_CDC_ACM_ENABLED 1
sdk_config.h(1526) : #define NRF_FPRINTF_ENABLED 1
sdk_config.h(1533) : #define NRF_FPRINTF_FLAG_AUTOMATIC_CR_ON_LF_ENABLED 1
sdk_config.h(4212) : #define NRF_SDH_BLE_LOG_ENABLED 1
sdk_config.h(4263) : #define NRF_SDH_LOG_ENABLED 1
sdk_config.h(4314) : #define NRF_SDH_SOC_LOG_ENABLED 1
sdk_config.h(4467) : #define PM_LOG_ENABLED 1
sdk_config.h(4584) : #define NRF_LOG_STR_FORMATTER_TIMESTAMP_FORMAT_ENABLED 1
sdk_config.h(4646) : #define NRF_SDH_BLE_ENABLED 1
sdk_config.h(5127) : #define NRF_SDH_ENABLED 1
sdk_config.h(5295) : #define NRF_SDH_SOC_ENABLED 1

Some I understand, most I do not. Which of these MUST be enabled in order for the trigger to work?

Parents Reply Children
  • One of the things it appears I need to do is to initialize and start usb. I just assumed the trigger library did that. in the example I have been referencing 

    project \examples\connectivity\ble_connectivity\pca10059\ser_s140_usb_hci 

    there is a softdevice wait ret_code_t ret_code = sd_app_evt_wait(); in main() and in  the fike nrf_sdh_ble.c a call to

    sd_ble_evt_get(evt_buffer, &evt_len);

    However, in my main() I handle events myself using the same call (BLE events for the most part). Can I have two sets of 

    sd_app_evt_wait();

    and

    sd_ble_evt_get()

    in the same code?

    From what I can read about it I think not. It sounds like they would conflict.

    Is there an easier way to initialize and handle USB when using the trigger? My app is pure Bluetooth; it does not use USB at all.

    This is my primary wait-loop where I poll for and dispatch events:

    static void main_loop(void)
    {
        uint8_t enabled;
        uint16_t len;
        ret_code_t result;
        for (;;)
        {
            send_data();            // when flag is set, a set of data is indicated or notified depending upon setup. 
                                    // Flag is reset in method
            main_wait();            // Contains the sd_app_evt_wait()
            if (!isEmpty(queue))
            {
                void *data = front(queue);
                if (encodeLiveData(data))
                {
                    NRF_LOG_INFO("Measurement taken from queue");
                    send_flag = true;
                    dequeue(queue);
                    bsp_board_led_off(RED_LED);
                }
            }
            if (restartAdv)
            {
                bsp_board_led_off(DISCONNECTED_LED);
                bsp_board_led_on(RED_LED);
                bsp_board_led_on(BLUE_LED);
                restartAdv = false;
                bring_up_adver();
            }
            while(true)
            {
                // uint32_t evt_id;
    
                // Don't continue on if disabled, for example when writing flash at the end
                sd_softdevice_is_enabled(&enabled);
                if (enabled != 1)
                {
                    NRF_LOG_DEBUG("Restarting application");
                    initializeBluetooth();
                 //   while(NRF_LOG_PROCESS());
                 //   NRF_POWER->RESETREAS = 0;
                 //   NVIC_SystemReset();
                 //   return;
                }
                result = sd_ble_evt_get(NULL, &len);    // Get size of event
                if (result == NRF_ERROR_NOT_FOUND)      // If there aren't any, go back to wait
                {
                    break;
                }
                evt_buf = (uint8_t *)calloc(1, len);                // Make space for event. evt_buf is 4-byte aligned
                result = sd_ble_evt_get((uint8_t *)evt_buf, &len);  // get the event
                if (result == NRF_SUCCESS)
                {
                    ble_evt_t *evt = (ble_evt_t *)evt_buf;
                    ble_evt_dispatch(evt);                          // dispatch event to handler. This handles only BTLE related events
                }
                else                                                // Hopefully no error but just in case log it.
                {                                                   // Should I do an NVIC_SystemReset() here?
                    NRF_LOG_DEBUG("PENDING BLE Event return error: %u", result);
                    free(evt_buf);  // Clean up
                    break;          // back to wait
                }
                free(evt_buf);      // clean up and get the next event
            }
        }
    }
    

  • Your assumption is correct, as long as the NRF_DFU_TRIGGER_USB_USB_SHARED option is disabled in sdk_config.h, the nrf_dfu_trigger_usb_init() will perform all the necessary initialization and starting of the USB stack. I tried that first, but the problem was that there were no standalone USB drivers available for the Trigger library, so Windows failed to recognize the device. This is why I opted to copy the configuration used by the connectivity FW and made a composite device with the CDC ACM class and the DFU trigger library. This allowed the me to re-use the existing driver we have for the connectivity dongle. If you want, I can try to integrate the same in your project.

    sd_app_evt_wait() is OK to call at multiples places, but  sd_ble_evt_get() should only be called from one place as events are cleared from the SD internal FIFO buffer as soon as they are read.

  • If you could do that it would be great. I set the interface to 0 and am trying to use BOARDS_WITH_USB_DFU_TRIGGER to get the trigger library to do all the usb work.

    I did not know there could be multiple calls to sd_app_evt_wait(). I got the impression (ages ago) that it could only be called in one location. Had I known that it could be called multiple places I would have let the SDK sdh library continue to call my event handler.

    All I wanted to do was to wait for an indication/notification to finish. After calling sd_ble_gatts_hvx() if the return was busy or tx queue full I needed to wait for the event or wait for the tx queue to empty and try again. So I jumped out of the send method and handled everything in the main_loop() where I had the wait call. Now it sounds like I could have just called the wait in the send method and retried there when it returned. Arrg. Would have made the code much simpler to follow!

    ble_app_ghs_keiser_bike.zip

    In your CDC example, is there a way to integrate my for(;;) loop with the one here. Is it possible to exit that loop once the USB has reached a certain state?

  • Here is your project with the DFU library:

     6431.ble_app_ghs_keiser_bike.zip

    Let me know if you have any questions/concerns to my changes. I took the liberty of removing the event polling from you main loop as you already had the nrf_sdh_ble.c module in your project. Doing this ensures that SDK libraries and drivers also receives SoC and BLE events from the Softdevice.

    I also updated the sdk_config.h header to fix some syntax errors (the CMSIS wizard couldn't parse it).

  • NOW I see that you didn't remove the entire wait loop, just the ble event poller

    So trying it out it half-worked. I get this error

    Error while probing usb device at bus.address 1.16: undefined. Please check that a libusb-compatible kernel driver is bound to this device, see https://github.com/NordicSemiconductor/pc-nrfconnect-launcher/blob/master/doc/win32-usb-troubleshoot.md

    I reinsert the dongle and this is what I get:

    10:21:30.829	Application data folder: C:\Users\brian\AppData\Roaming\nrfconnect\pc-nrfconnect-programmer
    10:21:30.926	Using nrfjprog library 10.12.1, pc-nrfjprog-js 1.7.6
    10:21:32.740	Error while probing usb device at bus.address 1.16: undefined. Please check that a libusb-compatible kernel driver is bound to this device, see https://github.com/NordicSemiconductor/pc-nrfconnect-launcher/blob/master/doc/win32-usb-troubleshoot.md
    10:24:52.174	Error while probing usb device at bus.address 1.17: undefined. Please check that a libusb-compatible kernel driver is bound to this device, see https://github.com/NordicSemiconductor/pc-nrfconnect-launcher/blob/master/doc/win32-usb-troubleshoot.md
    10:25:03.921	Using USB SDFU protocol to communicate with target
    10:25:08.927	Error when calling version command: Error: Error message: Timeout while reading from serial transport. See https://github.com/NordicSemiconductor/pc-nrfconnect-launcher/blob/master/doc/serial-timeout-troubleshoot.md
    10:25:08.928	Error when fetching device versions: TypeError: Cannot read property 'part' of undefined
    10:25:31.756	Using USB SDFU protocol to communicate with target
    10:25:36.760	Error when calling version command: Error: Error message: Timeout while reading from serial transport. See https://github.com/NordicSemiconductor/pc-nrfconnect-launcher/blob/master/doc/serial-timeout-troubleshoot.md
    10:25:36.761	Error when fetching device versions: TypeError: Cannot read property 'part' of undefined

    In that case I did not reload the LIBUSB. I am on Windows 10. Not sure what the issue is. It appears I have the right driver.

    On SES (the above was Keil) the install worked with no error BUT the application did not start. I am left with a blinking red LED. It should be a steady green LED showing it is advertising. That DOES happen in the Keil build.

    If I reinsert the dongle, the advertising starts. nRF COnnect sees the device, But selecting it causes the fleshing red LEDs and no memory map is shown. I need to reselect the device. Now a memory maps is shown but the device shown does not contain the CDC name any more. Just 'com port 4'. The memory map now shows and I can reinstall the program. It will get to the flashing red LED. If I reinstall again the dongle starts but the trigger interface dies. Now it is all messed up.

    Something is not quite right. NOt sure why it fails the way it does in KEIL except that it is a release mode whereas SES is debug mode. Huge difference in size!!!

    Why is the USB SHARED set? USB is used only by DFU, not by my application.

    Was able to test the dongle and the ble functionality is still good. However, its pretty clear what happens when trying to flash the dongle.

    1. Plug it in and the LED turns green - it is advertising
    2. The dongle is visible in the nRF Connect programmer as a com port and CDC DEMO 
    3. Click on the selection and the dongle fails to open but its still visible in the devices windw
    4. It now says only the COM port.
    5. Click on that and the address map is displayd.
    6. Now write the HEX files
    7. When done, there are somr RED LEDs being triggered, then green, and then flashing red.
    8. Re-insert the dongle and the LED turns green -  it is advertising and can be used.
    9. nFR Programmer mouse-over will show comport and USB CDC Demo as at the start.

    In Keil, the hex file does not work. After installation the Tigger library interface fails to install but the LED turns green. nFR Programmer can no longer find the device. Have been unable to get the Keil project to build a functioning HEX file. Don't know what's missing.

Related