Gazell Host Callback function not being call back when USB turn into suspend

I try to use Gazell and USB HID to remote wake up my computer. But after compter turns into sleep, the callback function on the Gazell Host Device doesn't being called back anymore. The callback function will start work again after I wake my computer up.

I don't know whether it is the problem of the Gazell Timer. The gazell will use Timer0 of the nrf52840.

/*****************************************************************************/
/** @name Gazell callback function definitions.  */
/*****************************************************************************/
/**
 * @brief RX data ready callback.
 *
 * @details
 */
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);

     if (!result_value)
    {
         NRF_LOG_ERROR("RX fifo error ");
     }

     if (data_payload_length > 0)
    {
         output_present(m_data_payload);
     }

    // Read buttons and load ACK payload into TX queue.
     m_ack_payload[0] = custom_LED_state_get(&m_app_hid_kbd); // Button logic is inverted.

     result_value = nrf_gzll_add_packet_to_tx_fifo(pipe, m_ack_payload, TX_PAYLOAD_LENGTH);
     if (!result_value)
    {
         NRF_LOG_ERROR("TX fifo error ");
     }

     LED_On(LED1);
}

/**
 * @brief Gazelle callback.
 * @warning Required for successful Gazell initialization.
 */
void nrf_gzll_device_tx_success(uint32_t pipe, nrf_gzll_device_tx_info_t tx_info)
{
}

/**
 * @brief Gazelle callback.
 * @warning Required for successful Gazell initialization.
 */
void nrf_gzll_device_tx_failed(uint32_t pipe, nrf_gzll_device_tx_info_t tx_info)
{
}

/**
 * @brief Gazelle callback.
 * @warning Required for successful Gazell initialization.
 */
void nrf_gzll_disabled()
{
}

void usb_init()
{
    ret_code_t ret;
    static const app_usbd_config_t usbd_config = {
        .ev_state_proc = usbd_user_ev_handler,
    };

    ret = nrf_drv_clock_init();
    APP_ERROR_CHECK(ret);

    // nrf_drv_clock_lfclk_request(NULL);
    // while (!nrf_drv_clock_lfclk_is_running())
    //{
    //     /* Just waiting */
    // }

    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_kbd_class_inst_get(&m_app_hid_kbd);
    ret = app_usbd_class_append(class_inst_kbd);

    APP_ERROR_CHECK(ret);

    // NRF_LOG_INFO("USBD HID composite example started.");

    if (USBD_POWER_DETECTION)
    {
        ret = app_usbd_power_events_enable();
        APP_ERROR_CHECK(ret);
    }
    else
    {
        // NRF_LOG_INFO("No USB power detection enabled\r\nStarting USB now");

        app_usbd_enable();
        app_usbd_start();
    }

    for (uint32_t i = 0; i < 200000; i++)
    {
        app_usbd_event_queue_process();
    }
}

/*****************************************************************************/
/**
 * @brief Main function.
 * @return ANSI required int return type.
 */
/*****************************************************************************/
int main()
{
    Pin_Cfg();

    // Set up the user interface.
    ui_init();

    // Initialize Gazell.
    bool result_value = nrf_gzll_init(NRF_GZLL_MODE_HOST);
    GAZELLE_ERROR_CODE_CHECK(result_value);
    // set Time Slot Period
    nrf_gzll_set_timeslot_period(900);

    result_value = nrf_gzll_set_base_address_1(0xbc010827);
    GAZELLE_ERROR_CODE_CHECK(result_value);
    result_value = nrf_gzll_set_address_prefix_byte(PIPE_NUMBER, 0x27);
    GAZELLE_ERROR_CODE_CHECK(result_value);

    // set frequency hopping
    nrf_gzll_set_channel_table(Channel_Table, Channel_Table_Size);
    nrf_gzll_set_timeslots_per_channel(3);
    nrf_gzll_set_timeslots_per_channel_when_device_out_of_sync(20);
    nrf_gzll_set_device_channel_selection_policy(NRF_GZLL_DEVICE_CHANNEL_SELECTION_POLICY_USE_CURRENT);
    nrf_gzll_set_sync_lifetime(45);

    // Load data into TX queue.
    m_ack_payload[0] = custom_LED_state_get(&m_app_hid_kbd);

    result_value = nrf_gzll_add_packet_to_tx_fifo(PIPE_NUMBER, m_data_payload, TX_PAYLOAD_LENGTH);
    if (!result_value)
    {
        // NRF_LOG_ERROR("TX fifo error ");
        NRF_LOG_FLUSH();
    }
    usb_init();

    // 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.");
    //nrfx_timer_enable(&TIMER_KBD);
    while (true)
    {        
        app_usbd_event_queue_process();
        //   NRF_LOG_FLUSH();
        if(nrf_gzll_is_enabled())
        {
          LED_On(LED0);
        }
        else
        {
        LED_Off(LED0);
        }
        LED_Off(LED1);
        __WFE();
        
    }
}

Parents
  • Hello,

    What is the implementation of usbd_user_ev_handler? Likely you are going to system off mode or similar on APP_USBD_EVT_DRV_SUSPEND event.

    Kenneth

  • Hi,

    Yes, the usbd_user_ev_handler will go APP_USBD_EVT_DRV_SUSPEND event. I just copy this part fo code from the SDK keyboard example. I have tried to remove the app_usbd_suspend_req(), but the gzll device still cannot communicate with the host.

    regards,

    Letian.

    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_SUSPEND:
            app_usbd_suspend_req(); // Allow the library to put the peripheral into sleep mode
            // bsp_board_leds_off();
            break;
        case APP_USBD_EVT_DRV_RESUME:
            // LED_On(BSP_LED_3);
            //  kbd_status(); /* Restore LED state - during SUSPEND all LEDS are turned off */
            break;
        case APP_USBD_EVT_STARTED:
            // LED_On(BSP_LED_3);
            break;
        case APP_USBD_EVT_STOPPED:
            app_usbd_disable();
            break;
        case APP_USBD_EVT_POWER_DETECTED:
            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();
            break;
        case APP_USBD_EVT_POWER_READY:
            NRF_LOG_INFO("USB ready");
            app_usbd_start();
            break;
        default:
            break;
        }
    }

Reply
  • Hi,

    Yes, the usbd_user_ev_handler will go APP_USBD_EVT_DRV_SUSPEND event. I just copy this part fo code from the SDK keyboard example. I have tried to remove the app_usbd_suspend_req(), but the gzll device still cannot communicate with the host.

    regards,

    Letian.

    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_SUSPEND:
            app_usbd_suspend_req(); // Allow the library to put the peripheral into sleep mode
            // bsp_board_leds_off();
            break;
        case APP_USBD_EVT_DRV_RESUME:
            // LED_On(BSP_LED_3);
            //  kbd_status(); /* Restore LED state - during SUSPEND all LEDS are turned off */
            break;
        case APP_USBD_EVT_STARTED:
            // LED_On(BSP_LED_3);
            break;
        case APP_USBD_EVT_STOPPED:
            app_usbd_disable();
            break;
        case APP_USBD_EVT_POWER_DETECTED:
            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();
            break;
        case APP_USBD_EVT_POWER_READY:
            NRF_LOG_INFO("USB ready");
            app_usbd_start();
            break;
        default:
            break;
        }
    }

Children
No Data
Related