Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add "Rockfall 3 Wireless" keyboard #24750

Open
wants to merge 5 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
324 changes: 324 additions & 0 deletions keyboards/hator/rockfall3/common/wireless/lowpower.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,324 @@
/* Copyright (C) 2024 koosikus
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include "quantum.h"
#include "wireless.h"
#include "usb_main.h"

#ifndef LPWR_TIMEOUT
# define LPWR_TIMEOUT 300000 // 5min
#endif

#ifndef LPWR_PRESLEEP_DELAY
# define LPWR_PRESLEEP_DELAY 200
#endif

#ifndef LPWR_STOP_DELAY
# define LPWR_STOP_DELAY 200
#endif

#ifndef LPWR_WAKEUP_DELAY
# define LPWR_WAKEUP_DELAY 200
#endif

static lpwr_state_t lpwr_state = LPWR_NORMAL;
static lpwr_mode_t lpwr_mode = LPWR_MODE_TIMEOUT;
static uint32_t lpwr_timeout_value = LPWR_TIMEOUT;
static uint32_t lpwr_timestamp = 0x00;
static lpwr_wakeupcd_t lpwr_wakeupcd = LPWR_WAKEUP_NONE;
static bool manual_timeout = false;

static bool rgb_enable_bak = false;

void last_matrix_activity_trigger(void);

void lpwr_clock_enable(void);
void lpwr_enter_stop(void);
void lpwr_exti_init(void);
void mcu_stop_mode(void);

extern void matrix_init_pins(void);

lpwr_state_t lpwr_get_state(void) {
return lpwr_state;
}

void lpwr_set_state(lpwr_state_t state) {
lpwr_state = state;
}

lpwr_mode_t lpwr_get_mode(void) {
return lpwr_mode;
}

void lpwr_set_mode(lpwr_mode_t mode) {
lpwr_mode = mode;
}

void lpwr_set_timeout_value(uint32_t timeout) {
lpwr_timeout_value = timeout;
}

uint32_t lpwr_timeout_value_read(void) {
return lpwr_timeout_value;
}

void lpwr_update_timestamp(void) {
lpwr_timestamp = sync_timer_read32();
}

uint32_t lpwr_timestamp_read(void) {
return lpwr_timestamp;
}

void lpwr_set_sleep_wakeupcd(lpwr_wakeupcd_t wakeupcd) {
lpwr_wakeupcd = wakeupcd;
}

lpwr_wakeupcd_t lpwr_get_sleep_wakeupcd(void) {
return lpwr_wakeupcd;
}

void lpwr_clock_enable(void) __attribute__((weak));
void lpwr_clock_enable(void) {}

void lpwr_exti_init(void) __attribute__((weak));
void lpwr_exti_init(void) {}

void mcu_stop_mode(void) __attribute__((weak));
void mcu_stop_mode(void) {}

void lpwr_enter_stop(void) {
chSysLock();
lpwr_exti_init();
chSysUnlock();

chSysDisable();
mcu_stop_mode();
lpwr_clock_enable();
matrix_init_pins();
chSysEnable();
}

void lpwr_set_timeout_manual(bool enable) {
manual_timeout = enable;
}

bool lpwr_get_timeout_manual(void) {
return manual_timeout;
}

// 2.4g mode, host state
void md_receive_host_cb(bool resume) {

if (resume) {
if (lpwr_get_state() != LPWR_NORMAL) {
lpwr_update_timestamp();
lpwr_set_state(LPWR_WAKEUP);
}
} else {
if (lpwr_get_state() == LPWR_NORMAL) {
manual_timeout = true;
}
}
}

bool lpwr_is_allow_timeout_hook(void) __attribute__((weak));
bool lpwr_is_allow_timeout_hook(void) {
return true;
}

bool lpwr_is_allow_timeout(void) __attribute__((weak));
bool lpwr_is_allow_timeout(void) {
uint32_t timeout = lpwr_timeout_value_read();

if (lpwr_is_allow_timeout_hook() != true) {
manual_timeout = false;
return false;
}

if ((wireless_get_current_devs() == DEVS_USB) && (USB_DRIVER.state == USB_ACTIVE)) {
manual_timeout = false;
return false;
}

if (manual_timeout || (timeout && (last_input_activity_elapsed() >= timeout))) {
manual_timeout = false;
return true;
}

return false;
}

bool lpwr_is_allow_presleep_hook(void) __attribute__((weak));
bool lpwr_is_allow_presleep_hook(void) {
return true;
}

bool lpwr_is_allow_presleep(void) __attribute__((weak));
bool lpwr_is_allow_presleep(void) {
uint32_t delay = LPWR_PRESLEEP_DELAY;

if (lpwr_is_allow_presleep_hook() != true) {
return false;
}

if (!delay || (sync_timer_elapsed32(lpwr_timestamp_read()) >= delay)) {
return true;
}

return false;
}

bool lpwr_is_allow_stop_hook(void) __attribute__((weak));
bool lpwr_is_allow_stop_hook(void) {
return true;
}

bool lpwr_is_allow_stop(void) __attribute__((weak));
bool lpwr_is_allow_stop(void) {
uint32_t delay = LPWR_STOP_DELAY;

if (lpwr_is_allow_stop_hook() != true) {
return false;
}

if (!delay || (sync_timer_elapsed32(lpwr_timestamp_read()) >= delay)) {
return true;
}

return false;
}

bool lpwr_is_allow_wakeup_hook(void) __attribute__((weak));
bool lpwr_is_allow_wakeup_hook(void) {
return true;
}

bool lpwr_is_allow_wakeup(void) __attribute__((weak));
bool lpwr_is_allow_wakeup(void) {
uint32_t delay = LPWR_WAKEUP_DELAY;

if (lpwr_is_allow_wakeup_hook() != true) {
return false;
}

if (!delay || (sync_timer_elapsed32(lpwr_timestamp_read()) >= delay)) {
return true;
}

return false;
}

void lpwr_presleep_hook(void) __attribute__((weak));
void lpwr_presleep_hook(void) {}

void lpwr_presleep_cb(void) __attribute__((weak));
void lpwr_presleep_cb(void) {

#if defined(RGB_MATRIX_ENABLE)
rgb_enable_bak = rgb_matrix_is_enabled();
rgb_matrix_disable_noeeprom();
#elif defined(RGBLIGHT_ENABLE)
rgb_enable_bak = rgblight_is_enabled();
rgblight_disable_noeeprom();
#else
rgb_enable_bak = false;
#endif
suspend_power_down();
lpwr_presleep_hook();
}

void lpwr_stop_hook_pre(void) __attribute__((weak));
void lpwr_stop_hook_pre(void) {}

void lpwr_stop_hook_post(void) __attribute__((weak));
void lpwr_stop_hook_post(void) {}

void lpwr_stop_cb(void) __attribute__((weak));
void lpwr_stop_cb(void) {

lpwr_set_sleep_wakeupcd(LPWR_WAKEUP_NONE);

lpwr_stop_hook_pre();
lpwr_enter_stop();

switch (lpwr_get_sleep_wakeupcd()) {
case LPWR_WAKEUP_UART: {
lpwr_set_state(LPWR_STOP);
} break;
default: {
lpwr_set_state(LPWR_WAKEUP);
} break;
}

lpwr_stop_hook_post();
}

void lpwr_wakeup_hook(void) __attribute__((weak));
void lpwr_wakeup_hook(void) {}

void lpwr_wakeup_cb(void) __attribute__((weak));
void lpwr_wakeup_cb(void) {

if (rgb_enable_bak) {
#if defined(RGB_MATRIX_ENABLE)
rgb_matrix_enable_noeeprom();
#elif defined(RGBLIGHT_ENABLE)
rgblight_enable_noeeprom();
#endif
}

suspend_wakeup_init();
lpwr_wakeup_hook();

last_matrix_activity_trigger();
}

void lpwr_task(void) __attribute__((weak));
void lpwr_task(void) {

switch (lpwr_get_state()) {
case LPWR_NORMAL: {
if (lpwr_is_allow_timeout()) {
lpwr_update_timestamp();
lpwr_set_state(LPWR_PRESLEEP);
}
} break;
case LPWR_PRESLEEP: {
if (lpwr_is_allow_presleep()) {
lpwr_presleep_cb();
lpwr_update_timestamp();
lpwr_set_state(LPWR_STOP);
}
} break;
case LPWR_STOP: {
if (lpwr_is_allow_stop()) {
lpwr_update_timestamp();
lpwr_stop_cb();
}
} break;
case LPWR_WAKEUP: {
if (lpwr_is_allow_wakeup()) {
lpwr_wakeup_cb();
lpwr_update_timestamp();
lpwr_set_state(LPWR_NORMAL);
}
} break;
default:
break;
}
}
52 changes: 52 additions & 0 deletions keyboards/hator/rockfall3/common/wireless/lowpower.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/* Copyright (C) 2024 koosikus
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once

typedef enum {
LPWR_NORMAL = 0,
LPWR_PRESLEEP,
LPWR_STOP,
LPWR_WAKEUP,
} lpwr_state_t;

typedef enum {
LPWR_WAKEUP_NONE = 0,
LPWR_WAKEUP_MATRIX,
LPWR_WAKEUP_UART,
LPWR_WAKEUP_CABLE,
LPWR_WAKEUP_USB,
LPWR_WAKEUP_ONEKEY,
LPWR_WAKEUP_ENCODER,
LPWR_WAKEUP_SWITCH,
} lpwr_wakeupcd_t;

typedef enum {
LPWR_MODE_TIMEOUT = 0,
} lpwr_mode_t;

lpwr_state_t lpwr_get_state(void);
lpwr_mode_t lpwr_get_mode(void);
uint32_t lpwr_timestamp_read(void);
uint32_t lpwr_timeout_value_read(void);
void lpwr_set_sleep_wakeupcd(lpwr_wakeupcd_t wakeupcd);
lpwr_wakeupcd_t lpwr_get_sleep_wakeupcd(void);
void lpwr_update_timestamp(void);
void lpwr_set_timeout_manual(bool enable);
bool lpwr_get_timeout_manual(void);
void lpwr_set_state(lpwr_state_t state);
void lpwr_set_mode(lpwr_mode_t mode);
void lpwr_task(void);
Loading
Loading