NRF52840, gzll combine with USBD HID and USBD CLI, COM port no output

Good day,

I am trying to combine gzll, USBD HID and USBD CLI with SDK 17.1.0 and nrf 52840. GZLL receiving input, send to USBD HID, USBD CLI output logs and debugs.

Below is part of codes.

USBD_CLI_CDC_CAM.C

NRF_CLI_CDC_ACM_DEF(m_cli_cdc_acm_transport);
NRF_CLI_DEF(m_cli_cdc_acm,
            "usb_cli:~$ ",
            &m_cli_cdc_acm_transport.transport,
            '\r',
            CLI_EXAMPLE_LOG_QUEUE_SIZE);


NRF_CLI_RTT_DEF(m_cli_rtt_transport);
NRF_CLI_DEF(m_cli_rtt,
            "rtt_cli:~$ ",
            &m_cli_rtt_transport.transport,
            '\n',
            CLI_EXAMPLE_LOG_QUEUE_SIZE);

nrf_cli_t const * get_cli_cdc_acm_addr(void) {
    return &m_cli_cdc_acm;
}

nrf_cli_t const * get_cli_rtt_addr(void) {
    return &m_cli_rtt;
}

void dongle_usbd_cli_init(void)
{
    ret_code_t ret;

    if (USE_CYCCNT_TIMESTAMP_FOR_LOG)
    {
        CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
        DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
        DWT->CYCCNT = 0;
        APP_ERROR_CHECK(NRF_LOG_INIT(cyccnt_get, 64000000));
    }
    else
    {
        APP_ERROR_CHECK(NRF_LOG_INIT(app_timer_cnt_get));
    }


    nrf_drv_clock_lfclk_request(NULL);

    ret = app_timer_create(&m_timer_0, APP_TIMER_MODE_REPEATED, timer_handle);
    APP_ERROR_CHECK(ret);

    ret = app_timer_start(m_timer_0, APP_TIMER_TICKS(1000), NULL);
    APP_ERROR_CHECK(ret);

    ret = nrf_cli_init(&m_cli_rtt, NULL, true, true, NRF_LOG_SEVERITY_INFO);
    APP_ERROR_CHECK(ret);

    ret = fds_init();
    APP_ERROR_CHECK(ret);

    UNUSED_RETURN_VALUE(nrf_log_config_load());

    APP_ERROR_CHECK(nrf_cli_task_create(&m_cli_rtt));

    flashlog_init();

    stack_guard_init();

    NRF_LOG_RAW_INFO("Command Line Interface example started.\n");
    NRF_LOG_RAW_INFO("Please press the Tab key to see all available commands.\n");
}

USBD_HID_SERVICE.C

static void usbd_user_ev_handler(app_usbd_event_type_t event) {
    switch (event) {
        case APP_USBD_EVT_DRV_SOF:
            break;
        case APP_USBD_EVT_DRV_RESET:
            m_report_pending = false;
            break;
        case APP_USBD_EVT_DRV_SUSPEND:  // 3
            m_report_pending = false;
            app_usbd_suspend_req();  // Allow the library to put the peripheral into sleep mode
            break;
        case APP_USBD_EVT_DRV_RESUME:  // 4
            m_report_pending = false;
            kbd_status(); /* Restore LED state - during SUSPEND all LEDS are turned off */
            break;
        case APP_USBD_EVT_STARTED:  // 2
            m_report_pending = false;
            break;
        case APP_USBD_EVT_STOPPED:
            app_usbd_disable();
            break;
        case APP_USBD_EVT_POWER_DETECTED:  // 0
            NRF_LOG_INFO("USB power detected");
            if (!nrf_drv_usbd_is_enabled()) {
                app_usbd_enable();
            }
            break;
        case APP_USBD_EVT_POWER_REMOVED:
            NRF_LOG_INFO("USB power removed");
            app_usbd_stop();
            (void)nrf_cli_uninit(get_cli_cdc_acm_addr());
            break;
        case APP_USBD_EVT_POWER_READY: {    // 1
            ret_code_t ret;
            NRF_LOG_INFO("USB ready");
            app_usbd_start();
            nrf_cli_t const * m_cli_cdc_acm = get_cli_cdc_acm_addr();
            ret = nrf_cli_init(m_cli_cdc_acm, NULL, true, true, NRF_LOG_SEVERITY_INFO);
            APP_ERROR_CHECK(nrf_cli_task_create(m_cli_cdc_acm));
            APP_ERROR_CHECK(ret);

        }   break;
        default:
            break;
    }
}

