From fd8650ea3fe90bd1438d3840e79d57952a582849 Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Sat, 29 Oct 2022 19:12:34 +0200 Subject: [PATCH] Teensy 4.1: implement USB remote wakeup This allows waking up a computer from Suspend-to-RAM by pressing a key on the keyboard (with the QMK keyboard firmware, which uses ChibiOS for the Teensy). --- ext/nxp-middleware-usb/device/usb_device_ehci.c | 14 ++++++++++++-- os/hal/ports/MIMXRT1062/LLD/USBHSv1/hal_usb_lld.c | 8 ++++++-- os/hal/ports/MIMXRT1062/LLD/USBHSv1/hal_usb_lld.h | 6 ++++-- .../MIMXRT1062/LLD/USBHSv1/usb_device_config.h | 4 ++-- 4 files changed, 24 insertions(+), 8 deletions(-) diff --git a/ext/nxp-middleware-usb/device/usb_device_ehci.c b/ext/nxp-middleware-usb/device/usb_device_ehci.c index e8b79ed0fa..ec3a8e767d 100644 --- a/ext/nxp-middleware-usb/device/usb_device_ehci.c +++ b/ext/nxp-middleware-usb/device/usb_device_ehci.c @@ -1555,6 +1555,13 @@ usb_status_t USB_DeviceEhciCancel(usb_device_controller_handle ehciHandle, uint8 return kStatus_USB_Success; } +static uint32_t ms_to_cycles(const uint32_t val) { + // 600 cycles at 0.6 cycles/ns == 1μs + const uint32_t cycles_per_us = 600; + const uint32_t ms_to_us = 1000; + return val * ms_to_us * cycles_per_us; +} + /*! * @brief Control the status of the selected item. * @@ -1696,8 +1703,11 @@ usb_status_t USB_DeviceEhciControl(usb_device_controller_handle ehciHandle, usb_ #endif ehciState->registerBase->PORTSC1 &= ~USBHS_PORTSC1_PHCD_MASK; ehciState->registerBase->PORTSC1 |= USBHS_PORTSC1_FPR_MASK; - startTick = deviceHandle->hwTick; - while ((deviceHandle->hwTick - startTick) < 10U) + // For easier ChibiOS integration, directly query the (already + // enabled) CYCCNT register instead of the deviceHandle->hwTick + // variable, which ChibiOS currently does not update. + startTick = DWT->CYCCNT; + while ((DWT->CYCCNT - startTick) < ms_to_cycles(10U)) { __NOP(); } diff --git a/os/hal/ports/MIMXRT1062/LLD/USBHSv1/hal_usb_lld.c b/os/hal/ports/MIMXRT1062/LLD/USBHSv1/hal_usb_lld.c index ccde0f6499..6e1c4a0104 100644 --- a/os/hal/ports/MIMXRT1062/LLD/USBHSv1/hal_usb_lld.c +++ b/os/hal/ports/MIMXRT1062/LLD/USBHSv1/hal_usb_lld.c @@ -116,12 +116,16 @@ static usb_status_t usb_device_callback(usb_device_handle handle, uint32_t callb break; case kUSB_DeviceEventSuspend: - printf_debug(" suspend"); + printf_debug(" suspend--nxp"); + // Call USB_DeviceSetStatus() to enable the “detect resume” interrupt. + usb_device_struct_t *dev_handle = (usb_device_struct_t *)handle; + (void)USB_DeviceSetStatus(dev_handle, kUSB_DeviceStatusBusSuspend, NULL); + printf_debug(" suspend--chibi"); _usb_suspend(usbp); break; case kUSB_DeviceEventResume: - printf_debug(" resume"); + printf_debug(" resume--chibi"); _usb_wakeup(usbp); break; } diff --git a/os/hal/ports/MIMXRT1062/LLD/USBHSv1/hal_usb_lld.h b/os/hal/ports/MIMXRT1062/LLD/USBHSv1/hal_usb_lld.h index 764fbc60a0..655f070c72 100644 --- a/os/hal/ports/MIMXRT1062/LLD/USBHSv1/hal_usb_lld.h +++ b/os/hal/ports/MIMXRT1062/LLD/USBHSv1/hal_usb_lld.h @@ -408,8 +408,10 @@ struct USBDriver { * @notapi */ #define usb_lld_wakeup_host(usbp) \ - do{ \ - } while (false) + do{ \ + usb_device_struct_t *dev_handle = (usb_device_struct_t *)handle; \ + (void)USB_DeviceSetStatus(dev_handle, kUSB_DeviceStatusBusResume, NULL); \ + } while (0) /*===========================================================================*/ diff --git a/os/hal/ports/MIMXRT1062/LLD/USBHSv1/usb_device_config.h b/os/hal/ports/MIMXRT1062/LLD/USBHSv1/usb_device_config.h index c00e7bff5a..a3968d9ee9 100644 --- a/os/hal/ports/MIMXRT1062/LLD/USBHSv1/usb_device_config.h +++ b/os/hal/ports/MIMXRT1062/LLD/USBHSv1/usb_device_config.h @@ -154,11 +154,11 @@ #define USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE (0U) #endif /*! @brief Whether the low power mode is enabled or not. */ -#define USB_DEVICE_CONFIG_LOW_POWER_MODE (0U) +#define USB_DEVICE_CONFIG_LOW_POWER_MODE (1U) #if ((defined(USB_DEVICE_CONFIG_LOW_POWER_MODE)) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U)) /*! @brief Whether device remote wakeup supported. 1U supported, 0U not supported */ -#define USB_DEVICE_CONFIG_REMOTE_WAKEUP (0U) +#define USB_DEVICE_CONFIG_REMOTE_WAKEUP (1U) /*! @brief Whether LPM is supported. 1U supported, 0U not supported */ #define USB_DEVICE_CONFIG_LPM_L1 (0U)