From 26f2e33227ce4ced95aae31ea3ddaa76e566590a Mon Sep 17 00:00:00 2001 From: Johann Fischer Date: Thu, 17 Dec 2020 18:02:59 +0100 Subject: [PATCH] drivers: usb_dc_nrfx: add attached event delay Add configurable attached event delay. Delay can be used to give USB Charging Controller time for initialization. Signed-off-by: Johann Fischer --- drivers/usb/device/Kconfig | 9 ++++++ drivers/usb/device/usb_dc_nrfx.c | 52 +++++++++++++++++++++++--------- 2 files changed, 46 insertions(+), 15 deletions(-) diff --git a/drivers/usb/device/Kconfig b/drivers/usb/device/Kconfig index c6463c526c2..00a56341d53 100644 --- a/drivers/usb/device/Kconfig +++ b/drivers/usb/device/Kconfig @@ -75,6 +75,15 @@ config USB_NRFX_WORK_QUEUE_STACK_SIZE for handling the events from the USBD ISR, i.e. executing endpoint callbacks and providing proper notifications to the USB device stack. +config USB_NRFX_ATTACHED_EVENT_DELAY + int "USBD attached event delay" + range 0 1000 + default 0 + depends on USB_NRFX + help + Configurable attached event delay in milliseconds. Delay can be used + to give USB Charging Controller time for initialization. + config USB_KINETIS bool "Kinetis USB Device Controller Driver" select USB_DEVICE_DRIVER diff --git a/drivers/usb/device/usb_dc_nrfx.c b/drivers/usb/device/usb_dc_nrfx.c index 64a8c493bc7..819c903aeca 100644 --- a/drivers/usb/device/usb_dc_nrfx.c +++ b/drivers/usb/device/usb_dc_nrfx.c @@ -466,14 +466,50 @@ static inline struct usbd_event *usbd_evt_alloc(void) return ev; } +static void submit_dc_power_event(enum usbd_periph_state state) +{ + struct usbd_event *ev = usbd_evt_alloc(); + + if (!ev) { + return; + } + + ev->evt_type = USBD_EVT_POWER; + ev->evt.pwr_evt.state = state; + + usbd_evt_put(ev); + + if (usbd_ctx.attached) { + usbd_work_schedule(); + } +} + +#if CONFIG_USB_NRFX_ATTACHED_EVENT_DELAY +static void attached_evt_delay_handler(struct k_timer *timer) +{ + LOG_DBG("ATTACHED event delay done"); + submit_dc_power_event(USBD_ATTACHED); +} + +static K_TIMER_DEFINE(delay_timer, attached_evt_delay_handler, NULL); +#endif + static void usb_dc_power_event_handler(nrfx_power_usb_evt_t event) { enum usbd_periph_state new_state; switch (event) { case NRFX_POWER_USB_EVT_DETECTED: +#if !CONFIG_USB_NRFX_ATTACHED_EVENT_DELAY new_state = USBD_ATTACHED; break; +#else + LOG_DBG("ATTACHED event delayed"); + k_timer_start(&delay_timer, + K_MSEC(CONFIG_USB_NRFX_ATTACHED_EVENT_DELAY), + K_NO_WAIT); + return; +#endif case NRFX_POWER_USB_EVT_READY: new_state = USBD_POWERED; break; @@ -485,21 +521,7 @@ static void usb_dc_power_event_handler(nrfx_power_usb_evt_t event) return; } - struct usbd_event *ev = usbd_evt_alloc(); - - if (!ev) { - return; - } - - ev->evt_type = USBD_EVT_POWER; - ev->evt.pwr_evt.state = new_state; - - - usbd_evt_put(ev); - - if (usbd_ctx.attached) { - usbd_work_schedule(); - } + submit_dc_power_event(new_state); } /* Stopping HFXO, algorithm supports case when stop comes before clock is