void dongle_usb_keyboard_init(void) {
    ret_code_t                     ret;

    ret = nrf_drv_clock_init();
    APP_ERROR_CHECK(ret);

    static const app_usbd_config_t usbd_config = {
                .ev_handler = app_usbd_event_execute,
                .ev_state_proc = usbd_user_ev_handler};

    ret = app_usbd_init(&usbd_config);
    APP_ERROR_CHECK(ret);

    app_usbd_class_inst_t const *class_inst_kbd;
    class_inst_kbd = app_usbd_hid_generic_class_inst_get(&m_app_hid_kbd);
    ret            = app_usbd_class_append(class_inst_kbd);
    APP_ERROR_CHECK(ret);

    app_usbd_class_inst_t const * class_cli_cdc_acm;
    class_cli_cdc_acm = app_usbd_cdc_acm_class_inst_get(&nrf_cli_cdc_acm);
    ret = app_usbd_class_append(class_cli_cdc_acm);
    APP_ERROR_CHECK(ret);

    NRF_LOG_INFO("USBD HID composite example started.");
    ret = app_usbd_power_events_enable(); //make sure run it before all sub class all appended.
    APP_ERROR_CHECK(ret);
}

MAIN.C

static void power_management_init(void)
{
    ret_code_t err_code;
    err_code = nrf_pwr_mgmt_init();
    APP_ERROR_CHECK(err_code);
}

static void timers_init(void) {
    ret_code_t err_code;
    err_code = app_timer_init();
    APP_ERROR_CHECK(err_code);
}

static void idle_state_handle(void * p_context)
{
    UNUSED_PARAMETER(p_context);
    for (;;) {
        if (NRF_LOG_PROCESS() == false) {
            nrf_pwr_mgmt_run();
        }
        // nrf_drv_wdt_channel_feed(m_channel_id);
        task_yield();
    }
}

int main(void) {
    power_management_init();
    timers_init();
    base_services_init();
    dongle_usb_keyboard_init();
    dongle_usbd_cli_init();
    dongle_gzll_host_start();
    NRF_LOG_INFO("Dongle started");
    task_manager_start(idle_state_handle, (void *)NULL);
}

GZLL_HOST_SERVICE.C

void nrf_gzll_host_rx_data_ready(uint32_t pipe, nrf_gzll_host_rx_info_t rx_info)
{
    uint32_t data_payload_length = NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH;

    // Pop packet and write first byte of the payload to the GPIO port.
    bool result_value = nrf_gzll_fetch_packet_from_rx_fifo(pipe,
                                                           m_data_payload,
                                                           &data_payload_length);
    NRF_LOG_INFO("Received packet on pipe %d, length %d, RSSI %d", pipe, data_payload_length, rx_info.rssi);
    if (!result_value)
    {
        NRF_LOG_ERROR("RX fifo error ");
    }
    ret_code_t ret = NRF_SUCCESS;
    if (NRF_USBD->ENABLE) {
        ret = hid_kbd_process_state(m_data_payload, data_payload_length);
    }
    APP_ERROR_CHECK(ret);
}

void start_gzll_tx_statistics(void *p_context) {
    UNUSED_PARAMETER(p_context);
    while (true)
    {
        // NRF_LOG_FLUSH();
        // __WFE();
    }
}

void dongle_gzll_host_start(void)
{
    // Set up the user interface.
    ret_code_t ret;

    // Initialize Gazell.
    bool result_value = nrf_gzll_init(NRF_GZLL_MODE_HOST);
    GAZELLE_ERROR_CODE_CHECK(result_value);

    // Enable Gazell to start sending over the air.
    result_value = nrf_gzll_enable();
    GAZELLE_ERROR_CODE_CHECK(result_value);
    
    NRF_LOG_INFO("Gzll ack payload host example started.");
    static char const task_name[] = "gzll_tx_stats";
    task_create(start_gzll_tx_statistics, task_name, (void *)NULL);
}

If not start GZLL_HOST_SERVICE, USBD HID and USBD CLI both working good. But if start GZLL_HOST_SERVICE, COM port could be connected, but no any output and reactions, even RTT_CLI no output, at the same time, USBD HID and GZLL's sending and receiving are working good.

I tried uncomment " NRF_LOG_FLUSH();__WFE();" in "void start_gzll_tx_statistics(void *p_context)", COM port still no output, but RTT_CLI output"lost logger, increase queue size", or suddenly flushed.

Pls help me to analyse where is the problem? I am guessing maybe GZLL's task blocked others?

Related