/** \brief run immediately after wakeup * * FIXME: needs doc */ void suspend_wakeup_init(void) { #ifdef RGB_MATRIX_ENABLE #ifdef USE_MASSDROP_CONFIGURATOR if (led_enabled) { I2C3733_Control_Set(1); } #else I2C3733_Control_Set(1); #endif #endif suspend_wakeup_init_kb(); }
/** \brief Suspend power down * * FIXME: needs doc */ void suspend_power_down(void) { #ifdef RGB_MATRIX_ENABLE I2C3733_Control_Set(0); //Disable LED driver #endif suspend_power_down_kb(); }
//WARNING: Automatic GCR is in place to prevent USB shutdown and LED driver overloading void gcr_compute(void) { uint8_t action = ACT_GCR_NONE; if (led_animation_breathing) gcr_use = gcr_breathe; else gcr_use = gcr_desired; //If the 5v takes a catastrophic hit, disable the LED drivers briefly, assert auto gcr mode, min gcr and let the auto take over if (v_5v < V5_CAT) { I2C3733_Control_Set(0); //CDC_print("USB: WARNING: 5V catastrophic level reached! Disabling LED drivers!\r\n"); //Blocking print is bad here! v_5v_cat_hit = 20; //~100ms recover gcr_actual = 0; //Minimize GCR usb_gcr_auto = 1; //Force auto mode enabled return; } else if (v_5v_cat_hit > 1) { v_5v_cat_hit--; return; } else if (v_5v_cat_hit == 1) { I2C3733_Control_Set(1); CDC_print("USB: WARNING: Re-enabling LED drivers\r\n"); v_5v_cat_hit = 0; return; } if (usb_gcr_auto) { if (v_5v_avg < V5_LOW) action = ACT_GCR_DEC; else if (v_5v_avg > V5_HIGH && gcr_actual < gcr_use) action = ACT_GCR_INC; else if (gcr_actual > gcr_use) action = ACT_GCR_DEC; } else { if (gcr_actual < gcr_use) action = ACT_GCR_INC; else if (gcr_actual > gcr_use) action = ACT_GCR_DEC; } if (action == ACT_GCR_NONE) { gcr_min_counter = 0; } else if (action == ACT_GCR_INC) { if (LED_GCR_STEP_AUTO > LED_GCR_MAX - gcr_actual) gcr_actual = LED_GCR_MAX; //Obey max and prevent wrapping else gcr_actual += LED_GCR_STEP_AUTO; gcr_min_counter = 0; } else if (action == ACT_GCR_DEC) { if (LED_GCR_STEP_AUTO > gcr_actual) //Prevent wrapping { gcr_actual = 0; //At this point, power can no longer be cut from the LED drivers, so focus on cutting out extra port if active if (usb_extra_state != USB_EXTRA_STATE_DISABLED_UNTIL_REPLUG) //If not in a wait for replug state { if (usb_extra_state == USB_EXTRA_STATE_ENABLED) //If extra usb is enabled { gcr_min_counter++; if (gcr_min_counter > 200) //5ms per check = 1s delay { USB_ExtraSetState(USB_EXTRA_STATE_DISABLED_UNTIL_REPLUG); usb_extra_manual = 0; //Force disable manual mode of extra port if (usb_extra_manual) CDC_print("USB: Disabling extra port until replug and manual mode toggle!\r\n"); else CDC_print("USB: Disabling extra port until replug!\r\n"); } } } } else { //Power successfully cut back from LED drivers gcr_actual -= LED_GCR_STEP_AUTO; gcr_min_counter = 0; //If breathe mode is active, the top end can fluctuate if the host can not supply enough current //So set the breathe GCR to where it becomes stable if (led_animation_breathing == 1) { gcr_breathe = gcr_actual; //PS: At this point, setting breathing to exhale makes a noticebly shorter cycle // and the same would happen maybe one or two more times. Therefore I'm favoring // powering through one full breathe and letting gcr settle completely } } } }
bool process_record_user(uint16_t keycode, keyrecord_t *record) { static uint32_t key_timer; switch (keycode) { case L_BRI: if (record->event.pressed) { if (LED_GCR_STEP > LED_GCR_MAX - gcr_desired) gcr_desired = LED_GCR_MAX; else gcr_desired += LED_GCR_STEP; if (led_animation_breathing) gcr_breathe = gcr_desired; } return false; case L_BRD: if (record->event.pressed) { if (LED_GCR_STEP > gcr_desired) gcr_desired = 0; else gcr_desired -= LED_GCR_STEP; if (led_animation_breathing) gcr_breathe = gcr_desired; } return false; case L_PTN: if (record->event.pressed) { if (led_animation_id == led_setups_count - 1) led_animation_id = 0; else led_animation_id++; } return false; case L_PTP: if (record->event.pressed) { if (led_animation_id == 0) led_animation_id = led_setups_count - 1; else led_animation_id--; } return false; case L_PSI: if (record->event.pressed) { led_animation_speed += ANIMATION_SPEED_STEP; } return false; case L_PSD: if (record->event.pressed) { led_animation_speed -= ANIMATION_SPEED_STEP; if (led_animation_speed < 0) led_animation_speed = 0; } return false; case L_T_MD: if (record->event.pressed) { led_lighting_mode++; if (led_lighting_mode > LED_MODE_MAX_INDEX) led_lighting_mode = LED_MODE_NORMAL; } return false; case L_T_ONF: if (record->event.pressed) { led_enabled = !led_enabled; I2C3733_Control_Set(led_enabled); } return false; case L_ON: if (record->event.pressed) { led_enabled = 1; I2C3733_Control_Set(led_enabled); } return false; case L_OFF: if (record->event.pressed) { led_enabled = 0; I2C3733_Control_Set(led_enabled); } return false; case L_T_BR: if (record->event.pressed) { led_animation_breathing = !led_animation_breathing; if (led_animation_breathing) { gcr_breathe = gcr_desired; led_animation_breathe_cur = BREATHE_MIN_STEP; breathe_dir = 1; } } return false; case L_T_PTD: if (record->event.pressed) { led_animation_direction = !led_animation_direction; } return false; case U_T_AGCR: if (record->event.pressed && MODS_SHIFT && MODS_CTRL) { TOGGLE_FLAG_AND_PRINT(usb_gcr_auto, "USB GCR auto mode"); } return false; case DBG_TOG: if (record->event.pressed) { TOGGLE_FLAG_AND_PRINT(debug_enable, "Debug mode"); } return false; case DBG_MTRX: if (record->event.pressed) { TOGGLE_FLAG_AND_PRINT(debug_matrix, "Debug matrix"); } return false; case DBG_KBD: if (record->event.pressed) { TOGGLE_FLAG_AND_PRINT(debug_keyboard, "Debug keyboard"); } return false; case DBG_MOU: if (record->event.pressed) { TOGGLE_FLAG_AND_PRINT(debug_mouse, "Debug mouse"); } return false; case MD_BOOT: if (record->event.pressed) { key_timer = timer_read32(); } else { if (timer_elapsed32(key_timer) >= 500) { reset_keyboard(); } } return false; default: return true; //Process all other keycodes normally } }