diff --git a/lib/KSDK_2.0_MK22FN512xxx12 b/lib/KSDK_2.0_MK22FN512xxx12 index 9fbf2bb..7ddde5e 160000 --- a/lib/KSDK_2.0_MK22FN512xxx12 +++ b/lib/KSDK_2.0_MK22FN512xxx12 @@ -1 +1 @@ -Subproject commit 9fbf2bbf085a065a96fb6b2db11d03c3112bf7ba +Subproject commit 7ddde5eadbd33eacc28c9ecee06f5481baf5aa89 diff --git a/right/src/led_display.c b/right/src/led_display.c index cb3d8c9..ed00fd7 100644 --- a/right/src/led_display.c +++ b/right/src/led_display.c @@ -90,7 +90,7 @@ void LedDisplay_SetCurrentKeymapText(void) LedDisplay_SetText(currentKeymap->abbreviationLen, currentKeymap->abbreviation); } -void LedDisplay_SetLayer(uint8_t layerId) +void LedDisplay_SetLayer(layer_id_t layerId) { for (uint8_t i = 13; i <= 45; i += 16) { LedDriverValues[LedDriverId_Left][i] = 0; @@ -101,6 +101,11 @@ void LedDisplay_SetLayer(uint8_t layerId) } } +bool LedDisplay_GetIcon(led_display_icon_t icon) +{ + return LedDriverValues[LedDriverId_Left][8 + icon]; +} + void LedDisplay_SetIcon(led_display_icon_t icon, bool isEnabled) { LedDriverValues[LedDriverId_Left][8 + icon] = isEnabled ? IconsAndLayerTextsBrightness : 0; diff --git a/right/src/led_display.h b/right/src/led_display.h index 8e76c23..aa1bbce 100644 --- a/right/src/led_display.h +++ b/right/src/led_display.h @@ -5,6 +5,7 @@ #include #include + #include "layer.h" // Typedefs: @@ -23,7 +24,9 @@ void LedDisplay_SetText(uint8_t length, const char* text); void LedDisplay_SetCurrentKeymapText(void); - void LedDisplay_SetLayer(uint8_t layerId); + void LedDisplay_SetLayer(layer_id_t layerId); void LedDisplay_SetIcon(led_display_icon_t icon, bool isEnabled); + bool LedDisplay_GetIcon(led_display_icon_t icon); + #endif diff --git a/right/src/timer.c b/right/src/timer.c index ac96d4c..4106877 100644 --- a/right/src/timer.c +++ b/right/src/timer.c @@ -1,7 +1,7 @@ #include "fsl_pit.h" #include "timer.h" -volatile uint32_t CurrentTime; +static volatile uint32_t CurrentTime; void PIT_TIMER_HANDLER(void) { @@ -24,6 +24,10 @@ void Timer_Init(void) PIT_StartTimer(PIT, PIT_TIMER_CHANNEL); } +uint32_t Timer_GetCurrentTime() { + return CurrentTime; +} + void Timer_SetCurrentTime(uint32_t *time) { *time = CurrentTime; diff --git a/right/src/timer.h b/right/src/timer.h index 69b54bc..1ce3218 100644 --- a/right/src/timer.h +++ b/right/src/timer.h @@ -9,13 +9,10 @@ #define TIMER_INTERVAL_MSEC 1 -// Variables: - - extern volatile uint32_t CurrentTime; - // Functions: void Timer_Init(void); + uint32_t Timer_GetCurrentTime(); void Timer_SetCurrentTime(uint32_t *time); uint32_t Timer_GetElapsedTime(uint32_t *time); uint32_t Timer_GetElapsedTimeAndSetCurrent(uint32_t *time); diff --git a/right/src/usb_commands/usb_command_get_debug_buffer.c b/right/src/usb_commands/usb_command_get_debug_buffer.c index 4439841..92d0073 100644 --- a/right/src/usb_commands/usb_command_get_debug_buffer.c +++ b/right/src/usb_commands/usb_command_get_debug_buffer.c @@ -22,7 +22,7 @@ void UsbCommand_GetDebugBuffer(void) SetDebugBufferUint32(13, I2cWatchdog_RecoveryCounter); SetDebugBufferUint32(17, KeyScannerCounter); SetDebugBufferUint32(21, UsbReportUpdateCounter); - SetDebugBufferUint32(25, CurrentTime); + SetDebugBufferUint32(25, Timer_GetCurrentTime()); SetDebugBufferUint32(29, UsbGenericHidActionCounter); SetDebugBufferUint32(33, UsbBasicKeyboardActionCounter); SetDebugBufferUint32(37, UsbMediaKeyboardActionCounter); diff --git a/right/src/usb_commands/usb_command_get_device_property.c b/right/src/usb_commands/usb_command_get_device_property.c index 62c1e5a..50d67c6 100644 --- a/right/src/usb_commands/usb_command_get_device_property.c +++ b/right/src/usb_commands/usb_command_get_device_property.c @@ -69,7 +69,7 @@ void UsbCommand_GetDeviceProperty(void) SetUsbTxBufferUint32(6, I2cMainBusActualBaudRateBps); break; case DevicePropertyId_Uptime: - SetUsbTxBufferUint32(1, CurrentTime); + SetUsbTxBufferUint32(1, Timer_GetCurrentTime()); break; default: SetUsbTxBufferUint8(0, UsbStatusCode_GetDeviceProperty_InvalidProperty); diff --git a/right/src/usb_composite_device.c b/right/src/usb_composite_device.c index a98b05c..2b43662 100644 --- a/right/src/usb_composite_device.c +++ b/right/src/usb_composite_device.c @@ -1,3 +1,6 @@ +#include "config.h" +#include "led_display.h" +#include "slave_drivers/is31fl3731_driver.h" #include "usb_device_config.h" #include "usb_composite_device.h" #include "usb_descriptors/usb_descriptor_hid.h" @@ -160,13 +163,67 @@ static usb_device_class_config_list_struct_t UsbDeviceCompositeConfigList = { } }}; +static bool computerSleeping = false; +#ifdef LED_DRIVERS_ENABLED +static uint8_t oldKeyBacklightBrightness = 0xFF; +static bool capsLockOn = false, agentOn = false, adaptiveOn = false; +#endif + +bool IsComputerSleeping(void) { + return computerSleeping; +} + +static void ComputerIsSleeping(void) { + computerSleeping = true; +#ifdef LED_DRIVERS_ENABLED + // Save the state of the icons + capsLockOn = LedDisplay_GetIcon(LedDisplayIcon_CapsLock); + agentOn = LedDisplay_GetIcon(LedDisplayIcon_Agent); + adaptiveOn = LedDisplay_GetIcon(LedDisplayIcon_Adaptive); + + // Disable keyboard backlight + oldKeyBacklightBrightness = KeyBacklightBrightness; + KeyBacklightBrightness = 0; + LedSlaveDriver_Init(LedDriverId_Right); + LedSlaveDriver_Init(LedDriverId_Left); + + // Turn layer LEDs off + LedDisplay_SetLayer(LayerId_Base); + + // Clear the text + LedDisplay_SetText(0, NULL); +#endif +} + +void WakeupComputer(bool sendResume) { + if (sendResume) // The device should wake up the computer + USB_DeviceSetStatus(UsbCompositeDevice.deviceHandle, kUSB_DeviceStatusBus, NULL); // Send resume signal - this will call USB_DeviceKhciControl(khciHandle, kUSB_DeviceControlResume, NULL); + + computerSleeping = false; // The computer is now awake + +#ifdef LED_DRIVERS_ENABLED + // Restore keyboard backlight and text + KeyBacklightBrightness = oldKeyBacklightBrightness; + LedSlaveDriver_Init(LedDriverId_Right); + LedSlaveDriver_Init(LedDriverId_Left); + + // Update the active layer + LedDisplay_SetLayer(GetActiveLayer()); + + // Restore icon states + LedDisplay_SetIcon(LedDisplayIcon_CapsLock, capsLockOn); + LedDisplay_SetIcon(LedDisplayIcon_Agent, agentOn); + LedDisplay_SetIcon(LedDisplayIcon_Adaptive, adaptiveOn); +#endif +} + static usb_status_t usbDeviceCallback(usb_device_handle handle, uint32_t event, void *param) { usb_status_t status = kStatus_USB_Error; uint16_t *temp16 = (uint16_t*)param; uint8_t *temp8 = (uint8_t*)param; - if (!param && event != kUSB_DeviceEventBusReset && event != kUSB_DeviceEventSetInterface) { + if (!param && event != kUSB_DeviceEventBusReset && event != kUSB_DeviceEventSetInterface && event != kUSB_DeviceEventSuspend && event != kUSB_DeviceEventResume) { return status; } @@ -175,6 +232,18 @@ static usb_status_t usbDeviceCallback(usb_device_handle handle, uint32_t event, UsbCompositeDevice.attach = 0; status = kStatus_USB_Success; break; + case kUSB_DeviceEventSuspend: + if (UsbCompositeDevice.attach) { + ComputerIsSleeping(); // The computer sends this event when it goes to sleep, so turn off all the LEDs + status = kStatus_USB_Success; + } + break; + case kUSB_DeviceEventResume: + if (computerSleeping) { + WakeupComputer(false); // The computer just woke up, so restore the LEDs + status = kStatus_USB_Success; + } + break; case kUSB_DeviceEventSetConfiguration: UsbCompositeDevice.attach = 1; UsbCompositeDevice.currentConfiguration = *temp8; diff --git a/right/src/usb_composite_device.h b/right/src/usb_composite_device.h index 34e9509..c443430 100644 --- a/right/src/usb_composite_device.h +++ b/right/src/usb_composite_device.h @@ -33,5 +33,7 @@ //Functions: void InitUsb(void); + bool IsComputerSleeping(void); + void WakeupComputer(bool sendResume); #endif diff --git a/right/src/usb_device_config.h b/right/src/usb_device_config.h index 1aa0013..e418b48 100644 --- a/right/src/usb_device_config.h +++ b/right/src/usb_device_config.h @@ -23,10 +23,10 @@ ) // Whether the device is self-powered: 1 supported, 0 not supported -#define USB_DEVICE_CONFIG_SELF_POWER 1 +#define USB_DEVICE_CONFIG_SELF_POWER 0 // Whether device remote wakeup supported: 1 supported, 0 not supported -#define USB_DEVICE_CONFIG_REMOTE_WAKEUP 0 +#define USB_DEVICE_CONFIG_REMOTE_WAKEUP 1 // The number of control endpoints, which is always 1 #define USB_CONTROL_ENDPOINT_COUNT 1 diff --git a/right/src/usb_report_updater.c b/right/src/usb_report_updater.c index 7fb3eeb..206968e 100644 --- a/right/src/usb_report_updater.c +++ b/right/src/usb_report_updater.c @@ -245,11 +245,11 @@ static void applyKeyAction(key_state_t *keyState, key_action_t *action) if (!keyState->previous && previousLayer == LayerId_Base && action->switchLayer.mode == SwitchLayerMode_HoldAndDoubleTapToggle) { if (doubleTapSwitchLayerKey && Timer_GetElapsedTimeAndSetCurrent(&doubleTapSwitchLayerStartTime) < DoubleTapSwitchLayerTimeout) { ToggledLayer = action->switchLayer.layer; - doubleTapSwitchLayerTriggerTime = CurrentTime; + doubleTapSwitchLayerTriggerTime = Timer_GetCurrentTime(); } else { doubleTapSwitchLayerKey = keyState; } - doubleTapSwitchLayerStartTime = CurrentTime; + doubleTapSwitchLayerStartTime = Timer_GetCurrentTime(); } break; case KeyActionType_SwitchKeymap: @@ -453,5 +453,8 @@ void UpdateUsbReports(void) IsUsbMouseReportSent = false; } + if ((previousLayer != LayerId_Base || !IsUsbBasicKeyboardReportSent || !IsUsbMediaKeyboardReportSent || !IsUsbSystemKeyboardReportSent || !IsUsbMouseReportSent) && IsComputerSleeping()) + WakeupComputer(true); // Wake up the computer if any key is pressed and the computer is sleeping + Timer_SetCurrentTime(&lastUsbUpdateTime); }