From 9b47ba20333263e6d9805a8f3e17540d5d43da44 Mon Sep 17 00:00:00 2001 From: yangdigi Date: Sat, 22 Jun 2024 12:59:55 +0800 Subject: [PATCH] Reduce the size of the compiled firmware for the ble51 series --- keyboards/ydkb/ble660c_980c/config.h | 76 +-- .../ydkb/ble660c_980c/keymaps/vial/config.h | 2 - .../ydkb/ble660c_980c/keymaps/vial/rules.mk | 5 +- .../ydkb/ble660c_980c/keymaps/vial/vial.json | 6 +- keyboards/ydkb/ble660c_980c/led_fn.c | 48 +- keyboards/ydkb/ble660c_980c/matrix.c | 198 +++++--- .../pre_compile_via/ydkb_ble660c_980c_via.zip | Bin 32000 -> 0 bytes keyboards/ydkb/ble660c_980c/rules.mk | 24 +- keyboards/ydkb/chicory/backlight_user.c | 54 ++ keyboards/ydkb/chicory/chicory.h | 8 + keyboards/ydkb/chicory/config.h | 101 ++++ .../keymaps/via/config.h | 2 +- keyboards/ydkb/chicory/keymaps/via/keymap.c | 28 ++ .../keymaps/via/readme.md | 0 .../keymaps/via/rules.mk | 0 keyboards/ydkb/chicory/keymaps/vial/config.h | 6 + keyboards/ydkb/chicory/keymaps/vial/keymap.c | 26 + keyboards/ydkb/chicory/keymaps/vial/readme.md | 3 + keyboards/ydkb/chicory/keymaps/vial/rules.mk | 7 + keyboards/ydkb/chicory/keymaps/vial/vial.json | 30 ++ keyboards/ydkb/chicory/led_fn.c | 59 +++ keyboards/ydkb/chicory/light_ws2812.c | 157 ++++++ keyboards/ydkb/chicory/light_ws2812.h | 66 +++ keyboards/ydkb/chicory/matrix.c | 312 ++++++++++++ keyboards/ydkb/chicory/rgblight.c | 467 ++++++++++++++++++ keyboards/ydkb/chicory/rgblight.h | 83 ++++ keyboards/ydkb/chicory/rules.mk | 34 ++ keyboards/ydkb/{00common => }/debounce_pk.h | 0 keyboards/ydkb/duang60v1/backlight_user.c | 52 ++ keyboards/ydkb/duang60v1/config.h | 77 +-- .../duang60v1/keymaps/minira2_vial/config.h | 6 +- .../duang60v1/keymaps/minira2_vial/keymap.c | 2 +- .../duang60v1/keymaps/minira2_vial/rules.mk | 5 +- .../duang60v1/keymaps/minira2_vial/vial.json | 29 +- .../ydkb/duang60v1/keymaps/vial/config.h | 6 +- .../ydkb/duang60v1/keymaps/vial/keymap.c | 2 +- .../ydkb/duang60v1/keymaps/vial/rules.mk | 5 +- .../ydkb/duang60v1/keymaps/vial/vial.json | 29 +- keyboards/ydkb/duang60v1/led_fn.c | 36 +- keyboards/ydkb/duang60v1/matrix.c | 183 ++++--- .../pre_compile_via/ydkb_duang60v1_via.zip | Bin 18328 -> 0 bytes keyboards/ydkb/duang60v1/rgblight.c | 239 +++++---- keyboards/ydkb/duang60v1/rgblight.h | 22 +- keyboards/ydkb/duang60v1/rules.mk | 31 +- keyboards/ydkb/duang60v1/switch_board.h | 1 - keyboards/ydkb/duang60v2/config.h | 35 +- .../ydkb/duang60v2/keymaps/vial/config.h | 4 +- .../ydkb/duang60v2/keymaps/vial/rules.mk | 5 +- .../ydkb/duang60v2/keymaps/vial/vial.json | 28 +- keyboards/ydkb/duang60v2/led_fn.c | 36 +- keyboards/ydkb/duang60v2/matrix.c | 135 +++-- .../pre_compile_via/ydkb_duang60v2_via.zip | Bin 18429 -> 0 bytes keyboards/ydkb/duang60v2/rgblight.c | 247 +++++---- keyboards/ydkb/duang60v2/rgblight.h | 4 +- keyboards/ydkb/duang60v2/rules.mk | 26 +- keyboards/ydkb/duang60v2/switch_board.h | 1 - keyboards/ydkb/hhkb_ble/config.h | 44 +- keyboards/ydkb/hhkb_ble/keymaps/via/keymap.c | 48 -- keyboards/ydkb/hhkb_ble/keymaps/vial/config.h | 4 +- keyboards/ydkb/hhkb_ble/keymaps/vial/keymap.c | 9 +- keyboards/ydkb/hhkb_ble/keymaps/vial/rules.mk | 4 +- .../ydkb/hhkb_ble/keymaps/vial/vial.json | 30 +- keyboards/ydkb/hhkb_ble/led_fn.c | 57 ++- keyboards/ydkb/hhkb_ble/matrix.c | 209 ++++---- .../pre_compile_via/ydkb_hhkb_ble_via.zip | Bin 16329 -> 0 bytes keyboards/ydkb/hhkb_ble/rules.mk | 4 +- keyboards/ydkb/just68v2/config.h | 29 +- keyboards/ydkb/just68v2/keymaps/vial/config.h | 2 - keyboards/ydkb/just68v2/keymaps/vial/rules.mk | 5 +- .../ydkb/just68v2/keymaps/vial/vial.json | 26 +- keyboards/ydkb/just68v2/led_fn.c | 36 +- keyboards/ydkb/just68v2/matrix.c | 138 +++--- keyboards/ydkb/just68v2/rgblight.c | 237 +++++---- keyboards/ydkb/just68v2/rules.mk | 27 +- keyboards/ydkb/louise/backlight_user.c | 52 ++ keyboards/ydkb/louise/config.h | 28 +- keyboards/ydkb/louise/keymaps/vial/config.h | 9 +- keyboards/ydkb/louise/keymaps/vial/keymap.c | 18 +- keyboards/ydkb/louise/keymaps/vial/rules.mk | 5 +- keyboards/ydkb/louise/keymaps/vial/vial.json | 26 +- keyboards/ydkb/louise/led_fn.c | 39 +- keyboards/ydkb/louise/matrix.c | 149 +++--- keyboards/ydkb/louise/rgblight.c | 214 ++++---- keyboards/ydkb/louise/rules.mk | 30 +- keyboards/ydkb/pearly_v1/backlight_user.c | 52 ++ keyboards/ydkb/pearly_v1/config.h | 26 +- .../ydkb/pearly_v1/keymaps/vial/config.h | 6 +- .../ydkb/pearly_v1/keymaps/vial/keymap.c | 13 +- .../ydkb/pearly_v1/keymaps/vial/rules.mk | 5 +- .../ydkb/pearly_v1/keymaps/vial/vial.json | 28 +- keyboards/ydkb/pearly_v1/led_fn.c | 29 +- keyboards/ydkb/pearly_v1/matrix.c | 138 +++--- keyboards/ydkb/pearly_v1/rgblight.c | 240 +++++---- keyboards/ydkb/pearly_v1/rgblight.h | 22 +- keyboards/ydkb/pearly_v1/rules.mk | 30 +- keyboards/ydkb/pearly_v2/config.h | 29 +- .../ydkb/pearly_v2/keymaps/vial/config.h | 3 - .../ydkb/pearly_v2/keymaps/vial/rules.mk | 5 +- .../ydkb/pearly_v2/keymaps/vial/vial.json | 26 +- keyboards/ydkb/pearly_v2/led_fn.c | 28 +- keyboards/ydkb/pearly_v2/light_ws2812.c | 1 - keyboards/ydkb/pearly_v2/matrix.c | 124 ++--- keyboards/ydkb/pearly_v2/rgblight.c | 207 +++++--- keyboards/ydkb/pearly_v2/rules.mk | 27 +- keyboards/ydkb/ydpm40ble/config.h | 21 +- .../ydkb/ydpm40ble/keymaps/vial/config.h | 2 - .../ydkb/ydpm40ble/keymaps/vial/rules.mk | 5 +- .../ydkb/ydpm40ble/keymaps/vial/vial.json | 24 +- keyboards/ydkb/ydpm40ble/matrix.c | 8 + keyboards/ydkb/ydpm40ble/rgblight.c | 1 - quantum/command.c | 13 + quantum/dynamic_keymap.c | 6 + quantum/eeconfig.c | 10 + quantum/keymap.h | 1 + quantum/keymap_common.c | 2 + quantum/keymap_introspection.c | 4 + quantum/mousekey.c | 3 +- quantum/via.c | 25 + quantum/vial.c | 26 + tmk_core/protocol/ble51.mk | 5 +- tmk_core/protocol/ble51/ble51.c | 236 +++++++-- tmk_core/protocol/ble51/ble51.h | 10 +- tmk_core/protocol/ble51/ble51_task.c | 272 ++++++---- tmk_core/protocol/ble51/ble51_task.h | 7 +- tmk_core/protocol/ble51/config_ble51.h | 53 ++ tmk_core/protocol/ble51/main.c | 100 +++- tmk_core/protocol/ble51/recore.h | 12 +- tmk_core/protocol/ble51/recore/action.c | 20 - tmk_core/protocol/ble51/recore/bootloader.c | 1 + tmk_core/protocol/ble51/recore/mousekey.c | 178 +++++++ tmk_core/protocol/ble51/recore/mousekey.h | 55 +++ tmk_core/protocol/ble51/recore/recore.c | 89 ++++ tmk_core/protocol/ble51/recore/serial.h | 46 ++ tmk_core/protocol/ble51/recore/serial_uart.c | 14 +- tmk_core/protocol/ble51/recore/suspend.c | 7 + tmk_core/protocol/host.c | 4 + tmk_core/protocol/host.h | 6 + tmk_core/protocol/report.c | 60 +++ 138 files changed, 4738 insertions(+), 2154 deletions(-) delete mode 100644 keyboards/ydkb/ble660c_980c/pre_compile_via/ydkb_ble660c_980c_via.zip create mode 100644 keyboards/ydkb/chicory/backlight_user.c create mode 100644 keyboards/ydkb/chicory/chicory.h create mode 100644 keyboards/ydkb/chicory/config.h rename keyboards/ydkb/{hhkb_ble => chicory}/keymaps/via/config.h (60%) create mode 100644 keyboards/ydkb/chicory/keymaps/via/keymap.c rename keyboards/ydkb/{hhkb_ble => chicory}/keymaps/via/readme.md (100%) rename keyboards/ydkb/{hhkb_ble => chicory}/keymaps/via/rules.mk (100%) create mode 100644 keyboards/ydkb/chicory/keymaps/vial/config.h create mode 100644 keyboards/ydkb/chicory/keymaps/vial/keymap.c create mode 100644 keyboards/ydkb/chicory/keymaps/vial/readme.md create mode 100644 keyboards/ydkb/chicory/keymaps/vial/rules.mk create mode 100644 keyboards/ydkb/chicory/keymaps/vial/vial.json create mode 100644 keyboards/ydkb/chicory/led_fn.c create mode 100644 keyboards/ydkb/chicory/light_ws2812.c create mode 100644 keyboards/ydkb/chicory/light_ws2812.h create mode 100644 keyboards/ydkb/chicory/matrix.c create mode 100644 keyboards/ydkb/chicory/rgblight.c create mode 100644 keyboards/ydkb/chicory/rgblight.h create mode 100644 keyboards/ydkb/chicory/rules.mk rename keyboards/ydkb/{00common => }/debounce_pk.h (100%) create mode 100644 keyboards/ydkb/duang60v1/backlight_user.c delete mode 100644 keyboards/ydkb/duang60v1/pre_compile_via/ydkb_duang60v1_via.zip delete mode 100644 keyboards/ydkb/duang60v2/pre_compile_via/ydkb_duang60v2_via.zip delete mode 100644 keyboards/ydkb/hhkb_ble/keymaps/via/keymap.c delete mode 100644 keyboards/ydkb/hhkb_ble/pre_compile_via/ydkb_hhkb_ble_via.zip create mode 100644 keyboards/ydkb/louise/backlight_user.c create mode 100644 keyboards/ydkb/pearly_v1/backlight_user.c create mode 100644 tmk_core/protocol/ble51/config_ble51.h delete mode 100644 tmk_core/protocol/ble51/recore/action.c create mode 100644 tmk_core/protocol/ble51/recore/mousekey.c create mode 100644 tmk_core/protocol/ble51/recore/mousekey.h create mode 100644 tmk_core/protocol/ble51/recore/recore.c create mode 100644 tmk_core/protocol/ble51/recore/serial.h diff --git a/keyboards/ydkb/ble660c_980c/config.h b/keyboards/ydkb/ble660c_980c/config.h index 2ef9008b286..5ccdf66a2c8 100644 --- a/keyboards/ydkb/ble660c_980c/config.h +++ b/keyboards/ydkb/ble660c_980c/config.h @@ -1,11 +1,10 @@ #pragma once #include "config_common.h" +#include "config_ble51.h" /* USB Device descriptor parameter */ -#define FW_VER QMK_DM4S -#define FW_VER_VIA VIA_DM4S -#define FW_VER_VIAL VIAL_DMCL +#define FW_VER_DATE DO5U #define VENDOR_ID 0x9D5B #define PRODUCT_ID 0x19C1 #define DEVICE_VER 0x0001 @@ -13,79 +12,24 @@ #define PRODUCT BLE660C/BLE980C (FW_VER) +/* matrix size */ #define MATRIX_ROWS 7 #define MATRIX_COLS 16 - - -#define TAPPING_TOGGLE 2 - -#define TAPPING_TERM 200 -#define IGNORE_MOD_TAP_INTERRUPT // this makes it possible to do rolling combos (zx) with keys that convert to other keys on hold (z becomes ctrl when you hold it, and when this option isn't enabled, z rapidly followed by x actually sends Ctrl-x. That's bad.) - - -/* key combination for command */ -#define IS_COMMAND() ( \ - (get_mods() == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT))) || \ - (get_mods() == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_LCTRL) | MOD_BIT(KC_RSHIFT))) \ -) -/* disable command for default layer */ -#define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS 0 -#define MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS 0 - -/* fix space cadet rollover issue */ -#define DISABLE_SPACE_CADET_ROLLOVER - -#if defined(__AVR_ATmega32U4__) || defined(__AVR_AT90USB1286__) - #define UCSR1D _SFR_MEM8(0xCB) - #define RTSEN 0 - #define CTSEN 1 - - #define SERIAL_UART_BAUD 76800 - #define SERIAL_UART_DATA UDR1 - #define SERIAL_UART_UBRR ((F_CPU/(8.0*SERIAL_UART_BAUD)-1+0.5)) - #define SERIAL_UART_RXD_VECT USART1_RX_vect - #define SERIAL_UART_TXD_READY (UCSR1A&(1<>8); \ - UCSR1B |= (1<. extern bool is_980c; +void led_all_off(void) { + DDRB |= (1<<6 |1<<5); + if (is_980c) { + PORTB &= ~(1<<6 |1<<5); + DDRD |= (1<<7); + PORTD &= ~(1<<7); + } else { + PORTB |= (1<<6 |1<<5); + } +} + +#if 0 void led_set_user(uint8_t usb_led) { + if (is_980c) { + PORTD &= ~(1<<7); + PORTB &= ~(1<<6 | 1<<5); + } else { + PORTB |= (1<<6 | 1<<5); + } if (usb_led & (1<event.pressed) { - switch (keycode) { - case USER00: - command_extra(KC_U); - break; - case USER01: //RESET - command_extra(KC_B); - break; - case USER02: //BATTERY LEVEL - command_extra(KC_V); - break; - case USER03: //LOCK MODE - command_extra(KC_L); - break; - } + static const uint8_t userx_to_command[4] = { + KC_U, // 0 Host Switch + KC_B, // 1 Reset + KC_V, // 2 Output Battery Value + KC_L // 3 Lock Mode + }; + if (keycode >= USER00 && keycode < USER04) command_extra(userx_to_command[keycode-USER00]); } } \ No newline at end of file diff --git a/keyboards/ydkb/ble660c_980c/matrix.c b/keyboards/ydkb/ble660c_980c/matrix.c index 43e17a7d789..52ab3f891eb 100644 --- a/keyboards/ydkb/ble660c_980c/matrix.c +++ b/keyboards/ydkb/ble660c_980c/matrix.c @@ -1,5 +1,5 @@ /* -Copyright 2011 Jun Wako +Copyright 2023 YANG 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 @@ -38,61 +38,82 @@ along with this program. If not, see . #include "switch_board.h" +// 这个时间即使加到800,980c也无法正常。但是980c加入22uf的电容后,200也可以。 +static uint8_t matrix_start_delay_timer = 200; // matrix state buffer(1:on, 0:off) static matrix_row_t *matrix; static matrix_row_t *matrix_prev; -static matrix_row_t _matrix0[MATRIX_ROWS]; -static matrix_row_t _matrix1[MATRIX_ROWS]; +static matrix_row_t _matrix0[MATRIX_ROWS] = {0}; +static matrix_row_t _matrix1[MATRIX_ROWS] = {0}; static uint8_t matrix_keys_down = 0; + +static uint16_t matrix_scan_timestamp = 0; static uint8_t fc_matrix_rows; +struct { + uint8_t rows; + uint8_t final_col; +} hhkb_matrix; + +void matrix_scan_user(void) {} +__attribute__ ((weak)) +void matrix_scan_kb(void) { + matrix_scan_user(); + hook_keyboard_loop(); +} + static uint8_t wake_scan = 0; bool is_980c = 0; -bool is_ver22 = 0; - void hook_early_init() { +#if 0 // 使用PF6判断 980C,舍弃此方法 DDRF &= ~(1<= 4) { + if (BT_POWERED == 0) { if (++sleep_timer < 80) return false; else sleep_timer = 0; } @@ -244,7 +281,7 @@ bool suspend_wakeup_condition(void) wake_scan = 1; matrix_scan(); //tp1685 fix - if (BLE51_PowerState >= 4) { + if (BT_POWERED == 0) { matrix_scan(); } if (matrix_scan() == 100) { @@ -257,70 +294,81 @@ bool suspend_wakeup_condition(void) void suspend_power_down_action(void) { KEY_POWER_OFF(); - if (is_980c) { - PORTD &= ~(1<<7); - PORTB &= ~(1<<6 | 1<<5); // turn off all leds. - } else { - PORTB |= (1<<6 | 1<<5); // turn off all leds. - } + led_all_off(); } void suspend_wakeup_init_action(void) { - if (BLE51_PowerState >=4) { - if (is_980c) { - PORTD |= (1<<7); - PORTB |= (1<<6 |1<<5); - } else { - PORTB &= ~(1<<6 |1<<5); - } - _delay_ms(400); + if (BT_POWERED == 0) { + matrix_start_delay_timer = 200; // matrix board works delay display_connection_status_check_times = 1; } } -void ble51_task_user(void) +void hook_keyboard_loop() { - static uint8_t ble51_task_steps = 0; + if (BLE51_PowerState > 1) return; + static uint8_t steps = 0; static uint16_t battery_timer = 0; - if (timer_elapsed(battery_timer) > 150) { + if (timer_elapsed(battery_timer) > 160) { battery_timer = timer_read(); - ble51_task_steps++; - if (low_battery) { - if (ble51_task_steps > 3) { - ble51_task_steps = (low_battery == 1)? 3:0; //value 1 is extremely low battery - if (PINE&(1<= 5) || ble51_task_steps >= 11 ) { - ble51_task_steps = 0; + + if (host_keyboard_leds() & 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 z + +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 . +*/ + +#include +#include +#include +#include "backlight.h" +#include "timer.h" + +extern bool no_backlight; + +void backlight_init_ports(void) { + DDRD &= ~(1<<0); + PORTD |= (1<<0); +} + +void backlight_task(void) { + return; +} + +void backlight_user_enable(void) +{ + + DDRD |= (1<<0); + PORTD &= ~(1<<0); +} + +void backlight_user_disable(void) +{ + DDRD &= ~(1<<0); + PORTD |= (1<<0); +} + +void backlight_set(uint8_t level) +{ + if (no_backlight) return; + if (level) backlight_user_enable(); + else backlight_user_disable(); +} + diff --git a/keyboards/ydkb/chicory/chicory.h b/keyboards/ydkb/chicory/chicory.h new file mode 100644 index 00000000000..bd6e6bce6c3 --- /dev/null +++ b/keyboards/ydkb/chicory/chicory.h @@ -0,0 +1,8 @@ +#pragma once + +#include "quantum.h" +#include +#include + +#define XXX KC_NO + diff --git a/keyboards/ydkb/chicory/config.h b/keyboards/ydkb/chicory/config.h new file mode 100644 index 00000000000..174215b935b --- /dev/null +++ b/keyboards/ydkb/chicory/config.h @@ -0,0 +1,101 @@ +#pragma once + +#include "config_common.h" + +/* USB Device descriptor parameter */ +#define FW_VER_DATE DO5U +#define CONTACT(x,y) x##y //https://blog.csdn.net/aiynmimi/article/details/123486956 +#define CONTACT2(x,y) CONTACT(x,y) +#define FW_VER CONTACT2(VIAL_, FW_VER_DATE) +#define VENDOR_ID 0x9D5B +#define PRODUCT_ID 0x1840 +#define DEVICE_VER 0x0001 +#define MANUFACTURER YDKB +#if CONSOLE_ENABLE +#define PRODUCT Chicory Debug (FW_VER) +#else +#define PRODUCT Chicory (FW_VER) +#endif + + +#define MATRIX_ROWS 4 +#define MATRIX_COLS 11 + + + +#define BACKLIGHT_LEVELS 1 +#define TAPPING_TOGGLE 3 + + +/* key combination for command */ +#define IS_COMMAND() ( \ + (get_mods() == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT))) || \ + (get_mods() == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_LCTRL) | MOD_BIT(KC_RSHIFT))) \ +) + +#define ws2812_PORTREG PORTD +#define ws2812_DDRREG DDRD +#define ws2812_pin PD1 +#define RGBLED_NUM 12 // Number of LEDs + +/* disable command for default layer */ +#define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS 0 +#define MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS 0 + + +#if defined(__AVR_ATmega32U4__) || defined(__AVR_AT90USB1286__) + #define UCSR1D _SFR_MEM8(0xCB) + #define RTSEN 0 + #define CTSEN 1 + + #define SERIAL_UART_BAUD 76800 + #define SERIAL_UART_DATA UDR1 + #define SERIAL_UART_UBRR ((F_CPU/(8.0*SERIAL_UART_BAUD)-1+0.5)) + #define SERIAL_UART_RXD_VECT USART1_RX_vect + #define SERIAL_UART_TXD_READY (UCSR1A&(1<>8); \ + UCSR1B |= (1<. +*/ + +#include +#include "quantum.h" +#include "stdint.h" +#include "led.h" +#include "via.h" +#include "command.h" +#include "ble51.h" +#include "rgblight.h" + + +void led_set_user(uint8_t usb_led) +{ + if (usb_led & (1<event.pressed) { + switch (keycode) { + case USER00: + command_extra(KC_U); + break; + case USER01: //RESET + command_extra(KC_B); + break; + case USER02: //BATTERY LEVEL + command_extra(KC_V); + break; + case USER03: //LOCK MODE + command_extra(KC_L); + break; + case USER04 ... USER11: + rgblight_action(keycode - USER04); + break; + } + } +} \ No newline at end of file diff --git a/keyboards/ydkb/chicory/light_ws2812.c b/keyboards/ydkb/chicory/light_ws2812.c new file mode 100644 index 00000000000..739c9ed8776 --- /dev/null +++ b/keyboards/ydkb/chicory/light_ws2812.c @@ -0,0 +1,157 @@ +/* +* light weight WS2812 lib V2.0b +* +* Controls WS2811/WS2812/WS2812B RGB-LEDs +* Author: Tim (cpldcpu@gmail.com) +* +* Jan 18th, 2014 v2.0b Initial Version +* +* License: GNU GPL v2 (see License.txt) +*/ + +#include "light_ws2812.h" +#include +#include +#include + +void ws2812_setleds(struct cRGB *ledarray) +{ + ws2812_DDRREG |= _BV(ws2812_pin); // Enable DDR + ws2812_sendarray_mask((uint8_t *)(ledarray), _BV(ws2812_pin)); + //_delay_us(50); +} + + +// Timing in ns +#define w_zeropulse 350 +#define w_onepulse 900 +#define w_totalperiod 1250 + +// Fixed cycles used by the inner loop +#define w_fixedlow 2 +#define w_fixedhigh 4 +#define w_fixedtotal 8 + +// Insert NOPs to match the timing, if possible +#define w_zerocycles (((F_CPU/1000)*w_zeropulse )/1000000) +#define w_onecycles (((F_CPU/1000)*w_onepulse +500000)/1000000) +#define w_totalcycles (((F_CPU/1000)*w_totalperiod +500000)/1000000) + +// w1 - nops between rising edge and falling edge - low +#define w1 (w_zerocycles-w_fixedlow) +// w2 nops between fe low and fe high +#define w2 (w_onecycles-w_fixedhigh-w1) +// w3 nops to complete loop +#define w3 (w_totalcycles-w_fixedtotal-w1-w2) + +#if w1>0 + #define w1_nops w1 +#else + #define w1_nops 0 +#endif + +// The only critical timing parameter is the minimum pulse length of the "0" +// Warn or throw error if this timing can not be met with current F_CPU settings. +#define w_lowtime ((w1_nops+w_fixedlow)*1000000)/(F_CPU/1000) +#if w_lowtime>550 + #error "Light_ws2812: Sorry, the clock speed is too low. Did you set F_CPU correctly?" +#elif w_lowtime>450 + #warning "Light_ws2812: The timing is critical and may only work on WS2812B, not on WS2812(S)." + #warning "Please consider a higher clockspeed, if possible" +#endif + +#if w2>0 +#define w2_nops w2 +#else +#define w2_nops 0 +#endif + +#if w3>0 +#define w3_nops w3 +#else +#define w3_nops 0 +#endif + +#define w_nop1 "nop \n\t" +#define w_nop2 "rjmp .+0 \n\t" +#define w_nop4 w_nop2 w_nop2 +#define w_nop8 w_nop4 w_nop4 +#define w_nop16 w_nop8 w_nop8 + +void ws2812_sendarray_mask(uint8_t *data ,uint8_t maskhi) +{ + uint8_t curbyte,ctr,masklo; + uint8_t sreg_prev; + uint8_t datlen = RGBLED_NUM*3; + + masklo =~maskhi&ws2812_PORTREG; + maskhi |= ws2812_PORTREG; + sreg_prev=SREG; + cli(); + + while (datlen--) { + curbyte=*data++; + + asm volatile( + " ldi %0,8 \n\t" + "loop%=: \n\t" + " out %2,%3 \n\t" // '1' [01] '0' [01] - re +#if (w1_nops&1) +w_nop1 +#endif +#if (w1_nops&2) +w_nop2 +#endif +#if (w1_nops&4) +w_nop4 +#endif +#if (w1_nops&8) +w_nop8 +#endif +#if (w1_nops&16) +w_nop16 +#endif + " sbrs %1,7 \n\t" // '1' [03] '0' [02] + " out %2,%4 \n\t" // '1' [--] '0' [03] - fe-low + " lsl %1 \n\t" // '1' [04] '0' [04] +#if (w2_nops&1) + w_nop1 +#endif +#if (w2_nops&2) + w_nop2 +#endif +#if (w2_nops&4) + w_nop4 +#endif +#if (w2_nops&8) + w_nop8 +#endif +#if (w2_nops&16) + w_nop16 +#endif + " out %2,%4 \n\t" // '1' [+1] '0' [+1] - fe-high +#if (w3_nops&1) +w_nop1 +#endif +#if (w3_nops&2) +w_nop2 +#endif +#if (w3_nops&4) +w_nop4 +#endif +#if (w3_nops&8) +w_nop8 +#endif +#if (w3_nops&16) +w_nop16 +#endif + + " dec %0 \n\t" // '1' [+2] '0' [+2] + " brne loop%=\n\t" // '1' [+3] '0' [+4] + : "=&d" (ctr) + : "r" (curbyte), "I" (_SFR_IO_ADDR(ws2812_PORTREG)), "r" (maskhi), "r" (masklo) + ); + } + + SREG=sreg_prev; +} diff --git a/keyboards/ydkb/chicory/light_ws2812.h b/keyboards/ydkb/chicory/light_ws2812.h new file mode 100644 index 00000000000..08187ac90a9 --- /dev/null +++ b/keyboards/ydkb/chicory/light_ws2812.h @@ -0,0 +1,66 @@ +/* + * light weight WS2812 lib include + * + * Version 2.0a3 - Jan 18th 2014 + * Author: Tim (cpldcpu@gmail.com) + * + * Please do not change this file! All configuration is handled in "ws2812_config.h" + * + * License: GNU GPL v2 (see License.txt) + + + */ + +#ifndef LIGHT_WS2812_H_ +#define LIGHT_WS2812_H_ + +#include +#include +//#include "ws2812_config.h" + +/* + * Structure of the LED array + */ + +struct cRGB { uint8_t g; uint8_t r; uint8_t b; }; + +/* User Interface + * + * Input: + * ledarray: An array of GRB data describing the LED colors + * number_of_leds: The number of LEDs to write + * pinmask (optional): Bitmask describing the output bin. e.g. _BV(PB0) + * + * The functions will perform the following actions: + * - Set the data-out pin as output + * - Send out the LED data + * - Wait 50µs to reset the LEDs + */ + +void ws2812_setleds (struct cRGB *ledarray); +//void ws2812_setleds (struct cRGB *ledarray, uint16_t number_of_leds); +//void ws2812_setleds_pin(struct cRGB *ledarray, uint16_t number_of_leds,uint8_t pinmask); + +/* + * Old interface / Internal functions + * + * The functions take a byte-array and send to the data output as WS2812 bitstream. + * The length is the number of bytes to send - three per LED. + */ + +//void ws2812_sendarray (uint8_t *array,uint16_t length); +void ws2812_sendarray_mask(uint8_t *array, uint8_t pinmask); + + +/* + * Internal defines + */ + +#ifndef CONCAT +#define CONCAT(a, b) a ## b +#endif +#define CONCAT_EXP(a, b) CONCAT(a, b) + +// #define ws2812_PORTREG CONCAT_EXP(PORT,ws2812_port) +// #define ws2812_DDRREG CONCAT_EXP(DDR,ws2812_port) + +#endif /* LIGHT_WS2812_H_ */ diff --git a/keyboards/ydkb/chicory/matrix.c b/keyboards/ydkb/chicory/matrix.c new file mode 100644 index 00000000000..896fb3a06df --- /dev/null +++ b/keyboards/ydkb/chicory/matrix.c @@ -0,0 +1,312 @@ +/* +Copyright 2023 YANG + +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 . +*/ + +/* + * scan matrix + */ +#include +#include +#include +#include +#include "action.h" +#include "print.h" +#include "debug.h" +#include "util.h" +#include "matrix.h" +#include "debounce_pk.h" +#include "ble51.h" +#include "ble51_task.h" +#include "rgblight.h" +#include "backlight.h" +#include "timer.h" +#include "wait.h" + +bool is_ble_version = 1; +bool is_ver2 = 0; +bool no_backlight = 0; +bool no_rgblight = 0; + +extern rgblight_config_t rgblight_config; +static matrix_row_t matrix[MATRIX_ROWS] = {0}; + +static uint16_t matrix_scan_timestamp = 0; +static uint8_t matrix_debouncing[MATRIX_ROWS][MATRIX_COLS] = {0}; +static uint8_t now_debounce_dn_mask = DEBOUNCE_NK_MASK; +static bool matrix_idle = false; +static bool first_key_scan = false; +static bool is_matrix_active(void); + +static void select_row(uint8_t row); +static void select_all_rows(void); +static uint8_t get_key(uint8_t col); +static void init_cols(void); +static void unselect_rows(void); + +static void init_cols(void); +__attribute__ ((weak)) +void matrix_scan_user(void) {} + +__attribute__ ((weak)) +void matrix_scan_kb(void) { + matrix_scan_user(); + hook_keyboard_loop(); +} + +void hook_early_init(void) { + DDRD &= ~(1<<0); + PORTD |= (1<<0); + WAIT_MS(2); + if (~PIND & (1<<0)) { + is_ver2 = 1; + no_backlight = 1; + no_rgblight = 1; + } + if (pgm_read_byte(0x7ff9) == 0xB0) { + is_ble_version = 0; + ble51_boot_on = 0; + } else { + if (ble_reset_key == 0xBBAA) { + if (ble51_boot_on) { + // PD3,TX_MCU to RX_51 + DDRD |= (1<<3 ); + PORTD &= ~(1<<3); + bt_power_init(); + // Light CapsLED + DDRB |= (1<<7); + PORTB |= (1<<7); + _delay_ms(5000); + // turn off bt and ready to reinit it. + turn_off_bt(); + } + } + } +} + +void matrix_init(void) +{ + //software ble reset + if (ble_reset_key == 0xBBAA) { + ble_reset_key = 0; + ble51_factory_reset(); + } + + // led init + DDRB |= (1<<7); + PORTB &= ~(1<<7); + + init_cols(); + rgblight_init(); +} + +uint8_t matrix_scan(void) +{ + if (matrix_idle) { + if (is_matrix_active() == false) return 1; + else { + matrix_idle = false; + first_key_scan = true; + } + } + + //scan matrix every 1ms except first_key_scan. maybe not necessary for some avr kbd. + #if 1 + if (!first_key_scan) { + uint16_t time_check = timer_read(); + if (matrix_scan_timestamp == time_check) return 1; + matrix_scan_timestamp = time_check; + } + #endif + + uint8_t *debounce = &matrix_debouncing[0][0]; + uint8_t matrix_up_keys = MATRIX_ROWS * MATRIX_COLS; + for (uint8_t row=0; row> 1) | key; + + + //if ((*debounce > 0) && (*debounce < 0xff)) { + if (1) { //always update matrix[row], it costs only a little time. + matrix_row_t *p_row = &matrix[row]; + matrix_row_t col_mask = ((matrix_row_t)1 << col); + if (*debounce >= now_debounce_dn_mask) { //debounce KEY DOWN + *p_row |= col_mask; + } else if (*debounce <= DEBOUNCE_UP_MASK) { //debounce KEY UP + *p_row &= ~col_mask; + if (*debounce == 0) matrix_up_keys--; + } + } + } + + //if key pressed, update kb_idle_times + //if (matrix[row] > 0) { + // if (!rgblight_config.enable && !backlight_config.enable) kb_idle_times = 12; + // else kb_idle_times = 0; + //} + } + + // 最终检测一次是不是完全没有按键按下 + if (matrix_up_keys == 0) { + select_all_rows(); + matrix_idle = true; + } else { + if (!rgblight_config.enable) kb_idle_times = 12; + else kb_idle_times = 0; + // 从空闲到检测第一个按键时多扫一次 + if (first_key_scan) { + first_key_scan = false; + matrix_scan(); + } + //unselect_rows(); + } + + matrix_scan_quantum(); + return 1; +} + + +inline +bool matrix_is_on(uint8_t row, uint8_t col) +{ + return (matrix[row] & ((matrix_row_t)1<= 10) { + matrix_scan(); + // K14 F, K17 J + uint8_t *debounce = &matrix_debouncing[0][0]; + uint8_t matrix_keys_down = 0; + for (uint8_t i=0; i< MATRIX_ROWS * MATRIX_COLS; i++, *debounce++) { + if (*debounce > 0) { + if (i == KP(1,4) || i == KP(1,7)) matrix_keys_down += 100; + else matrix_keys_down++; + } + } + if (matrix_keys_down == 200) { // only two keys down. + if (!ble51_boot_on) command_extra(KC_W); + return true; + } else if (!ble51_boot_on && matrix_keys_down) return true; //蓝牙功能关闭时唤醒电脑 + } else { + select_all_rows(); + _delay_us(6); + return is_matrix_active(); + } + return false; +} + +void bootmagic_lite(void) +{ + //do nothing + return; + +} + + +void hook_nkro_change(void) { + //return; + uint8_t kbd_nkro = keymap_config.nkro; + if (!kbd_nkro) { // kbd_nkro before hook_nkro_change() + now_debounce_dn_mask = DEBOUNCE_NK_MASK; + } else { + now_debounce_dn_mask = DEBOUNCE_DN_MASK; + } + type_num(kbd_nkro?6:0); +} \ No newline at end of file diff --git a/keyboards/ydkb/chicory/rgblight.c b/keyboards/ydkb/chicory/rgblight.c new file mode 100644 index 00000000000..0992acaf418 --- /dev/null +++ b/keyboards/ydkb/chicory/rgblight.c @@ -0,0 +1,467 @@ +#include +#include +#include +#include "progmem.h" +#include "timer.h" +#include "action.h" +#include "rgblight.h" +#include "debug.h" +#include "lufa.h" +#include "ble51.h" +#include "ble51_task.h" +#include "backlight.h" +#include "led.h" +#include "quantum.h" + +#define rgblight_timer_init() do { DDRD |= (1<<4);} while(0) +#define rgblight_timer_enable() do { PORTD &= ~(1<<4);} while(0) +#define rgblight_timer_disable() do { PORTD |= (1<<4);} while(0) +#define rgblight_timer_enabled (~PORTD & (1<<4)) +#define RGBLED_TEMP RGBLED_NUM +const uint8_t RGBLED_BREATHING_TABLE[128] PROGMEM = {0,0,0,0,1,1,1,2,2,3,4,5,5,6,7,9,10,11,12,14,15,17,18,20,21,23,25,27,29,31,33,35,37,40,42,44,47,49,52,54,57,59,62,65,67,70,73,76,79,82,85,88,90,93,97,100,103,106,109,112,115,118,121,124,127,131,134,137,140,143,146,149,152,155,158,162,165,167,170,173,176,179,182,185,188,190,193,196,198,201,203,206,208,211,213,215,218,220,222,224,226,228,230,232,234,235,237,238,240,241,243,244,245,246,248,249,250,250,251,252,253,253,254,254,254,255,255,255}; + +//battery +extern bool no_rgblight; + +static uint8_t rgb_fading_index = 0; //使用 RGBLED_BREATHING_TABLE + +rgblight_config_t rgblight_config = {.enable = 1, .mode = 8,.hue = 640, .sat = 255, .val = 255}; + +struct cRGB led[RGBLED_NUM+1]; + + +uint16_t hue_fix(uint16_t hue) +{ + // hue needs to be 0x100 to 0x3ff + hue += 0x300; + while (hue > 0x3ff) hue -= 0x300; + return hue; +} + +void sethsv(uint16_t hue, uint8_t saturation, uint8_t brightness, struct cRGB *led1) +{ + /* + original code: https://blog.adafruit.com/2012/03/14/constant-brightness-hsb-to-rgb-algorithm/ + when calculating hue, it may below 0. + So I save hue as 0x100 to 0x3ff (256 to 1023) instead of (0 to 767). + And n changes from 0-2 to 1-3. + */ + uint8_t r, g, b; + uint8_t temp[5]; + // uint8_t n = (hue >> 8) % 3; + hue = hue_fix(hue); + uint8_t n = hue >> 8; + if (n > 3) return; // 0 would be error. just leave it. + uint8_t x = ((((hue & 255) * saturation) >> 8) * brightness) >> 8; + uint8_t s = ((256 - saturation) * brightness) >> 8; + temp[0] = temp[3] = s; + temp[1] = temp[4] = x + s; + temp[2] = brightness - x; + r = temp[n + 1]; + g = temp[n]; + b = temp[n - 1]; + setrgb(r,g,b, led1); +} + +void setrgb(uint8_t r, uint8_t g, uint8_t b, struct cRGB *led1) +{ + (*led1).r = r; + (*led1).g = g; + (*led1).b = b; +} + + +uint32_t eeconfig_read_rgblight(void) +{ + return eeprom_read_dword(EECONFIG_RGBLIGHT); +} + +void eeconfig_write_rgblight(uint32_t val) +{ + eeprom_update_dword(EECONFIG_RGBLIGHT, val); +} + +void eeconfig_write_rgblight_default(void) +{ + dprintf("eeconfig_write_rgblight_default\n"); + + eeconfig_write_rgblight(rgblight_config.raw); //rgblight_config.raw); +} + +void eeconfig_debug_rgblight(void) { + dprintf("rgblight_config eeprom\n"); + dprintf("enable = %d\n", rgblight_config.enable); + dprintf("mode = %d\n", rgblight_config.mode); + dprintf("hue = %d\n", rgblight_config.hue); + dprintf("sat = %d\n", rgblight_config.sat); + dprintf("val = %d\n", rgblight_config.val); +} + +void rgblight_init(void) +{ + dprintf("rgblight_init start!\n"); +#if 1 + if (!eeconfig_is_enabled()) { + dprintf("rgblight_init eeconfig is not enabled.\n"); + eeconfig_init(); + eeconfig_write_rgblight_default(); + } +#endif + rgblight_config.raw = eeconfig_read_rgblight(); + if (rgblight_config.val == 0) rgblight_config.val = 127; + + eeconfig_debug_rgblight(); // display current eeprom values + + rgblight_timer_init(); // setup the timer + + rgblight_mode(rgblight_config.mode); +} + + +void rgblight_mode(int8_t mode) +{ + // rgb off, new way to save about 60B + if (!rgblight_config.enable) { + //rgblight_clear(); + //rgblight_set(); + rgblight_timer_disable(); + rgb_fading_index = 0; + } else { + // rgb on + if (mode < 0) mode = RGBLIGHT_MODES - 1; + else if (mode >= RGBLIGHT_MODES) mode = 0; + rgblight_config.mode = mode; + dprintf("rgblight mode: %u\n", rgblight_config.mode); + + rgblight_timer_enable(); + } + // save config + eeconfig_write_rgblight(rgblight_config.raw); + rgblight_sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val); +} + +inline +void rgblight_toggle(void) +{ + rgblight_config.enable ^= 1; + dprintf("rgblight toggle: rgblight_config.enable = %u\n", rgblight_config.enable); + rgblight_mode(rgblight_config.mode); +} + + +void rgblight_action(uint8_t action) +{ + /* 0 toggle + 1 mode- 2 mode+ + 3 hue- 4 hue+ + 5 sat- 6 sat+ + 7 val- 8 val+ + */ + uint16_t hue = rgblight_config.hue; + int16_t sat = rgblight_config.sat; + int16_t val = rgblight_config.val; + int8_t increament = 1; + if (action & 1) increament = -1; + if (get_mods() & MOD_BIT(KC_LSHIFT)) { + increament *= -1; + } + switch (action) { + case 0: + rgblight_toggle(); + break; + case 1: + case 2: + rgblight_mode(rgblight_config.mode + increament); + break; + case 3: + case 4: + hue = rgblight_config.hue + RGBLIGHT_HUE_STEP * increament; + break; + case 5: + case 6: + sat = rgblight_config.sat + RGBLIGHT_SAT_STEP * increament; + if (sat > 255) sat = 255; + if (sat < 0) sat = 0; + break; + case 7: + case 8: + val = rgblight_config.val + RGBLIGHT_VAL_STEP * increament; + if (val > 255) val = 255; + if (val < 0) val = 0; + break; + default: + break; + } + if (action >= 3) rgblight_sethsv(hue, sat, val); +} + +void rgblight_sethsv_noeeprom(uint16_t hue, uint8_t sat, uint8_t val) +{ + if (rgblight_config.enable) { + sethsv(hue, sat, val, &led[RGBLED_TEMP]); + for (uint8_t i=0; i< RGBLED_NUM; i++) { + led[i] = led[RGBLED_TEMP]; + } + rgblight_set(); + } +} + +void rgblight_sethsv(uint16_t hue, uint8_t sat, uint8_t val) +{ + hue = hue_fix(hue); + if (rgblight_config.enable) { + if (rgblight_config.mode == 1) { + // same static color + rgblight_sethsv_noeeprom(hue, sat, val); + } + rgblight_config.hue = hue; + rgblight_config.sat = sat; + rgblight_config.val = val; + eeconfig_write_rgblight(rgblight_config.raw); + dprintf("rgblight set hsv [EEPROM]: %u,%u,%u\n", rgblight_config.hue, rgblight_config.sat, rgblight_config.val); + } +} + +void rgblight_setrgb(uint8_t r, uint8_t g, uint8_t b) +{ + for (uint8_t i=0;i= 13); + if (rgb_fading) { + if (kb_idle_times >= 13 && rgb_fading_index >= RGB_FADING_STEP) rgb_fading_index -= RGB_FADING_STEP; // fading in + else if (kb_idle_times < 13) rgb_fading_index += RGB_FADING_STEP; // fading out + // 设置底灯淡入淡出 + uint8_t *p = &led[0]; + for (uint8_t i=0;i 126) { + increament *= -1; + } +} + +void rgblight_effect_rainbow_mood(uint8_t interval) +{ + static uint16_t current_hue = 0; + rgblight_sethsv_noeeprom(current_hue, rgblight_config.sat, rgblight_config.val); + current_hue = hue_fix(current_hue + interval * 3); +} + +void rgblight_effect_rainbow_swirl(uint8_t interval) +{ + static uint16_t current_hue=0; + uint16_t hue; + uint8_t i; + uint8_t interval2 = interval/2; + if (interval & 1) interval2 *= -1; + for (i=0; i interval2) { + led_step = 0; + rgblight_clear(); + if (interval%2) increament = -1; + for (i=0; i= RGBLED_NUM) target_led -= RGBLED_NUM; + sethsv(rgblight_config.hue+i*50, rgblight_config.sat, rgblight_config.val, &led[target_led]); + //sethsv(rgblight_config.hue+i*50, rgblight_config.sat, rgblight_config.val, &led[(pos+i*increament+RGBLED_NUM)%RGBLED_NUM]); + } + pos += increament; + if (pos > RGBLED_NUM) pos = 0; + else if (pos < 0 ) pos = RGBLED_NUM; + rgblight_set(); + } +} + +void rgblight_effect_knight(uint8_t interval) +{ + static int8_t pos = RGBLED_NUM - 1; + static uint8_t sled_step = 0; + static uint16_t current_hue=0; + uint8_t i; + static int8_t increament = 1; + if (++sled_step > interval) { + bool need_update = 0; + sled_step = 0; + rgblight_clear(); + for (i=0; i= 0){ + need_update = 1; + led[target_col] = led[RGBLED_TEMP]; + } + } + if (need_update) rgblight_set(); //Keep the first or last col on when increament changes. + pos += increament; + if (pos <= 0 - RGBLIGHT_EFFECT_KNIGHT_LENGTH || pos >= RGBLED_NUM) { + increament *= -1; + current_hue = hue_fix(current_hue + 40); + sethsv(current_hue, rgblight_config.sat, rgblight_config.val, &led[RGBLED_TEMP]); + } + } +} + +void suspend_power_down_action(void) +{ + PORTB &= ~(1<<7); + backlight_user_disable(); + rgblight_timer_disable(); //RGB_VCC off + rgb_fading_index = 0; +} + +void suspend_wakeup_init_action(void) +{ + if (!low_battery) { + backlight_init(); + rgblight_init(); + } + if (BT_POWERED == 0) display_connection_status_check_times = 1; +} + +void hook_keyboard_loop() +{ + static uint16_t rgb_update_timer = 0; + if (rgblight_timer_enabled && timer_elapsed(rgb_update_timer) > 40) { + rgb_update_timer = timer_read(); + if (!display_connection_status_check_times || !ble51_boot_on) rgblight_task(); + } +} + +void ble51_task_user(void) +{ + static uint8_t ble51_task_steps = 0; + static uint16_t battery_timer = 0; + if (timer_elapsed(battery_timer) > 150) { + battery_timer = timer_read(); + ble51_task_steps++; + if (low_battery) { + if (ble51_task_steps > 3) { + ble51_task_steps = (low_battery == 1)? 3:0; //value 1 is extremely low battery + if (USB_DeviceState != DEVICE_STATE_Configured) { //not charging + backlight_disable(); + rgblight_timer_disable(); + PORTB ^= (1<<7); + } else { + low_battery = 0; + suspend_wakeup_init_action(); + } + } + } else if (display_connection_status_check_times) { + rgblight_timer_enable(); + if (ble51_task_steps == 1) { + PORTB &= ~(1<<7); + rgblight_clear(); + rgblight_set(); + } else if (ble51_task_steps == 3) { + PORTB |= (1<<7); + uint8_t g_color = bt_connected? 128:0; + uint8_t b_color = bt_connected? 0:128; + rgblight_setrgb(0,g_color,b_color); + } + if ((!bt_connected && ble51_task_steps >= 5) || ble51_task_steps >= 11) { + ble51_task_steps = 0; + } + } + } +} diff --git a/keyboards/ydkb/chicory/rgblight.h b/keyboards/ydkb/chicory/rgblight.h new file mode 100644 index 00000000000..906f9495ea0 --- /dev/null +++ b/keyboards/ydkb/chicory/rgblight.h @@ -0,0 +1,83 @@ +#ifndef RGBLIGHT_H +#define RGBLIGHT_H + +#ifndef RGBLIGHT_MODES +#define RGBLIGHT_MODES 23 +#endif + +#ifndef RGBLIGHT_EFFECT_SNAKE_LENGTH +#define RGBLIGHT_EFFECT_SNAKE_LENGTH 4 +#endif + +#ifndef RGBLIGHT_EFFECT_KNIGHT_LENGTH +#define RGBLIGHT_EFFECT_KNIGHT_LENGTH 4 +#endif +#ifndef RGBLIGHT_EFFECT_KNIGHT_OFFSET +#define RGBLIGHT_EFFECT_KNIGHT_OFFSET RGBLED_NUM +#endif + +#ifndef RGBLIGHT_EFFECT_DUALKNIGHT_LENGTH +#define RGBLIGHT_EFFECT_DUALKNIGHT_LENGTH 4 +#endif + +#ifndef RGBLIGHT_HUE_STEP +#define RGBLIGHT_HUE_STEP 20 +#endif +#ifndef RGBLIGHT_SAT_STEP +#define RGBLIGHT_SAT_STEP 17 +#endif +#ifndef RGBLIGHT_VAL_STEP +#define RGBLIGHT_VAL_STEP 17 +#endif + +#define RGBLED_TIMER_TOP F_CPU/(256*32) + +#include +#include +#include "eeconfig.h" +#include "light_ws2812.h" + +typedef union { + uint32_t raw; + struct { + uint16_t hue :10; + uint16_t enable :1; + uint16_t mode :5; + uint8_t sat :8; + uint8_t val :8; + }; +} rgblight_config_t; + +void rgblight_init(void); +void rgblight_action(uint8_t action); +void rgblight_toggle(void); +void sw_bottom_sync_toggle(void); +void rgblight_mode(int8_t mode); +void rgblight_set(void); +void rgblight_sethsv(uint16_t hue, uint8_t sat, uint8_t val); +void rgblight_setrgb(uint8_t r, uint8_t g, uint8_t b); + +uint32_t eeconfig_read_rgblight(void); +void eeconfig_write_rgblight(uint32_t val); +void eeconfig_write_rgblight_default(void); +void eeconfig_debug_rgblight(void); + +void sethsv(uint16_t hue, uint8_t sat, uint8_t val, struct cRGB *led1); +void setrgb(uint8_t r, uint8_t g, uint8_t b, struct cRGB *led1); +void rgblight_sethsv_noeeprom(uint16_t hue, uint8_t sat, uint8_t val); + +void rgblight_clear(void); +void rgblight_timer_init(void); +void rgblight_timer_enable(void); +void rgblight_timer_disable(void); +void rgblight_timer_toggle(void); +void rgblight_task(void); +void rgblight_effect_breathing(uint8_t interval); +void rgblight_effect_rainbow_mood(uint8_t interval); +void rgblight_effect_rainbow_swirl(uint8_t interval); +void rgblight_effect_snake(uint8_t interval); +void rgblight_effect_knight(uint8_t interval); + +void hook_keyboard_loop(void); + +#endif diff --git a/keyboards/ydkb/chicory/rules.mk b/keyboards/ydkb/chicory/rules.mk new file mode 100644 index 00000000000..b5c8aa01d89 --- /dev/null +++ b/keyboards/ydkb/chicory/rules.mk @@ -0,0 +1,34 @@ +# MCU name +MCU = atmega32u4 + +# Processor frequency +F_CPU = 8000000 + +# Bootloader selection +BOOTLOADER = bootloadhid +BOOTLOADER_SIZE = 2048 + +# Build Options +# change yes to no to disable +# +CUSTOM_MATRIX = yes # Custom matrix file +UNICODE_ENABLE = yes # Unicode +BOOTMAGIC_ENABLE = yes # Enable Bootmagic Lite +MOUSEKEY_ENABLE = yes # Mouse keys +EXTRAKEY_ENABLE = yes # Audio control and System control +CONSOLE_ENABLE = no # Console for debug +COMMAND_ENABLE = yes # Commands for debug and configuration +NKRO_ENABLE = yes # Enable N-Key Rollover +BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality +RGBLIGHT_ENABLE = no +LTO_ENABLE = yes +BACKLIGHT_DRIVER = custom + +# project specific files +SRC ?= matrix.c \ + led_fn.c \ + light_ws2812.c \ + backlight_user.c \ + rgblight.c + +include $(TMK_DIR)/protocol/ble51.mk diff --git a/keyboards/ydkb/00common/debounce_pk.h b/keyboards/ydkb/debounce_pk.h similarity index 100% rename from keyboards/ydkb/00common/debounce_pk.h rename to keyboards/ydkb/debounce_pk.h diff --git a/keyboards/ydkb/duang60v1/backlight_user.c b/keyboards/ydkb/duang60v1/backlight_user.c new file mode 100644 index 00000000000..ec2eacc7c1d --- /dev/null +++ b/keyboards/ydkb/duang60v1/backlight_user.c @@ -0,0 +1,52 @@ +/* +Copyright 2020 YANG + +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 . +*/ + +#include +#include +#include +#include "backlight.h" +#include "timer.h" + + +void backlight_init_ports(void) { + DDRC |= (1<<6); + //PORTC |= (1<<6); +} + +void backlight_task(void) { + return; +} + +void backlight_user_enable(void) +{ + + //DDRC |= (1<<6); + PORTC &= ~(1<<6); +} + +void backlight_user_disable(void) +{ + //DDRC &= ~(1<<6); + PORTC |= (1<<6); +} + +void backlight_set(uint8_t level) +{ + if (level) backlight_user_enable(); + else backlight_user_disable(); +} + diff --git a/keyboards/ydkb/duang60v1/config.h b/keyboards/ydkb/duang60v1/config.h index 33d36879ee5..b779c712353 100644 --- a/keyboards/ydkb/duang60v1/config.h +++ b/keyboards/ydkb/duang60v1/config.h @@ -1,11 +1,10 @@ #pragma once #include "config_common.h" +#include "config_ble51.h" /* USB Device descriptor parameter */ -#define FW_VER QMK_DMCM -#define FW_VER_VIA VIA_DMCM -#define FW_VER_VIAL VIAL_DMCM +#define FW_VER_DATE DO6A #define VENDOR_ID 0x9D5B #define PRODUCT_ID 0x2060 #define DEVICE_VER 0x0001 @@ -13,90 +12,34 @@ #define PRODUCT Duang60v1 (FW_VER) +/* matrix size */ #define MATRIX_ROWS 5 //595 #define MATRIX_COLS 16 - -#define TAPPING_TOGGLE 2 - -#define TAPPING_TERM 200 -#define IGNORE_MOD_TAP_INTERRUPT // this makes it possible to do rolling combos (zx) with keys that convert to other keys on hold (z becomes ctrl when you hold it, and when this option isn't enabled, z rapidly followed by x actually sends Ctrl-x. That's bad.) - #define BACKLIGHT_PIN C6 -#define BACKLIGHT_LEVELS 6 +#define BACKLIGHT_LEVELS 1 #define BACKLIGHT_ON_STATE 0 -/* key combination for command */ -#define IS_COMMAND() ( \ - (get_mods() == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT))) || \ - (get_mods() == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_LCTRL) | MOD_BIT(KC_RSHIFT))) \ -) - #define ws2812_PORTREG PORTD #define ws2812_DDRREG DDRD #define ws2812_pin PD0 #define RGBLED_NUM 4 // Number of LEDs +#define RGBLIGHT_MODES 14 //less rgblight mode to save some space for vial -/* disable command for default layer */ -#define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS 0 -#define MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS 0 - -/* fix space cadet rollover issue */ -#define DISABLE_SPACE_CADET_ROLLOVER - -#if defined(__AVR_ATmega32U4__) || defined(__AVR_AT90USB1286__) - #define UCSR1D _SFR_MEM8(0xCB) - #define RTSEN 0 - #define CTSEN 1 - - #define SERIAL_UART_BAUD 76800 - #define SERIAL_UART_DATA UDR1 - #define SERIAL_UART_UBRR ((F_CPU/(8.0*SERIAL_UART_BAUD)-1+0.5)) - #define SERIAL_UART_RXD_VECT USART1_RX_vect - #define SERIAL_UART_TXD_READY (UCSR1A&(1<>8); \ - UCSR1B |= (1<. #include "rgblight.h" -void led_set_user(uint8_t usb_led) -{ - if (usb_led & (1<event.pressed) { - switch (keycode) { - case USER00: - command_extra(KC_U); - break; - case USER01: //RESET - command_extra(KC_B); - break; - case USER02: //BATTERY LEVEL - command_extra(KC_V); - break; - case USER03: //LOCK MODE - command_extra(KC_L); - break; - case USER04 ... USER12: - rgblight_action(keycode - USER04); - break; + static const uint8_t userx_to_command[4] = { + KC_U, // 0 Host Switch + KC_B, // 1 Reset + KC_V, // 2 Output Battery Value + KC_L // 3 Lock Mode + }; + if (keycode >= USER00) { + if (keycode < USER04) command_extra(userx_to_command[keycode-USER00]); + else if (keycode <= USER12) rgblight_action(keycode - USER04); } } } \ No newline at end of file diff --git a/keyboards/ydkb/duang60v1/matrix.c b/keyboards/ydkb/duang60v1/matrix.c index d63e54ce2f3..90147555c4f 100644 --- a/keyboards/ydkb/duang60v1/matrix.c +++ b/keyboards/ydkb/duang60v1/matrix.c @@ -1,3 +1,23 @@ +/* +Copyright 2023 YANG + +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 . +*/ + +/* + * scan matrix + */ #include #include #include @@ -13,6 +33,7 @@ #include "keyboard.h" #include "timer.h" #include "matrix.h" +#include "debounce_pk.h" #include "suspend.h" #include "lufa.h" #include "rgblight.h" @@ -20,18 +41,14 @@ #include "ble51_task.h" #include "switch_board.h" -#define DEBOUNCE_DN_MASK (uint8_t)(~(0x80 >> 5)) -#define DEBOUNCE_UP_MASK (uint8_t)(0x80 >> 5) - -bool is_ble_version = 1; -extern rgblight_config_t rgblight_config; static matrix_row_t matrix[MATRIX_ROWS] = {0}; static uint8_t matrix_current_row = 0; static uint16_t matrix_scan_timestamp = 0; static uint8_t matrix_debouncing[MATRIX_ROWS][MATRIX_COLS] = {0}; +static uint8_t now_debounce_dn_mask = DEBOUNCE_NK_MASK; static uint8_t encoder_state_prev[2][2] = {0}; static void select_key(uint8_t mode); static uint8_t get_key(uint8_t col); @@ -46,51 +63,39 @@ void matrix_scan_kb(void) { hook_keyboard_loop(); } -inline -uint8_t matrix_rows(void) -{ - return MATRIX_ROWS; -} - -inline -uint8_t matrix_cols(void) -{ - return MATRIX_COLS; -} void hook_early_init() { - if (pgm_read_byte(0x7e65) == 0x4c) { - // USB Only version - is_ble_version = 0; + // PE6 for BLE Reset, PE2 for BT_SW + DDRE = 0; + PORTE |= (1<<2); + WAIT_MS(6); + + if ( (pgm_read_byte(0x7e65) == 0x4c) || (~PINE & (1<<2)) ) { + // USB Only version or BTSW_OFF ble51_boot_on = 0; } else { - // PE6 for BLE Reset, PE2 for BT_SW - DDRE &= ~(1<<6 | 1<<2); - PORTE |= (1<<6 | 1<<2); - _delay_ms(2); - if (~PINE & (1<<2)) ble51_boot_on = 0; //BLE Reset if (ble_reset_key == 0xBBAA) { - if (ble51_boot_on) { - // PE6 for BLE Reset - DDRE |= (1<<6); - PORTE &= ~(1<<6); - bt_power_init(); - // light CapsLED - DDRD |= (1<<4); - PORTD |= (1<<4); - _delay_ms(5000); - bootloader_jump(); - } + ble_reset_key = 0; + // PE6 for BLE Reset + DDRE |= (1<<6); + PORTE &= ~(1<<6); + bt_power_init(); + // light CapsLED + DDRD |= (1<<4); + PORTD |= (1<<4); + _delay_ms(5000); + bootloader_jump(); } } } void matrix_init(void) { + // led init DDRD |= (1<<4); - PORTD &= ~(1<<4); + //PORTD &= ~(1<<4); init_cols(); rgblight_init(); } @@ -98,15 +103,16 @@ void matrix_init(void) uint8_t matrix_scan(void) { - uint16_t time_check = timer_read(); - if (matrix_scan_timestamp == time_check) return 1; - matrix_scan_timestamp = time_check; + //uint16_t time_check = timer_read(); + //if (matrix_scan_timestamp == time_check) return 1; + //matrix_scan_timestamp = time_check; + uint8_t matrix_keys_down = 0; select_key(0); uint8_t *debounce = &matrix_debouncing[0][0]; - for (uint8_t row=0; row> 1) | key; if (real_col >= 8) select_key(1); - + //if ((*debounce > 0) && (*debounce < 255)) { if (1) { matrix_row_t *p_row = &matrix[row]; matrix_row_t col_mask = ((matrix_row_t)1 << real_col); - if (*debounce >= DEBOUNCE_DN_MASK) { + if (*debounce >= DEBOUNCE_DN_MASK) { //debounce KEY DOWN *p_row |= col_mask; - } else if (*debounce <= DEBOUNCE_UP_MASK) { + } else if (*debounce <= DEBOUNCE_UP_MASK) { //debounce KEY UP *p_row &= ~col_mask; } - } - } - if (matrix[row] > 0) { - if (!rgblight_config.enable) kb_idle_times = 12; - else kb_idle_times = 0; + } + if (*debounce) matrix_keys_down++; } } - + + if (matrix_keys_down) { + if (BLE_LIGHT_ON == 0) kb_idle_times = 12; + else kb_idle_times = 0; + } + matrix_scan_quantum(); - return 1; + return matrix_keys_down; } @@ -151,10 +159,10 @@ matrix_row_t matrix_get_row(uint8_t row) void matrix_print(void) { - print("\nr/c 01234567\n"); + print("\nr/c 0123456789ABCDEF\n"); for (uint8_t row = 0; row < MATRIX_ROWS; row++) { print_hex8(row); print(": "); - print_bin_reverse8(matrix_get_row(row)); + print_bin_reverse16(matrix_get_row(row)); print("\n"); } } @@ -172,7 +180,7 @@ void init_cols(void) { //595 pin DDRB |= (1<= 10) { //lock mode - matrix_scan(); - // Left21 F, Right22 J. KP(2,2) KP(2,5) - uint8_t *debounce = &matrix_debouncing[0][0]; - uint8_t matrix_keys_down = 0; - for (uint8_t i=0; i< MATRIX_ROWS * MATRIX_COLS; i++, *debounce++) { - if (*debounce > 0) { - if (i == KP(2,2) || i == KP(2,5)) matrix_keys_down += 100; - else matrix_keys_down++; - } - } - if (matrix_keys_down == 200) { - return true; - } - } else { - //check encoder - DS_PL_LO(); - for (uint8_t i = 0; i < 2; i++) { - for (uint8_t j = 0; j < 8; j++) { - CLOCK_PULSE(); - DS_PL_HI(); - } - _delay_us(6); - uint8_t encoder_state_0 = PINF&(1<= 10) {//lock mode + if (matrix_keys_down == 2) { + // Left21 F, Right22 J. KP(2,2) KP(2,5) + if (matrix_debouncing[2][2] == 0xff && matrix_debouncing[2][5] == 0xff) return true; } + if (!ble51_boot_on) return true; //蓝牙功能关闭时唤醒电脑 + return false; } - return false; + + return matrix_keys_down; +} + +void bootmagic_lite(void) +{ + //do nothing + return; + } + +void hook_nkro_change(void) +{ + return; + uint8_t kbd_nkro = keymap_config.nkro; + type_num(kbd_nkro?6:0); +} \ No newline at end of file diff --git a/keyboards/ydkb/duang60v1/pre_compile_via/ydkb_duang60v1_via.zip b/keyboards/ydkb/duang60v1/pre_compile_via/ydkb_duang60v1_via.zip deleted file mode 100644 index e382408f30caa41d8abd3d2da464fd0bb2573156..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18328 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 diff --git a/keyboards/ydkb/duang60v1/rgblight.c b/keyboards/ydkb/duang60v1/rgblight.c index 061337719a8..76b6e6859b3 100644 --- a/keyboards/ydkb/duang60v1/rgblight.c +++ b/keyboards/ydkb/duang60v1/rgblight.c @@ -9,7 +9,6 @@ #include "lufa.h" #include "ble51.h" #include "ble51_task.h" -#include "backlight.h" #include "led.h" #include "quantum.h" @@ -17,37 +16,79 @@ #define rgblight_timer_enable() do { PORTD &= ~(1<<1);} while(0) #define rgblight_timer_disable() do { PORTD |= (1<<1);} while(0) #define rgblight_timer_enabled (~PORTD & (1<<1)) + #define RGBLED_TEMP RGBLED_NUM +#define INDICATOR_NUM 0 +struct cRGB rgbled[RGBLED_NUM+INDICATOR_NUM+1]; +struct cRGB *led = &rgbled[INDICATOR_NUM]; + //const uint8_t RGBLED_BREATHING_TABLE[128] PROGMEM= {0,0,0,0,1,1,1,2,2,3,4,5,5,6,7,9,10,11,12,14,15,17,18,20,21,23,25,27,29,31,33,35,37,40,42,44,47,49,52,54,57,59,62,65,67,70,73,76,79,82,85,88,90,93,97,100,103,106,109,112,115,118,121,124,127,131,134,137,140,143,146,149,152,155,158,162,165,167,170,173,176,179,182,185,188,190,193,196,198,201,203,206,208,211,213,215,218,220,222,224,226,228,230,232,234,235,237,238,240,241,243,244,245,246,248,249,250,250,251,252,253,253,254,254,254,255,255,255}; const uint8_t RGBLED_BREATHING_TABLE[64] PROGMEM= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 3, 4, 5, 6, 8, 10, 12, 15, 17, 20, 24, 28, 32, 36, 41, 46, 51, 57, 63, 70, 76, 83, 91, 98, 106, 113, 121, 129, 138, 146, 154, 162, 170, 178, 185, 193, 200, 207, 213, 220, 225, 231, 235, 240, 244, 247, 250, 252, 253, 254, 255}; -//battery -extern bool no_rgblight; -extern bool is_ble_version; - rgblight_config_t rgblight_config = {.enable = 1, .mode = 8,.hue = 640, .sat = 255, .val = 255}; -struct cRGB led[RGBLED_NUM+1]; +void sethsv(uint8_t hue, uint8_t saturation, uint8_t brightness, struct cRGB *led1) +{ + /* + original code: https://blog.adafruit.com/2012/03/14/constant-brightness-hsb-to-rgb-algorithm/ + use 8bit hue, hue16 = hue*3 to reach 0 to 767. + */ + uint8_t r, g, b; + uint8_t temp[5]; + uint16_t hue16 = hue*3; + uint8_t n = hue16 >> 8; + uint8_t x = ((((hue16 & 255) * saturation) >> 8) * brightness) >> 8; + uint8_t s = ((256 - saturation) * brightness) >> 8; + + //temp[n] g r b as struct cRGB of ws2812. save 18B + temp[0] = temp[3] = x + s; + temp[1] = temp[4] = brightness - x; + temp[2] = s; + memcpy(led1, &temp[n], 3); +} + +#if 0 // my old code. the new way use 8bit hue saves about 134B +uint16_t hue_fix(uint16_t hue) +{ + // hue needs to be 0x100 to 0x3ff + hue += 0x300; + while (hue > 0x3ff) hue -= 0x300; + return hue; +} void sethsv(uint16_t hue, uint8_t saturation, uint8_t brightness, struct cRGB *led1) { /* original code: https://blog.adafruit.com/2012/03/14/constant-brightness-hsb-to-rgb-algorithm/ + when calculating hue, it may below 0. + So I save hue as 0x100 to 0x3ff (256 to 1023) instead of (0 to 767). + And n changes from 0-2 to 1-3. */ uint8_t r, g, b; uint8_t temp[5]; - uint8_t n = (hue >> 8) % 3; + // uint8_t n = (hue >> 8) % 3; + hue = hue_fix(hue); + uint8_t n = hue >> 8; + if (n > 3) return; // 0 would be error. just leave it. uint8_t x = ((((hue & 255) * saturation) >> 8) * brightness) >> 8; uint8_t s = ((256 - saturation) * brightness) >> 8; +#if 0 //temp[n-1] b g r temp[0] = temp[3] = s; temp[1] = temp[4] = x + s; temp[2] = brightness - x; - r = temp[n + 2]; - g = temp[n + 1]; - b = temp[n]; + r = temp[n + 1]; + g = temp[n]; + b = temp[n - 1]; setrgb(r,g,b, led1); +#else //temp[n-1] g r b as struct cRGB of ws2812. save 18B + temp[0] = temp[3] = x + s; + temp[1] = temp[4] = brightness - x; + temp[2] = s; + memcpy(led1, &temp[n-1], 3); +#endif } +#endif void setrgb(uint8_t r, uint8_t g, uint8_t b, struct cRGB *led1) { @@ -86,7 +127,7 @@ void eeconfig_debug_rgblight(void) { void rgblight_init(void) { dprintf("rgblight_init start!\n"); -#if 0 +#if 1 if (!eeconfig_is_enabled()) { dprintf("rgblight_init eeconfig is not enabled.\n"); eeconfig_init(); @@ -103,25 +144,33 @@ void rgblight_init(void) rgblight_mode(rgblight_config.mode); } +uint8_t limit_value_0to255(int16_t value) { + if (value > 255) return 255; + else if (value < 0) return 0; + else return value; +} void rgblight_mode(int8_t mode) { - // rgb off + // rgb off, new way to save about 60B if (!rgblight_config.enable) { //rgblight_clear(); //rgblight_set(); rgblight_timer_disable(); } else { // rgb on + #if 1 //less than 0 can always be 0. save 8B if (mode < 0) mode = RGBLIGHT_MODES - 1; - else if (mode >= RGBLIGHT_MODES) mode = 0; + else + #endif + if (mode >= RGBLIGHT_MODES) mode = 0; rgblight_config.mode = mode; dprintf("rgblight mode: %u\n", rgblight_config.mode); rgblight_timer_enable(); } - // save config - eeconfig_write_rgblight(rgblight_config.raw); + // save config. rgblight_sethsv() will save config. + //eeconfig_write_rgblight(rgblight_config.raw); rgblight_sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val); } @@ -142,9 +191,9 @@ void rgblight_action(uint8_t action) 5 sat- 6 sat+ 7 val- 8 val+ */ - uint16_t hue = rgblight_config.hue; - int16_t sat = rgblight_config.sat; - int16_t val = rgblight_config.val; + uint8_t hue = rgblight_config.hue; + uint8_t sat = rgblight_config.sat; + uint8_t val = rgblight_config.val; int8_t increament = 1; if (action & 1) increament = -1; if (get_mods() & MOD_BIT(KC_LSHIFT)) { @@ -160,19 +209,15 @@ void rgblight_action(uint8_t action) break; case 3: case 4: - hue = (rgblight_config.hue + 768 + RGBLIGHT_HUE_STEP * increament) % 768; + hue = rgblight_config.hue + RGBLIGHT_HUE_STEP * increament; break; case 5: case 6: - sat = rgblight_config.sat + RGBLIGHT_SAT_STEP * increament; - if (sat > 255) sat = 255; - if (sat < 0) sat = 0; + sat = limit_value_0to255(rgblight_config.sat + RGBLIGHT_SAT_STEP * increament); break; case 7: case 8: - val = rgblight_config.val + RGBLIGHT_VAL_STEP * increament; - if (val > 255) val = 255; - if (val < 0) val = 0; + val = limit_value_0to255(rgblight_config.val + RGBLIGHT_VAL_STEP * increament); break; default: break; @@ -180,58 +225,62 @@ void rgblight_action(uint8_t action) if (action >= 3) rgblight_sethsv(hue, sat, val); } -void rgblight_sethsv_noeeprom(uint16_t hue, uint8_t sat, uint8_t val) +void rgblight_sethsv_noeeprom(uint8_t hue, uint8_t sat, uint8_t val) { if (rgblight_config.enable) { sethsv(hue, sat, val, &led[RGBLED_TEMP]); for (uint8_t i=0; i< RGBLED_NUM; i++) { led[i] = led[RGBLED_TEMP]; } - rgblight_set(); + //rgblight_set(); } } -void rgblight_sethsv(uint16_t hue, uint8_t sat, uint8_t val) +void rgblight_sethsv(uint8_t hue, uint8_t sat, uint8_t val) { + //hue = hue_fix(hue); if (rgblight_config.enable) { + #if 0 // will do rgblight_sethsv_noeeprom() in rgblight_task if (rgblight_config.mode == 1) { // same static color rgblight_sethsv_noeeprom(hue, sat, val); } + #endif rgblight_config.hue = hue; rgblight_config.sat = sat; rgblight_config.val = val; - eeconfig_write_rgblight(rgblight_config.raw); dprintf("rgblight set hsv [EEPROM]: %u,%u,%u\n", rgblight_config.hue, rgblight_config.sat, rgblight_config.val); } + // when rgblight_config.enable == 0, just save config.raw. + eeconfig_write_rgblight(rgblight_config.raw); } void rgblight_setrgb(uint8_t r, uint8_t g, uint8_t b) { - for (uint8_t i=0;i 15 case 15 ... 20: - rgblight_effect_snake(rgblight_config.mode-13); + rgblight_effect_snake(rgblight_config.mode-14); // 0 to 5 (0 to 2) break; #endif #if RGBLIGHT_MODES > 21 @@ -257,6 +306,7 @@ void rgblight_task(void) break; #endif } + rgblight_set(); } else { rgblight_timer_disable(); } @@ -276,29 +326,24 @@ void rgblight_effect_breathing(uint8_t interval) } } +static uint8_t current_hue = 0; + void rgblight_effect_rainbow_mood(uint8_t interval) { - static uint16_t current_hue = 0; rgblight_sethsv_noeeprom(current_hue, rgblight_config.sat, rgblight_config.val); - current_hue = (current_hue + interval * 3) % 768; + current_hue += interval; } void rgblight_effect_rainbow_swirl(uint8_t interval) { - static uint16_t current_hue=0; - uint16_t hue; - uint8_t i; - uint8_t interval2 = interval/2; - for (i=0; i 15 @@ -314,12 +359,15 @@ void rgblight_effect_snake(uint8_t interval) rgblight_clear(); if (interval%2) increament = -1; for (i=0; i= RGBLED_NUM) target_led -= RGBLED_NUM; + sethsv(rgblight_config.hue+i*16, rgblight_config.sat, rgblight_config.val, &led[target_led]); } pos += increament; if (pos > RGBLED_NUM) pos = 0; else if (pos < 0 ) pos = RGBLED_NUM; - rgblight_set(); + //rgblight_set(); } } #endif @@ -329,7 +377,6 @@ void rgblight_effect_knight(uint8_t interval) { static int8_t pos = RGBLED_NUM - 1; static uint8_t sled_step = 0; - static uint16_t current_hue=0; uint8_t i; static int8_t increament = 1; if (++sled_step > interval) { @@ -337,17 +384,17 @@ void rgblight_effect_knight(uint8_t interval) sled_step = 0; rgblight_clear(); for (i=0; i= 0){ + int8_t target_col = pos+i; + if (target_col < RGBLED_NUM && target_col >= 0){ need_update = 1; - uint8_t tmp_col = pos+i; - led[tmp_col%RGBLED_NUM] = led[RGBLED_TEMP]; + led[target_col] = led[RGBLED_TEMP]; } } if (need_update) rgblight_set(); //Keep the first or last col on when increament changes. pos += increament; if (pos <= 0 - RGBLIGHT_EFFECT_KNIGHT_LENGTH || pos >= RGBLED_NUM) { increament *= -1; - current_hue = (current_hue + 40) % 768; + current_hue = current_hue + 16; sethsv(current_hue, rgblight_config.sat, rgblight_config.val, &led[RGBLED_TEMP]); } } @@ -358,7 +405,6 @@ void suspend_power_down_action(void) { PORTD &= ~(1<<4); DDRC &= ~(1<<6); //backlight_disable(); - rgblight_timer_disable(); //RGB_VCC off } @@ -366,52 +412,51 @@ void suspend_wakeup_init_action(void) { rgblight_init(); DDRC |= (1<<6); - if (BLE51_PowerState >= 4) display_connection_status_check_times = 1; } void hook_keyboard_loop() { + if (BLE51_PowerState > 1) return; static uint16_t rgb_update_timer = 0; - if (rgblight_timer_enabled && timer_elapsed(rgb_update_timer) > 40) { + static uint8_t steps = 0; + if (timer_elapsed(rgb_update_timer) > 40) { rgb_update_timer = timer_read(); - if (!display_connection_status_check_times || !ble51_boot_on) rgblight_task(); - } -} + if (!display_connection_status_check_times) rgblight_task(); -void ble51_task_user(void) -{ - static uint8_t ble51_task_steps = 0; - static uint16_t battery_timer = 0; - if (timer_elapsed(battery_timer) > 150) { - battery_timer = timer_read(); - ble51_task_steps++; - if (low_battery) { - if (ble51_task_steps > 3) { - ble51_task_steps = (low_battery == 1)? 3:0; //value 1 is extremely low battery - if (PINC & (1<<6)) { //not charging - backlight_disable(); - rgblight_timer_disable(); - PORTB ^= (1<<6); + if ((steps++ & 0b11)) return; + //led_status_task(); + // run every 4*40 = 160ms + PORTD &= ~(1<<4); //led off + if (ble51_boot_on && (low_battery || display_connection_status_check_times)) { + rgblight_timer_enable(); + rgblight_clear(); + // 320ms on,320ms off. bt connected: 320ms*3 on, 320ms off. + if (low_battery) { + rgblight_timer_disable(); + if (steps & 0b1000) PORTD |= (1<<4); + } else { + if (bt_connected) { + if (steps & 0b11000) { + PORTD |= (1<<4); + rgblight_setrgb(0,128,0); //green + } } else { - low_battery = 0; - suspend_wakeup_init_action(); + if (steps & 0b1000) { + PORTD |= (1<<4); + rgblight_setrgb(0,0,128); //blue + } } } - } else if (display_connection_status_check_times) { - rgblight_timer_enable(); - if (ble51_task_steps == 1) { - PORTD &= ~(1<<4); - rgblight_clear(); - rgblight_set(); - } else if (ble51_task_steps == 3) { - PORTD |= (1<<4); - uint8_t g_color = bt_connected? 128:0; - uint8_t b_color = bt_connected? 0:128; - rgblight_setrgb(0,g_color,b_color); - } - if ((!bt_connected && ble51_task_steps >= 5) || ble51_task_steps >= 11) { - ble51_task_steps = 0; - } + ws2812_setleds(rgbled); + } + // capslock + else if (host_keyboard_leds() & (1<. #include "rgblight.h" -void led_set_user(uint8_t usb_led) -{ - if (usb_led & (1<event.pressed) { - switch (keycode) { - case USER00: - command_extra(KC_U); - break; - case USER01: //RESET - command_extra(KC_B); - break; - case USER02: //BATTERY LEVEL - command_extra(KC_V); - break; - case USER03: //LOCK MODE - command_extra(KC_L); - break; - case USER04 ... USER12: - rgblight_action(keycode - USER04); - break; + static const uint8_t userx_to_command[4] = { + KC_U, // 0 Host Switch + KC_B, // 1 Reset + KC_V, // 2 Output Battery Value + KC_L // 3 Lock Mode + }; + if (keycode >= USER00) { + if (keycode < USER04) command_extra(userx_to_command[keycode-USER00]); + else if (keycode <= USER12) rgblight_action(keycode - USER04); } } } \ No newline at end of file diff --git a/keyboards/ydkb/duang60v2/matrix.c b/keyboards/ydkb/duang60v2/matrix.c index 3b7071f7bf7..0e98698a3cd 100644 --- a/keyboards/ydkb/duang60v2/matrix.c +++ b/keyboards/ydkb/duang60v2/matrix.c @@ -1,18 +1,34 @@ +/* +Copyright 2023 YANG + +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 . +*/ + +/* + * scan matrix + */ #include #include -#include -#include #include #include -#include "avr_config.h" #include "print.h" #include "debug.h" #include "util.h" -#include "action.h" #include "command.h" -#include "keyboard.h" #include "timer.h" #include "matrix.h" +#include "debounce_pk.h" #include "suspend.h" #include "lufa.h" #include "rgblight.h" @@ -20,17 +36,12 @@ #include "ble51_task.h" #include "switch_board.h" -#define DEBOUNCE_DN_MASK (uint8_t)(~(0x80 >> 5)) -#define DEBOUNCE_UP_MASK (uint8_t)(0x80 >> 5) - -bool is_ble_version = 1; -bool no_rgblight; -extern rgblight_config_t rgblight_config; static matrix_row_t matrix[MATRIX_ROWS] = {0}; static uint16_t matrix_scan_timestamp = 0; static uint8_t matrix_debouncing[MATRIX_ROWS][MATRIX_COLS] = {0}; +static uint8_t now_debounce_dn_mask = DEBOUNCE_NK_MASK; static void select_key(uint8_t mode); static uint8_t get_key(void); @@ -44,29 +55,19 @@ void matrix_scan_kb(void) { hook_keyboard_loop(); } -inline -uint8_t matrix_rows(void) -{ - return MATRIX_ROWS; -} - -inline -uint8_t matrix_cols(void) -{ - return MATRIX_COLS; -} +extern bool no_rgblight; void hook_early_init() { // rama kara version has no rgblight. PF0 - DDRF &= ~(1<<0); - PORTF |= (1<<0); - _delay_ms(2); - if (~PINF & (1<<0)) no_rgblight = 1; + // fly60 has no rgblight and bt-sw low on. PF1 + DDRF &= ~(1<<1 | 1<<0); + PORTF |= (1<<1 | 1<<0); + WAIT_MS(2); + if (~PINF & (1<<1 | 1<<0)) no_rgblight = 1; if (pgm_read_byte(0x7ea4) == 0x91) { // USB Only version - is_ble_version = 0; ble51_boot_on = 0; } else { // PD4 for BLE Reset, PF7 for BT_SW @@ -74,15 +75,20 @@ void hook_early_init() PORTD |= (1<<4); DDRF &= ~(1<<7); PORTF |= (1<<7); - _delay_ms(2); - if (~PINF & (1<<7)) ble51_boot_on = 0; + WAIT_MS(2); + //从硬件开关判断蓝牙状态 + if (~PINF & (1<<1)) { // fly60 low-on + if (PINF & (1<<7)) ble51_boot_on = 0; + } else { + if (~PINF & (1<<7)) ble51_boot_on = 0; + } //BLE Reset if (ble_reset_key == 0xBBAA) { ble_reset_key = 0; if (ble51_boot_on) { - // PE6 for BLE Reset - DDRD |= (1<<4); - PORTD &= ~(1<<4); + // PE6 for BLE Reset, PD3 TX + DDRD |= (1<<4 | 1<<3); + PORTD &= ~(1<<4 | 1<<3); bt_power_init(); // light CapsLED DDRB |= (1<<6); @@ -96,8 +102,9 @@ void hook_early_init() void matrix_init(void) { + // led init DDRB |= (1<<6); - PORTB &= ~(1<<6); + //PORTB &= ~(1<<6); init_cols(); rgblight_init(); } @@ -108,33 +115,36 @@ uint8_t matrix_scan(void) uint16_t time_check = timer_read(); if (matrix_scan_timestamp == time_check) return 1; matrix_scan_timestamp = time_check; + uint8_t matrix_keys_down = 0; select_key(0); uint8_t *debounce = &matrix_debouncing[0][0]; - for (uint8_t row=0; row> 1) | key; - + //select next key select_key(1); - if ((*debounce > 0) && (*debounce < 255)) { + if (1) { matrix_row_t *p_row = &matrix[row]; matrix_row_t col_mask = ((matrix_row_t)1 << col); - if (*debounce >= DEBOUNCE_DN_MASK) { + if (*debounce >= DEBOUNCE_DN_MASK) { //debounce KEY DOWN *p_row |= col_mask; - } else if (*debounce <= DEBOUNCE_UP_MASK) { + } else if (*debounce <= DEBOUNCE_UP_MASK) { //debounce KEY UP *p_row &= ~col_mask; } - } - } - if (matrix[row] > 0) { - if (!rgblight_config.enable) kb_idle_times = 12; - else kb_idle_times = 0; + } + if (*debounce) matrix_keys_down++; } } - + + if (matrix_keys_down) { + if (BLE_LIGHT_ON == 0) kb_idle_times = 12; + else kb_idle_times = 0; + } + matrix_scan_quantum(); - return 1; + return matrix_keys_down; } @@ -164,7 +174,7 @@ uint8_t matrix_key_count(void) { uint8_t count = 0; for (uint8_t i = 0; i < MATRIX_ROWS; i++) { - count += bitpop16(matrix[i]); + count += bitpop8(matrix[i]); } return count; } @@ -178,11 +188,19 @@ void init_cols(void) } -static uint8_t get_key(void) { +static uint8_t get_key(void) +{ return PINB&(1<<2) ? 0 : 0x80; } +void select_all_keys(void) +{ + DS_PL_LO(); + for (uint8_t i = 0; i < MATRIX_ROWS * MATRIX_COLS; i++) { + CLOCK_PULSE(); + } +} void unselect_rows(void) { @@ -207,7 +225,7 @@ static void select_key(uint8_t mode) bool suspend_wakeup_condition(void) { - if (BLE51_PowerState >= 10) { //lock mode + if (BLE51_PowerState>= 10) { //lock mode matrix_scan(); // K24 F, K61 J uint8_t *debounce = &matrix_debouncing[0][0]; @@ -223,10 +241,7 @@ bool suspend_wakeup_condition(void) } } else { //check all keys - DS_PL_LO(); - for (uint8_t i = 0; i < MATRIX_ROWS * MATRIX_COLS; i++) { - CLOCK_PULSE(); - } + select_all_keys(); _delay_us(5); if (get_key()) { // return true; @@ -234,3 +249,17 @@ bool suspend_wakeup_condition(void) } return false; } + +void bootmagic_lite(void) +{ + //do nothing + return; + +} + +void hook_nkro_change(void) +{ + return; + uint8_t kbd_nkro = keymap_config.nkro; + type_num(kbd_nkro?6:0); +} diff --git a/keyboards/ydkb/duang60v2/pre_compile_via/ydkb_duang60v2_via.zip b/keyboards/ydkb/duang60v2/pre_compile_via/ydkb_duang60v2_via.zip deleted file mode 100644 index 22ea5fef5bd864f43c717835e1b7d3aebcd363e9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18429 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 diff --git a/keyboards/ydkb/duang60v2/rgblight.c b/keyboards/ydkb/duang60v2/rgblight.c index e400911abff..49857c690e1 100644 --- a/keyboards/ydkb/duang60v2/rgblight.c +++ b/keyboards/ydkb/duang60v2/rgblight.c @@ -16,34 +16,51 @@ #define rgblight_timer_enable() do { PORTC &= ~(1<<7);} while(0) #define rgblight_timer_disable() do { PORTC |= (1<<7);} while(0) #define rgblight_timer_enabled (~PORTC & (1<<7)) + #define RGBLED_TEMP RGBLED_NUM -const uint8_t RGBLED_BREATHING_TABLE[128] PROGMEM = {0,0,0,0,1,1,1,2,2,3,4,5,5,6,7,9,10,11,12,14,15,17,18,20,21,23,25,27,29,31,33,35,37,40,42,44,47,49,52,54,57,59,62,65,67,70,73,76,79,82,85,88,90,93,97,100,103,106,109,112,115,118,121,124,127,131,134,137,140,143,146,149,152,155,158,162,165,167,170,173,176,179,182,185,188,190,193,196,198,201,203,206,208,211,213,215,218,220,222,224,226,228,230,232,234,235,237,238,240,241,243,244,245,246,248,249,250,250,251,252,253,253,254,254,254,255,255,255}; +#define INDICATOR_NUM 0 +struct cRGB rgbled[RGBLED_NUM+INDICATOR_NUM+1]; +struct cRGB *led = &rgbled[INDICATOR_NUM]; + +//const uint8_t RGBLED_BREATHING_TABLE[128] PROGMEM= {0,0,0,0,1,1,1,2,2,3,4,5,5,6,7,9,10,11,12,14,15,17,18,20,21,23,25,27,29,31,33,35,37,40,42,44,47,49,52,54,57,59,62,65,67,70,73,76,79,82,85,88,90,93,97,100,103,106,109,112,115,118,121,124,127,131,134,137,140,143,146,149,152,155,158,162,165,167,170,173,176,179,182,185,188,190,193,196,198,201,203,206,208,211,213,215,218,220,222,224,226,228,230,232,234,235,237,238,240,241,243,244,245,246,248,249,250,250,251,252,253,253,254,254,254,255,255,255}; +const uint8_t RGBLED_BREATHING_TABLE[64] PROGMEM= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 3, 4, 5, 6, 8, 10, 12, 15, 17, 20, 24, 28, 32, 36, 41, 46, 51, 57, 63, 70, 76, 83, 91, 98, 106, 113, 121, 129, 138, 146, 154, 162, 170, 178, 185, 193, 200, 207, 213, 220, 225, 231, 235, 240, 244, 247, 250, 252, 253, 254, 255}; -//battery -extern bool no_rgblight; -extern bool is_ble_version; +static uint8_t rgb_fading_index = 0; //使用 RGBLED_BREATHING_TABLE -rgblight_config_t rgblight_config = {.enable = 1, .mode = 8,.hue = 640, .sat = 255, .val = 255}; +rgblight_config_t rgblight_config = {.enable = 0, .mode = 8,.hue = 640, .sat = 255, .val = 255}; -struct cRGB led[RGBLED_NUM+1]; +bool no_rgblight; +uint16_t hue_fix(uint16_t hue) +{ + // hue needs to be 0x100 to 0x3ff + hue += 0x300; + while (hue > 0x3ff) hue -= 0x300; + return hue; +} void sethsv(uint16_t hue, uint8_t saturation, uint8_t brightness, struct cRGB *led1) { /* original code: https://blog.adafruit.com/2012/03/14/constant-brightness-hsb-to-rgb-algorithm/ + when calculating hue, it may below 0. + So I save hue as 0x100 to 0x3ff (256 to 1023) instead of (0 to 767). + And n changes from 0-2 to 1-3. */ uint8_t r, g, b; uint8_t temp[5]; - uint8_t n = (hue >> 8) % 3; + // uint8_t n = (hue >> 8) % 3; + hue = hue_fix(hue); + uint8_t n = hue >> 8; + if (n > 3) return; // 0 would be error. just leave it. uint8_t x = ((((hue & 255) * saturation) >> 8) * brightness) >> 8; uint8_t s = ((256 - saturation) * brightness) >> 8; temp[0] = temp[3] = s; temp[1] = temp[4] = x + s; temp[2] = brightness - x; - r = temp[n + 2]; - g = temp[n + 1]; - b = temp[n]; + r = temp[n + 1]; + g = temp[n]; + b = temp[n - 1]; setrgb(r,g,b, led1); } @@ -98,29 +115,34 @@ void rgblight_init(void) rgblight_timer_init(); // setup the timer - if (rgblight_config.enable) { - rgblight_mode(rgblight_config.mode); - } else { - rgblight_set(); - rgblight_timer_disable(); - } + rgblight_mode(rgblight_config.mode); } +uint8_t limit_value_0to255(int16_t value) { + if (value > 255) return 255; + else if (value < 0) return 0; + else return value; +} void rgblight_mode(int8_t mode) { + // rgb off, new way to save about 60B if (!rgblight_config.enable) { - return; - } - if (mode < 0) mode = RGBLIGHT_MODES -1; - else if (mode >= RGBLIGHT_MODES) mode = 0; - rgblight_config.mode = mode; + //rgblight_clear(); + //rgblight_set(); + rgblight_timer_disable(); + rgb_fading_index = 0; + } else { + // rgb on + if (mode < 0) mode = RGBLIGHT_MODES - 1; + else if (mode >= RGBLIGHT_MODES) mode = 0; + rgblight_config.mode = mode; + dprintf("rgblight mode: %u\n", rgblight_config.mode); - eeconfig_write_rgblight(rgblight_config.raw); - dprintf("rgblight mode: %u\n", rgblight_config.mode); - if (rgblight_config.enable) { rgblight_timer_enable(); } + // save config. rgblight_sethsv() will save config. + //eeconfig_write_rgblight(rgblight_config.raw); rgblight_sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val); } @@ -128,17 +150,8 @@ inline void rgblight_toggle(void) { rgblight_config.enable ^= 1; - eeconfig_write_rgblight(rgblight_config.raw); dprintf("rgblight toggle: rgblight_config.enable = %u\n", rgblight_config.enable); - if (rgblight_config.enable) { - rgblight_mode(rgblight_config.mode); - } else { - rgblight_clear(); - rgblight_set(); - if (USB_DeviceState != DEVICE_STATE_Configured) { - rgblight_timer_disable(); - } - } + rgblight_mode(rgblight_config.mode); } @@ -151,8 +164,8 @@ void rgblight_action(uint8_t action) 7 val- 8 val+ */ uint16_t hue = rgblight_config.hue; - int16_t sat = rgblight_config.sat; - int16_t val = rgblight_config.val; + uint8_t sat = rgblight_config.sat; + uint8_t val = rgblight_config.val; int8_t increament = 1; if (action & 1) increament = -1; if (get_mods() & MOD_BIT(KC_LSHIFT)) { @@ -168,19 +181,15 @@ void rgblight_action(uint8_t action) break; case 3: case 4: - hue = (rgblight_config.hue + 768 + RGBLIGHT_HUE_STEP * increament) % 768; + hue = rgblight_config.hue + RGBLIGHT_HUE_STEP * increament; break; case 5: case 6: - sat = rgblight_config.sat + RGBLIGHT_SAT_STEP * increament; - if (sat > 255) sat = 255; - if (sat < 0) sat = 0; + sat = limit_value_0to255(rgblight_config.sat + RGBLIGHT_SAT_STEP * increament); break; case 7: case 8: - val = rgblight_config.val + RGBLIGHT_VAL_STEP * increament; - if (val > 255) val = 255; - if (val < 0) val = 0; + val = limit_value_0to255(rgblight_config.val + RGBLIGHT_VAL_STEP * increament); break; default: break; @@ -201,38 +210,57 @@ void rgblight_sethsv_noeeprom(uint16_t hue, uint8_t sat, uint8_t val) void rgblight_sethsv(uint16_t hue, uint8_t sat, uint8_t val) { + hue = hue_fix(hue); if (rgblight_config.enable) { + #if 0 // will do rgblight_sethsv_noeeprom() in rgblight_task if (rgblight_config.mode == 1) { // same static color rgblight_sethsv_noeeprom(hue, sat, val); } + #endif rgblight_config.hue = hue; rgblight_config.sat = sat; rgblight_config.val = val; - eeconfig_write_rgblight(rgblight_config.raw); dprintf("rgblight set hsv [EEPROM]: %u,%u,%u\n", rgblight_config.hue, rgblight_config.sat, rgblight_config.val); } + // when rgblight_config.enable == 0, just save config.raw. + eeconfig_write_rgblight(rgblight_config.raw); } void rgblight_setrgb(uint8_t r, uint8_t g, uint8_t b) { - for (uint8_t i=0;i= 13); + if (rgb_fading) { + if (kb_idle_times >= 13 && rgb_fading_index >= RGB_FADING_STEP) rgb_fading_index -= RGB_FADING_STEP; // fading in + else if (kb_idle_times < 13) rgb_fading_index += RGB_FADING_STEP; // fading out + // 设置底灯淡入淡出 + uint8_t *p = (uint8_t *)(&led[0]); + for (uint8_t i=0;i 15 case 15 ... 20: - rgblight_effect_snake(rgblight_config.mode-13); + rgblight_effect_snake(rgblight_config.mode-14); // 0 to 5 (0 to 2) break; + #endif + #if RGBLIGHT_MODES > 21 case 21 ... 23: rgblight_effect_knight(rgblight_config.mode-19); break; + #endif } } else { rgblight_timer_disable(); @@ -279,7 +311,8 @@ void rgblight_effect_breathing(uint8_t interval) static int8_t increament = 1; rgblight_sethsv_noeeprom(rgblight_config.hue, rgblight_config.sat, pgm_read_byte(&RGBLED_BREATHING_TABLE[pos])); pos = pos + interval*increament; - if (pos < interval || pos+interval > 126) { + if (pos < interval || pos+interval > 62) { + //if (pos < interval || pos+interval > 126) { increament *= -1; } } @@ -288,7 +321,7 @@ void rgblight_effect_rainbow_mood(uint8_t interval) { static uint16_t current_hue = 0; rgblight_sethsv_noeeprom(current_hue, rgblight_config.sat, rgblight_config.val); - current_hue = (current_hue + interval * 3) % 768; + current_hue = hue_fix(current_hue + interval * 3); } void rgblight_effect_rainbow_swirl(uint8_t interval) @@ -297,17 +330,16 @@ void rgblight_effect_rainbow_swirl(uint8_t interval) uint16_t hue; uint8_t i; uint8_t interval2 = interval/2; + if (interval & 1) interval2 *= -1; for (i=0; i 15 void rgblight_effect_snake(uint8_t interval) { static int8_t pos = 0 - RGBLIGHT_EFFECT_SNAKE_LENGTH; @@ -320,7 +352,11 @@ void rgblight_effect_snake(uint8_t interval) rgblight_clear(); if (interval%2) increament = -1; for (i=0; i= RGBLED_NUM) target_led -= RGBLED_NUM; + sethsv(rgblight_config.hue+i*50, rgblight_config.sat, rgblight_config.val, &led[target_led]); + //sethsv(rgblight_config.hue+i*50, rgblight_config.sat, rgblight_config.val, &led[(pos+i*increament+RGBLED_NUM)%RGBLED_NUM]); } pos += increament; if (pos > RGBLED_NUM) pos = 0; @@ -328,7 +364,9 @@ void rgblight_effect_snake(uint8_t interval) rgblight_set(); } } +#endif +#if RGBLIGHT_MODES > 21 void rgblight_effect_knight(uint8_t interval) { static int8_t pos = RGBLED_NUM - 1; @@ -341,76 +379,79 @@ void rgblight_effect_knight(uint8_t interval) sled_step = 0; rgblight_clear(); for (i=0; i= 0){ + int8_t target_col = pos+i; + if (target_col < RGBLED_NUM && target_col >= 0){ need_update = 1; - uint8_t tmp_col = pos+i; - led[tmp_col%RGBLED_NUM] = led[RGBLED_TEMP]; + led[target_col] = led[RGBLED_TEMP]; } } if (need_update) rgblight_set(); //Keep the first or last col on when increament changes. pos += increament; if (pos <= 0 - RGBLIGHT_EFFECT_KNIGHT_LENGTH || pos >= RGBLED_NUM) { increament *= -1; - current_hue = (current_hue + 40) % 768; + current_hue = hue_fix(current_hue + 40); sethsv(current_hue, rgblight_config.sat, rgblight_config.val, &led[RGBLED_TEMP]); } } } +#endif void suspend_power_down_action(void) { PORTB &= ~(1<<6); rgblight_timer_disable(); //RGB_VCC off + rgb_fading_index = 0; } void suspend_wakeup_init_action(void) { rgblight_init(); - if (BLE51_PowerState >= 4) display_connection_status_check_times = 1; } void hook_keyboard_loop() { + if (BLE51_PowerState > 1) return; static uint16_t rgb_update_timer = 0; - if (rgblight_timer_enabled && timer_elapsed(rgb_update_timer) > 40) { + static uint8_t steps = 0; + if (timer_elapsed(rgb_update_timer) > 40) { rgb_update_timer = timer_read(); - if (!display_connection_status_check_times || !ble51_boot_on) rgblight_task(); - } -} + if (!display_connection_status_check_times) rgblight_task(); -void ble51_task_user(void) -{ - static uint8_t ble51_task_steps = 0; - static uint16_t battery_timer = 0; - if (timer_elapsed(battery_timer) > 150) { - battery_timer = timer_read(); - ble51_task_steps++; - if (low_battery) { - if (ble51_task_steps > 3) { - ble51_task_steps = (low_battery == 1)? 3:0; //value 1 is extremely low battery - if (PINC & (1<<6)) { //not charging - rgblight_timer_disable(); - PORTB ^= (1<<6); + if ((steps++ & 0b11)) return; + //led_status_task(); + // run every 4*40 = 160ms + PORTB &= ~(1<<6); //caps off + if (ble51_boot_on && (low_battery || display_connection_status_check_times)) { + rgblight_timer_enable(); + rgblight_clear(); + rgb_fading_index = 63; //not fading for all leds. + // 320ms on,320ms off. bt connected: 320ms*3 on, 320ms off. + if (low_battery) { + rgblight_timer_disable(); + if (steps & 0b1000) PORTC |= (1<<6); + } else { + if (bt_connected) { + if (steps & 0b11000) { + PORTB |= (1<<6); + rgblight_setrgb(0,128,0); //green + } } else { - low_battery = 0; - suspend_wakeup_init_action(); + if (steps & 0b1000) { + PORTB |= (1<<6); + rgblight_setrgb(0,0,128); //blue + } } } - } else if (display_connection_status_check_times) { - rgblight_timer_enable(); - if (ble51_task_steps == 1) { - PORTB &= ~(1<<6); - rgblight_clear(); - rgblight_set(); - } else if (ble51_task_steps == 3) { - PORTB |= (1<<6); - uint8_t g_color = bt_connected? 128:0; - uint8_t b_color = bt_connected? 0:128; - rgblight_setrgb(0,g_color,b_color); - } - if ((!bt_connected && ble51_task_steps >= 5) || ble51_task_steps >= 11) { - ble51_task_steps = 0; - } + rgblight_set(); + } + // capslock + else if (host_keyboard_leds() & (1<. #include "command.h" #include "ble51.h" -extern bool is_980c; +void led_all_off(void) { + DDRF |= (1<event.pressed) { - switch (keycode) { - case USER00: - command_extra(KC_U); - break; - case USER01: //RESET - command_extra(KC_B); - break; - case USER02: //BATTERY LEVEL - command_extra(KC_V); - break; - case USER03: //LOCK MODE - command_extra(KC_L); - break; - case USER04: - if (PORTF & (1<= USER00 && keycode < USER04) command_extra(userx_to_command[keycode-USER00]); + else if (keycode == USER04) DDRF ^= (1<<7); + } + #if 0 + static uint8_t mod_keys_registered; + uint8_t pressed_mods = get_mods(); + switch (keycode) { + // 0x5f8f for Alt+Esc=f4 and RShift+Esc=~ + case 0x5F8F: + if (record->event.pressed) { + if ((pressed_mods & MOD_BIT(KC_RSHIFT)) && (~pressed_mods & MOD_BIT(KC_LCTRL))) { + mod_keys_registered = KC_GRV; + } else if (pressed_mods & MOD_BIT(KC_LALT)) { + mod_keys_registered = KC_F4; } else { - DDRF &= ~(1< +Copyright 2023 YANG 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 @@ -31,6 +31,7 @@ along with this program. If not, see . #include "keyboard.h" #include "timer_avr.h" #include "matrix.h" +#include "debounce_pk.h" #include "suspend.h" #include "lufa.h" #include "ble51.h" @@ -38,69 +39,63 @@ along with this program. If not, see . #include "switch_board.h" - // matrix state buffer(1:on, 0:off) static matrix_row_t *matrix; static matrix_row_t *matrix_prev; -static matrix_row_t _matrix0[MATRIX_ROWS]; -static matrix_row_t _matrix1[MATRIX_ROWS]; +static matrix_row_t _matrix0[MATRIX_ROWS] = {0}; +static matrix_row_t _matrix1[MATRIX_ROWS] = {0}; static uint8_t matrix_keys_down = 0; + + +static uint8_t matrix_debouncing[90] = {0}; //JP matrix is 16*5. Pro is 8*8 + struct { uint8_t rows; uint8_t final_col; } hhkb_matrix; +void matrix_scan_user(void) {} +__attribute__ ((weak)) +void matrix_scan_kb(void) { + matrix_scan_user(); + hook_keyboard_loop(); +} static uint8_t wake_scan = 0; bool is_ver_jp = 0; -bool is_ver25 = 0; + void hook_early_init() { /* led init */ - DDRF |= (1<= 10) _delay_us(3); // 必需,否则无法识别到按键或者连击。但是节能时可以不用。 + + uint8_t key = (~PIND & (1<<7))? 0x80 : 0; // save key state + + *debounce = (*debounce >> 1) | key; + KEY_PREV_OFF(); + KEY_UNABLE(); // 确定在return 100前执行 - if (KEY_STATE()) { - matrix[row] &= ~(1<= DEBOUNCE_DN_MASK) { + kb_idle_times = 0; + matrix_keys_down++; + matrix[row] |= (1< 0) { - if (BLE51_PowerState < 2) { - kb_idle_times = 0; - } else if (BLE51_PowerState < 10) { - return 100; - } - } - - _delay_us(5); - KEY_PREV_OFF(); - KEY_UNABLE(); + //_delay_us(5); //作用未知,去除后似乎无影响。 + //KEY_PREV_OFF(); + //KEY_UNABLE(); if (BLE51_PowerState >= 2) { - _delay_us(10); // scan faster when power saving - if (wake_scan && r == 7 && c == 4) { // wake scan complete + //似乎部分从Lock Mode唤醒还需要这个。 + //如果我在一个C1和C3拆除的HHKB上不使用这个延迟,正常时又会触发2。用10us是可以的,3us会2 + _delay_us(6); // scan faster when power saving + if (wake_scan && row == 7 && col == 6) { // wake scan complete + //if (wake_scan && row == (hhkb_matrix_rows >> 1 )) { // 4的时候US正常(12号发的固件,13号接到有人反应2唤醒时不能按),JP节能时无法唤醒。 wake_scan = 0; return 1; } } else { // NOTE: KEY_STATE keep its state in 20us after KEY_ENABLE. // This takes 25us or more to make sure KEY_STATE returns to idle state. - _delay_us(30); + //_delay_us(20); } } } - + // 二级节能唤醒检测 + if (BLE51_PowerState == 4 && matrix_keys_down) return 100; if (BLE51_PowerState >= 10) { //after a whole scan, check F and J when LOCK MODE // jp version, matrix[5,6] is F, matrix[9,6] is J. @@ -215,8 +222,9 @@ uint8_t matrix_scan(void) if (matrix[1] == (1<<5) && matrix[4] == (1<<5)) { return 100; } - } + } else if (!ble51_boot_on && matrix_keys_down) return 100; //蓝牙功能关闭时唤醒电脑 } + matrix_scan_quantum(); return 1; } @@ -239,15 +247,25 @@ void matrix_print(void) bool suspend_wakeup_condition(void) { static uint8_t sleep_timer = 0; - if (BLE51_PowerState >= 4) { + if (BT_POWERED == 0) { if (++sleep_timer < 80) return false; else sleep_timer = 0; } KEY_POWER_ON(); + // 如果不使用wake_scan,前4行的按键节能时无法识别。wake_scan也只需要扫到第5行即可。 wake_scan = 1; matrix_scan(); + + /* some 660c(maybe with tp1685) need one more scan when deep sleep. But maybe there is no hhkb pro2 with tp1685 + * 一个 hhkb pro2 (ajajz),如果隔太久(一晚上),Lock Mode 无法唤醒,尝试加回下面这一条。添加回后他和另一个人测试正常。 */ + if (BT_POWERED == 0) { + matrix_scan(); + //matrix_scan(); //因为加入了防抖,多扫一次。不在这里使用,在matrix.c的防抖里面直接多处理一次 + } + //*/ if (matrix_scan() == 100) { + //KEY_UNABLE(); return true; } KEY_POWER_OFF(); @@ -256,47 +274,60 @@ bool suspend_wakeup_condition(void) void suspend_power_down_action(void) { - KEY_POWER_OFF(); - PORTF &= ~(1<=4) { + if (BT_POWERED == 0) { PORTF |= (1< 1) return; + static uint8_t steps = 0; static uint16_t battery_timer = 0; - if (timer_elapsed(battery_timer) > 150) { + if (timer_elapsed(battery_timer) > 160) { battery_timer = timer_read(); - ble51_task_steps++; - if (low_battery) { - if (ble51_task_steps > 3) { - ble51_task_steps = (low_battery == 1)? 3:0; //value 1 is extremely low battery - if (PINF&(1<= 5) || ble51_task_steps >= 11 ) { - ble51_task_steps = 0; - } } + // capslock + else if (host_keyboard_leds() & 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. #include "rgblight.h" -void led_set_user(uint8_t usb_led) -{ - if (usb_led & (1<event.pressed) { - switch (keycode) { - case USER00: - command_extra(KC_U); - break; - case USER01: //RESET - command_extra(KC_B); - break; - case USER02: //BATTERY LEVEL - command_extra(KC_V); - break; - case USER03: //LOCK MODE - command_extra(KC_L); - break; - case USER04 ... USER12: - rgblight_action(keycode - USER04); - break; + static const uint8_t userx_to_command[4] = { + KC_U, // 0 Host Switch + KC_B, // 1 Reset + KC_V, // 2 Output Battery Value + KC_L // 3 Lock Mode + }; + if (keycode >= USER00) { + if (keycode < USER04) command_extra(userx_to_command[keycode-USER00]); + else if (keycode <= USER12) rgblight_action(keycode - USER04); } } } diff --git a/keyboards/ydkb/just68v2/matrix.c b/keyboards/ydkb/just68v2/matrix.c index 9efac5a2019..19500257069 100644 --- a/keyboards/ydkb/just68v2/matrix.c +++ b/keyboards/ydkb/just68v2/matrix.c @@ -1,3 +1,23 @@ +/* +Copyright 2023 YANG + +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 . +*/ + +/* + * scan matrix + */ #include #include #include @@ -13,6 +33,7 @@ #include "keyboard.h" #include "timer.h" #include "matrix.h" +#include "debounce_pk.h" #include "suspend.h" #include "lufa.h" #include "rgblight.h" @@ -20,10 +41,6 @@ #include "ble51_task.h" #include "switch_board.h" -#define DEBOUNCE_DN_MASK (uint8_t)(~(0x80 >> 5)) -#define DEBOUNCE_UP_MASK (uint8_t)(0x80 >> 5) - -bool is_ble_version = 1; extern rgblight_config_t rgblight_config; static matrix_row_t matrix[MATRIX_ROWS] = {0}; @@ -33,6 +50,7 @@ static uint8_t matrix_current_row = 0; static uint16_t matrix_scan_timestamp = 0; static uint8_t matrix_debouncing[MATRIX_ROWS][MATRIX_COLS] = {0}; static uint8_t encoder_state_prev[1][2] = {0}; +static uint8_t now_debounce_dn_mask = DEBOUNCE_NK_MASK; static void select_key(uint8_t mode); static uint8_t get_key(uint8_t col); @@ -46,23 +64,10 @@ void matrix_scan_kb(void) { hook_keyboard_loop(); } -inline -uint8_t matrix_rows(void) -{ - return MATRIX_ROWS; -} - -inline -uint8_t matrix_cols(void) -{ - return MATRIX_COLS; -} - void hook_early_init() { if (pgm_read_byte(0x7ea0) == 0x77) { // USB Only version - is_ble_version = 0; ble51_boot_on = 0; } else { // PD1 for BLE Reset, PF0 for BT_SW @@ -84,7 +89,7 @@ void hook_early_init() DDRC |= (1<<6); PORTC |= (1<<6); _delay_ms(5000); - bootloader_jump(); + bootloader_jump(); } } } @@ -93,7 +98,7 @@ void hook_early_init() void matrix_init(void) { DDRC |= (1<<6); - PORTC &= ~(1<<6); + //PORTC &= ~(1<<6); init_cols(); rgblight_init(); } @@ -101,15 +106,16 @@ void matrix_init(void) uint8_t matrix_scan(void) { - uint16_t time_check = timer_read(); - if (matrix_scan_timestamp == time_check) return 1; - matrix_scan_timestamp = time_check; + //uint16_t time_check = timer_read(); + //if (matrix_scan_timestamp == time_check) return 1; + //matrix_scan_timestamp = time_check; + uint8_t matrix_keys_down = 0; select_key(0); uint8_t *debounce = &matrix_debouncing[0][0]; - for (uint8_t row=0; row> 1) | key; if (real_col >= 8) select_key(1); - + //if ((*debounce > 0) && (*debounce < 255)) { if (1) { matrix_row_t *p_row = &matrix[row]; matrix_row_t col_mask = ((matrix_row_t)1 << real_col); - if (*debounce >= DEBOUNCE_DN_MASK) { + if (*debounce >= DEBOUNCE_DN_MASK) { //debounce KEY DOWN *p_row |= col_mask; - } else if (*debounce <= DEBOUNCE_UP_MASK) { + } else if (*debounce <= DEBOUNCE_UP_MASK) { //debounce KEY UP *p_row &= ~col_mask; } } - } - if (matrix[row] > 0) { - if (!rgblight_config.enable) kb_idle_times = 12; - else kb_idle_times = 0; + if (*debounce) matrix_keys_down++; } } - + + if (matrix_keys_down) { + if (BLE_LIGHT_ON == 0) kb_idle_times = 12; + else kb_idle_times = 0; + } + matrix_scan_quantum(); - return 1; + return matrix_keys_down; } @@ -239,48 +247,30 @@ static void select_key(uint8_t mode) bool suspend_wakeup_condition(void) { - if (BLE51_PowerState >= 10) { //lock mode - matrix_scan(); - // ver595: Key1_S24 F (debounce[2][8]), Key2_K20 J (debounce[2][1]) - uint8_t *debounce = &matrix_debouncing[0][0]; - uint8_t matrix_keys_down = 0; - for (uint8_t i=0; i< MATRIX_ROWS * MATRIX_COLS; i++, *debounce++) { - if (*debounce > 0) { - if (i == KP(2,1) || i == KP(2,8)) matrix_keys_down += 100; - else matrix_keys_down++; - } - } - if (matrix_keys_down == 200) { - return true; - } else if (!ble51_boot_on && matrix_keys_down) return true; - } else { - //check encoder and two key - DS_PL_LO(); - for (uint8_t i = 0; i < 2; i++) { - for (uint8_t j = 0; j < 8; j++) { - CLOCK_PULSE(); - DS_PL_HI(); - } - _delay_us(6); - uint8_t key1 = PINF&(1<<5); - uint8_t encoder_state = PINF&(1<<1) ? 0 : 1; - if (encoder_state != encoder_state_prev[0][i] || key1 == 0) { - return true; - } - } + uint8_t matrix_keys_down = matrix_scan(); + if (matrix_keys_down == 0) return false; - //check other keys - for (uint8_t i = 0; i < 5; i++) { - for (uint8_t j = 0; j < 8; j++) { - if (i >= 3 && j == 0) DS_PL_HI(); - else DS_PL_LO(); - CLOCK_PULSE(); - } - } - _delay_us(6); - if ( (PINF&0b100010) < 0b100010) { // - return true; + if (BLE51_PowerState >= 10) {//lock mode + if (matrix_keys_down == 2) { + // ver595: Key1_S24 F (debounce[2][8]), Key2_K20 J (debounce[2][1]) + if (matrix_debouncing[2][8] == 0xff && matrix_debouncing[2][1] == 0xff) return true; } + if (!ble51_boot_on) return true; //ܹرʱѵ + return false; } - return false; + return matrix_keys_down; } + +void bootmagic_lite(void) +{ + //do nothing + return; + +} + +void hook_nkro_change(void) +{ + return; + uint8_t kbd_nkro = keymap_config.nkro; + type_num(kbd_nkro?6:0); +} \ No newline at end of file diff --git a/keyboards/ydkb/just68v2/rgblight.c b/keyboards/ydkb/just68v2/rgblight.c index efbb508d81f..d5ce9e77ccd 100644 --- a/keyboards/ydkb/just68v2/rgblight.c +++ b/keyboards/ydkb/just68v2/rgblight.c @@ -16,33 +16,50 @@ #define rgblight_timer_enable() do { PORTE &= ~(1<<6);} while(0) #define rgblight_timer_disable() do { PORTE |= (1<<6);} while(0) #define rgblight_timer_enabled (~PORTE & (1<<6)) + #define RGBLED_TEMP RGBLED_NUM -const uint8_t RGBLED_BREATHING_TABLE[128] PROGMEM = {0,0,0,0,1,1,1,2,2,3,4,5,5,6,7,9,10,11,12,14,15,17,18,20,21,23,25,27,29,31,33,35,37,40,42,44,47,49,52,54,57,59,62,65,67,70,73,76,79,82,85,88,90,93,97,100,103,106,109,112,115,118,121,124,127,131,134,137,140,143,146,149,152,155,158,162,165,167,170,173,176,179,182,185,188,190,193,196,198,201,203,206,208,211,213,215,218,220,222,224,226,228,230,232,234,235,237,238,240,241,243,244,245,246,248,249,250,250,251,252,253,253,254,254,254,255,255,255}; +#define INDICATOR_NUM 0 +struct cRGB rgbled[RGBLED_NUM+INDICATOR_NUM+1]; +struct cRGB *led = &rgbled[INDICATOR_NUM]; + +//const uint8_t RGBLED_BREATHING_TABLE[128] PROGMEM= {0,0,0,0,1,1,1,2,2,3,4,5,5,6,7,9,10,11,12,14,15,17,18,20,21,23,25,27,29,31,33,35,37,40,42,44,47,49,52,54,57,59,62,65,67,70,73,76,79,82,85,88,90,93,97,100,103,106,109,112,115,118,121,124,127,131,134,137,140,143,146,149,152,155,158,162,165,167,170,173,176,179,182,185,188,190,193,196,198,201,203,206,208,211,213,215,218,220,222,224,226,228,230,232,234,235,237,238,240,241,243,244,245,246,248,249,250,250,251,252,253,253,254,254,254,255,255,255}; +const uint8_t RGBLED_BREATHING_TABLE[64] PROGMEM= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 3, 4, 5, 6, 8, 10, 12, 15, 17, 20, 24, 28, 32, 36, 41, 46, 51, 57, 63, 70, 76, 83, 91, 98, 106, 113, 121, 129, 138, 146, 154, 162, 170, 178, 185, 193, 200, 207, 213, 220, 225, 231, 235, 240, 244, 247, 250, 252, 253, 254, 255}; -//battery -extern bool is_ble_version; +static uint8_t rgb_fading_index = 0; //使用 RGBLED_BREATHING_TABLE rgblight_config_t rgblight_config = {.enable = 1, .mode = 8,.hue = 640, .sat = 255, .val = 255}; -struct cRGB led[RGBLED_NUM+1]; +uint16_t hue_fix(uint16_t hue) +{ + // hue needs to be 0x100 to 0x3ff + hue += 0x300; + while (hue > 0x3ff) hue -= 0x300; + return hue; +} void sethsv(uint16_t hue, uint8_t saturation, uint8_t brightness, struct cRGB *led1) { /* original code: https://blog.adafruit.com/2012/03/14/constant-brightness-hsb-to-rgb-algorithm/ + when calculating hue, it may below 0. + So I save hue as 0x100 to 0x3ff (256 to 1023) instead of (0 to 767). + And n changes from 0-2 to 1-3. */ uint8_t r, g, b; uint8_t temp[5]; - uint8_t n = (hue >> 8) % 3; + // uint8_t n = (hue >> 8) % 3; + hue = hue_fix(hue); + uint8_t n = hue >> 8; + if (n > 3) return; // 0 would be error. just leave it. uint8_t x = ((((hue & 255) * saturation) >> 8) * brightness) >> 8; uint8_t s = ((256 - saturation) * brightness) >> 8; temp[0] = temp[3] = s; temp[1] = temp[4] = x + s; temp[2] = brightness - x; - r = temp[n + 2]; - g = temp[n + 1]; - b = temp[n]; + r = temp[n + 1]; + g = temp[n]; + b = temp[n - 1]; setrgb(r,g,b, led1); } @@ -97,29 +114,34 @@ void rgblight_init(void) rgblight_timer_init(); // setup the timer - if (rgblight_config.enable) { - rgblight_mode(rgblight_config.mode); - } else { - rgblight_set(); - rgblight_timer_disable(); - } + rgblight_mode(rgblight_config.mode); } +uint8_t limit_value_0to255(int16_t value) { + if (value > 255) return 255; + else if (value < 0) return 0; + else return value; +} void rgblight_mode(int8_t mode) { + // rgb off, new way to save about 60B if (!rgblight_config.enable) { - return; - } - if (mode < 0) mode = RGBLIGHT_MODES -1; - else if (mode >= RGBLIGHT_MODES) mode = 0; - rgblight_config.mode = mode; + //rgblight_clear(); + //rgblight_set(); + rgblight_timer_disable(); + rgb_fading_index = 0; + } else { + // rgb on + if (mode < 0) mode = RGBLIGHT_MODES - 1; + else if (mode >= RGBLIGHT_MODES) mode = 0; + rgblight_config.mode = mode; + dprintf("rgblight mode: %u\n", rgblight_config.mode); - eeconfig_write_rgblight(rgblight_config.raw); - dprintf("rgblight mode: %u\n", rgblight_config.mode); - if (rgblight_config.enable) { rgblight_timer_enable(); } + // save config. rgblight_sethsv() will save config. + //eeconfig_write_rgblight(rgblight_config.raw); rgblight_sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val); } @@ -127,17 +149,8 @@ inline void rgblight_toggle(void) { rgblight_config.enable ^= 1; - eeconfig_write_rgblight(rgblight_config.raw); dprintf("rgblight toggle: rgblight_config.enable = %u\n", rgblight_config.enable); - if (rgblight_config.enable) { - rgblight_mode(rgblight_config.mode); - } else { - rgblight_clear(); - rgblight_set(); - if (USB_DeviceState != DEVICE_STATE_Configured) { - rgblight_timer_disable(); - } - } + rgblight_mode(rgblight_config.mode); } @@ -150,8 +163,8 @@ void rgblight_action(uint8_t action) 7 val- 8 val+ */ uint16_t hue = rgblight_config.hue; - int16_t sat = rgblight_config.sat; - int16_t val = rgblight_config.val; + uint8_t sat = rgblight_config.sat; + uint8_t val = rgblight_config.val; int8_t increament = 1; if (action & 1) increament = -1; if (get_mods() & MOD_BIT(KC_LSHIFT)) { @@ -167,19 +180,15 @@ void rgblight_action(uint8_t action) break; case 3: case 4: - hue = (rgblight_config.hue + 768 + RGBLIGHT_HUE_STEP * increament) % 768; + hue = rgblight_config.hue + RGBLIGHT_HUE_STEP * increament; break; case 5: case 6: - sat = rgblight_config.sat + RGBLIGHT_SAT_STEP * increament; - if (sat > 255) sat = 255; - if (sat < 0) sat = 0; + sat = limit_value_0to255(rgblight_config.sat + RGBLIGHT_SAT_STEP * increament); break; case 7: case 8: - val = rgblight_config.val + RGBLIGHT_VAL_STEP * increament; - if (val > 255) val = 255; - if (val < 0) val = 0; + val = limit_value_0to255(rgblight_config.val + RGBLIGHT_VAL_STEP * increament); break; default: break; @@ -200,45 +209,60 @@ void rgblight_sethsv_noeeprom(uint16_t hue, uint8_t sat, uint8_t val) void rgblight_sethsv(uint16_t hue, uint8_t sat, uint8_t val) { + hue = hue_fix(hue); if (rgblight_config.enable) { + #if 0 // will do rgblight_sethsv_noeeprom() in rgblight_task if (rgblight_config.mode == 1) { // same static color rgblight_sethsv_noeeprom(hue, sat, val); } + #endif rgblight_config.hue = hue; rgblight_config.sat = sat; rgblight_config.val = val; - eeconfig_write_rgblight(rgblight_config.raw); dprintf("rgblight set hsv [EEPROM]: %u,%u,%u\n", rgblight_config.hue, rgblight_config.sat, rgblight_config.val); } + // when rgblight_config.enable == 0, just save config.raw. + eeconfig_write_rgblight(rgblight_config.raw); } void rgblight_setrgb(uint8_t r, uint8_t g, uint8_t b) { - for (uint8_t i=0;i= 13); + if (rgb_fading) { + if (kb_idle_times >= 13 && rgb_fading_index >= RGB_FADING_STEP) rgb_fading_index -= RGB_FADING_STEP; // fading in + else if (kb_idle_times < 13) rgb_fading_index += RGB_FADING_STEP; // fading out + // 设置底灯淡入淡出 + uint8_t *p = (uint8_t *)(&led[0]); + for (uint8_t i=0;i 15 case 15 ... 20: - rgblight_effect_snake(rgblight_config.mode-13); + rgblight_effect_snake(rgblight_config.mode-14); // 0 to 5 (0 to 2) break; + #endif + #if RGBLIGHT_MODES > 21 case 21 ... 23: rgblight_effect_knight(rgblight_config.mode-19); break; + #endif } } else { rgblight_timer_disable(); @@ -273,7 +301,8 @@ void rgblight_effect_breathing(uint8_t interval) static int8_t increament = 1; rgblight_sethsv_noeeprom(rgblight_config.hue, rgblight_config.sat, pgm_read_byte(&RGBLED_BREATHING_TABLE[pos])); pos = pos + interval*increament; - if (pos < interval || pos+interval > 126) { + if (pos < interval || pos+interval > 62) { + //if (pos < interval || pos+interval > 126) { increament *= -1; } } @@ -282,7 +311,7 @@ void rgblight_effect_rainbow_mood(uint8_t interval) { static uint16_t current_hue = 0; rgblight_sethsv_noeeprom(current_hue, rgblight_config.sat, rgblight_config.val); - current_hue = (current_hue + interval * 3) % 768; + current_hue = hue_fix(current_hue + interval * 3); } void rgblight_effect_rainbow_swirl(uint8_t interval) @@ -291,17 +320,16 @@ void rgblight_effect_rainbow_swirl(uint8_t interval) uint16_t hue; uint8_t i; uint8_t interval2 = interval/2; + if (interval & 1) interval2 *= -1; for (i=0; i 15 void rgblight_effect_snake(uint8_t interval) { static int8_t pos = 0 - RGBLIGHT_EFFECT_SNAKE_LENGTH; @@ -314,7 +342,11 @@ void rgblight_effect_snake(uint8_t interval) rgblight_clear(); if (interval%2) increament = -1; for (i=0; i= RGBLED_NUM) target_led -= RGBLED_NUM; + sethsv(rgblight_config.hue+i*50, rgblight_config.sat, rgblight_config.val, &led[target_led]); + //sethsv(rgblight_config.hue+i*50, rgblight_config.sat, rgblight_config.val, &led[(pos+i*increament+RGBLED_NUM)%RGBLED_NUM]); } pos += increament; if (pos > RGBLED_NUM) pos = 0; @@ -322,7 +354,9 @@ void rgblight_effect_snake(uint8_t interval) rgblight_set(); } } +#endif +#if RGBLIGHT_MODES > 21 void rgblight_effect_knight(uint8_t interval) { static int8_t pos = RGBLED_NUM - 1; @@ -335,76 +369,79 @@ void rgblight_effect_knight(uint8_t interval) sled_step = 0; rgblight_clear(); for (i=0; i= 0){ + int8_t target_col = pos+i; + if (target_col < RGBLED_NUM && target_col >= 0){ need_update = 1; - uint8_t tmp_col = pos+i; - led[tmp_col%RGBLED_NUM] = led[RGBLED_TEMP]; + led[target_col] = led[RGBLED_TEMP]; } } if (need_update) rgblight_set(); //Keep the first or last col on when increament changes. pos += increament; if (pos <= 0 - RGBLIGHT_EFFECT_KNIGHT_LENGTH || pos >= RGBLED_NUM) { increament *= -1; - current_hue = (current_hue + 40) % 768; + current_hue = hue_fix(current_hue + 40); sethsv(current_hue, rgblight_config.sat, rgblight_config.val, &led[RGBLED_TEMP]); } } } +#endif void suspend_power_down_action(void) { PORTC &= ~(1<<6); rgblight_timer_disable(); //RGB_VCC off + rgb_fading_index = 0; } void suspend_wakeup_init_action(void) { rgblight_init(); - if (BLE51_PowerState >= 4) display_connection_status_check_times = 1; } void hook_keyboard_loop() { + if (BLE51_PowerState > 1) return; static uint16_t rgb_update_timer = 0; - if (rgblight_timer_enabled && timer_elapsed(rgb_update_timer) > 40) { + static uint8_t steps = 0; + if (timer_elapsed(rgb_update_timer) > 40) { rgb_update_timer = timer_read(); - if (!display_connection_status_check_times || !ble51_boot_on) rgblight_task(); - } -} + if (!display_connection_status_check_times) rgblight_task(); -void ble51_task_user(void) -{ - static uint8_t ble51_task_steps = 0; - static uint16_t battery_timer = 0; - if (timer_elapsed(battery_timer) > 150) { - battery_timer = timer_read(); - ble51_task_steps++; - if (low_battery) { - if (ble51_task_steps > 3) { - ble51_task_steps = (low_battery == 1)? 3:0; //value 1 is extremely low battery - if (PINC & (1<<7)) { //not charging - rgblight_timer_disable(); - PORTC ^= (1<<6); + if ((steps++ & 0b11)) return; + //led_status_task(); + // run every 4*40 = 160ms + PORTC &= ~(1<<6); //caps off + if (ble51_boot_on && (low_battery || display_connection_status_check_times)) { + rgblight_timer_enable(); + rgblight_clear(); + rgb_fading_index = 63; //not fading for all leds. + // 320ms on,320ms off. bt connected: 320ms*3 on, 320ms off. + if (low_battery) { + rgblight_timer_disable(); + if (steps & 0b1000) PORTC |= (1<<6); + } else { + if (bt_connected) { + if (steps & 0b11000) { + PORTC |= (1<<6); + rgblight_setrgb(0,128,0); //green + } } else { - low_battery = 0; - suspend_wakeup_init_action(); + if (steps & 0b1000) { + PORTC |= (1<<6); + rgblight_setrgb(0,0,128); //blue + } } } - } else if (display_connection_status_check_times) { - rgblight_timer_enable(); - if (ble51_task_steps == 1) { - PORTC &= ~(1<<6); - rgblight_clear(); - rgblight_set(); - } else if (ble51_task_steps == 3) { - PORTC |= (1<<6); - uint8_t g_color = bt_connected? 255:0; - uint8_t b_color = bt_connected? 0:255; - rgblight_setrgb(0,g_color,b_color); - } - if ((!bt_connected && ble51_task_steps >= 5) || ble51_task_steps >= 11) { - ble51_task_steps = 0; - } + ws2812_setleds(rgbled); + } + // capslock + else if (host_keyboard_leds() & (1< + +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 . +*/ + +#include +#include +#include +#include "backlight.h" +#include "timer.h" + + +void backlight_init_ports(void) { + DDRC &= ~(1<<6); + PORTC |= (1<<6); +} + +void backlight_task(void) { + return; +} + +void backlight_user_enable(void) +{ + + DDRC |= (1<<6); + PORTC &= ~(1<<6); +} + +void backlight_user_disable(void) +{ + DDRC &= ~(1<<6); + PORTC |= (1<<6); +} + +void backlight_set(uint8_t level) +{ + if (level) backlight_user_enable(); + else backlight_user_disable(); +} + diff --git a/keyboards/ydkb/louise/config.h b/keyboards/ydkb/louise/config.h index 64f5633f4bf..dbbf9112b8c 100644 --- a/keyboards/ydkb/louise/config.h +++ b/keyboards/ydkb/louise/config.h @@ -3,9 +3,10 @@ #include "config_common.h" /* USB Device descriptor parameter */ -#define FW_VER QMK_DMCM -#define FW_VER_VIA VIA_DMCM -#define FW_VER_VIAL VIAL_DMCM +#define FW_VER_DATE DO6A +#define CONTACT(x,y) x##y +#define CONTACT2(x,y) CONTACT(x,y) +#define FW_VER CONTACT2(VIAL_, FW_VER_DATE) #define VENDOR_ID 0x9D5B #define PRODUCT_ID 0x2141 #define DEVICE_VER 0x0001 @@ -17,12 +18,6 @@ #define MATRIX_COLS 16 - -#define TAPPING_TOGGLE 2 - -#define TAPPING_TERM 200 -#define IGNORE_MOD_TAP_INTERRUPT // this makes it possible to do rolling combos (zx) with keys that convert to other keys on hold (z becomes ctrl when you hold it, and when this option isn't enabled, z rapidly followed by x actually sends Ctrl-x. That's bad.) - #define BACKLIGHT_PIN C6 #define BACKLIGHT_LEVELS 6 #define BACKLIGHT_ON_STATE 0 @@ -37,13 +32,12 @@ #define ws2812_DDRREG DDRD #define ws2812_pin PD7 #define RGBLED_NUM 8 // Number of LEDs +#define RGBLIGHT_MODES 14 //less rgblight mode to save some space for vial /* disable command for default layer */ #define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS 0 #define MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS 0 -/* fix space cadet rollover issue */ -#define DISABLE_SPACE_CADET_ROLLOVER #if defined(__AVR_ATmega32U4__) || defined(__AVR_AT90USB1286__) #define UCSR1D _SFR_MEM8(0xCB) @@ -70,9 +64,10 @@ #endif /* BT Power Control */ #define BT_POWERED (~PORTD & (1<<5)) -#define bt_power_init() do { DDRD |= (1<<5); PORTD &= ~(1<<5);} while(0) -#define turn_off_bt() do { PORTD |= (1<<5); UCSR1B &= ~(1<. #include "rgblight.h" -void led_set_user(uint8_t usb_led) -{ - if (usb_led & (1<event.pressed) { - switch (keycode) { - case USER00: - command_extra(KC_U); - break; - case USER01: //RESET - command_extra(KC_B); - break; - case USER02: //BATTERY LEVEL - command_extra(KC_V); - break; - case USER03: //LOCK MODE - command_extra(KC_L); - break; - case USER04 ... USER11: - rgblight_action(keycode - USER04); - break; + static const uint8_t userx_to_command[4] = { + KC_U, // 0 Host Switch + KC_B, // 1 Reset + KC_V, // 2 Output Battery Value + KC_L // 3 Lock Mode + }; + if (keycode >= USER00) { + if (keycode < USER04) command_extra(userx_to_command[keycode-USER00]); + else if (keycode <= USER12) rgblight_action(keycode - USER04); } } } \ No newline at end of file diff --git a/keyboards/ydkb/louise/matrix.c b/keyboards/ydkb/louise/matrix.c index b300371909c..87dc6331669 100644 --- a/keyboards/ydkb/louise/matrix.c +++ b/keyboards/ydkb/louise/matrix.c @@ -1,3 +1,23 @@ +/* +Copyright 2023 YANG + +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 . +*/ + +/* + * scan matrix + */ #include #include #include @@ -13,6 +33,7 @@ #include "keyboard.h" #include "timer.h" #include "matrix.h" +#include "debounce_pk.h" #include "suspend.h" #include "lufa.h" #include "rgblight.h" @@ -20,16 +41,12 @@ #include "ble51_task.h" #include "switch_board.h" -#define DEBOUNCE_DN_MASK (uint8_t)(~(0x80 >> 5)) -#define DEBOUNCE_UP_MASK (uint8_t)(0x80 >> 5) - -bool is_ble_version = 1; -extern rgblight_config_t rgblight_config; static matrix_row_t matrix[MATRIX_ROWS] = {0}; static uint16_t matrix_scan_timestamp = 0; static uint8_t matrix_debouncing[MATRIX_ROWS][MATRIX_COLS] = {0}; +static uint8_t now_debounce_dn_mask = DEBOUNCE_NK_MASK; static void select_key(uint8_t mode); static uint8_t get_key(uint8_t col); @@ -43,18 +60,6 @@ void matrix_scan_kb(void) { hook_keyboard_loop(); } -inline -uint8_t matrix_rows(void) -{ - return MATRIX_ROWS; -} - -inline -uint8_t matrix_cols(void) -{ - return MATRIX_COLS; -} - static void get_key_ready(void) { DDRB &= ~(1<<3); PORTB |= (1<<3); @@ -69,7 +74,6 @@ void hook_early_init() { if (pgm_read_byte(0x7e65) == 0x4c) { // USB Only version - is_ble_version = 0; ble51_boot_on = 0; } else { // PF7 for BLE Reset, PE2 for BT_SW @@ -87,13 +91,12 @@ void hook_early_init() DDRF |= (1<> 1) | key; if (real_col >= 8) select_key(1); - + //if ((*debounce > 0) && (*debounce < 255)) { if (1) { matrix_row_t *p_row = &matrix[row]; matrix_row_t col_mask = ((matrix_row_t)1 << real_col); - if (*debounce >= DEBOUNCE_DN_MASK) { + if (*debounce >= DEBOUNCE_DN_MASK) { //debounce KEY DOWN *p_row |= col_mask; - } else if (*debounce <= DEBOUNCE_UP_MASK) { + } else if (*debounce <= DEBOUNCE_UP_MASK) { //debounce KEY UP *p_row &= ~col_mask; } - } - } - if (matrix[row] > 0) { - if (!rgblight_config.enable) kb_idle_times = 12; - else kb_idle_times = 0; + } + if (*debounce) matrix_keys_down++; } } - + + if (matrix_keys_down) { + if (BLE_LIGHT_ON == 0) kb_idle_times = 12; + else kb_idle_times = 0; + } + matrix_scan_quantum(); - return 1; + return matrix_keys_down; } @@ -189,20 +195,20 @@ void init_cols(void) { //595 pin DDRB |= (1<= 10) { //lock mode - matrix_scan(); - // Key1_S14 F, real debounce p is 1*16+4*2 - // Key2_K14 J, real debounce p is 1*16+4*2+1 - uint8_t *debounce = &matrix_debouncing[0][0]; - uint8_t matrix_keys_down = 0; - for (uint8_t i=0; i< MATRIX_ROWS * MATRIX_COLS; i++, *debounce++) { - if (*debounce > 0) { - if (i == KP(1,8) || i == KP(1,9)) matrix_keys_down += 100; - else matrix_keys_down++; - } - } - if (matrix_keys_down == 200) { - return true; - } - } else { - //check all keys - select_key_ready(); - DS_PL_LO(); - for (uint8_t i = 0; i < MATRIX_ROWS * MATRIX_COLS / 2; i++) { - CLOCK_PULSE(); - } - get_key_ready(); - if (get_key(0) || get_key(8)) { // - return true; + uint8_t matrix_keys_down = matrix_scan(); + if (matrix_keys_down == 0) return false; + + if (BLE51_PowerState >= 10) {//lock mode + if (matrix_keys_down == 2) { + // Key1_S14 F, real debounce p is 1*16+4*2 + // Key2_K14 J, real debounce p is 1*16+4*2+1 + if (matrix_debouncing[1][8] == 0xff && matrix_debouncing[1][9] == 0xff) return true; } + if (!ble51_boot_on) return true; //蓝牙功能关闭时唤醒电脑 + return false; } - return false; + + return matrix_keys_down; +} + +void bootmagic_lite(void) +{ + //do nothing + return; + } + +void hook_nkro_change(void) +{ + return; + uint8_t kbd_nkro = keymap_config.nkro; + type_num(kbd_nkro?6:0); +} \ No newline at end of file diff --git a/keyboards/ydkb/louise/rgblight.c b/keyboards/ydkb/louise/rgblight.c index fc7135fb5e6..3daa4acd81e 100644 --- a/keyboards/ydkb/louise/rgblight.c +++ b/keyboards/ydkb/louise/rgblight.c @@ -17,34 +17,49 @@ #define rgblight_timer_enable() do { PORTD &= ~(1<<6);} while(0) #define rgblight_timer_disable() do { PORTD |= (1<<6);} while(0) #define rgblight_timer_enabled (~PORTD & (1<<6)) + #define RGBLED_TEMP RGBLED_NUM -const uint8_t RGBLED_BREATHING_TABLE[128] PROGMEM = {0,0,0,0,1,1,1,2,2,3,4,5,5,6,7,9,10,11,12,14,15,17,18,20,21,23,25,27,29,31,33,35,37,40,42,44,47,49,52,54,57,59,62,65,67,70,73,76,79,82,85,88,90,93,97,100,103,106,109,112,115,118,121,124,127,131,134,137,140,143,146,149,152,155,158,162,165,167,170,173,176,179,182,185,188,190,193,196,198,201,203,206,208,211,213,215,218,220,222,224,226,228,230,232,234,235,237,238,240,241,243,244,245,246,248,249,250,250,251,252,253,253,254,254,254,255,255,255}; +#define INDICATOR_NUM 0 +struct cRGB rgbled[RGBLED_NUM+INDICATOR_NUM+1]; +struct cRGB *led = &rgbled[INDICATOR_NUM]; + +//const uint8_t RGBLED_BREATHING_TABLE[128] PROGMEM= {0,0,0,0,1,1,1,2,2,3,4,5,5,6,7,9,10,11,12,14,15,17,18,20,21,23,25,27,29,31,33,35,37,40,42,44,47,49,52,54,57,59,62,65,67,70,73,76,79,82,85,88,90,93,97,100,103,106,109,112,115,118,121,124,127,131,134,137,140,143,146,149,152,155,158,162,165,167,170,173,176,179,182,185,188,190,193,196,198,201,203,206,208,211,213,215,218,220,222,224,226,228,230,232,234,235,237,238,240,241,243,244,245,246,248,249,250,250,251,252,253,253,254,254,254,255,255,255}; +const uint8_t RGBLED_BREATHING_TABLE[64] PROGMEM= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 3, 4, 5, 6, 8, 10, 12, 15, 17, 20, 24, 28, 32, 36, 41, 46, 51, 57, 63, 70, 76, 83, 91, 98, 106, 113, 121, 129, 138, 146, 154, 162, 170, 178, 185, 193, 200, 207, 213, 220, 225, 231, 235, 240, 244, 247, 250, 252, 253, 254, 255}; -//battery -extern bool no_rgblight; -extern bool is_ble_version; -rgblight_config_t rgblight_config = {.enable = 1, .mode = 8,.hue = 640, .sat = 255, .val = 255}; +rgblight_config_t rgblight_config = {.enable = 0, .mode = 8,.hue = 640, .sat = 255, .val = 255}; -struct cRGB led[RGBLED_NUM+1]; +uint16_t hue_fix(uint16_t hue) +{ + // hue needs to be 0x100 to 0x3ff + hue += 0x300; + while (hue > 0x3ff) hue -= 0x300; + return hue; +} void sethsv(uint16_t hue, uint8_t saturation, uint8_t brightness, struct cRGB *led1) { /* original code: https://blog.adafruit.com/2012/03/14/constant-brightness-hsb-to-rgb-algorithm/ + when calculating hue, it may below 0. + So I save hue as 0x100 to 0x3ff (256 to 1023) instead of (0 to 767). + And n changes from 0-2 to 1-3. */ uint8_t r, g, b; uint8_t temp[5]; - uint8_t n = (hue >> 8) % 3; + // uint8_t n = (hue >> 8) % 3; + hue = hue_fix(hue); + uint8_t n = hue >> 8; + if (n > 3) return; // 0 would be error. just leave it. uint8_t x = ((((hue & 255) * saturation) >> 8) * brightness) >> 8; uint8_t s = ((256 - saturation) * brightness) >> 8; temp[0] = temp[3] = s; temp[1] = temp[4] = x + s; temp[2] = brightness - x; - r = temp[n + 2]; - g = temp[n + 1]; - b = temp[n]; + r = temp[n + 1]; + g = temp[n]; + b = temp[n - 1]; setrgb(r,g,b, led1); } @@ -99,29 +114,33 @@ void rgblight_init(void) rgblight_timer_init(); // setup the timer - if (rgblight_config.enable) { - rgblight_mode(rgblight_config.mode); - } else { - rgblight_set(); - rgblight_timer_disable(); - } + rgblight_mode(rgblight_config.mode); } +uint8_t limit_value_0to255(int16_t value) { + if (value > 255) return 255; + else if (value < 0) return 0; + else return value; +} void rgblight_mode(int8_t mode) { + // rgb off, new way to save about 60B if (!rgblight_config.enable) { - return; - } - if (mode < 0) mode = RGBLIGHT_MODES - 1; - else if (mode >= RGBLIGHT_MODES) mode = 0; - rgblight_config.mode = mode; + rgblight_clear(); + rgblight_set(); + //if (!indicator_state) rgblight_timer_disable(); + } else { + // rgb on + if (mode < 0) mode = RGBLIGHT_MODES - 1; + else if (mode >= RGBLIGHT_MODES) mode = 0; + rgblight_config.mode = mode; + dprintf("rgblight mode: %u\n", rgblight_config.mode); - eeconfig_write_rgblight(rgblight_config.raw); - dprintf("rgblight mode: %u\n", rgblight_config.mode); - if (rgblight_config.enable) { rgblight_timer_enable(); } + // save config. rgblight_sethsv() will save config. + //eeconfig_write_rgblight(rgblight_config.raw); rgblight_sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val); } @@ -129,17 +148,8 @@ inline void rgblight_toggle(void) { rgblight_config.enable ^= 1; - eeconfig_write_rgblight(rgblight_config.raw); dprintf("rgblight toggle: rgblight_config.enable = %u\n", rgblight_config.enable); - if (rgblight_config.enable) { - rgblight_mode(rgblight_config.mode); - } else { - rgblight_clear(); - rgblight_set(); - if (USB_DeviceState != DEVICE_STATE_Configured) { - rgblight_timer_disable(); - } - } + rgblight_mode(rgblight_config.mode); } @@ -152,8 +162,8 @@ void rgblight_action(uint8_t action) 7 val- 8 val+ */ uint16_t hue = rgblight_config.hue; - int16_t sat = rgblight_config.sat; - int16_t val = rgblight_config.val; + uint8_t sat = rgblight_config.sat; + uint8_t val = rgblight_config.val; int8_t increament = 1; if (action & 1) increament = -1; if (get_mods() & MOD_BIT(KC_LSHIFT)) { @@ -169,19 +179,15 @@ void rgblight_action(uint8_t action) break; case 3: case 4: - hue = (rgblight_config.hue + 768 + RGBLIGHT_HUE_STEP * increament) % 768; + hue = rgblight_config.hue + RGBLIGHT_HUE_STEP * increament; break; case 5: case 6: - sat = rgblight_config.sat + RGBLIGHT_SAT_STEP * increament; - if (sat > 255) sat = 255; - if (sat < 0) sat = 0; + sat = limit_value_0to255(rgblight_config.sat + RGBLIGHT_SAT_STEP * increament); break; case 7: case 8: - val = rgblight_config.val + RGBLIGHT_VAL_STEP * increament; - if (val > 255) val = 255; - if (val < 0) val = 0; + val = limit_value_0to255(rgblight_config.val + RGBLIGHT_VAL_STEP * increament); break; default: break; @@ -202,43 +208,49 @@ void rgblight_sethsv_noeeprom(uint16_t hue, uint8_t sat, uint8_t val) void rgblight_sethsv(uint16_t hue, uint8_t sat, uint8_t val) { + hue = hue_fix(hue); if (rgblight_config.enable) { + #if 0 // will do rgblight_sethsv_noeeprom() in rgblight_task if (rgblight_config.mode == 1) { // same static color rgblight_sethsv_noeeprom(hue, sat, val); } + #endif rgblight_config.hue = hue; rgblight_config.sat = sat; rgblight_config.val = val; - eeconfig_write_rgblight(rgblight_config.raw); dprintf("rgblight set hsv [EEPROM]: %u,%u,%u\n", rgblight_config.hue, rgblight_config.sat, rgblight_config.val); } + // when rgblight_config.enable == 0, just save config.raw. + eeconfig_write_rgblight(rgblight_config.raw); } void rgblight_setrgb(uint8_t r, uint8_t g, uint8_t b) { - for (uint8_t i=0;i 15 case 15 ... 20: - rgblight_effect_snake(rgblight_config.mode-13); + rgblight_effect_snake(rgblight_config.mode-14); // 0 to 5 (0 to 2) break; #endif #if RGBLIGHT_MODES > 21 @@ -264,6 +276,7 @@ void rgblight_task(void) break; #endif } + } } } @@ -274,7 +287,8 @@ void rgblight_effect_breathing(uint8_t interval) static int8_t increament = 1; rgblight_sethsv_noeeprom(rgblight_config.hue, rgblight_config.sat, pgm_read_byte(&RGBLED_BREATHING_TABLE[pos])); pos = pos + interval*increament; - if (pos < interval || pos+interval > 126) { + if (pos < interval || pos+interval > 62) { + //if (pos < interval || pos+interval > 126) { increament *= -1; } } @@ -283,7 +297,7 @@ void rgblight_effect_rainbow_mood(uint8_t interval) { static uint16_t current_hue = 0; rgblight_sethsv_noeeprom(current_hue, rgblight_config.sat, rgblight_config.val); - current_hue = (current_hue + interval * 3) % 768; + current_hue = hue_fix(current_hue + interval * 3); } void rgblight_effect_rainbow_swirl(uint8_t interval) @@ -292,16 +306,13 @@ void rgblight_effect_rainbow_swirl(uint8_t interval) uint16_t hue; uint8_t i; uint8_t interval2 = interval/2; + if (interval & 1) interval2 *= -1; for (i=0; i 15 @@ -317,7 +328,10 @@ void rgblight_effect_snake(uint8_t interval) rgblight_clear(); if (interval%2) increament = -1; for (i=0; i= RGBLED_NUM) target_led -= RGBLED_NUM; + sethsv(rgblight_config.hue+i*50, rgblight_config.sat, rgblight_config.val, &led[target_led]); } pos += increament; if (pos > RGBLED_NUM) pos = 0; @@ -340,17 +354,17 @@ void rgblight_effect_knight(uint8_t interval) sled_step = 0; rgblight_clear(); for (i=0; i= 0){ + int8_t target_col = pos+i; + if (target_col < RGBLED_NUM && target_col >= 0){ need_update = 1; - uint8_t tmp_col = pos+i; - led[tmp_col%RGBLED_NUM] = led[RGBLED_TEMP]; + led[target_col] = led[RGBLED_TEMP]; } } if (need_update) rgblight_set(); //Keep the first or last col on when increament changes. pos += increament; if (pos <= 0 - RGBLIGHT_EFFECT_KNIGHT_LENGTH || pos >= RGBLED_NUM) { increament *= -1; - current_hue = (current_hue + 40) % 768; + current_hue = hue_fix(current_hue + 40); sethsv(current_hue, rgblight_config.sat, rgblight_config.val, &led[RGBLED_TEMP]); } } @@ -362,7 +376,6 @@ void suspend_power_down_action(void) PORTE &= ~(1<<6); PORTF &= ~(1<<0); PORTB &= ~(1<<2); - DDRC &= ~(1<<6); //backlight_disable(); rgblight_timer_disable(); //RGB_VCC off @@ -372,53 +385,48 @@ void suspend_wakeup_init_action(void) { rgblight_init(); DDRC |= (1<<6); - if (BLE51_PowerState >= 4) display_connection_status_check_times = 1; } void hook_keyboard_loop() { + if (BLE51_PowerState > 1) return; static uint16_t rgb_update_timer = 0; - if (rgblight_timer_enabled && timer_elapsed(rgb_update_timer) > 40) { + static uint8_t steps = 0; + if (timer_elapsed(rgb_update_timer) > 40) { rgb_update_timer = timer_read(); - if (!low_battery) { - if (!display_connection_status_check_times || !ble51_boot_on) rgblight_task(); + //if (!display_connection_status_check_times || !ble51_boot_on) rgblight_task(); + rgblight_task(); + + if ((steps++ & 0b11)) return; + //led_status_task(); + // run every 4*40 = 160ms + PORTE &= ~(1<<6); // led1 off + PORTF &= ~(1<<0); // led2 off + PORTB &= ~(1<<2); // led3 off + // low_battery and display_connection_status when ble51_on + if (ble51_boot_on && (low_battery || display_connection_status_check_times)) { + rgblight_timer_enable(); + // 320ms on,320ms off. bt connected: 320ms*3 on, 320ms off. + if (low_battery) { + backlight_disable(); + rgblight_timer_disable(); + if (steps & 0b1000) PORTB |= (1<<2); + } else { + if (bt_connected) { + if (steps & 0b11000) { PORTB |= (1<<2); PORTF |= (1<<0); } + } else { + if (steps & 0b1000) { PORTB |= (1<<2); } + } + } + } + // capslock + if (host_keyboard_leds() & (1< 150) { - battery_timer = timer_read(); - ble51_task_steps++; - if (low_battery) { - if (ble51_task_steps > 3) { - ble51_task_steps = (low_battery == 1)? 3:0; //value 1 is extremely low battery - if (PINC & (1<<7)) { //not charging - backlight_disable(); - rgblight_timer_disable(); - PORTB ^= (1<<2); - } else { - low_battery = 0; - suspend_wakeup_init_action(); - } - } - } else if (display_connection_status_check_times) { - if (ble51_task_steps == 1) { - PORTB &= ~(1<<2); - PORTF &= ~(1<<0); - } - if (ble51_task_steps == 3) { - PORTB |= (1<<2); - if (bt_connected) { - PORTF |= (1<<0); - } - } - if ((!bt_connected && ble51_task_steps >= 5) || ble51_task_steps >= 11) { - ble51_task_steps = 0; - } - } - } + return; } diff --git a/keyboards/ydkb/louise/rules.mk b/keyboards/ydkb/louise/rules.mk index 0190456ae21..28ec28834c9 100644 --- a/keyboards/ydkb/louise/rules.mk +++ b/keyboards/ydkb/louise/rules.mk @@ -6,27 +6,31 @@ F_CPU = 8000000 # Bootloader selection BOOTLOADER = lufa-ms -BOOTLOADER_SIZE = 6144 +BOOTLOADER_SIZE = 6400 # Build Options # change yes to no to disable # CUSTOM_MATRIX = yes # Custom matrix file -UNICODE_ENABLE = yes # Unicode -BOOTMAGIC_ENABLE = yes # Enable Bootmagic Lite -MOUSEKEY_ENABLE = yes # Mouse keys -EXTRAKEY_ENABLE = yes # Audio control and System control -CONSOLE_ENABLE = no # Console for debug -COMMAND_ENABLE = yes # Commands for debug and configuration -NKRO_ENABLE = yes # Enable N-Key Rollover -BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality -RGBLIGHT_ENABLE = no -LTO_ENABLE = yes +BOOTMAGIC_ENABLE = no # Enable Bootmagic Lite +MOUSEKEY_ENABLE ?= yes # Mouse keys +EXTRAKEY_ENABLE ?= yes # Audio control and System control +CONSOLE_ENABLE ?= no # Console for debug +COMMAND_ENABLE = yes # Commands for debug and configuration +# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE +#SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend +# if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work +NKRO_ENABLE = yes # USB Nkey Rollover +BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality +RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow +LTO_ENABLE = yes # Enable Link Time Optimization +BACKLIGHT_DRIVER = custom -# project specific files -SRC ?= matrix.c \ +SRC += matrix.c \ led_fn.c \ light_ws2812.c \ + backlight_user.c \ rgblight.c + include $(TMK_DIR)/protocol/ble51.mk diff --git a/keyboards/ydkb/pearly_v1/backlight_user.c b/keyboards/ydkb/pearly_v1/backlight_user.c new file mode 100644 index 00000000000..948dc2116b7 --- /dev/null +++ b/keyboards/ydkb/pearly_v1/backlight_user.c @@ -0,0 +1,52 @@ +/* +Copyright 2020 YANG + +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 . +*/ + +#include +#include +#include +#include "backlight.h" +#include "timer.h" + + +void backlight_init_ports(void) { + DDRB |= (1<<7); + //PORTB |= (1<<7); +} + +void backlight_task(void) { + return; +} + +void backlight_user_enable(void) +{ + + //DDRB |= (1<<7); + PORTB &= ~(1<<7); +} + +void backlight_user_disable(void) +{ + //DDRB &= ~(1<<7); + PORTB |= (1<<7); +} + +void backlight_set(uint8_t level) +{ + if (level) backlight_user_enable(); + else backlight_user_disable(); +} + diff --git a/keyboards/ydkb/pearly_v1/config.h b/keyboards/ydkb/pearly_v1/config.h index 83747fff950..5fc04c88d53 100644 --- a/keyboards/ydkb/pearly_v1/config.h +++ b/keyboards/ydkb/pearly_v1/config.h @@ -3,14 +3,19 @@ #include "config_common.h" /* USB Device descriptor parameter */ -#define FW_VER QMK_DMCN -#define FW_VER_VIA VIA_DMCN -#define FW_VER_VIAL VIAL_DMCN +#define FW_VER_DATE DO69 +#define CONTACT(x,y) x##y +#define CONTACT2(x,y) CONTACT(x,y) +#define FW_VER CONTACT2(VIAL_, FW_VER_DATE) #define VENDOR_ID 0x9D5B #define PRODUCT_ID 0x2040 #define DEVICE_VER 0x0001 #define MANUFACTURER YDKB +#if CONSOLE_ENABLE +#define PRODUCT Pearly Debug (FW_VER) +#else #define PRODUCT Pearly (FW_VER) +#endif #define MATRIX_ROWS 4 @@ -21,7 +26,7 @@ #define TAPPING_TOGGLE 2 #define BACKLIGHT_PIN B7 -#define BACKLIGHT_LEVELS 6 +#define BACKLIGHT_LEVELS 1 #define BACKLIGHT_ON_STATE 0 /* key combination for command */ @@ -34,6 +39,7 @@ #define ws2812_DDRREG DDRD #define ws2812_pin PD0 #define RGBLED_NUM 12 // Number of LEDs +#define RGBLIGHT_MODES 14 //less rgblight mode to save some space for vial /* disable command for default layer */ #define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS 0 @@ -67,15 +73,18 @@ #endif /* BT Power Control */ #define BT_POWERED (~PORTD & (1<<5)) -#define bt_power_init() do { DDRD |= (1<<5); PORTD &= ~(1<<5);} while(0) -#define turn_off_bt() do { PORTD |= (1<<5); UCSR1B &= ~(1<. #include "ble51.h" #include "rgblight.h" - +#if 0 void led_set_user(uint8_t usb_led) { if (usb_led & (1<event.pressed) { - switch (keycode) { - case USER00: - command_extra(KC_U); - break; - case USER01: //RESET - command_extra(KC_B); - break; - case USER02: //BATTERY LEVEL - command_extra(KC_V); - break; - case USER03: //LOCK MODE - command_extra(KC_L); - break; - case USER04 ... USER12: - rgblight_action(keycode - USER04); - break; + static const uint8_t userx_to_command[4] = { + KC_U, // 0 Host Switch + KC_B, // 1 Reset + KC_V, // 2 Output Battery Value + KC_L // 3 Lock Mode + }; + if (keycode >= USER00) { + if (keycode < USER04) command_extra(userx_to_command[keycode-USER00]); + else if (keycode <= USER12) rgblight_action(keycode - USER04); } } } \ No newline at end of file diff --git a/keyboards/ydkb/pearly_v1/matrix.c b/keyboards/ydkb/pearly_v1/matrix.c index 73d42c4dba3..e689569b3ae 100644 --- a/keyboards/ydkb/pearly_v1/matrix.c +++ b/keyboards/ydkb/pearly_v1/matrix.c @@ -13,6 +13,7 @@ #include "keyboard.h" #include "timer.h" #include "matrix.h" +#include "debounce_pk.h" #include "suspend.h" #include "lufa.h" #include "rgblight.h" @@ -20,10 +21,6 @@ #include "ble51_task.h" #include "backlight.h" -#define DEBOUNCE_DN_MASK (uint8_t)(~(0x80 >> 5)) -#define DEBOUNCE_UP_MASK (uint8_t)(0x80 >> 5) - -bool is_ble_version = 1; extern rgblight_config_t rgblight_config; extern backlight_config_t backlight_config; @@ -41,54 +38,48 @@ static void select_row(uint8_t row); static uint8_t get_key(uint8_t col); static void init_cols(void); -__attribute__ ((weak)) -void matrix_scan_user(void) {} +void matrix_scan_user(void) {} __attribute__ ((weak)) void matrix_scan_kb(void) { matrix_scan_user(); hook_keyboard_loop(); } -inline -uint8_t matrix_rows(void) +inline uint8_t matrix_rows(void) { return MATRIX_ROWS; } -inline -uint8_t matrix_cols(void) +inline uint8_t matrix_cols(void) { return MATRIX_COLS; } void hook_early_init() { - if (pgm_read_byte(0x7e72) == 0x4c) { + // PD1 for BLE Reset, PB3 for BT_SW + DDRD &= ~(1<<1); + PORTD |= (1<<1); + DDRB &= ~(1<<3); + PORTB |= (1<<3); + WAIT_MS(6); + if ( (pgm_read_byte(0x7e72) == 0x4c) || (~PINB & (1<<3))) { // USB Only version - is_ble_version = 0; ble51_boot_on = 0; } else { - // PD1 for BLE Reset, PB3 for BT_SW - DDRD &= ~(1<<1); - PORTD |= (1<<1); - DDRB &= ~(1<<3); - PORTB |= (1<<3); - _delay_ms(2); - if ((~PINB & (1<<3))) ble51_boot_on = 0; //BLE Reset if (ble_reset_key == 0xBBAA) { - if (ble51_boot_on) { - // PE6 for BLE Reset - DDRD |= (1<<1); - PORTD &= ~(1<<1); - bt_power_init(); - // light CapsLED - DDRB |= (1<<2); - PORTB |= (1<<2); - _delay_ms(5000); - bootloader_jump(); - } + ble_reset_key = 0; + // PE6 for BLE Reset + DDRD |= (1<<1); + PORTD &= ~(1<<1); + bt_power_init(); + // light CapsLED + DDRB |= (1<<2); + PORTB |= (1<<2); + _delay_ms(5000); + bootloader_jump(); } } } @@ -105,19 +96,19 @@ uint8_t matrix_scan(void) { uint16_t time_check = timer_read(); - if (matrix_scan_timestamp == time_check) return 1; + if (matrix_scan_timestamp == time_check) return 0; matrix_scan_timestamp = time_check; + uint8_t matrix_keys_down = 0; uint8_t *debounce = &matrix_debouncing[0][0]; - for (uint8_t row=0; row> 1) | key; - - if (BLE51_PowerState >= 2 && BLE51_PowerState < 10 && key == 0x80) return 100; + //if ((*debounce > 0) && (*debounce < 255)) { if (1) { matrix_row_t *p_row = &matrix[row]; @@ -128,16 +119,18 @@ uint8_t matrix_scan(void) *p_row &= ~col_mask; } } + if (*debounce) matrix_keys_down++; } - if (matrix[row] > 0) { - if (!rgblight_config.enable && !backlight_config.enable) kb_idle_times = 12; - else kb_idle_times = 0; - } - //unselect_rows(); } - + + if (matrix_keys_down) { + //if (BLE_LIGHT_ON == 0) kb_idle_times = 12; + //else kb_idle_times = 0; + kb_idle_times = 0; + } + matrix_scan_quantum(); - return 1; + return matrix_keys_down; } @@ -163,14 +156,6 @@ void matrix_print(void) } } -uint8_t matrix_key_count(void) -{ - uint8_t count = 0; - for (uint8_t i = 0; i < MATRIX_ROWS; i++) { - count += bitpop16(matrix[i]); - } - return count; -} static const struct AVR_PINS col_PIN[] = { PD(6), PD(7), PB(4), PB(5), PB(6), PC(6), PC(7), PE(2), PF(7), PF(6), PB(0), PF(5) }; static const struct AVR_PINS row_PIN[] = {PF(4), PF(1), PF(0), PE(6)}; @@ -230,7 +215,7 @@ static uint8_t get_key(uint8_t col) * row: 0 1 2 3 * pin: F4 F1 F0 E6 */ -void unselect_rows(void) +static void unselect_rows(void) { } @@ -242,34 +227,33 @@ static void select_row(uint8_t row) } } + bool suspend_wakeup_condition(void) { - if (BLE51_PowerState >= 10) { - matrix_scan(); - // K14 F, K17 J - uint8_t *debounce = &matrix_debouncing[0][0]; - uint8_t matrix_keys_down = 0; - for (uint8_t i=0; i< MATRIX_ROWS * MATRIX_COLS; i++, *debounce++) { - if (*debounce > 0) { - if (i == KP(1,4) || i == KP(1,7)) matrix_keys_down += 100; - else matrix_keys_down++; - } - } - if (matrix_keys_down == 200) { - return true; - } else if (!ble51_boot_on && matrix_keys_down) return true; - } else { - //check encoder - select_row(3); - _delay_us(6); - uint8_t encoder_state_check[2][2]; - encoder_state_check[0][1] = PIND&(1<= 10) {//lock mode + if (matrix_keys_down == 2) { + // K14 F, K17 J + if (matrix_debouncing[1][4] == 0xff && matrix_debouncing[1][7] == 0xff) return true; } + if (!ble51_boot_on) return true; + return false; } - return false; + + return matrix_keys_down; +} + +void bootmagic_lite(void) +{ + //do nothing + return; } + +void hook_nkro_change(void) +{ + return; + uint8_t kbd_nkro = keymap_config.nkro; + type_num(kbd_nkro?6:0); +} \ No newline at end of file diff --git a/keyboards/ydkb/pearly_v1/rgblight.c b/keyboards/ydkb/pearly_v1/rgblight.c index 423a62edd52..1c3f517a995 100644 --- a/keyboards/ydkb/pearly_v1/rgblight.c +++ b/keyboards/ydkb/pearly_v1/rgblight.c @@ -9,7 +9,6 @@ #include "lufa.h" #include "ble51.h" #include "ble51_task.h" -#include "backlight.h" #include "led.h" #include "quantum.h" @@ -17,37 +16,79 @@ #define rgblight_timer_enable() do { PORTD &= ~(1<<4);} while(0) #define rgblight_timer_disable() do { PORTD |= (1<<4);} while(0) #define rgblight_timer_enabled (~PORTD & (1<<4)) + #define RGBLED_TEMP RGBLED_NUM +#define INDICATOR_NUM 0 +struct cRGB rgbled[RGBLED_NUM+INDICATOR_NUM+1]; +struct cRGB *led = &rgbled[INDICATOR_NUM]; + //const uint8_t RGBLED_BREATHING_TABLE[128] PROGMEM= {0,0,0,0,1,1,1,2,2,3,4,5,5,6,7,9,10,11,12,14,15,17,18,20,21,23,25,27,29,31,33,35,37,40,42,44,47,49,52,54,57,59,62,65,67,70,73,76,79,82,85,88,90,93,97,100,103,106,109,112,115,118,121,124,127,131,134,137,140,143,146,149,152,155,158,162,165,167,170,173,176,179,182,185,188,190,193,196,198,201,203,206,208,211,213,215,218,220,222,224,226,228,230,232,234,235,237,238,240,241,243,244,245,246,248,249,250,250,251,252,253,253,254,254,254,255,255,255}; const uint8_t RGBLED_BREATHING_TABLE[64] PROGMEM= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 3, 4, 5, 6, 8, 10, 12, 15, 17, 20, 24, 28, 32, 36, 41, 46, 51, 57, 63, 70, 76, 83, 91, 98, 106, 113, 121, 129, 138, 146, 154, 162, 170, 178, 185, 193, 200, 207, 213, 220, 225, 231, 235, 240, 244, 247, 250, 252, 253, 254, 255}; -//battery -extern bool no_rgblight; -extern bool is_ble_version; - rgblight_config_t rgblight_config = {.enable = 1, .mode = 8,.hue = 640, .sat = 255, .val = 255}; -struct cRGB led[RGBLED_NUM+1]; +void sethsv(uint8_t hue, uint8_t saturation, uint8_t brightness, struct cRGB *led1) +{ + /* + original code: https://blog.adafruit.com/2012/03/14/constant-brightness-hsb-to-rgb-algorithm/ + use 8bit hue, hue16 = hue*3 to reach 0 to 767. + */ + uint8_t r, g, b; + uint8_t temp[5]; + uint16_t hue16 = hue*3; + uint8_t n = hue16 >> 8; + uint8_t x = ((((hue16 & 255) * saturation) >> 8) * brightness) >> 8; + uint8_t s = ((256 - saturation) * brightness) >> 8; + + //temp[n] g r b as struct cRGB of ws2812. save 18B + temp[0] = temp[3] = x + s; + temp[1] = temp[4] = brightness - x; + temp[2] = s; + memcpy(led1, &temp[n], 3); +} + +#if 0 // my old code. the new way use 8bit hue saves about 134B +uint16_t hue_fix(uint16_t hue) +{ + // hue needs to be 0x100 to 0x3ff + hue += 0x300; + while (hue > 0x3ff) hue -= 0x300; + return hue; +} void sethsv(uint16_t hue, uint8_t saturation, uint8_t brightness, struct cRGB *led1) { /* original code: https://blog.adafruit.com/2012/03/14/constant-brightness-hsb-to-rgb-algorithm/ + when calculating hue, it may below 0. + So I save hue as 0x100 to 0x3ff (256 to 1023) instead of (0 to 767). + And n changes from 0-2 to 1-3. */ uint8_t r, g, b; uint8_t temp[5]; - uint8_t n = (hue >> 8) % 3; + // uint8_t n = (hue >> 8) % 3; + hue = hue_fix(hue); + uint8_t n = hue >> 8; + if (n > 3) return; // 0 would be error. just leave it. uint8_t x = ((((hue & 255) * saturation) >> 8) * brightness) >> 8; uint8_t s = ((256 - saturation) * brightness) >> 8; +#if 0 //temp[n-1] b g r temp[0] = temp[3] = s; temp[1] = temp[4] = x + s; temp[2] = brightness - x; - r = temp[n + 2]; - g = temp[n + 1]; - b = temp[n]; + r = temp[n + 1]; + g = temp[n]; + b = temp[n - 1]; setrgb(r,g,b, led1); +#else //temp[n-1] g r b as struct cRGB of ws2812. save 18B + temp[0] = temp[3] = x + s; + temp[1] = temp[4] = brightness - x; + temp[2] = s; + memcpy(led1, &temp[n-1], 3); +#endif } +#endif void setrgb(uint8_t r, uint8_t g, uint8_t b, struct cRGB *led1) { @@ -86,7 +127,7 @@ void eeconfig_debug_rgblight(void) { void rgblight_init(void) { dprintf("rgblight_init start!\n"); -#if 0 +#if 1 if (!eeconfig_is_enabled()) { dprintf("rgblight_init eeconfig is not enabled.\n"); eeconfig_init(); @@ -103,25 +144,33 @@ void rgblight_init(void) rgblight_mode(rgblight_config.mode); } +uint8_t limit_value_0to255(int16_t value) { + if (value > 255) return 255; + else if (value < 0) return 0; + else return value; +} void rgblight_mode(int8_t mode) { - // rgb off + // rgb off, new way to save about 60B if (!rgblight_config.enable) { //rgblight_clear(); //rgblight_set(); rgblight_timer_disable(); } else { // rgb on + #if 1 //less than 0 can always be 0. save 8B if (mode < 0) mode = RGBLIGHT_MODES - 1; - else if (mode >= RGBLIGHT_MODES) mode = 0; + else + #endif + if (mode >= RGBLIGHT_MODES) mode = 0; rgblight_config.mode = mode; dprintf("rgblight mode: %u\n", rgblight_config.mode); rgblight_timer_enable(); } - // save config - eeconfig_write_rgblight(rgblight_config.raw); + // save config. rgblight_sethsv() will save config. + //eeconfig_write_rgblight(rgblight_config.raw); rgblight_sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val); } @@ -142,9 +191,9 @@ void rgblight_action(uint8_t action) 5 sat- 6 sat+ 7 val- 8 val+ */ - uint16_t hue = rgblight_config.hue; - int16_t sat = rgblight_config.sat; - int16_t val = rgblight_config.val; + uint8_t hue = rgblight_config.hue; + uint8_t sat = rgblight_config.sat; + uint8_t val = rgblight_config.val; int8_t increament = 1; if (action & 1) increament = -1; if (get_mods() & MOD_BIT(KC_LSHIFT)) { @@ -160,19 +209,15 @@ void rgblight_action(uint8_t action) break; case 3: case 4: - hue = (rgblight_config.hue + 768 + RGBLIGHT_HUE_STEP * increament) % 768; + hue = rgblight_config.hue + RGBLIGHT_HUE_STEP * increament; break; case 5: case 6: - sat = rgblight_config.sat + RGBLIGHT_SAT_STEP * increament; - if (sat > 255) sat = 255; - if (sat < 0) sat = 0; + sat = limit_value_0to255(rgblight_config.sat + RGBLIGHT_SAT_STEP * increament); break; case 7: case 8: - val = rgblight_config.val + RGBLIGHT_VAL_STEP * increament; - if (val > 255) val = 255; - if (val < 0) val = 0; + val = limit_value_0to255(rgblight_config.val + RGBLIGHT_VAL_STEP * increament); break; default: break; @@ -180,58 +225,62 @@ void rgblight_action(uint8_t action) if (action >= 3) rgblight_sethsv(hue, sat, val); } -void rgblight_sethsv_noeeprom(uint16_t hue, uint8_t sat, uint8_t val) +void rgblight_sethsv_noeeprom(uint8_t hue, uint8_t sat, uint8_t val) { if (rgblight_config.enable) { sethsv(hue, sat, val, &led[RGBLED_TEMP]); for (uint8_t i=0; i< RGBLED_NUM; i++) { led[i] = led[RGBLED_TEMP]; } - rgblight_set(); + //rgblight_set(); } } -void rgblight_sethsv(uint16_t hue, uint8_t sat, uint8_t val) +void rgblight_sethsv(uint8_t hue, uint8_t sat, uint8_t val) { + //hue = hue_fix(hue); if (rgblight_config.enable) { + #if 0 // will do rgblight_sethsv_noeeprom() in rgblight_task if (rgblight_config.mode == 1) { // same static color rgblight_sethsv_noeeprom(hue, sat, val); } + #endif rgblight_config.hue = hue; rgblight_config.sat = sat; rgblight_config.val = val; - eeconfig_write_rgblight(rgblight_config.raw); dprintf("rgblight set hsv [EEPROM]: %u,%u,%u\n", rgblight_config.hue, rgblight_config.sat, rgblight_config.val); } + // when rgblight_config.enable == 0, just save config.raw. + eeconfig_write_rgblight(rgblight_config.raw); } void rgblight_setrgb(uint8_t r, uint8_t g, uint8_t b) { - for (uint8_t i=0;i 15 case 15 ... 20: - rgblight_effect_snake(rgblight_config.mode-13); + rgblight_effect_snake(rgblight_config.mode-14); // 0 to 5 (0 to 2) break; #endif #if RGBLIGHT_MODES > 21 @@ -257,6 +306,7 @@ void rgblight_task(void) break; #endif } + rgblight_set(); } else { rgblight_timer_disable(); } @@ -276,29 +326,24 @@ void rgblight_effect_breathing(uint8_t interval) } } +static uint8_t current_hue = 0; + void rgblight_effect_rainbow_mood(uint8_t interval) { - static uint16_t current_hue = 0; rgblight_sethsv_noeeprom(current_hue, rgblight_config.sat, rgblight_config.val); - current_hue = (current_hue + interval * 3) % 768; + current_hue += interval; } void rgblight_effect_rainbow_swirl(uint8_t interval) { - static uint16_t current_hue=0; - uint16_t hue; - uint8_t i; - uint8_t interval2 = interval/2; - for (i=0; i 15 @@ -314,12 +359,15 @@ void rgblight_effect_snake(uint8_t interval) rgblight_clear(); if (interval%2) increament = -1; for (i=0; i= RGBLED_NUM) target_led -= RGBLED_NUM; + sethsv(rgblight_config.hue+i*16, rgblight_config.sat, rgblight_config.val, &led[target_led]); } pos += increament; if (pos > RGBLED_NUM) pos = 0; else if (pos < 0 ) pos = RGBLED_NUM; - rgblight_set(); + //rgblight_set(); } } #endif @@ -329,7 +377,6 @@ void rgblight_effect_knight(uint8_t interval) { static int8_t pos = RGBLED_NUM - 1; static uint8_t sled_step = 0; - static uint16_t current_hue=0; uint8_t i; static int8_t increament = 1; if (++sled_step > interval) { @@ -337,17 +384,17 @@ void rgblight_effect_knight(uint8_t interval) sled_step = 0; rgblight_clear(); for (i=0; i= 0){ + int8_t target_col = pos+i; + if (target_col < RGBLED_NUM && target_col >= 0){ need_update = 1; - uint8_t tmp_col = pos+i; - led[tmp_col%RGBLED_NUM] = led[RGBLED_TEMP]; + led[target_col] = led[RGBLED_TEMP]; } } if (need_update) rgblight_set(); //Keep the first or last col on when increament changes. pos += increament; if (pos <= 0 - RGBLIGHT_EFFECT_KNIGHT_LENGTH || pos >= RGBLED_NUM) { increament *= -1; - current_hue = (current_hue + 40) % 768; + current_hue = current_hue + 16; sethsv(current_hue, rgblight_config.sat, rgblight_config.val, &led[RGBLED_TEMP]); } } @@ -358,7 +405,6 @@ void suspend_power_down_action(void) { PORTB &= ~(1<<2 | 1<<1); // PB2 Caps, PB1 LED2 DDRB &= ~(1<= 4) display_connection_status_check_times = 1; } void hook_keyboard_loop() { + if (BLE51_PowerState > 1) return; static uint16_t rgb_update_timer = 0; - if (rgblight_timer_enabled && timer_elapsed(rgb_update_timer) > 40) { + static uint8_t steps = 0; + if (timer_elapsed(rgb_update_timer) > 40) { rgb_update_timer = timer_read(); - if (!display_connection_status_check_times || !ble51_boot_on) rgblight_task(); - } -} + if (!display_connection_status_check_times) rgblight_task(); -void ble51_task_user(void) -{ - static uint8_t ble51_task_steps = 0; - static uint16_t battery_timer = 0; - if (timer_elapsed(battery_timer) > 150) { - battery_timer = timer_read(); - ble51_task_steps++; - if (low_battery) { - if (ble51_task_steps > 3) { - ble51_task_steps = (low_battery == 1)? 3:0; //value 1 is extremely low battery - if (USB_DeviceState != DEVICE_STATE_Configured) { //not charging - backlight_disable(); - rgblight_timer_disable(); - PORTB ^= (1<<2); + if ((steps++ & 0b11)) return; + //led_status_task(); + // run every 4*40 = 160ms + PORTB &= ~(1<<2 | 1<<1); //led off + if (ble51_boot_on && (low_battery || display_connection_status_check_times)) { + rgblight_timer_enable(); + rgblight_clear(); + // 320ms on,320ms off. bt connected: 320ms*3 on, 320ms off. + if (low_battery) { + rgblight_timer_disable(); + if (steps & 0b1000) PORTB |= (1<<2); + } else { + if (bt_connected) { + if (steps & 0b11000) { + PORTB |= (1<<2 | 1<<2); + rgblight_setrgb(0,128,0); //green + } } else { - low_battery = 0; - suspend_wakeup_init_action(); + if (steps & 0b1000) { + PORTB |= (1<<1); + rgblight_setrgb(0,0,128); //blue + } } } - } else if (display_connection_status_check_times) { - rgblight_timer_enable(); - if (ble51_task_steps == 1) { - PORTB &= ~(1<<2 | 1<<1); - rgblight_clear(); - rgblight_set(); - } else if (ble51_task_steps == 3) { - PORTB |= (1<<1); - if (bt_connected) PORTB |= (1<<2); - uint8_t g_color = bt_connected? 128:0; - uint8_t b_color = bt_connected? 0:128; - rgblight_setrgb(0,g_color,b_color); - } - if ((!bt_connected && ble51_task_steps >= 5) || ble51_task_steps >= 11) { - ble51_task_steps = 0; - } + ws2812_setleds(rgbled); + } + // capslock + else if (host_keyboard_leds() & (1<. #include "ble51.h" #include "rgblight.h" - +#if 0 void led_set_user(uint8_t usb_led) { if (usb_led & (1<event.pressed) { - switch (keycode) { - case USER00: - command_extra(KC_U); - break; - case USER01: //RESET - command_extra(KC_B); - break; - case USER02: //BATTERY LEVEL - command_extra(KC_V); - break; - case USER03: //LOCK MODE - command_extra(KC_L); - break; - case USER04 ... USER12: - rgblight_action(keycode - USER04); - break; + static const uint8_t userx_to_command[4] = { + KC_U, // 0 Host Switch + KC_B, // 1 Reset + KC_V, // 2 Output Battery Value + KC_L // 3 Lock Mode + }; + if (keycode >= USER00) { + if (keycode < USER04) command_extra(userx_to_command[keycode-USER00]); + else if (keycode <= USER12) rgblight_action(keycode - USER04); } } } \ No newline at end of file diff --git a/keyboards/ydkb/pearly_v2/light_ws2812.c b/keyboards/ydkb/pearly_v2/light_ws2812.c index 739c9ed8776..19122dda669 100644 --- a/keyboards/ydkb/pearly_v2/light_ws2812.c +++ b/keyboards/ydkb/pearly_v2/light_ws2812.c @@ -21,7 +21,6 @@ void ws2812_setleds(struct cRGB *ledarray) //_delay_us(50); } - // Timing in ns #define w_zeropulse 350 #define w_onepulse 900 diff --git a/keyboards/ydkb/pearly_v2/matrix.c b/keyboards/ydkb/pearly_v2/matrix.c index 4cf24bbc0ee..6c95107d27e 100644 --- a/keyboards/ydkb/pearly_v2/matrix.c +++ b/keyboards/ydkb/pearly_v2/matrix.c @@ -1,30 +1,37 @@ -#include -#include -#include -#include -#include -#include -#include "avr_config.h" +/* +Copyright 2023 YANG + +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 . +*/ + +/* + * scan matrix + */ +#include "wait.h" +#include "action_layer.h" #include "print.h" #include "debug.h" #include "util.h" -#include "action.h" -#include "command.h" -#include "keyboard.h" #include "timer.h" #include "matrix.h" +#include "debounce_pk.h" #include "suspend.h" -#include "lufa.h" #include "rgblight.h" #include "ble51.h" -#include "ble51_task.h" -#define DEBOUNCE_DN_MASK (uint8_t)(~(0x80 >> 5)) -#define DEBOUNCE_UP_MASK (uint8_t)(0x80 >> 5) - -bool is_ble_version = 1; -extern rgblight_config_t rgblight_config; +/* matrix state(1:on, 0:off) */ static matrix_row_t matrix[MATRIX_ROWS] = {0}; static uint16_t matrix_scan_timestamp = 0; @@ -47,17 +54,6 @@ void matrix_scan_kb(void) { hook_keyboard_loop(); } -inline -uint8_t matrix_rows(void) -{ - return MATRIX_ROWS; -} - -inline -uint8_t matrix_cols(void) -{ - return MATRIX_COLS; -} void hook_early_init() { @@ -71,6 +67,7 @@ void hook_early_init() if ((~PINB & (1<<3))) ble51_boot_on = 0; //BLE Reset if (ble_reset_key == 0xBBAA) { + ble_reset_key = 0; if (ble51_boot_on) { // PD3,TX_MCU to RX_51 DDRD |= (1<<3 ); @@ -80,7 +77,7 @@ void hook_early_init() DDRB |= (1<<2); PORTB |= (1<<2); _delay_ms(5000); - bootloader_jump(); + bootloader_jump(); } } } @@ -89,26 +86,27 @@ void hook_early_init() void matrix_init(void) { DDRB |= (1<<2); - PORTB &= ~(1<<2); + //PORTB &= ~(1<<2); init_cols(); rgblight_init(); } uint8_t matrix_scan(void) { - uint16_t time_check = timer_read(); if (matrix_scan_timestamp == time_check) return 1; matrix_scan_timestamp = time_check; + uint8_t matrix_keys_down = 0; + uint8_t *debounce = &matrix_debouncing[0][0]; - for (uint8_t row=0; row> 1) | key; - + //if ((*debounce > 0) && (*debounce < 255)) { if (1) { matrix_row_t *p_row = &matrix[row]; @@ -119,16 +117,18 @@ uint8_t matrix_scan(void) *p_row &= ~col_mask; } } + if (*debounce) matrix_keys_down++; } - if (matrix[row] > 0) { - if (!rgblight_config.enable) kb_idle_times = 12; - else kb_idle_times = 0; - } - //unselect_rows(); } - + + if (matrix_keys_down) { + if (BLE_LIGHT_ON == 0) kb_idle_times = 12; + else kb_idle_times = 0; + } + //unselect_rows(); + matrix_scan_quantum(); - return 1; + return matrix_keys_down; } @@ -146,10 +146,10 @@ matrix_row_t matrix_get_row(uint8_t row) void matrix_print(void) { - print("\nr/c 01234567\n"); + print("\nr/c 0123456789ABCDEF\n"); for (uint8_t row = 0; row < MATRIX_ROWS; row++) { print_hex8(row); print(": "); - print_bin_reverse8(matrix_get_row(row)); + print_bin_reverse16(matrix_get_row(row)); print("\n"); } } @@ -172,7 +172,7 @@ static const struct AVR_PINS row_PIN[] = {PF(4), PF(1), PF(0), PE(6)}; */ static void init_cols(void) { - for (uint8_t col=0; col= 10) { - matrix_scan(); - // K14 F, K17 J - uint8_t *debounce = &matrix_debouncing[0][0]; - uint8_t matrix_keys_down = 0; - for (uint8_t i=0; i< MATRIX_ROWS * MATRIX_COLS; i++, *debounce++) { - if (*debounce > 0) { - if (i == KP(1,4) || i == KP(1,7)) matrix_keys_down += 100; - else matrix_keys_down++; - } + uint8_t matrix_keys_down = matrix_scan(); + if (matrix_keys_down == 2) { + // K14 F, K17 J + if (matrix_debouncing[1][4] == 0xff && matrix_debouncing[1][7] == 0xff) return true; } - if (matrix_keys_down == 200) { - return true; - } else if (!ble51_boot_on && matrix_keys_down) return true; + if (!ble51_boot_on) return true; + return false; + } else { select_all_rows(); _delay_us(6); @@ -231,3 +226,18 @@ bool suspend_wakeup_condition(void) } return false; } + +void bootmagic_lite(void) +{ + //do nothing + return; + +} + +void hook_nkro_change(void) +{ + return; + uint8_t kbd_nkro = keymap_config.nkro; + type_num(kbd_nkro?6:0); +} + diff --git a/keyboards/ydkb/pearly_v2/rgblight.c b/keyboards/ydkb/pearly_v2/rgblight.c index c332a35503b..bcfddb63e74 100644 --- a/keyboards/ydkb/pearly_v2/rgblight.c +++ b/keyboards/ydkb/pearly_v2/rgblight.c @@ -17,33 +17,48 @@ #define rgblight_timer_disable() do { PORTD |= (1<<4);} while(0) #define rgblight_timer_enabled (~PORTD & (1<<4)) #define RGBLED_TEMP RGBLED_NUM -const uint8_t RGBLED_BREATHING_TABLE[128] PROGMEM = {0,0,0,0,1,1,1,2,2,3,4,5,5,6,7,9,10,11,12,14,15,17,18,20,21,23,25,27,29,31,33,35,37,40,42,44,47,49,52,54,57,59,62,65,67,70,73,76,79,82,85,88,90,93,97,100,103,106,109,112,115,118,121,124,127,131,134,137,140,143,146,149,152,155,158,162,165,167,170,173,176,179,182,185,188,190,193,196,198,201,203,206,208,211,213,215,218,220,222,224,226,228,230,232,234,235,237,238,240,241,243,244,245,246,248,249,250,250,251,252,253,253,254,254,254,255,255,255}; +#define INDICATOR_NUM 0 +struct cRGB rgbled[RGBLED_NUM+INDICATOR_NUM+1]; +struct cRGB *led = &rgbled[INDICATOR_NUM]; -//battery -extern bool no_rgblight; -extern bool is_ble_version; +//const uint8_t RGBLED_BREATHING_TABLE[128] PROGMEM= {0,0,0,0,1,1,1,2,2,3,4,5,5,6,7,9,10,11,12,14,15,17,18,20,21,23,25,27,29,31,33,35,37,40,42,44,47,49,52,54,57,59,62,65,67,70,73,76,79,82,85,88,90,93,97,100,103,106,109,112,115,118,121,124,127,131,134,137,140,143,146,149,152,155,158,162,165,167,170,173,176,179,182,185,188,190,193,196,198,201,203,206,208,211,213,215,218,220,222,224,226,228,230,232,234,235,237,238,240,241,243,244,245,246,248,249,250,250,251,252,253,253,254,254,254,255,255,255}; +const uint8_t RGBLED_BREATHING_TABLE[64] PROGMEM= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 3, 4, 5, 6, 8, 10, 12, 15, 17, 20, 24, 28, 32, 36, 41, 46, 51, 57, 63, 70, 76, 83, 91, 98, 106, 113, 121, 129, 138, 146, 154, 162, 170, 178, 185, 193, 200, 207, 213, 220, 225, 231, 235, 240, 244, 247, 250, 252, 253, 254, 255}; + +static uint8_t rgb_fading_index = 0; //ʹ RGBLED_BREATHING_TABLE rgblight_config_t rgblight_config = {.enable = 1, .mode = 8,.hue = 640, .sat = 255, .val = 255}; -struct cRGB led[RGBLED_NUM+1]; +uint16_t hue_fix(uint16_t hue) +{ + // hue needs to be 0x100 to 0x3ff + hue += 0x300; + while (hue > 0x3ff) hue -= 0x300; + return hue; +} void sethsv(uint16_t hue, uint8_t saturation, uint8_t brightness, struct cRGB *led1) { /* original code: https://blog.adafruit.com/2012/03/14/constant-brightness-hsb-to-rgb-algorithm/ + when calculating hue, it may below 0. + So I save hue as 0x100 to 0x3ff (256 to 1023) instead of (0 to 767). + And n changes from 0-2 to 1-3. */ uint8_t r, g, b; uint8_t temp[5]; - uint8_t n = (hue >> 8) % 3; + // uint8_t n = (hue >> 8) % 3; + hue = hue_fix(hue); + uint8_t n = hue >> 8; + if (n > 3) return; // 0 would be error. just leave it. uint8_t x = ((((hue & 255) * saturation) >> 8) * brightness) >> 8; uint8_t s = ((256 - saturation) * brightness) >> 8; temp[0] = temp[3] = s; temp[1] = temp[4] = x + s; temp[2] = brightness - x; - r = temp[n + 2]; - g = temp[n + 1]; - b = temp[n]; + r = temp[n + 1]; + g = temp[n]; + b = temp[n - 1]; setrgb(r,g,b, led1); } @@ -84,7 +99,7 @@ void eeconfig_debug_rgblight(void) { void rgblight_init(void) { dprintf("rgblight_init start!\n"); -#if 0 +#if 1 if (!eeconfig_is_enabled()) { dprintf("rgblight_init eeconfig is not enabled.\n"); eeconfig_init(); @@ -101,14 +116,20 @@ void rgblight_init(void) rgblight_mode(rgblight_config.mode); } +uint8_t limit_value_0to255(int16_t value) { + if (value > 255) return 255; + else if (value < 0) return 0; + else return value; +} void rgblight_mode(int8_t mode) { - // rgb off + // rgb off, new way to save about 60B if (!rgblight_config.enable) { //rgblight_clear(); //rgblight_set(); rgblight_timer_disable(); + rgb_fading_index = 0; } else { // rgb on if (mode < 0) mode = RGBLIGHT_MODES - 1; @@ -118,8 +139,8 @@ void rgblight_mode(int8_t mode) rgblight_timer_enable(); } - // save config - eeconfig_write_rgblight(rgblight_config.raw); + // save config. rgblight_sethsv() will save config. + //eeconfig_write_rgblight(rgblight_config.raw); rgblight_sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val); } @@ -141,8 +162,8 @@ void rgblight_action(uint8_t action) 7 val- 8 val+ */ uint16_t hue = rgblight_config.hue; - int16_t sat = rgblight_config.sat; - int16_t val = rgblight_config.val; + uint8_t sat = rgblight_config.sat; + uint8_t val = rgblight_config.val; int8_t increament = 1; if (action & 1) increament = -1; if (get_mods() & MOD_BIT(KC_LSHIFT)) { @@ -158,19 +179,15 @@ void rgblight_action(uint8_t action) break; case 3: case 4: - hue = (rgblight_config.hue + 768 + RGBLIGHT_HUE_STEP * increament) % 768; + hue = rgblight_config.hue + RGBLIGHT_HUE_STEP * increament; break; case 5: case 6: - sat = rgblight_config.sat + RGBLIGHT_SAT_STEP * increament; - if (sat > 255) sat = 255; - if (sat < 0) sat = 0; + sat = limit_value_0to255(rgblight_config.sat + RGBLIGHT_SAT_STEP * increament); break; case 7: case 8: - val = rgblight_config.val + RGBLIGHT_VAL_STEP * increament; - if (val > 255) val = 255; - if (val < 0) val = 0; + val = limit_value_0to255(rgblight_config.val + RGBLIGHT_VAL_STEP * increament); break; default: break; @@ -191,45 +208,60 @@ void rgblight_sethsv_noeeprom(uint16_t hue, uint8_t sat, uint8_t val) void rgblight_sethsv(uint16_t hue, uint8_t sat, uint8_t val) { + hue = hue_fix(hue); if (rgblight_config.enable) { + #if 0 // will do rgblight_sethsv_noeeprom() in rgblight_task if (rgblight_config.mode == 1) { // same static color rgblight_sethsv_noeeprom(hue, sat, val); } + #endif rgblight_config.hue = hue; rgblight_config.sat = sat; rgblight_config.val = val; - eeconfig_write_rgblight(rgblight_config.raw); dprintf("rgblight set hsv [EEPROM]: %u,%u,%u\n", rgblight_config.hue, rgblight_config.sat, rgblight_config.val); } + // when rgblight_config.enable == 0, just save config.raw. + eeconfig_write_rgblight(rgblight_config.raw); } void rgblight_setrgb(uint8_t r, uint8_t g, uint8_t b) { - for (uint8_t i=0;i= 13); + if (rgb_fading) { + if (kb_idle_times >= 13 && rgb_fading_index >= RGB_FADING_STEP) rgb_fading_index -= RGB_FADING_STEP; // fading in + else if (kb_idle_times < 13) rgb_fading_index += RGB_FADING_STEP; // fading out + // õ׵Ƶ뵭 + uint8_t *p = (uint8_t *)(&led[0]); + for (uint8_t i=0;i 15 case 15 ... 20: - rgblight_effect_snake(rgblight_config.mode-13); + rgblight_effect_snake(rgblight_config.mode-14); // 0 to 5 (0 to 2) break; + #endif + #if RGBLIGHT_MODES > 21 case 21 ... 23: rgblight_effect_knight(rgblight_config.mode-19); break; + #endif } } else { rgblight_timer_disable(); @@ -264,7 +300,8 @@ void rgblight_effect_breathing(uint8_t interval) static int8_t increament = 1; rgblight_sethsv_noeeprom(rgblight_config.hue, rgblight_config.sat, pgm_read_byte(&RGBLED_BREATHING_TABLE[pos])); pos = pos + interval*increament; - if (pos < interval || pos+interval > 126) { + if (pos < interval || pos+interval > 62) { + //if (pos < interval || pos+interval > 126) { increament *= -1; } } @@ -273,7 +310,7 @@ void rgblight_effect_rainbow_mood(uint8_t interval) { static uint16_t current_hue = 0; rgblight_sethsv_noeeprom(current_hue, rgblight_config.sat, rgblight_config.val); - current_hue = (current_hue + interval * 3) % 768; + current_hue = hue_fix(current_hue + interval * 3); } void rgblight_effect_rainbow_swirl(uint8_t interval) @@ -282,17 +319,16 @@ void rgblight_effect_rainbow_swirl(uint8_t interval) uint16_t hue; uint8_t i; uint8_t interval2 = interval/2; + if (interval & 1) interval2 *= -1; for (i=0; i 15 void rgblight_effect_snake(uint8_t interval) { static int8_t pos = 0 - RGBLIGHT_EFFECT_SNAKE_LENGTH; @@ -305,7 +341,11 @@ void rgblight_effect_snake(uint8_t interval) rgblight_clear(); if (interval%2) increament = -1; for (i=0; i= RGBLED_NUM) target_led -= RGBLED_NUM; + sethsv(rgblight_config.hue+i*50, rgblight_config.sat, rgblight_config.val, &led[target_led]); + //sethsv(rgblight_config.hue+i*50, rgblight_config.sat, rgblight_config.val, &led[(pos+i*increament+RGBLED_NUM)%RGBLED_NUM]); } pos += increament; if (pos > RGBLED_NUM) pos = 0; @@ -313,7 +353,9 @@ void rgblight_effect_snake(uint8_t interval) rgblight_set(); } } +#endif +#if RGBLIGHT_MODES > 21 void rgblight_effect_knight(uint8_t interval) { static int8_t pos = RGBLED_NUM - 1; @@ -326,76 +368,79 @@ void rgblight_effect_knight(uint8_t interval) sled_step = 0; rgblight_clear(); for (i=0; i= 0){ + int8_t target_col = pos+i; + if (target_col < RGBLED_NUM && target_col >= 0){ need_update = 1; - uint8_t tmp_col = pos+i; - led[tmp_col%RGBLED_NUM] = led[RGBLED_TEMP]; + led[target_col] = led[RGBLED_TEMP]; } } if (need_update) rgblight_set(); //Keep the first or last col on when increament changes. pos += increament; if (pos <= 0 - RGBLIGHT_EFFECT_KNIGHT_LENGTH || pos >= RGBLED_NUM) { increament *= -1; - current_hue = (current_hue + 40) % 768; + current_hue = hue_fix(current_hue + 40); sethsv(current_hue, rgblight_config.sat, rgblight_config.val, &led[RGBLED_TEMP]); } } } +#endif void suspend_power_down_action(void) { PORTB &= ~(1<<2); rgblight_timer_disable(); //RGB_VCC off + rgb_fading_index = 0; } void suspend_wakeup_init_action(void) { rgblight_init(); - if (BLE51_PowerState >= 4) display_connection_status_check_times = 1; } void hook_keyboard_loop() { + if (BLE51_PowerState > 1) return; static uint16_t rgb_update_timer = 0; - if (rgblight_timer_enabled && timer_elapsed(rgb_update_timer) > 40) { + static uint8_t steps = 0; + if (timer_elapsed(rgb_update_timer) > 40) { rgb_update_timer = timer_read(); - if (!display_connection_status_check_times || !ble51_boot_on) rgblight_task(); - } -} + if (!display_connection_status_check_times) rgblight_task(); -void ble51_task_user(void) -{ - static uint8_t ble51_task_steps = 0; - static uint16_t battery_timer = 0; - if (timer_elapsed(battery_timer) > 150) { - battery_timer = timer_read(); - ble51_task_steps++; - if (low_battery) { - if (ble51_task_steps > 3) { - ble51_task_steps = (low_battery == 1)? 3:0; //value 1 is extremely low battery - if (PINB & (1<<1)) { //not charging - rgblight_timer_disable(); - PORTB ^= (1<<2); + if ((steps++ & 0b11)) return; + //led_status_task(); + // run every 4*40 = 160ms + PORTB &= ~(1<<2); //caps off + if (ble51_boot_on && (low_battery || display_connection_status_check_times)) { + rgblight_timer_enable(); + rgblight_clear(); + rgb_fading_index = 63; //not fading for all leds. + // 320ms on,320ms off. bt connected: 320ms*3 on, 320ms off. + if (low_battery) { + rgblight_timer_disable(); + if (steps & 0b1000) PORTB |= (1<<2); + } else { + if (bt_connected) { + if (steps & 0b11000) { + PORTB |= (1<<2); + rgblight_setrgb(0,128,0); //green + } } else { - low_battery = 0; - suspend_wakeup_init_action(); + if (steps & 0b1000) { + PORTB |= (1<<2); + rgblight_setrgb(0,0,128); //blue + } } } - } else if (display_connection_status_check_times) { - rgblight_timer_enable(); - if (ble51_task_steps == 1) { - PORTB &= ~(1<<2); - rgblight_clear(); - rgblight_set(); - } else if (ble51_task_steps == 3) { - PORTB |= (1<<2); - uint8_t g_color = bt_connected? 128:0; - uint8_t b_color = bt_connected? 0:128; - rgblight_setrgb(0,g_color,b_color); - } - if ((!bt_connected && ble51_task_steps >= 5) || ble51_task_steps >= 11) { - ble51_task_steps = 0; - } + ws2812_setleds(rgbled); + } + // capslock + else if (host_keyboard_leds() & (1<= 4) display_connection_status_check_times = 1; } void hook_keyboard_loop() diff --git a/quantum/command.c b/quantum/command.c index f7b82c3f105..fcab51be1f4 100644 --- a/quantum/command.c +++ b/quantum/command.c @@ -66,6 +66,10 @@ static void switch_default_layer(uint8_t layer); command_state_t command_state = ONESHOT; bool command_proc(uint8_t code) { +#ifdef NO_DEFAULT_COMMAND //32B + if (!IS_COMMAND()) return false; + return command_extra(code); +#endif switch (command_state) { case ONESHOT: if (!IS_COMMAND()) return false; @@ -324,6 +328,9 @@ static void print_eeconfig(void) { #endif /* !NO_PRINT && !USER_PRINT */ static bool command_common(uint8_t code) { +#ifdef NO_DEFAULT_COMMAND + return true; +#endif #ifdef KEYBOARD_LOCK_ENABLE static host_driver_t *host_driver = 0; #endif @@ -554,6 +561,9 @@ static void command_console_help(void) { } static bool command_console(uint8_t code) { +#ifdef NO_DEFAULT_COMMAND + return true; +#endif switch (code) { case KC_H: case KC_SLASH: /* ? */ @@ -636,6 +646,9 @@ static void mousekey_console_help(void) { * any doubt: we return `false` to return to the main console, * which differs from the `bool` that `command_proc()` returns. */ bool mousekey_console(uint8_t code) { +#ifdef NO_DEFAULT_COMMAND + return true; +#endif static uint8_t param = 0; static uint8_t *pp = NULL; static char * desc = NULL; diff --git a/quantum/dynamic_keymap.c b/quantum/dynamic_keymap.c index f7f9e073a74..79d50df0604 100644 --- a/quantum/dynamic_keymap.c +++ b/quantum/dynamic_keymap.c @@ -274,11 +274,17 @@ void dynamic_keymap_reset(void) { for (int layer = 0; layer < DYNAMIC_KEYMAP_LAYER_COUNT; layer++) { for (int row = 0; row < MATRIX_ROWS; row++) { for (int column = 0; column < MATRIX_COLS; column++) { +#ifdef FLASH_KEYMAP8_COUNT + dynamic_keymap_set_keycode(layer, row, column, (layer < FLASH_KEYMAP8_COUNT)? pgm_read_byte(&keymaps8[layer][row][column]):1); +#elif defined(FLASH_KEYMAP_COUNT) + dynamic_keymap_set_keycode(layer, row, column, (layer < FLASH_KEYMAP_COUNT)? pgm_read_word(&keymaps[layer][row][column]):1); +#else if (layer < keymap_layer_count()) { dynamic_keymap_set_keycode(layer, row, column, pgm_read_word(&keymaps[layer][row][column])); } else { dynamic_keymap_set_keycode(layer, row, column, KC_TRANSPARENT); } +#endif } } #ifdef ENCODER_MAP_ENABLE diff --git a/quantum/eeconfig.c b/quantum/eeconfig.c index 0ff9996ca41..43493af5466 100644 --- a/quantum/eeconfig.c +++ b/quantum/eeconfig.c @@ -41,6 +41,13 @@ void eeconfig_init_quantum(void) { #if defined(EEPROM_DRIVER) eeprom_driver_erase(); #endif +#ifdef RECORE //save 116B + eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER); + for (uint8_t i=2; i <= 34; i++) { + eeprom_update_byte((uint8_t *)i,0); + } + default_layer_state = 0; +#else eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER); eeprom_update_byte(EECONFIG_DEBUG, 0); eeprom_update_byte(EECONFIG_DEFAULT_LAYER, 0); @@ -56,6 +63,7 @@ void eeconfig_init_quantum(void) { eeprom_update_byte(EECONFIG_VELOCIKEY, 0); eeprom_update_dword(EECONFIG_RGB_MATRIX, 0); eeprom_update_word(EECONFIG_RGB_MATRIX_EXTENDED, 0); +#endif // TODO: Remove once ARM has a way to configure EECONFIG_HANDEDNESS // within the emulated eeprom via dfu-util or another tool @@ -73,8 +81,10 @@ void eeconfig_init_quantum(void) { // this is used in case haptic is disabled, but we still want sane defaults // in the haptic configuration eeprom. All zero will trigger a haptic_reset // when a haptic-enabled firmware is loaded onto the keyboard. +#ifndef RECORE //14B eeprom_update_dword(EECONFIG_HAPTIC, 0); #endif +#endif #if defined(VIA_ENABLE) // Invalidate VIA eeprom config, and then reset. // Just in case if power is lost mid init, this makes sure that it pets diff --git a/quantum/keymap.h b/quantum/keymap.h index edff4841290..14e887fa06a 100644 --- a/quantum/keymap.h +++ b/quantum/keymap.h @@ -55,6 +55,7 @@ along with this program. If not, see . uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key); extern const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS]; +extern const uint8_t keymaps8[][MATRIX_ROWS][MATRIX_COLS]; #ifdef ENCODER_MAP_ENABLE // Ensure we have a forward declaration for the encoder map diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c index c41bf8f8bd5..82cf30159c8 100644 --- a/quantum/keymap_common.c +++ b/quantum/keymap_common.c @@ -43,8 +43,10 @@ action_t action_for_key(uint8_t layer, keypos_t key) { }; action_t action_for_keycode(uint16_t keycode) { +#ifndef RECORE //disable for BLE51 // keycode remapping keycode = keycode_config(keycode); +#endif action_t action = {}; uint8_t action_layer, mod; diff --git a/quantum/keymap_introspection.c b/quantum/keymap_introspection.c index 179b5eb0376..a1fe2d86b1a 100644 --- a/quantum/keymap_introspection.c +++ b/quantum/keymap_introspection.c @@ -11,7 +11,11 @@ #include "keymap_introspection.h" +#ifdef FLASH_KEYMAP8_COUNT +#define NUM_KEYMAP_LAYERS ((uint8_t)(sizeof(keymaps8) / ((MATRIX_ROWS) * (MATRIX_COLS)))) +#else #define NUM_KEYMAP_LAYERS ((uint8_t)(sizeof(keymaps) / ((MATRIX_ROWS) * (MATRIX_COLS) * sizeof(uint16_t)))) +#endif uint8_t keymap_layer_count(void) { return NUM_KEYMAP_LAYERS; diff --git a/quantum/mousekey.c b/quantum/mousekey.c index b7aaac57443..2d8e62c56e8 100644 --- a/quantum/mousekey.c +++ b/quantum/mousekey.c @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - +#ifndef RECORE #include #include #include "keycode.h" @@ -537,3 +537,4 @@ report_mouse_t mousekey_get_report(void) { bool should_mousekey_report_send(report_mouse_t *mouse_report) { return mouse_report->x || mouse_report->y || mouse_report->v || mouse_report->h; } +#endif \ No newline at end of file diff --git a/quantum/via.c b/quantum/via.c index e00d092ab9e..0003bfcad99 100644 --- a/quantum/via.c +++ b/quantum/via.c @@ -85,6 +85,11 @@ void eeconfig_update_rgb_matrix(void); // EEPROM is invalid and use/save defaults. bool via_eeprom_is_valid(void) { #ifdef VIAL_ENABLE + #ifdef RECORE + // build_id.py: print("#define BUILD_ID ((uint32_t)0x{:08X})".format(random.randrange(0, 2 ** 24 - 1))) + // use 16bit,and it should not be 0xffff. + return (eeprom_read_word((void *)VIA_EEPROM_MAGIC_ADDR) == (BUILD_ID & 0xfffe)); + #endif uint8_t magic0 = BUILD_ID & 0xFF; uint8_t magic1 = (BUILD_ID >> 8) & 0xFF; uint8_t magic2 = (BUILD_ID >> 16) & 0xFF; @@ -102,6 +107,10 @@ bool via_eeprom_is_valid(void) { // Keyboard level code (eg. via_init_kb()) should not call this void via_eeprom_set_valid(bool valid) { #ifdef VIAL_ENABLE + #ifdef RECORE + eeprom_update_word((void *)VIA_EEPROM_MAGIC_ADDR, valid ? (BUILD_ID & 0xfffe) : 0xffff); + return; + #endif uint8_t magic0 = BUILD_ID & 0xFF; uint8_t magic1 = (BUILD_ID >> 8) & 0xFF; uint8_t magic2 = (BUILD_ID >> 16) & 0xFF; @@ -140,8 +149,13 @@ void via_init(void) { } void eeconfig_init_via(void) { +#ifdef __AVR__ + cli(); +#endif // set the magic number to false, in case this gets interrupted + #ifndef RECORE via_eeprom_set_valid(false); + #endif // This resets the layout options via_set_layout_options(VIA_EEPROM_LAYOUT_OPTIONS_DEFAULT); // This resets the keymaps in EEPROM to what is in flash. @@ -150,6 +164,9 @@ void eeconfig_init_via(void) { dynamic_keymap_macro_reset(); // Save the magic number last, in case saving was interrupted via_eeprom_set_valid(true); +#ifdef __AVR__ + sei(); +#endif } // This is generalized so the layout options EEPROM usage can be @@ -193,6 +210,7 @@ bool process_record_via(uint16_t keycode, keyrecord_t *record) { // TODO: ideally this would be generalized and refactored into // QMK core as advanced keycodes, until then, the simple case // can be available here to keyboards using VIA + #ifndef RECORE switch (keycode) { case FN_MO13: if (record->event.pressed) { @@ -215,6 +233,7 @@ bool process_record_via(uint16_t keycode, keyrecord_t *record) { return false; break; } + #endif return true; } @@ -238,6 +257,7 @@ void raw_hid_receive(uint8_t *data, uint8_t length) { uint8_t *command_data = &(data[1]); #ifdef VIAL_ENABLE + #ifndef VIAL_INSECURE /* When unlock is in progress, we can only react to a subset of commands */ if (vial_unlock_in_progress) { if (data[0] != id_vial_prefix) @@ -246,6 +266,7 @@ void raw_hid_receive(uint8_t *data, uint8_t length) { if (cmd != vial_get_keyboard_id && cmd != vial_get_size && cmd != vial_get_def && cmd != vial_get_unlock_status && cmd != vial_unlock_start && cmd != vial_unlock_poll) goto skip; } + #endif #endif switch (*command_id) { @@ -274,9 +295,11 @@ void raw_hid_receive(uint8_t *data, uint8_t length) { } case id_switch_matrix_state: { #ifdef VIAL_ENABLE + #ifndef VIAL_INSECURE /* Disable wannabe keylogger unless unlocked */ if (!vial_unlocked) goto skip; + #endif #endif #if ((MATRIX_COLS / 8 + 1) * MATRIX_ROWS <= 28) @@ -424,9 +447,11 @@ void raw_hid_receive(uint8_t *data, uint8_t length) { } case id_dynamic_keymap_macro_set_buffer: { #ifdef VIAL_ENABLE + #ifndef VIAL_INSECURE /* Until keyboard is unlocked, don't allow changing macros */ if (!vial_unlocked) goto skip; + #endif #endif uint16_t offset = (command_data[0] << 8) | command_data[1]; uint16_t size = command_data[2]; // size <= 28 diff --git a/quantum/vial.c b/quantum/vial.c index 93bb15e4e94..5df35d375a2 100644 --- a/quantum/vial.c +++ b/quantum/vial.c @@ -137,6 +137,7 @@ void vial_handle_cmd(uint8_t *msg, uint8_t length) { } #endif case vial_get_unlock_status: { +#ifndef RECORE /* Reset message to all FF's */ memset(msg, 0xFF, length); /* First byte of message contains the status: whether board is unlocked */ @@ -151,12 +152,15 @@ void vial_handle_cmd(uint8_t *msg, uint8_t length) { } #endif break; +#endif } case vial_unlock_start: { +#if !defined(VIAL_INSECURE) && !defined(RECORE) vial_unlock_in_progress = 1; vial_unlock_counter = VIAL_UNLOCK_COUNTER_MAX; vial_unlock_timer = timer_read(); break; +#endif } case vial_unlock_poll: { #ifndef VIAL_INSECURE @@ -179,9 +183,15 @@ void vial_handle_cmd(uint8_t *msg, uint8_t length) { } } #endif +#ifndef RECORE msg[0] = vial_unlocked; msg[1] = vial_unlock_in_progress; msg[2] = vial_unlock_counter; +#else + msg[0] = 1;//vial_unlocked; + msg[1] = 0;//vial_unlock_in_progress; + msg[2] = 0;//vial_unlock_counter; +#endif break; } case vial_lock: { @@ -238,12 +248,22 @@ void vial_handle_cmd(uint8_t *msg, uint8_t length) { uint8_t idx = msg[3]; vial_tap_dance_entry_t td; memcpy(&td, &msg[4], sizeof(td)); +#ifndef RECORE td.on_tap = vial_keycode_firewall(td.on_tap); td.on_hold = vial_keycode_firewall(td.on_hold); td.on_double_tap = vial_keycode_firewall(td.on_double_tap); td.on_tap_hold = vial_keycode_firewall(td.on_tap_hold); msg[0] = dynamic_keymap_set_tap_dance(idx, &td); reload_tap_dance(); + +#else + //td.on_tap = vial_keycode_firewall(td.on_tap); + //td.on_hold = vial_keycode_firewall(td.on_hold); + //td.on_double_tap = vial_keycode_firewall(td.on_double_tap); + //td.on_tap_hold = vial_keycode_firewall(td.on_tap_hold); + msg[0] = dynamic_keymap_set_tap_dance(idx, &td); + vial_init(); +#endif break; } #endif @@ -259,9 +279,15 @@ void vial_handle_cmd(uint8_t *msg, uint8_t length) { uint8_t idx = msg[3]; vial_combo_entry_t entry; memcpy(&entry, &msg[4], sizeof(entry)); +#ifndef RECORE entry.output = vial_keycode_firewall(entry.output); msg[0] = dynamic_keymap_set_combo(idx, &entry); reload_combo(); +#else + //entry.output = vial_keycode_firewall(entry.output); + msg[0] = dynamic_keymap_set_combo(idx, &entry); + vial_init(); +#endif break; } #endif diff --git a/tmk_core/protocol/ble51.mk b/tmk_core/protocol/ble51.mk index 69e791a4b3c..907df20488f 100644 --- a/tmk_core/protocol/ble51.mk +++ b/tmk_core/protocol/ble51.mk @@ -1,9 +1,10 @@ BLE51_DIR = protocol/ble51 SRC += $(BLE51_DIR)/recore/serial_uart.c \ - $(BLE51_DIR)/recore/action.c \ + $(BLE51_DIR)/recore/recore.c \ $(BLE51_DIR)/recore/bootloader.c \ $(BLE51_DIR)/recore/suspend.c \ + $(BLE51_DIR)/recore/mousekey.c \ $(BLE51_DIR)/ble51.c \ $(BLE51_DIR)/ble51_task.c \ $(BLE51_DIR)/main.c @@ -14,3 +15,5 @@ OPT_DEFS += -DRECORE VPATH += $(TMK_DIR)/$(BLE51_DIR) VPATH += $(TMK_DIR)/$(BLE51_DIR)/recore + +ALLOW_WARNINGS = yes \ No newline at end of file diff --git a/tmk_core/protocol/ble51/ble51.c b/tmk_core/protocol/ble51/ble51.c index c71fcf6a4d3..0783b7e43ed 100644 --- a/tmk_core/protocol/ble51/ble51.c +++ b/tmk_core/protocol/ble51/ble51.c @@ -25,11 +25,20 @@ along with this program. If not, see . #include "debug.h" #include "timer.h" #include "wait.h" - +#ifndef NOT_BLE #ifndef BLE51_CONSUMER_ON_DELAY -#define BLE51_CONSUMER_ON_DELAY 633 +#define BLE51_CONSUMER_ON_DELAY 255 //633 works for normal kbd with 8M avr #endif +#if (SERIAL_UART_BAUD == 76800) && !defined(SERIAL_UART_BAUD_STR) +#define SERIAL_UART_BAUD_STR "76800" +#endif +/* +Starting with firmware version 0.6.7, +when the TX FIFO buffer is full a 200ms blocking delay will be used to see +if any free space becomes available in the FIFO before returning ERROR. +*/ + /* Host driver */ static uint8_t keyboard_leds(void); static void send_keyboard(report_keyboard_t *report); @@ -47,38 +56,64 @@ host_driver_t ble51_driver = { uint8_t ble51_stop_sending = 0; bool report_error = false; -static uint16_t consumer_ble51_on = 0; +//Confirm the result when all keys pop up +uint8_t g_u8_kbd_report_clear_failed_count = 0; +static uint8_t ble51_recv2_finished = 0; // 0: false; other: true +static uint8_t consumer_ble51_on = 0; static uint16_t consumer_ble51_data; -char ble51_buf[30]; +/* ble51_buf */ +char ble51_buf[32]; static inline void serial_init_1st(void) { +#if 0 cli(); UBRR1L = ((F_CPU/(8.0*9600)-1+0.5)); /* baud rate 9600*/ - UBRR1H = 103>>8; /* baud rate */ + //UBRR1H = 103>>8; /* baud rate H. 9600bps with 8M/16M will not exceed 0xff */ UCSR1B |= (1<mods, - report->keys[0], - report->keys[1], - report->keys[2], - report->keys[3], - report->keys[4], - report->keys[5]); - dprint("sending keyboard..."); - if (memcmp(ble51_cmd(ble51_buf), "ERROR", 5) == 0) { - report_error = 1; + + #if 0 //may save some flash + sprintf(ble51_buf, "%02X-00-%02X-%02X-%02X-%02X-%02X-%02X\n", + report->mods, + report->keys[0], + report->keys[1], + report->keys[2], + report->keys[3], + report->keys[4], + report->keys[5]); + #else + uint8_t *p_report = &report->mods; + for (uint8_t i=0; i<8; i++) { + sprintf(ble51_buf+i*3, "%02X-", *p_report++); + } + ble51_buf[23] = '\n'; // the last '-' to '\n' + #endif + dprint("sending keyboard..."); +#ifndef DEBUG_BLE51 // no need to get the result of keyboard command + ble51_puts(ble51_buf); + + if (report->mods == 0 && report->keys[0] == 0) { + const char *result = ble51_gets(); + dprintf("rpt_Clear %X: %s\n", timer_read(), result); + //result is 'O'K + if (result[0] == 'O') { + g_u8_kbd_report_clear_failed_count = 0; } else { - report_error = 0; - dprint("end\n"); - } -#ifndef NO_BLE51_LED - uint8_t key = report->keys[0]; - if (report->mods == 0 ) { - uint8_t key_led = 0; - if (key == KC_NLCK) key_led = 16; - else if (key == KC_CAPS) key_led = 17; - else if (key == KC_SLCK) key_led = 18; - if (key_led) ble51_led_set(key_led); + g_u8_kbd_report_clear_failed_count++; + //kb_idle_times = 0; } + } + _delay_us(15); +#else + if (memcmp(ble51_cmd(ble51_buf), "ERROR", 5) == 0) { + report_error = 1; + } else { + report_error = 0; + dprint("end\n"); + } #endif +#ifndef NO_BLE51_LED + uint8_t key = report->keys[0]; + if (report->mods == 0 ) { + uint8_t key_led = 0; + if (key == KC_NLCK) key_led = 16; + else if (key == KC_CAPS) key_led = 17; + else if (key == KC_SLCK) key_led = 18; + if (key_led) ble51_led_set(key_led); } +#endif } } @@ -226,6 +347,9 @@ static void send_mouse(report_mouse_t *report) report->y, report->v, report->h); +#ifndef DEBUG_BLE51 // no need to get the result of keyboard command + ble51_puts(ble51_buf); +#else if (memcmp(ble51_cmd(ble51_buf), "OK", 2) == 0) { report_error = 0; dprint("end\n"); @@ -233,6 +357,7 @@ static void send_mouse(report_mouse_t *report) else { report_error = 1; } +#endif } #ifndef MOUSEBUTTON_NO_CHECK @@ -245,6 +370,9 @@ static void send_mouse(report_mouse_t *report) dprint("sending mouse button..."); //sprintf(ble51_buf, "AT+BLEHIDMOUSEBUTTON=%d\n", report->buttons); sprintf(ble51_buf+strlen("AT+BLEHIDMOUSE"), "BUTTON=%d\n", report->buttons); +#ifndef DEBUG_BLE51 // no need to get the result of keyboard command + ble51_puts(ble51_buf); +#else if (memcmp(ble51_cmd(ble51_buf), "OK", 2) == 0) { report_error = 0; dprint("end\n"); @@ -252,6 +380,7 @@ static void send_mouse(report_mouse_t *report) else { report_error = 1; } +#endif } } @@ -270,12 +399,16 @@ static void send_consumer(uint16_t data) if (!report_error) { dprintf("sending consumer...%X...", data); sprintf(ble51_buf, "AT+BLEHIDCONTROLKEY=%d\n",data); +#ifndef DEBUG_BLE51 // no need to get the result of keyboard command + ble51_puts(ble51_buf); +#else if (memcmp(ble51_cmd(ble51_buf), "OK", 2) == 0) { report_error = 0; dprint("end\n"); } else { report_error = 1; } +#endif } } @@ -285,9 +418,11 @@ void ble51_consumer_task(void) if (consumer_ble51_on > 1 ) { consumer_ble51_on--; } else { - static uint8_t sending_consumer_step = 0; //controll repeat speed to be similar to USB - if (++sending_consumer_step >= (0xF3 - consumer_ble51_data)) { - sending_consumer_step = 0; + static uint16_t sending_consumer_timer = 0; //controll repeat speed to be similar to USB + //if (++sending_consumer_step >= (0xF3 - consumer_ble51_data)) { + // ʹ ble51_puts() ble51_cmd()ʱ졣ԷͼҪ//0xe9 volup + if (timer_elapsed(sending_consumer_timer) > 40) { + sending_consumer_timer = timer_read(); send_consumer(consumer_ble51_data); } } @@ -310,6 +445,7 @@ void ble51_set_connectable(uint8_t mode) void ble51_set_blehiden(uint8_t mode) { + //save space if (mode == '0') ble51_init_cmd("AT+BLEHIDEN=0\n"); else ble51_init_cmd("AT+BLEHIDEN=1\n"); } @@ -331,3 +467,5 @@ void ble51_del_bonds(void) { ble51_init_cmd("AT+GAPDELBONDS\n"); } + +#endif \ No newline at end of file diff --git a/tmk_core/protocol/ble51/ble51.h b/tmk_core/protocol/ble51/ble51.h index 2df823a3d5f..de1c1bceb20 100644 --- a/tmk_core/protocol/ble51/ble51.h +++ b/tmk_core/protocol/ble51/ble51.h @@ -2,18 +2,15 @@ #define BLE51_H #include -#include #include "host_driver.h" #include "ble51_task.h" #include "recore.h" -#define TIMEOUT 100 - host_driver_t ble51_driver; void ble51_init(void); int16_t ble51_getc(void); -const char *ble51_gets(uint16_t timeout); +const char *ble51_gets(void); void ble51_putc(uint8_t c); void ble51_puts(char *s); void ble51_consumer_task(void); @@ -21,7 +18,10 @@ void ble51_led_set(uint8_t key_led); const char *ble51_cmd(char *s); void ble51_init_cmd(char *s); +void ble51_clear_recv2(void); void ble51_clear_keys(void); +void ble51_stop_sending_end_action(void); + void ble51_init_blename(void); void ble51_factory_reset(void); @@ -32,5 +32,7 @@ uint8_t ble51_get_connection_status(void); void ble51_del_bonds(void); extern uint8_t ble51_stop_sending; +//Confirm the result when all keys pop up +extern uint8_t g_u8_kbd_report_clear_failed_count; #endif diff --git a/tmk_core/protocol/ble51/ble51_task.c b/tmk_core/protocol/ble51/ble51_task.c index d1d6b09921a..850608d94ba 100644 --- a/tmk_core/protocol/ble51/ble51_task.c +++ b/tmk_core/protocol/ble51/ble51_task.c @@ -43,9 +43,10 @@ along with this program. If not, see . #define BT_POWER_OFF_TIME 9000000 #endif -static void update_battery(uint8_t mode); -static void update_battery_value(uint8_t value); +//static void update_battery(uint8_t mode); +static void update_battery_value(void); static void ble51_reset(uint8_t pressed_mods); +//static void ble51_device_switching(uint8_t mode); //device_switching costs about 212B uint16_t ble_reset_key __attribute__ ((section (".noinit"))); extern debug_config_t debug_config; @@ -62,13 +63,16 @@ uint16_t kb_idle_times = 0; uint8_t usb_connected = 4; +bool usb_connected_once = 0; bool bt_connected = 0; +//bool display_connection_status = true; uint8_t display_connection_status_check_times = 1; -#define U8V(x) (x/16 - 1024/16) //convert voltage to uint8_t (0-255) -static const uint8_t battery_level_value[9] = {U8V(4050), U8V(3950), U8V(3900), U8V(3800), U8V(3750), U8V(3700), U8V(3650), U8V(3600), U8V(3550)}; +//#define U8V(x) (x/16 - 1024/16) //convert voltage to uint8_t (0-255) +#define U8V(x) (x/8 - (330-25)) //adc_u8 +static const uint8_t battery_level_value[9] = {U8V(4070), U8V(3970), U8V(3900), U8V(3800), U8V(3750), U8V(3700), U8V(3650), U8V(3600), U8V(3550)}; uint8_t battery_calc_u8 = 0; uint16_t battery_voltage = 3699; uint8_t battery_check_timer = 0; @@ -87,7 +91,11 @@ uint8_t low_battery = 0; bool is_charging = 0; #endif +// BLE51_PowerState: work 1 | dozing 2 | update battery 3(delete) | sleeping 4 | lock mode 10 +// BLE51_PowerDozing_EN: default 1 | no_sleep 0 +// ble51_off and no usb, 12 uint8_t BLE51_PowerState = 1; +uint8_t BLE51_PowerDozing_EN = 1; void ble51_task_init(void) @@ -95,16 +103,14 @@ void ble51_task_init(void) #ifdef CHARGING_STATE_INIT CHARGING_STATE_INIT(); #endif - update_battery(1); + update_battery(1); //update battery value when keyboard boots. } __attribute__ ((weak)) void ble51_task_user(void){} -static uint8_t usb_nkro; - -void ble51_task(void) +void usb_bt_state_task(void) { // update USB states usb_connected = (USB_DeviceState == DEVICE_STATE_Configured)? 1 : 0; @@ -112,25 +118,57 @@ void ble51_task(void) /* Bluetooth mode | USB mode */ if (keyboard_protocol & (1<<7)) { if (host_get_driver() != &ble51_driver) { + //usb_connected = 0; //set it to 0 to reconfirm USB_DeviceState print("Bluetooth\n"); - usb_nkro = keymap_config.nkro; + //ble51_usb_nkro = keymap_config.nkro; host_set_driver(&ble51_driver); - } - keymap_config.nkro = 0; // always disable NKRO for BT mode + //function_led_state &= ~(1<<1); //Bluetooth Mode, LED off + //keyboard_function_led_set(); + } + if (!usb_connected_once && usb_connected) { + keyboard_protocol &= ~(1<<7); + } } else { - if (host_get_driver() != &lufa_driver) { - print("USB\n"); - keymap_config.nkro = usb_nkro; - host_set_driver(&lufa_driver); - } else if (!usb_connected) { + if (!usb_connected) { + // no usb, switch to bt if ble51_boot_on if (ble51_boot_on) keyboard_protocol |= (1<<7); else BLE51_PowerState = 12; + } else if (host_get_driver() != &lufa_driver) { + print("USB\n"); + host_set_driver(&lufa_driver); + //function_led_state |= (1<<1); //USB Mode, LED On + //keyboard_function_led_set(); + usb_connected_once = 1; } } - - if (!ble51_boot_on) return; +} + +void ble51_task(void) +{ + //if (!ble51_boot_on) return; if (BT_POWERED) { +#ifndef DEBUG_BLE51 + //get the result(OK or ERROR) of keyboard_cmd ble51_puts() with no waiting. + ble51_clear_recv2(); + // to confirm report_clear(key up action) is executed + if (g_u8_kbd_report_clear_failed_count && bt_connected) { + ble51_clear_keys(); + // After many failures, try to restart. + xprintf("clear failed times: %d\n", g_u8_kbd_report_clear_failed_count); + if (g_u8_kbd_report_clear_failed_count == 16) { + #ifdef bt_power_reset() + //run only once when the count is specified. + bt_connected = 0; + bt_power_reset(); + print("bt power reset\n"); + #else + for (;;); + #endif + } + } +#else + /* if error */ if (report_error) { print("\nerroring..."); if (memcmp(ble51_cmd("AT\n"), "OK", 2) == 0) { @@ -148,16 +186,10 @@ void ble51_task(void) need_clear = 0; } } +#endif - - if (BLE51_PowerState == 2) { - update_battery(1); - BLE51_PowerState = 3; - } - - /* check every 1s.*/ - if (!need_clear && timer_elapsed(check_timer) > 1000) { + if (!need_clear && timer_elapsed(check_timer) >= 1000) { check_timer = timer_read(); static uint8_t check_connection_times = 0; /* if bt_connected, check every 4s */ @@ -174,28 +206,38 @@ void ble51_task(void) if (bt_connected) print("BT disconnected\n"); bt_connected = 0; disconnect_s++; - /* if disconnected for more than 90s, turn off bt */ - if (!usb_connected && BLE51_PowerState && disconnect_s >= 90) { + /* if usb_connected == 0 and disconnected for more than 90s, turn off bt */ + //if (!usb_connected && BLE51_PowerState && disconnect_s >= 90) { + if (!usb_connected && disconnect_s >= 90) { print("90s now. BT is off. Sleeping.\n"); - //if (USB_DeviceState != DEVICE_STATE_Configured) { - turn_off_bt(); - BLE51_PowerState = 4; - //} + turn_off_bt(); + //BLE51_PowerState = 4; disconnect_s = 0; } - } else { - //xprintf("%s\n", result); + } + #ifdef DEBUG_BLE51 + else { + xprintf("%s\n", result); need_clear = 1; } + #endif } /* Display connect status*/ if (display_connection_status_check_times) { - if (display_connection_status_check_times == 100) { + if (++display_connection_status_check_times > 20) { display_connection_status_check_times = 0; + // qmk led_wakeup(); - } else if (++display_connection_status_check_times >= 20 || bt_connected == 1) { - display_connection_status_check_times = 100; + } else { + //display_connection_status_check_times++; + if (bt_connected == 1) { + // After a 20s timeout or bt_connected, the next loop ends. + // So there is 1s to indicate that it is connected. + display_connection_status_check_times = 100; + // 重置check_connection_times,确保已连接指示有4s左右(闪三次) + check_connection_times = 0; + } } } } @@ -212,37 +254,48 @@ void ble51_task(void) #endif } - if (!usb_connected && !display_connection_status_check_times) { + if (!usb_connected && !display_connection_status_check_times && BLE51_PowerDozing_EN) { + // count idle time kb_idle_times++; dprintf("idle times: %d, PowerState: %d\n", kb_idle_times, BLE51_PowerState); - - if (BLE51_PowerState == 1 && (kb_idle_times >= (BT_POWER_SAVE_TIME/1000))) { - print("dozing\n"); - ble51_clear_keys(); - BLE51_PowerState = 2; - } - - if (BLE51_PowerState == 3 && (kb_idle_times >= (BT_POWER_OFF_TIME/1000))) { - print("BT is idle for a long time. Turn off. \n"); + if (kb_idle_times >= (BT_POWER_OFF_TIME/1000)) { + // 暂时保留 BLE51_PowerState 4,HHKB BLE和BLE660C等有使用到 BLE51_PowerState = 4; turn_off_bt(); + } else + // always set State to 2, when BT_POWERED and kb_idle_times for POWER_SAVE_TIME. + if (kb_idle_times >= (BT_POWER_SAVE_TIME/1000)) { + BLE51_PowerState = 2; } } } - + /* ble set once + *AT+GAPSETADVDATA=02-01-04/n Discoverable OFF KC_O + *AT+GAPSETADVDATA=02-01-06/n Discoverable ON KC_I + *AT+GAPDELBONDS\n Pair Clear KC_R + */ if (ble_set_code > 0) { + //watchdog_off(); if (ble_set_code == KC_I) { - ble51_cmd("AT+GAPSETADVDATA=02-01-06\n"); + ble51_puts("AT+GAPSETADVDATA=02-01-0"); + ble51_cmd("6\n"); } else if (ble_set_code == KC_O) { - ble51_cmd("AT+GAPSETADVDATA=02-01-04\n"); + ble51_puts("AT+GAPSETADVDATA=02-01-0"); + ble51_cmd("4\n"); + //watchdog_on(); } else if (ble_set_code == KC_R) { + //ble51_set_connectable('0'); + //ble51_cmd("AT+GAPDISCONNECT\n"); + //ble51_cmd("AT+GATTCLEAR\n"); //clear battery service. ble51_del_bonds(); ble51_set_blehiden('0'); ble51_set_blehiden('1'); + //ble51_set_connectable('1'); ble51_cmd("ATZ\n"); - ble51_cmd("AT+GAPSETADVDATA=02-01-06\n"); + ble51_puts("AT+GAPSETADVDATA=02-01-0"); + ble51_cmd("6\n"); } ble_set_code = 0; } @@ -250,13 +303,9 @@ void ble51_task(void) /* hold consumer key */ ble51_consumer_task(); } - - - - if (BLE51_PowerState <= 1) ble51_task_user(); } -static void update_battery(uint8_t mode) { +void update_battery(uint8_t mode) { /* mode 0: not update bat_value, only get voltage and calc low_battery. */ /*only update when light is off.*/ @@ -269,30 +318,59 @@ static void update_battery(uint8_t mode) { #endif const char *result = ble51_cmd("AT+HWADC=6\n"); + /* simple calculate batt level + * Char "0"->"9" = 0x30->0x39 Char "O"=0x4F. atol() needs more space. + * When no battery, ADC value is 32 and voltage measured by multimeter is 54mv. + * So result[2] will be "_" not 0. + */ +#ifdef DEBUG_BLE51 if (result[1] < '0' || result[1] > '9') need_clear = 1; else if(result[2] > '9') print("No battery or wrong!\n"); else { - uint16_t battery_voltage_get = ((result[0]-48)*100 + (result[1]-48)*10 + result[2]- 48 -32) * 8 + 54; - battery_voltage = (battery_voltage_get + ((battery_voltage == 3699)?battery_voltage_get:battery_voltage)) / 2; - dprintf(" Battery Voltage: %dmv, ADC Value:%s\n", battery_voltage, result); - -#ifdef UPDATE_BATTERY_WHEN_CHARGING - if (BATTERY_CHARGING) { - is_charging = 1; - battery_voltage -= CHARGING_FIX_VALUE; - } else { - is_charging = 0; - } +#else + // confirm the result is voltage + if (result[0] >= '3' && result[2] >= '0' && result[2] <= '9') { #endif - battery_calc_u8 = U8V(battery_voltage); - if (battery_calc_u8 > U8V(3600)) low_battery = 0; - else if (battery_calc_u8 < U8V(3420)) low_battery = 1; - else if (battery_calc_u8 < U8V(3550)) low_battery = 5; + //uint16_t battery_voltage_get = ((result[0]-48)*100 + (result[1]-48)*10 + result[2]- 48 -32) * 8 + 54; + // adc - 330, to unit8_t, max voltage = 4480 + uint8_t bat_adc_u8 = result[0]*100 + result[1]*10 + result[2]- 48*100 - 48*10 - 48 - 330; + + // Control the effective range of adc_u8, and update only within this range. + if (bat_adc_u8 > U8V(3350)) { + #ifndef BLE51_NO_BATTERY_VOLTAGE //save space + uint16_t battery_voltage_get = bat_adc_u8 * 8 + (330-25)*8; + battery_voltage = (battery_voltage_get + ((battery_voltage == 3699)?battery_voltage_get:battery_voltage)) / 2; + dprintf(" BAT Volt: %dmv, ADC:%s\n", battery_voltage, result); + battery_calc_u8 = U8V(battery_voltage); + #else + battery_calc_u8 = bat_adc_u8; + #endif + #ifdef UPDATE_BATTERY_WHEN_CHARGING + if (BATTERY_CHARGING) { + is_charging = 1; + //battery_voltage -= CHARGING_FIX_VALUE; + //Directly testing the battery voltage during charging is not accurate. + if (battery_calc_u8 < U8V(4208)) battery_calc_u8 -= ((CHARGING_FIX_VALUE+2) / 4); + else battery_calc_u8 -= ((CHARGING_FIX_VALUE+4) / 8); + dprintf(" CHG Calc: %dmv\n", battery_calc_u8*8+(330-25)*8); + } else { + is_charging = 0; + } + #endif + #ifdef BLE51_NO_ULTRA_LOW_BATTERY + low_battery = (battery_calc_u8 < U8V(3550))? 5:0; + #else + if (battery_calc_u8 > U8V(3600)) low_battery = 0; + else if (battery_calc_u8 < U8V(3420)) low_battery = 1; //Ultra low battery + else if (battery_calc_u8 < U8V(3550)) low_battery = 5; + #endif + } } #ifdef BLE_BATTERY_SERVICE if (mode == 1) { + /* Calculate battery level */ uint8_t battery_level = 44; uint8_t i = 0; for (uint8_t j = 90; j > 0; j -= 10) { @@ -313,16 +391,21 @@ static void update_battery(uint8_t mode) { #else if (battery_calc_u8 >= U8V(4140)) battery_level = 100; #endif - update_battery_value(battery_level); + battery_percentage = battery_level; + update_battery_value(); } #endif } -static void update_battery_value(uint8_t value) { - battery_percentage = value; - ble51_puts("AT+GATTCHAR=1,"); - sprintf(ble51_buf, "%d\n", value); + +static void update_battery_value(void) { + #ifdef BLE51_USE_BLEBATT // Two ways for battery service. Only use one of them. + sprintf(ble51_buf, "AT+BLEBATTVAL=%d\n", battery_percentage); + #else + sprintf(ble51_buf, "AT+GATTCHAR=1,%d\n", battery_percentage); + #endif ble51_cmd(ble51_buf); + ble51_cmd(ble51_buf); // run it one more time to properly refresh on macOS. } #define MODS_SHIFT_MASK (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) @@ -338,12 +421,12 @@ static void ble51_reset(uint8_t pressed_mods) { } } - bool command_extra(uint8_t code) { uint8_t pressed_mods = get_mods(); clear_keyboard(); switch (code) { +#ifndef NOT_BLE case KC_U: if (ble51_boot_on) keyboard_protocol ^= (1<<7); return true; @@ -360,21 +443,29 @@ bool command_extra(uint8_t code) return false; } case KC_S: + // 1: start to display + // 100: end display and restore ledmapu. display_connection_status_check_times = display_connection_status_check_times? 100:1; return true; case KC_P: - BLE51_PowerState ^= 1; - type_num(BLE51_PowerState); - return true; - case KC_B: - ble51_reset(pressed_mods); + BLE51_PowerDozing_EN ^= 1; + type_num(BLE51_PowerDozing_EN); return true; - case KC_V: + case KC_W: +#if !defined(HARDWARE_BT_SWITCH) && !defined(NO_BT_SWITCH) + // EECONFIG_USER (uint32_t *)19, (uint8_t)0xBD mean off + eeprom_update_byte(EECONFIG_USER, (pressed_mods&MOD_BIT(KC_LCTRL))?0xBD:1); + for (;;); +#endif + case KC_V: // output battery and bt connection type_numbers(battery_percentage); + #ifndef BLE51_NO_BATTERY_VOLTAGE + //display voltage with LCtrl pressed. 30Byte if (pressed_mods & MOD_BIT(KC_LCTRL)) { tap_code(KC_MINS); type_numbers(battery_voltage); } + #endif tap_code(KC_MINS); type_num(bt_connected); return true; @@ -386,9 +477,18 @@ bool command_extra(uint8_t code) layer_clear(); } return true; +#endif // USB only, less + case KC_B: // decide what (LCtrl+)LRShift+B by user action_function + ble51_reset(pressed_mods); + return true; + case KC_N: // for hook; + hook_nkro_change(); + //ble51_usb_nkro = !ble51_usb_nkro; + #ifdef NO_DEFAULT_COMMAND + keymap_config.nkro = !keymap_config.nkro; + #endif + return true; default: - return false; + return false; // yield to default command } - return true; } - diff --git a/tmk_core/protocol/ble51/ble51_task.h b/tmk_core/protocol/ble51/ble51_task.h index 301b6a2d5fa..1aa2da1de17 100644 --- a/tmk_core/protocol/ble51/ble51_task.h +++ b/tmk_core/protocol/ble51/ble51_task.h @@ -4,18 +4,23 @@ #include #include "ble51.h" -extern uint8_t BLE51_PowerState; +extern uint8_t BLE51_PowerState; //no_sleep 0, work 1,dozing 2, check battery once when dozing 3, sleeping 4, lock mode 10 +extern uint8_t BLE51_PowerDozing_EN; // extern bool ble51_boot_on; extern uint16_t kb_idle_times; extern uint8_t display_connection_status_check_times; extern bool bt_connected; extern uint8_t usb_connected; +extern bool usb_connected_once; extern uint8_t low_battery; extern uint16_t battery_voltage; +extern uint8_t ble51_usb_nkro; +void usb_bt_state_task(void); void ble51_task_init(void); void ble51_task(void); void ble51_task_user(void); +void update_battery(uint8_t mode); extern uint16_t ble_reset_key; #endif diff --git a/tmk_core/protocol/ble51/config_ble51.h b/tmk_core/protocol/ble51/config_ble51.h new file mode 100644 index 00000000000..5deb76c7666 --- /dev/null +++ b/tmk_core/protocol/ble51/config_ble51.h @@ -0,0 +1,53 @@ +#pragma once + +#define CONTACT(x,y) x##y //https://blog.csdn.net/aiynmimi/article/details/123486956 +#define CONTACT2(x,y) CONTACT(x,y) +#if CONSOLE_ENABLE +#define FW_VER CONTACT2(DEBUG_VIAL_, FW_VER_DATE) +#else +#define FW_VER CONTACT2(VIAL_, FW_VER_DATE) +#endif + +/* command. LShift+RShift+X and LShift+RShift+LCtrl+X for YDKB*/ +#define IS_COMMAND() ( \ + (get_mods() == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT))) || \ + (get_mods() == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_LCTRL) | MOD_BIT(KC_RSHIFT))) \ +) + +/* disable command for default layer */ +#define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS 0 +#define MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS 0 + +/* UART Config */ +#if defined(__AVR_ATmega32U4__) || defined(__AVR_AT90USB1286__) + #define UCSR1D _SFR_MEM8(0xCB) + #define RTSEN 0 + #define CTSEN 1 + + #define SERIAL_UART_BAUD 76800 + #define SERIAL_UART_DATA UDR1 + #define SERIAL_UART_UBRR ((F_CPU/(8.0*SERIAL_UART_BAUD)-1+0.5)) + #define SERIAL_UART_RXD_VECT USART1_RX_vect + #define SERIAL_UART_TXD_READY (UCSR1A&(1<>8); \ + UCSR1B |= (1<. #include "timer.h" #include "suspend.h" #include "ble51.h" -#include "ble51_task.h" - void protocol_post_task(void); +/* hooks */ +__attribute__((weak)) +void hook_early_init(void) {} + +static int8_t sendchar_func(uint8_t c) +{ + //xmit(c); // SUART + sendchar(c); // LUFA + return 0; +} + static void SetupHardware(void) { /* Disable clock division */ @@ -51,38 +60,58 @@ static void SetupHardware(void) } int main(void) __attribute__ ((weak)); + +#ifndef NOT_BLE // BLE Ver + int main(void) { SetupHardware(); sei(); +#if !defined(HARDWARE_BT_SWITCH) && !defined(NO_BT_SWITCH) + if (eeprom_read_byte(EECONFIG_USER) == 0xBD) ble51_boot_on = 0; +#endif + + // BLE Power on + if (ble51_boot_on) { + ble51_init(); + ble51_task_init(); + } +#if 1 //def CONSOLE_ENABLE /* wait for USB startup to get ready for debug output */ uint8_t timeout = 255; while (timeout-- && USB_DeviceState != DEVICE_STATE_Configured) { - _delay_ms(6); + WAIT_MS(12); // wait for USB about 3s +#ifdef PS2_USE_INT // BLE980M may need more time. + WAIT_MS(16); +#endif #if !defined(INTERRUPT_CONTROL_ENDPOINT) USB_USBTask(); #endif } print("\nUSB init\n"); - - if (ble51_boot_on) { - ble51_init(); - ble51_task_init(); - } +#endif /* init modules */ keyboard_init(); print("Keyboard start\n"); +#ifdef DEFAULT_6KRO + keymap_config.nkro = 0; +#else + keymap_config.nkro = 1; // default force nkro on for ble series +#endif watchdog_on(); while (1) { - if (BLE51_PowerState < 4){ + //if (BT_POWERED){ + usb_bt_state_task(); + if (BLE51_PowerState < 10){ wdt_reset(); if (BLE51_PowerState <= 1) { keyboard_task(); protocol_post_task(); + if (ble51_boot_on) ble51_task_user(); } ble51_task(); } @@ -91,14 +120,59 @@ int main(void) watchdog_on(); if (suspend_wakeup_condition()) { kb_idle_times = 0; + if (ble51_boot_on) { + BLE51_PowerState = 1; + if (BT_POWERED) { + update_battery(1); + } else { + display_connection_status_check_times = 1; + turn_on_bt(); + } + } suspend_wakeup_init_action(); - BLE51_PowerState = 1; - if (ble51_boot_on) { - turn_on_bt(); + if (usb_connected_once && USB_DeviceState == DEVICE_STATE_Suspended) { + USB_Device_SendRemoteWakeup(); } - else if (USB_DeviceState == DEVICE_STATE_Suspended) USB_Device_SendRemoteWakeup(); } } } } +#else // Not BLE +int main(void) +{ + SetupHardware(); + sei(); + + /* wait for USB startup & debug output */ + while (USB_DeviceState != DEVICE_STATE_Configured) { +#if !defined(INTERRUPT_CONTROL_ENDPOINT) + USB_USBTask(); +#endif + } + + print("\nUSB init\n"); + /* init modules */ + keyboard_init(); + host_set_driver(&lufa_driver); + usb_connected = 1; + print("Keyboard start\n"); + watchdog_on(); + while (1) { + // usb suspend + while (USB_DeviceState == DEVICE_STATE_Suspended) { + suspend_power_down(); + watchdog_on(); + if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) { + USB_Device_SendRemoteWakeup(); + //suspend_wakeup_init_action(); + for (;;); //restart keyboard + } + } + wdt_reset(); + keyboard_task(); + protocol_post_task(); // for via? + } +} + +#endif \ No newline at end of file diff --git a/tmk_core/protocol/ble51/recore.h b/tmk_core/protocol/ble51/recore.h index 00e397ad439..c33331a248e 100644 --- a/tmk_core/protocol/ble51/recore.h +++ b/tmk_core/protocol/ble51/recore.h @@ -6,23 +6,27 @@ #include "ble51.h" #include "bootloader.h" #include "quantum.h" -#include "send_string.h" //qmk +//#include "send_string.h" //qmk #include "keycode_config.h" //qmk +#ifdef NOT_BLE +#define BT_POWERED 0 +#endif // for lock mode, *debounce + x #define KP(row,col) (row * MATRIX_COLS + col) -#define type_num(x) send_nibble(x) +#define WAIT_MS(x) _delay_ms(x) +//#define type_num(x) send_nibble(x) +#define type_num(x) type_numbers(x) //save 40B void type_numbers(uint16_t value); - void suspend_power_down_action(void); void suspend_wakeup_init_action(void); void watchdog_on(void); -__attribute__ ((weak)) void hook_early_init(void); +void hook_nkro_change(void) ; #endif diff --git a/tmk_core/protocol/ble51/recore/action.c b/tmk_core/protocol/ble51/recore/action.c deleted file mode 100644 index 62a6c74bd74..00000000000 --- a/tmk_core/protocol/ble51/recore/action.c +++ /dev/null @@ -1,20 +0,0 @@ -#include -#include -#include -#include -#include "matrix.h" -#include "action.h" -#include "suspend.h" -#include "timer.h" -#include "send_string.h" -#include "recore.h" - -void type_numbers(uint16_t value) -{ - for (uint16_t i=10000; i>=1; i=i/10) { - uint8_t this_num = value/i % 10; - if (value/i) { - send_nibble(this_num); - } - } -} \ No newline at end of file diff --git a/tmk_core/protocol/ble51/recore/bootloader.c b/tmk_core/protocol/ble51/recore/bootloader.c index 9582aee6f35..07956dcee82 100644 --- a/tmk_core/protocol/ble51/recore/bootloader.c +++ b/tmk_core/protocol/ble51/recore/bootloader.c @@ -35,6 +35,7 @@ void bootloader_jump(void) { if (BLE51_PowerState <= 1) { _delay_ms(10); USB_Disable(); + // When BLE51_PowerState > 1, watchdog already on watchdog_on(); } for (;;); diff --git a/tmk_core/protocol/ble51/recore/mousekey.c b/tmk_core/protocol/ble51/recore/mousekey.c new file mode 100644 index 00000000000..956de12373c --- /dev/null +++ b/tmk_core/protocol/ble51/recore/mousekey.c @@ -0,0 +1,178 @@ +/* +Copyright 2019 YANG + +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 . +*/ + +#include +#include "keycode.h" +#include "host.h" +#include "timer.h" +#include "print.h" +#include "debug.h" +#include "mousekey.h" + +#include "action_util.h" + + + +report_mouse_t mouse_report = {}; + +static uint8_t mouse_repeat_start = 0; +static uint8_t mouse_wheel_timer = 0; + +static uint8_t mousekey_accel = 0; + +static void mousekey_debug(void); + +// rapidfire key + +/* + * Mouse keys acceleration algorithm + * http://en.wikipedia.org/wiki/Mouse_keys + * + * speed = delta * max_speed * (repeat / time_to_max)**((1000+curve)/1000) + */ +/* milliseconds between the initial key press and first repeated motion event (0-2550) */ +//uint8_t mk_delay = MOUSEKEY_DELAY/10; +/* milliseconds between repeated motion events (0-255) */ +//uint8_t mk_interval = MOUSEKEY_INTERVAL; +/* steady speed (in action_delta units) applied each event (0-255) */ +//uint8_t mk_max_speed = MOUSEKEY_MAX_SPEED; +/* number of events (count) accelerating to steady speed (0-255) */ +//uint8_t mk_time_to_max = MOUSEKEY_TIME_TO_MAX; +/* ramp used to reach maximum pointer speed (NOT SUPPORTED) */ +//int8_t mk_curve = 0; +/* wheel params */ +//uint8_t mk_wheel_max_speed = MOUSEKEY_WHEEL_MAX_SPEED; +//uint8_t mk_wheel_time_to_max = MOUSEKEY_WHEEL_TIME_TO_MAX; + + +static uint16_t last_timer = 0; + + + +void mousekey_task(void) +{ + + if (timer_elapsed(last_timer) < (mouse_repeat_start == 2 ? 5 : 40)) //delay about 40ms to start //(mouse_repeat ? mk_interval : mk_delay*10)) + return; + + //int8_t *p = &mouse_report.x; + //if ((*p++ | *p++ | *p++ | *p++) == 0) { + if ((mouse_report.x | mouse_report.y | mouse_report.v | mouse_report.h) == 0) { + //if (mouse_report.x == 0 && mouse_report.y == 0 && mouse_report.v == 0 && mouse_report.h == 0) + mouse_repeat_start = 0; + return; + } else if (mouse_repeat_start < 2) { + mouse_repeat_start++; + return; + } + //control wheel speed + int8_t mouse_v, mouse_h; + mouse_v = mouse_report.v; + mouse_h = mouse_report.h; + if ((++mouse_wheel_timer) & 0b1111) { + mouse_report.v = 0; + mouse_report.h = 0; + } + mousekey_send(); + mouse_report.v = mouse_v; + mouse_report.h = mouse_h; + + static uint8_t timer1 = 0; + if (++timer1 > MOUSEKEY_REPEAT_UPDATE_INTERVAL) { //control mouse speedup +#if defined(BLE_NAME) || defined(BLE_NAME_VARIABLE) + #if (SERIAL_UART_BAUD == 19200) + //默认REPEAT_INTERVAL是12,蓝牙5到12是7,使用19200时改到10 + timer1 = (keyboard_protocol & (1<<7))? 10:0; + #else + timer1 = (keyboard_protocol & (1<<7))? 5:0; + #endif +#else + timer1 = 0; +#endif + int8_t *p_report = &mouse_report.x; + for (uint8_t i=0; i<4; i++, *p_report++) { + if (*p_report == 0) continue; + if (mousekey_accel) { // 定速移动 + *p_report = (MOUSEKEY_MOVE_REPEAT_MAX / 4) * mousekey_accel * (*p_report > 0? 1: -1); // mousekey_accel 1 2 4 + } else if (*p_report > 0) { + if (++(*p_report) > MOUSEKEY_MOVE_REPEAT_MAX) { + *p_report = MOUSEKEY_MOVE_REPEAT_MAX; + } + } else if (--(*p_report) < -MOUSEKEY_MOVE_REPEAT_MAX) { + *p_report = -MOUSEKEY_MOVE_REPEAT_MAX; + } + } + } + +} + +void mousekey_on(uint8_t code) +{ + if (code < KC_MS_UP) return; + if (code == KC_MS_UP) mouse_report.y = -1; + else if (code == KC_MS_DOWN) mouse_report.y = 1; + else if (code == KC_MS_LEFT) mouse_report.x = -1; + else if (code == KC_MS_RIGHT) mouse_report.x = 1; + else if (code <= KC_MS_BTN5) mouse_report.buttons |= (1<<(code-KC_MS_BTN1)); //0xF4 - 0xF8 + else if (code == KC_MS_WH_UP) mouse_report.v = 1; + else if (code == KC_MS_WH_DOWN) mouse_report.v = -1; + else if (code == KC_MS_WH_LEFT) mouse_report.h = -1; + else if (code == KC_MS_WH_RIGHT) mouse_report.h = 1; + else if (code <= KC_MS_ACCEL2) mousekey_accel |= (1<<(code-KC_MS_ACCEL0)); //0xFD - 0xFF + if (code >= KC_MS_WH_UP && code <= KC_MS_WH_RIGHT) mouse_wheel_timer = 0; +} + +void mousekey_off(uint8_t code) +{ + if (code < KC_MS_UP) return; + if (code == KC_MS_UP ) { if (mouse_report.y < 0) mouse_report.y = 0; } + else if (code == KC_MS_DOWN ) { if (mouse_report.y > 0) mouse_report.y = 0; } + else if (code == KC_MS_LEFT ) { if (mouse_report.x < 0) mouse_report.x = 0; } + else if (code == KC_MS_RIGHT ) { if (mouse_report.x > 0) mouse_report.x = 0; } + else if (code <= KC_MS_BTN5 ) { mouse_report.buttons &= ~(1<<(code-KC_MS_BTN1)); }//0xF4 - 0xF8 + else if (code == KC_MS_WH_UP ) { if (mouse_report.v > 0) mouse_report.v = 0; } + else if (code == KC_MS_WH_DOWN ) { if (mouse_report.v < 0) mouse_report.v = 0; } + else if (code == KC_MS_WH_LEFT ) { if (mouse_report.h < 0) mouse_report.h = 0; } + else if (code == KC_MS_WH_RIGHT) { if (mouse_report.h > 0) mouse_report.h = 0; } + else if (code <= KC_MS_ACCEL2 ) { mousekey_accel &= ~(1<<(code-KC_MS_ACCEL0)); } //0xFD - 0xFF + +} + +void mousekey_send(void) +{ + mousekey_debug(); + host_mouse_send(&mouse_report); + last_timer = timer_read(); +} + +void mousekey_clear(void) +{ + mouse_report = (report_mouse_t){}; + mousekey_accel = 0; +} + +static void mousekey_debug(void) +{ + if (!debug_mouse) return; + print("mousekey [btn|x y v h](rep/acl): ["); + print_hex8(mouse_report.buttons); print("|"); + print_decs(mouse_report.x); print(" "); + print_decs(mouse_report.y); print(" "); + print_decs(mouse_report.v); print(" "); + print_decs(mouse_report.h); print("]("); + print_dec(mousekey_accel); print(")\n"); +} diff --git a/tmk_core/protocol/ble51/recore/mousekey.h b/tmk_core/protocol/ble51/recore/mousekey.h new file mode 100644 index 00000000000..4b3d1ecb787 --- /dev/null +++ b/tmk_core/protocol/ble51/recore/mousekey.h @@ -0,0 +1,55 @@ +/* +Copyright 2022 YANG + +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 . +*/ + +#ifndef MOUSEKEY_H +#define MOUSEKEY_H + +#include +#include "host.h" + + +#define MOUSEKEY_MOVE_REPEAT_MAX 20 // 4的倍数 +#ifndef MOUSEKEY_REPEAT_UPDATE_INTERVAL +#define MOUSEKEY_REPEAT_UPDATE_INTERVAL 12 // for 8M +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + +extern uint8_t mk_delay; +extern uint8_t mk_interval; +extern uint8_t mk_max_speed; +extern uint8_t mk_time_to_max; +extern uint8_t mk_wheel_max_speed; +extern uint8_t mk_wheel_time_to_max; + +extern bool rapidfire_key[]; +extern bool rapidfire_mode; + +void mousekey_task(void); +void mousekey_on(uint8_t code); +void mousekey_off(uint8_t code); +void mousekey_clear(void); +void mousekey_send(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/protocol/ble51/recore/recore.c b/tmk_core/protocol/ble51/recore/recore.c new file mode 100644 index 00000000000..306c78b390e --- /dev/null +++ b/tmk_core/protocol/ble51/recore/recore.c @@ -0,0 +1,89 @@ +/* +Copyright 2023 YANG + +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 . +*/ +#include +#include +#include +#include +#include "matrix.h" +#include "action.h" +#include "suspend.h" +#include "timer.h" +#include "send_string.h" +#include "recore.h" + +// 使用 send_string 里的 send_nibble(), 进行数字输出。 +void type_numbers(uint16_t value) +{ +#if 1 //save 24B + static char numbers[5] = {0}; + sprintf(numbers,"%d",value); // char 0 to 9, 48 to 57. but key code 1 to 9 to 0, 30 to 39. + for (uint8_t i=0; i<5; i++) { // strlen(str) needs 14B more + uint8_t code = numbers[i]; + if (code == '\0') break; + else { + if (code == 48) code = 58; + tap_code(code - 19); + } + } +#else + for (uint16_t i=10000; i>=1; i=i/10) { + uint8_t this_num = value/i % 10; + if (value/i) { + send_nibble(this_num); + } + } +#endif +} + +void keyboard_post_init_kb(void) +{ +#ifdef VIAL_ENABLE + vial_init(); +#endif +} + +//22B +void tap_code(uint8_t code) { + register_code(code); + if (code == KC_CAPS) wait_ms(100); + unregister_code(code); +} + +// 4B ever if (mods) +void register_mods(uint8_t mods) { + add_mods(mods); + send_keyboard_report(); +} + +void unregister_mods(uint8_t mods) { + del_mods(mods); + send_keyboard_report(); +} + +void register_weak_mods(uint8_t mods) { + add_weak_mods(mods); + send_keyboard_report(); +} + +void unregister_weak_mods(uint8_t mods) { + del_weak_mods(mods); + send_keyboard_report(); +} +// if (mods) end. 4B*4 = 16B + +__attribute__((weak)) +void hook_nkro_change(void) {} diff --git a/tmk_core/protocol/ble51/recore/serial.h b/tmk_core/protocol/ble51/recore/serial.h new file mode 100644 index 00000000000..0204b84a921 --- /dev/null +++ b/tmk_core/protocol/ble51/recore/serial.h @@ -0,0 +1,46 @@ +/* +Copyright 2012 Jun WAKO + +This software is licensed with a Modified BSD License. +All of this is supposed to be Free Software, Open Source, DFSG-free, +GPL-compatible, and OK to use in both free and proprietary applications. +Additions and corrections to this file are welcome. + + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + +* Neither the name of the copyright holders nor the names of + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +*/ + +#pragma once + +#define SERIAL_UART_DATA UDR1 + +/* host role */ +void serial_init(void); +uint8_t serial_recv(void); +int16_t serial_recv2(void); +void serial_send(uint8_t data); diff --git a/tmk_core/protocol/ble51/recore/serial_uart.c b/tmk_core/protocol/ble51/recore/serial_uart.c index 3316304b10c..ec9162893a3 100644 --- a/tmk_core/protocol/ble51/recore/serial_uart.c +++ b/tmk_core/protocol/ble51/recore/serial_uart.c @@ -38,8 +38,9 @@ POSSIBILITY OF SUCH DAMAGE. #include #include #include -#include "protocol/serial.h" +#include "serial.h" +#ifndef NOT_BLE #if defined(SERIAL_UART_RTS_LO) && defined(SERIAL_UART_RTS_HI) // Buffer state @@ -76,7 +77,8 @@ uint8_t serial_recv(void) } data = rbuf[rbuf_tail]; - rbuf_tail = (rbuf_tail + 1) % RBUF_SIZE; + //rbuf_tail = (rbuf_tail + 1) % RBUF_SIZE; + rbuf_tail = (rbuf_tail + 1) & 0xff; rbuf_check_rts_lo(); return data; } @@ -89,7 +91,8 @@ int16_t serial_recv2(void) } data = rbuf[rbuf_tail]; - rbuf_tail = (rbuf_tail + 1) % RBUF_SIZE; + //rbuf_tail = (rbuf_tail + 1) % RBUF_SIZE; + rbuf_tail = (rbuf_tail + 1) & 0xff; rbuf_check_rts_lo(); return data; } @@ -103,10 +106,13 @@ void serial_send(uint8_t data) // USART RX complete interrupt ISR(SERIAL_UART_RXD_VECT) { - uint8_t next = (rbuf_head + 1) % RBUF_SIZE; + //uint8_t next = (rbuf_head + 1) % RBUF_SIZE; + uint8_t next = (rbuf_head + 1) & 0xff; if (next != rbuf_tail) { rbuf[rbuf_head] = SERIAL_UART_DATA; rbuf_head = next; } rbuf_check_rts_hi(); } + +#endif \ No newline at end of file diff --git a/tmk_core/protocol/ble51/recore/suspend.c b/tmk_core/protocol/ble51/recore/suspend.c index 82605998ea4..0287212d558 100644 --- a/tmk_core/protocol/ble51/recore/suspend.c +++ b/tmk_core/protocol/ble51/recore/suspend.c @@ -58,6 +58,9 @@ static void power_down(uint8_t wdto) void suspend_power_down(void) { +#ifdef WDTO_EXTRA_15MS + power_down(WDTO_15MS); +#endif power_down(WDTO_30MS); } @@ -71,7 +74,11 @@ void suspend_wakeup_init(void) ISR(WDT_vect) { + // default 30ms instead of 15ms if (wdt_timeout == WDTO_30MS) { timer_count += 30 + 2; } +#ifdef WDTO_EXTRA_15MS + else if (wdt_timeout == WDTO_15MS) { timer_count += 15 + 2;} //from observation +#endif } diff --git a/tmk_core/protocol/host.c b/tmk_core/protocol/host.c index 3d8604d5414..7e83e548e5d 100644 --- a/tmk_core/protocol/host.c +++ b/tmk_core/protocol/host.c @@ -65,7 +65,11 @@ led_t host_keyboard_led_state(void) { void host_keyboard_send(report_keyboard_t *report) { if (!driver) return; #if defined(NKRO_ENABLE) && defined(NKRO_SHARED_EP) +#ifndef RECORE if (keyboard_protocol && keymap_config.nkro) { +#else + if (IS_NKRO()) { +#endif /* The callers of this function assume that report->mods is where mods go in. * But report->nkro.mods can be at a different offset if core keyboard does not have a report ID. */ diff --git a/tmk_core/protocol/host.h b/tmk_core/protocol/host.h index 6b15f0d0c10..fcaec9132ba 100644 --- a/tmk_core/protocol/host.h +++ b/tmk_core/protocol/host.h @@ -33,6 +33,12 @@ along with this program. If not, see . extern "C" { #endif +#ifdef RECORE +#define IS_NKRO() (keyboard_protocol == 1 && keymap_config.nkro) +#else +#define IS_NKRO() (keyboard_protocol && keymap_config.nkro) +#endif + extern uint8_t keyboard_idle; extern uint8_t keyboard_protocol; diff --git a/tmk_core/protocol/report.c b/tmk_core/protocol/report.c index 5755098c60f..f50c1d1c19e 100644 --- a/tmk_core/protocol/report.c +++ b/tmk_core/protocol/report.c @@ -36,11 +36,24 @@ static int8_t cb_count = 0; * FIXME: Needs doc */ uint8_t has_anykey(report_keyboard_t* keyboard_report) { +#ifdef RECORE //26B, + // Only check if key, no need to get how many keys. + uint8_t *pr = keyboard_report->keys; + uint8_t lpr = sizeof(keyboard_report->nkro.bits); + while (lpr--) { + if (*pr++) return 1; + } + return 0; +#endif uint8_t cnt = 0; uint8_t* p = keyboard_report->keys; uint8_t lp = sizeof(keyboard_report->keys); #ifdef NKRO_ENABLE +#ifndef RECORE if (keyboard_protocol && keymap_config.nkro) { +#else + if (IS_NKRO()) { +#endif p = keyboard_report->nkro.bits; lp = sizeof(keyboard_report->nkro.bits); } @@ -57,7 +70,11 @@ uint8_t has_anykey(report_keyboard_t* keyboard_report) { */ uint8_t get_first_key(report_keyboard_t* keyboard_report) { #ifdef NKRO_ENABLE +#ifndef RECORE if (keyboard_protocol && keymap_config.nkro) { +#else + if (IS_NKRO()) { +#endif uint8_t i = 0; for (; i < KEYBOARD_REPORT_BITS && !keyboard_report->nkro.bits[i]; i++) ; @@ -84,11 +101,21 @@ uint8_t get_first_key(report_keyboard_t* keyboard_report) { * Note: The function doesn't support modifers currently, and it returns false for KC_NO */ bool is_key_pressed(report_keyboard_t* keyboard_report, uint8_t key) { +#ifdef RECORE + //https://github.com/qmk/qmk_firmware/issues/1708 + // disable with return, save 110B(false, and not work) + // save 90B (true). Then always del_key before add + return true; +#endif if (key == KC_NO) { return false; } #ifdef NKRO_ENABLE +#ifndef RECORE if (keyboard_protocol && keymap_config.nkro) { +#else + if (IS_NKRO()) { +#endif if ((key >> 3) < KEYBOARD_REPORT_BITS) { return keyboard_report->nkro.bits[key >> 3] & 1 << (key & 7); } else { @@ -109,6 +136,23 @@ bool is_key_pressed(report_keyboard_t* keyboard_report, uint8_t key) { * FIXME: Needs doc */ void add_key_byte(report_keyboard_t* keyboard_report, uint8_t code) { +#ifdef RECORE +#define KEYBOARD_REPORT_6KRO_BUFFER 6 //(KEYBOARD_REPORT_KEYS - 1) + //save 16B + int8_t target_pos = -1; + /* find the code pos, or when finding the first 0, the code is not in report. */ + for (uint8_t i=0; i < KEYBOARD_REPORT_6KRO_BUFFER; i++) { + if (keyboard_report->keys[i] == code || keyboard_report->keys[i] == 0) { + target_pos = i; + break; + } + } + + if (target_pos != -1) { + keyboard_report->keys[target_pos] = code; + } + return; +#endif #ifdef RING_BUFFERED_6KRO_REPORT_ENABLE int8_t i = cb_head; int8_t empty = -1; @@ -242,7 +286,11 @@ void del_key_bit(report_keyboard_t* keyboard_report, uint8_t code) { */ void add_key_to_report(report_keyboard_t* keyboard_report, uint8_t key) { #ifdef NKRO_ENABLE +#ifndef RECORE if (keyboard_protocol && keymap_config.nkro) { +#else + if (IS_NKRO()) { +#endif add_key_bit(keyboard_report, key); return; } @@ -256,7 +304,11 @@ void add_key_to_report(report_keyboard_t* keyboard_report, uint8_t key) { */ void del_key_from_report(report_keyboard_t* keyboard_report, uint8_t key) { #ifdef NKRO_ENABLE +#ifndef RECORE if (keyboard_protocol && keymap_config.nkro) { +#else + if (IS_NKRO()) { +#endif del_key_bit(keyboard_report, key); return; } @@ -269,9 +321,17 @@ void del_key_from_report(report_keyboard_t* keyboard_report, uint8_t key) { * FIXME: Needs doc */ void clear_keys_from_report(report_keyboard_t* keyboard_report) { +#ifdef RECORE //always clear all. save 20B + memset(keyboard_report->nkro.bits, 0, KEYBOARD_REPORT_BITS); + return; +#endif // not clear mods #ifdef NKRO_ENABLE +#ifndef RECORE if (keyboard_protocol && keymap_config.nkro) { +#else + if (IS_NKRO()) { +#endif memset(keyboard_report->nkro.bits, 0, sizeof(keyboard_report->nkro.bits)); return; }