From 43b9a48828eb3340d154ee160639de73cfa5e0e3 Mon Sep 17 00:00:00 2001 From: yangdigi Date: Sat, 22 Jun 2024 15:12:26 +0800 Subject: [PATCH] Xikii i6x/i8x/i104 do6m --- keyboards/ydkb/xikii/xikii_i104/config.h | 47 ++ .../xikii/xikii_i104/keymaps/vial/config.h | 6 + .../xikii/xikii_i104/keymaps/vial/keymap.c | 35 ++ .../xikii/xikii_i104/keymaps/vial/readme.md | 1 + .../xikii/xikii_i104/keymaps/vial/rules.mk | 7 + .../xikii/xikii_i104/keymaps/vial/vial.json | 32 ++ keyboards/ydkb/xikii/xikii_i104/led_fn.c | 75 +++ .../ydkb/xikii/xikii_i104/light_ws2812.c | 157 ++++++ .../ydkb/xikii/xikii_i104/light_ws2812.h | 66 +++ keyboards/ydkb/xikii/xikii_i104/matrix.c | 307 ++++++++++++ keyboards/ydkb/xikii/xikii_i104/rgblight.c | 426 +++++++++++++++++ keyboards/ydkb/xikii/xikii_i104/rgblight.h | 83 ++++ keyboards/ydkb/xikii/xikii_i104/rules.mk | 32 ++ .../ydkb/xikii/xikii_i104/switch_board.h | 18 + keyboards/ydkb/xikii/xikii_i104/xikii_i104.h | 8 + keyboards/ydkb/xikii/xikii_i6x/config.h | 43 ++ .../xikii/xikii_i6x/keymaps/vial/config.h | 6 + .../xikii/xikii_i6x/keymaps/vial/keymap.c | 45 ++ .../xikii/xikii_i6x/keymaps/vial/readme.md | 1 + .../xikii/xikii_i6x/keymaps/vial/rules.mk | 7 + .../xikii/xikii_i6x/keymaps/vial/vial.json | 43 ++ keyboards/ydkb/xikii/xikii_i6x/led_fn.c | 75 +++ keyboards/ydkb/xikii/xikii_i6x/light_ws2812.c | 157 ++++++ keyboards/ydkb/xikii/xikii_i6x/light_ws2812.h | 66 +++ keyboards/ydkb/xikii/xikii_i6x/matrix.c | 308 ++++++++++++ keyboards/ydkb/xikii/xikii_i6x/rgblight.c | 451 +++++++++++++++++ keyboards/ydkb/xikii/xikii_i6x/rgblight.h | 83 ++++ keyboards/ydkb/xikii/xikii_i6x/rules.mk | 32 ++ keyboards/ydkb/xikii/xikii_i6x/switch_board.h | 18 + keyboards/ydkb/xikii/xikii_i6x/xikii_i6x.h | 8 + keyboards/ydkb/xikii/xikii_i8x/config.h | 43 ++ .../xikii/xikii_i8x/keymaps/vial/config.h | 6 + .../xikii/xikii_i8x/keymaps/vial/keymap.c | 47 ++ .../xikii/xikii_i8x/keymaps/vial/readme.md | 1 + .../xikii/xikii_i8x/keymaps/vial/rules.mk | 7 + .../xikii/xikii_i8x/keymaps/vial/vial.json | 32 ++ keyboards/ydkb/xikii/xikii_i8x/led_fn.c | 75 +++ keyboards/ydkb/xikii/xikii_i8x/light_ws2812.c | 157 ++++++ keyboards/ydkb/xikii/xikii_i8x/light_ws2812.h | 66 +++ keyboards/ydkb/xikii/xikii_i8x/matrix.c | 308 ++++++++++++ keyboards/ydkb/xikii/xikii_i8x/rgblight.c | 452 ++++++++++++++++++ keyboards/ydkb/xikii/xikii_i8x/rgblight.h | 83 ++++ keyboards/ydkb/xikii/xikii_i8x/rules.mk | 32 ++ keyboards/ydkb/xikii/xikii_i8x/switch_board.h | 18 + keyboards/ydkb/xikii/xikii_i8x/xikii_i8x.h | 8 + 45 files changed, 3978 insertions(+) create mode 100644 keyboards/ydkb/xikii/xikii_i104/config.h create mode 100644 keyboards/ydkb/xikii/xikii_i104/keymaps/vial/config.h create mode 100644 keyboards/ydkb/xikii/xikii_i104/keymaps/vial/keymap.c create mode 100644 keyboards/ydkb/xikii/xikii_i104/keymaps/vial/readme.md create mode 100644 keyboards/ydkb/xikii/xikii_i104/keymaps/vial/rules.mk create mode 100644 keyboards/ydkb/xikii/xikii_i104/keymaps/vial/vial.json create mode 100644 keyboards/ydkb/xikii/xikii_i104/led_fn.c create mode 100644 keyboards/ydkb/xikii/xikii_i104/light_ws2812.c create mode 100644 keyboards/ydkb/xikii/xikii_i104/light_ws2812.h create mode 100644 keyboards/ydkb/xikii/xikii_i104/matrix.c create mode 100644 keyboards/ydkb/xikii/xikii_i104/rgblight.c create mode 100644 keyboards/ydkb/xikii/xikii_i104/rgblight.h create mode 100644 keyboards/ydkb/xikii/xikii_i104/rules.mk create mode 100644 keyboards/ydkb/xikii/xikii_i104/switch_board.h create mode 100644 keyboards/ydkb/xikii/xikii_i104/xikii_i104.h create mode 100644 keyboards/ydkb/xikii/xikii_i6x/config.h create mode 100644 keyboards/ydkb/xikii/xikii_i6x/keymaps/vial/config.h create mode 100644 keyboards/ydkb/xikii/xikii_i6x/keymaps/vial/keymap.c create mode 100644 keyboards/ydkb/xikii/xikii_i6x/keymaps/vial/readme.md create mode 100644 keyboards/ydkb/xikii/xikii_i6x/keymaps/vial/rules.mk create mode 100644 keyboards/ydkb/xikii/xikii_i6x/keymaps/vial/vial.json create mode 100644 keyboards/ydkb/xikii/xikii_i6x/led_fn.c create mode 100644 keyboards/ydkb/xikii/xikii_i6x/light_ws2812.c create mode 100644 keyboards/ydkb/xikii/xikii_i6x/light_ws2812.h create mode 100644 keyboards/ydkb/xikii/xikii_i6x/matrix.c create mode 100644 keyboards/ydkb/xikii/xikii_i6x/rgblight.c create mode 100644 keyboards/ydkb/xikii/xikii_i6x/rgblight.h create mode 100644 keyboards/ydkb/xikii/xikii_i6x/rules.mk create mode 100644 keyboards/ydkb/xikii/xikii_i6x/switch_board.h create mode 100644 keyboards/ydkb/xikii/xikii_i6x/xikii_i6x.h create mode 100644 keyboards/ydkb/xikii/xikii_i8x/config.h create mode 100644 keyboards/ydkb/xikii/xikii_i8x/keymaps/vial/config.h create mode 100644 keyboards/ydkb/xikii/xikii_i8x/keymaps/vial/keymap.c create mode 100644 keyboards/ydkb/xikii/xikii_i8x/keymaps/vial/readme.md create mode 100644 keyboards/ydkb/xikii/xikii_i8x/keymaps/vial/rules.mk create mode 100644 keyboards/ydkb/xikii/xikii_i8x/keymaps/vial/vial.json create mode 100644 keyboards/ydkb/xikii/xikii_i8x/led_fn.c create mode 100644 keyboards/ydkb/xikii/xikii_i8x/light_ws2812.c create mode 100644 keyboards/ydkb/xikii/xikii_i8x/light_ws2812.h create mode 100644 keyboards/ydkb/xikii/xikii_i8x/matrix.c create mode 100644 keyboards/ydkb/xikii/xikii_i8x/rgblight.c create mode 100644 keyboards/ydkb/xikii/xikii_i8x/rgblight.h create mode 100644 keyboards/ydkb/xikii/xikii_i8x/rules.mk create mode 100644 keyboards/ydkb/xikii/xikii_i8x/switch_board.h create mode 100644 keyboards/ydkb/xikii/xikii_i8x/xikii_i8x.h diff --git a/keyboards/ydkb/xikii/xikii_i104/config.h b/keyboards/ydkb/xikii/xikii_i104/config.h new file mode 100644 index 00000000000..7883936efda --- /dev/null +++ b/keyboards/ydkb/xikii/xikii_i104/config.h @@ -0,0 +1,47 @@ + +#pragma once + +#include "config_common.h" +#include "config_ble51.h" + +/* USB Device descriptor parameter */ +#define FW_VER_DATE DO6M +#define VENDOR_ID 0x9D5B +#define PRODUCT_ID 0x21A0 +#define DEVICE_VER 0x0001 +#define MANUFACTURER YDKB +#define PRODUCT Xikii i104 (FW_VER) + + +/* key matrix size */ +#define MATRIX_ROWS 13 +#define MATRIX_COLS 8 + +#define DEFAULT_6KRO // macOS's Capslock switching between Chinese and English has compatibility issues with NKRO + +#define SUSPEND_ACTION + +#define BACKLIGHT_PIN C6 +#define BACKLIGHT_LEVELS 6 +#define BACKLIGHT_ON_STATE 0 + +#define ws2812_PORTREG PORTD +#define ws2812_DDRREG DDRD +#define ws2812_pin PD1 +#define RGBLED_NUM 12 // Number of LEDs + +/* BT Power Control */ +#define BT_POWERED (~PORTD & (1<<5)) +#define bt_power_init() do { DDRD |= (1<<5); PORTD &= ~(1<<5); } while(0) +#define bt_power_reset() do {PORTD |= (1<<5); WAIT_MS(100); PORTD &= ~(1<<5);} while(0) +#define turn_off_bt() do { PORTD |= (1<<5); 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_fn_init(void) { + // led init + DDRD |= (1<<7 | 1<<6 | 1<<4); + PORTD &= ~(1<<7 | 1<<6 | 1<<4); +} + +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; + } + } +} \ No newline at end of file diff --git a/keyboards/ydkb/xikii/xikii_i104/light_ws2812.c b/keyboards/ydkb/xikii/xikii_i104/light_ws2812.c new file mode 100644 index 00000000000..739c9ed8776 --- /dev/null +++ b/keyboards/ydkb/xikii/xikii_i104/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/xikii/xikii_i104/light_ws2812.h b/keyboards/ydkb/xikii/xikii_i104/light_ws2812.h new file mode 100644 index 00000000000..08187ac90a9 --- /dev/null +++ b/keyboards/ydkb/xikii/xikii_i104/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/xikii/xikii_i104/matrix.c b/keyboards/ydkb/xikii/xikii_i104/matrix.c new file mode 100644 index 00000000000..8991cc6c1ab --- /dev/null +++ b/keyboards/ydkb/xikii/xikii_i104/matrix.c @@ -0,0 +1,307 @@ +/* +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 "print.h" +#include "debug.h" +#include "util.h" +#include "command.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" +#include "switch_board.h" + +#define DOUBLE_CLICK_FIX_DELAY 10 + +bool is_ble_version = 1; + + +extern debug_config_t debug_config; +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; +static uint8_t matrix_debouncing[MATRIX_ROWS][MATRIX_COLS] = {0}; +static uint8_t matrix_double_click_fix[MATRIX_ROWS][MATRIX_COLS] = {0}; +#ifdef DEFAULT_6KRO +static uint8_t now_debounce_dn_mask = DEBOUNCE_DN_MASK; +#else +static uint8_t now_debounce_dn_mask = DEBOUNCE_NK_MASK; +#endif +static bool matrix_idle = false; +static bool first_key_scan = false; + +static void select_key(uint8_t mode); +static void select_all_keys(void); +static uint8_t get_key(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() +{ + // PB4 for BLE Check; + DDRB &= ~(1<<4); + PORTB |= (1<<4); + WAIT_MS(2); + if (PINB & (1<<4)) { + // USB Only version + is_ble_version = 0; + ble51_boot_on = 0; + // light LED3 + //DDRD |= (1<<4); + //PORTD |= (1<<4); + //_delay_ms(1000); + } else { + is_ble_version = 1; + //DDRD |= (1<<7); + //PORTD |= (1<<7); + //_delay_ms(1000); + // PE2 for BT_SW + DDRE &= ~(1<<2); + PORTE |= (1<<2); + // PB4 for BLE Check; PB5 for BLE Reset + DDRB &= ~(1<<5); + PORTB |= (1<<5); + WAIT_MS(10); // 2ms时似乎有问题,可能一直是 ble51_boot_on = 1 + if (~PINE & (1<<2)) ble51_boot_on = 0; + else ble51_boot_on = 1; + + //BLE Reset + if (ble_reset_key == 0xBBAA) { + ble_reset_key = 0; + if (ble51_boot_on) { + // PB6 for BLE Reset + DDRB |= (1<<5); + PORTB &= ~(1<<5); + bt_power_init(); + // light LED3 + DDRD |= (1<<4); + PORTD |= (1<<4); + _delay_ms(5000); + bootloader_jump(); + } + } + } + // led init + led_fn_init(); + //DDRD |= (1<<7 | 1<<6 | 1<<4); + //PORTD &= ~(1<<7 | 1<<6 | 1<<4); +} + +void matrix_init(void) +{ + init_cols(); + rgblight_init(); +} + +uint8_t matrix_scan(void) +{ + matrix_scan_quantum(); // qmk needs this to run hook_keyboard_loop() + + if (matrix_idle) { + if (get_key() == 0) return 1; + else { + matrix_idle = false; + first_key_scan = true; + } + } + if (!first_key_scan) { + //scan matrix every 1ms + uint16_t time_check = timer_read(); + if (matrix_scan_timestamp == time_check) return 1; + matrix_scan_timestamp = time_check; + } + + select_key(0); + uint8_t *debounce = &matrix_debouncing[0][0]; + uint8_t *double_click_fix = &matrix_double_click_fix[0][0]; + uint8_t one_scan_down = 0; + uint8_t matrix_up_keys = MATRIX_ROWS * MATRIX_COLS; + for (uint8_t row=0; row> 1) | key; + //select next key + select_key(1); + if (1) { + matrix_row_t *p_row = &matrix[row]; + matrix_row_t col_mask = ((matrix_row_t)1 << col); + if (*double_click_fix > 0 && (*p_row & col_mask) == 0) { + (*double_click_fix)--; + } else { + if (*debounce > now_debounce_dn_mask) { //debounce KEY DOWN + *p_row |= col_mask; + *double_click_fix = DOUBLE_CLICK_FIX_DELAY; + } else if (*debounce < DEBOUNCE_UP_MASK) { //debounce KEY UP + *p_row &= ~col_mask; + matrix_up_keys--; + } + } + } + } + } + + // 最终检测一次是不是完全没有按键按下 + if (matrix_up_keys == 0) { + select_all_keys(); + matrix_idle = true; + } else { + kb_idle_times = 0; + // 从空闲到检测第一个按键时多扫一次 + if (first_key_scan) { + first_key_scan = false; + #if DEBOUNCE_NK > 0 + matrix_scan(); + #endif + } + } + + return 1; +} + + +inline +bool matrix_is_on(uint8_t row, uint8_t col) +{ + return (matrix[row] & ((matrix_row_t)1<= 10) { //lock mode + matrix_scan(); + // K95 F, K75 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(7,5) || i == KP(9,5)) 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 all keys + select_all_keys(); + _delay_us(5); + if (get_key()) { // + return true; + } + } + return false; +} + +void hook_nkro_change(void) { + uint8_t kbd_nkro = (keyboard_protocol & (1<<4)); + 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/xikii/xikii_i104/rgblight.c b/keyboards/ydkb/xikii/xikii_i104/rgblight.c new file mode 100644 index 00000000000..a2efe36bb1c --- /dev/null +++ b/keyboards/ydkb/xikii/xikii_i104/rgblight.c @@ -0,0 +1,426 @@ +#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 "led.h" +#include "quantum.h" + +#define rgblight_timer_init() do { DDRD |= (1<<0);} while(0) +#define rgblight_timer_enable() do { PORTD &= ~(1<<0);} while(0) +#define rgblight_timer_disable() do { PORTD |= (1<<0);} while(0) +#define rgblight_timer_enabled (~PORTD & (1<<0)) +#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}; +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; + +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 0 + 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(); + } 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 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); + } +} + +void rgblight_setrgb(uint8_t r, uint8_t g, uint8_t b) +{ + for (uint8_t i=0;i 62) { + //if (pos < interval || pos+interval > 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) +{ + PORTD &= ~(1<<7 | 1<<6 | 1<<4); + DDRC &= ~(1<<6); //backlight_disable(); + + rgblight_timer_disable(); //RGB_VCC off +} + +void suspend_wakeup_init_action(void) +{ + rgblight_init(); + DDRC |= (1<<6); +} + +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 (PINC & (1<<7)) { //not charging + backlight_disable(); + rgblight_timer_disable(); + PORTD ^= (1<<4); + } else { + low_battery = 0; + suspend_wakeup_init_action(); + } + } + } else if (display_connection_status_check_times) { + rgblight_timer_enable(); + if (ble51_task_steps == 1) { + PORTD &= ~(1<<6 | 1<<4); + rgblight_clear(); + rgblight_set(); + } else if (ble51_task_steps == 3) { + PORTD |= (1<<4); //led3 on + if (bt_connected) PORTD |= (1<<6); //led2 on too. + 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; + } + } + } +} diff --git a/keyboards/ydkb/xikii/xikii_i104/rgblight.h b/keyboards/ydkb/xikii/xikii_i104/rgblight.h new file mode 100644 index 00000000000..4f6e166b1eb --- /dev/null +++ b/keyboards/ydkb/xikii/xikii_i104/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_clear(void); +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_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/xikii/xikii_i104/rules.mk b/keyboards/ydkb/xikii/xikii_i104/rules.mk new file mode 100644 index 00000000000..b9feac39d6e --- /dev/null +++ b/keyboards/ydkb/xikii/xikii_i104/rules.mk @@ -0,0 +1,32 @@ +# MCU name +MCU = atmega32u4 + +# Processor frequency +F_CPU = 8000000 + +# Bootloader selection +BOOTLOADER = lufa-ms +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 + +# project specific files +SRC ?= matrix.c \ + led_fn.c \ + light_ws2812.c \ + rgblight.c + +include $(TMK_DIR)/protocol/ble51.mk diff --git a/keyboards/ydkb/xikii/xikii_i104/switch_board.h b/keyboards/ydkb/xikii/xikii_i104/switch_board.h new file mode 100644 index 00000000000..a9af01b320e --- /dev/null +++ b/keyboards/ydkb/xikii/xikii_i104/switch_board.h @@ -0,0 +1,18 @@ +#ifndef SWITCH_BOARD_H +#define SWITCH_BOARD_H + +#include +#include +#include + +#define DS_PL_HI() (PORTB |= (1<<3)) +#define DS_PL_LO() (PORTB &= ~(1<<3)) + + +#define CLOCK_PULSE() \ + do { \ + PORTB |= (1<<1); \ + PORTB &= ~(1<<1); \ + } while(0) + +#endif \ No newline at end of file diff --git a/keyboards/ydkb/xikii/xikii_i104/xikii_i104.h b/keyboards/ydkb/xikii/xikii_i104/xikii_i104.h new file mode 100644 index 00000000000..bd6e6bce6c3 --- /dev/null +++ b/keyboards/ydkb/xikii/xikii_i104/xikii_i104.h @@ -0,0 +1,8 @@ +#pragma once + +#include "quantum.h" +#include +#include + +#define XXX KC_NO + diff --git a/keyboards/ydkb/xikii/xikii_i6x/config.h b/keyboards/ydkb/xikii/xikii_i6x/config.h new file mode 100644 index 00000000000..7a121e40873 --- /dev/null +++ b/keyboards/ydkb/xikii/xikii_i6x/config.h @@ -0,0 +1,43 @@ + +#pragma once + +#include "config_common.h" +#include "config_ble51.h" + +/* USB Device descriptor parameter */ +#define FW_VER_DATE DO6M +#define VENDOR_ID 0x9D5B +#define PRODUCT_ID 0x2166 +#define DEVICE_VER 0x0001 +#define MANUFACTURER YDKB +#define PRODUCT Xikii i6x (FW_VER) + + +/* key matrix size */ +#define MATRIX_ROWS 10 //595 +#define MATRIX_COLS 8 + +#define DEFAULT_6KRO // macOS's Capslock switching between Chinese and English has compatibility issues with NKRO + +#define SUSPEND_ACTION + +#define ws2812_PORTREG PORTD +#define ws2812_DDRREG DDRD +#define ws2812_pin PD1 +#define RGBLED_NUM 14 // Number of LEDs for calc + +/* BT Power Control */ +#define BT_POWERED (~PORTD & (1<<5)) +#define bt_power_init() do { DDRD |= (1<<5); PORTD &= ~(1<<5); } while(0) +#define bt_power_reset() do {PORTD |= (1<<5); WAIT_MS(100); PORTD &= ~(1<<5);} while(0) +#define turn_off_bt() do { PORTD |= (1<<5); 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_fn_init(void) { + // led init + DDRD |= (1<<7 | 1<<6 | 1<<4); + PORTD &= ~(1<<7 | 1<<6 | 1<<4); +} + +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; + } + } +} \ No newline at end of file diff --git a/keyboards/ydkb/xikii/xikii_i6x/light_ws2812.c b/keyboards/ydkb/xikii/xikii_i6x/light_ws2812.c new file mode 100644 index 00000000000..252433e006a --- /dev/null +++ b/keyboards/ydkb/xikii/xikii_i6x/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*2 + 3; //RGB_NUM 14, real 29. + + 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/xikii/xikii_i6x/light_ws2812.h b/keyboards/ydkb/xikii/xikii_i6x/light_ws2812.h new file mode 100644 index 00000000000..08187ac90a9 --- /dev/null +++ b/keyboards/ydkb/xikii/xikii_i6x/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/xikii/xikii_i6x/matrix.c b/keyboards/ydkb/xikii/xikii_i6x/matrix.c new file mode 100644 index 00000000000..71f5b7e0d25 --- /dev/null +++ b/keyboards/ydkb/xikii/xikii_i6x/matrix.c @@ -0,0 +1,308 @@ +/* +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 "print.h" +#include "debug.h" +#include "util.h" +#include "command.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" +#include "switch_board.h" + +#define DOUBLE_CLICK_FIX_DELAY 10 + +bool is_ble_version = 1; + + +extern debug_config_t debug_config; +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; +static uint8_t matrix_debouncing[MATRIX_ROWS][MATRIX_COLS] = {0}; +static uint8_t matrix_double_click_fix[MATRIX_ROWS][MATRIX_COLS] = {0}; +#ifdef DEFAULT_6KRO +static uint8_t now_debounce_dn_mask = DEBOUNCE_DN_MASK; +#else +static uint8_t now_debounce_dn_mask = DEBOUNCE_NK_MASK; +#endif +static bool matrix_idle = false; +static bool first_key_scan = false; + +static void select_key(uint8_t mode); +static void select_all_keys(void); +static uint8_t get_key(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() +{ + // PB4 for BLE Check; + DDRB &= ~(1<<4); + PORTB |= (1<<4); + WAIT_MS(2); + if (PINB & (1<<4)) { + // USB Only version + is_ble_version = 0; + ble51_boot_on = 0; + // light LED3 + //DDRD |= (1<<4); + //PORTD |= (1<<4); + //_delay_ms(1000); + } else { + is_ble_version = 1; + //DDRD |= (1<<7); + //PORTD |= (1<<7); + //_delay_ms(1000); + // PE2 for BT_SW + DDRE &= ~(1<<2); + PORTE |= (1<<2); + // PB4 for BLE Check; PB5 for BLE Reset + DDRB &= ~(1<<5); + PORTB |= (1<<5); + WAIT_MS(10); // 2ms时似乎有问题,可能一直是 ble51_boot_on = 1 + if (~PINE & (1<<2)) ble51_boot_on = 0; + else ble51_boot_on = 1; + + //BLE Reset + if (ble_reset_key == 0xBBAA) { + ble_reset_key = 0; + if (ble51_boot_on) { + // PB6 for BLE Reset + DDRB |= (1<<5); + PORTB &= ~(1<<5); + bt_power_init(); + // light LED3 + DDRD |= (1<<4); + PORTD |= (1<<4); + _delay_ms(5000); + bootloader_jump(); + } + } + } + // led init + led_fn_init(); + //DDRD |= (1<<7 | 1<<6 | 1<<4); + //PORTD &= ~(1<<7 | 1<<6 | 1<<4); +} + +void matrix_init(void) +{ + init_cols(); + rgblight_init(); +} + +uint8_t matrix_scan(void) +{ + matrix_scan_quantum(); // qmk needs this to run hook_keyboard_loop() + + if (matrix_idle) { + if (get_key() == 0) return 1; + else { + matrix_idle = false; + first_key_scan = true; + } + } + if (!first_key_scan) { + //scan matrix every 1ms + uint16_t time_check = timer_read(); + if (matrix_scan_timestamp == time_check) return 1; + matrix_scan_timestamp = time_check; + } + + select_key(0); + uint8_t *debounce = &matrix_debouncing[0][0]; + uint8_t *double_click_fix = &matrix_double_click_fix[0][0]; + uint8_t one_scan_down = 0; + uint8_t matrix_up_keys = MATRIX_ROWS * MATRIX_COLS; + for (uint8_t row=0; row> 1) | key; + //select next key + select_key(1); + if (1) { + matrix_row_t *p_row = &matrix[row]; + matrix_row_t col_mask = ((matrix_row_t)1 << col); + if (*double_click_fix > 0 && (*p_row & col_mask) == 0) { + (*double_click_fix)--; + } else { + if (*debounce > now_debounce_dn_mask) { //debounce KEY DOWN + *p_row |= col_mask; + *double_click_fix = DOUBLE_CLICK_FIX_DELAY; + } else if (*debounce < DEBOUNCE_UP_MASK) { //debounce KEY UP + *p_row &= ~col_mask; + matrix_up_keys--; + } + } + } + } + } + + // 最终检测一次是不是完全没有按键按下 + if (matrix_up_keys == 0) { + select_all_keys(); + 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; + #if DEBOUNCE_NK > 0 + matrix_scan(); + #endif + } + } + + return 1; +} + + +inline +bool matrix_is_on(uint8_t row, uint8_t col) +{ + return (matrix[row] & ((matrix_row_t)1<= 10) { //lock mode + matrix_scan(); + // K73 F, // K76 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(7,3) || i == KP(7,6)) 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 all keys + select_all_keys(); + _delay_us(5); + if (get_key()) { // + return true; + } + } + return false; +} + +void hook_nkro_change(void) { + uint8_t kbd_nkro = (keyboard_protocol & (1<<4)); + 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/xikii/xikii_i6x/rgblight.c b/keyboards/ydkb/xikii/xikii_i6x/rgblight.c new file mode 100644 index 00000000000..582f43e69c3 --- /dev/null +++ b/keyboards/ydkb/xikii/xikii_i6x/rgblight.c @@ -0,0 +1,451 @@ +#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 "led.h" +#include "quantum.h" + +#define rgblight_timer_init() do { DDRD |= (1<<0);} while(0) +#define rgblight_timer_enable() do { PORTD &= ~(1<<0);} while(0) +#define rgblight_timer_disable() do { PORTD |= (1<<0);} while(0) +#define rgblight_timer_enabled (~PORTD & (1<<0)) +#define RGBLED_TEMP (RGBLED_NUM*2 + 1) //29 + +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 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*2+2]; //29+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) +{ + PORTD &= ~(1<<7 | 1<<6 | 1<<4); + rgblight_timer_disable(); //RGB_VCC off + rgb_fading_index = 0; +} + +void suspend_wakeup_init_action(void) +{ + rgblight_init(); +} + +void hook_keyboard_loop() +{ + static uint16_t rgb_update_timer = 0; + if (rgblight_timer_enabled && timer_elapsed(rgb_update_timer) > 30) { + 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 (PINC & (1<<7)) { //not charging + rgblight_timer_disable(); + PORTD ^= (1<<4); + } else { + low_battery = 0; + suspend_wakeup_init_action(); + } + } + } else if (display_connection_status_check_times) { + rgblight_timer_enable(); + if (ble51_task_steps == 1) { + PORTD &= ~(1<<6 | 1<<4); + rgblight_clear(); + rgblight_set(); + } else if (ble51_task_steps == 3) { + PORTD |= (1<<4); //led3 on + if (bt_connected) PORTD |= (1<<6); //led2 on too. + 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; + } + } + } +} diff --git a/keyboards/ydkb/xikii/xikii_i6x/rgblight.h b/keyboards/ydkb/xikii/xikii_i6x/rgblight.h new file mode 100644 index 00000000000..4f6e166b1eb --- /dev/null +++ b/keyboards/ydkb/xikii/xikii_i6x/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_clear(void); +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_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/xikii/xikii_i6x/rules.mk b/keyboards/ydkb/xikii/xikii_i6x/rules.mk new file mode 100644 index 00000000000..d943e008707 --- /dev/null +++ b/keyboards/ydkb/xikii/xikii_i6x/rules.mk @@ -0,0 +1,32 @@ +# MCU name +MCU = atmega32u4 + +# Processor frequency +F_CPU = 8000000 + +# Bootloader selection +BOOTLOADER = lufa-ms +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 = no # Enable keyboard backlight functionality +RGBLIGHT_ENABLE = no +LTO_ENABLE = yes + +# project specific files +SRC ?= matrix.c \ + led_fn.c \ + light_ws2812.c \ + rgblight.c + +include $(TMK_DIR)/protocol/ble51.mk diff --git a/keyboards/ydkb/xikii/xikii_i6x/switch_board.h b/keyboards/ydkb/xikii/xikii_i6x/switch_board.h new file mode 100644 index 00000000000..a9af01b320e --- /dev/null +++ b/keyboards/ydkb/xikii/xikii_i6x/switch_board.h @@ -0,0 +1,18 @@ +#ifndef SWITCH_BOARD_H +#define SWITCH_BOARD_H + +#include +#include +#include + +#define DS_PL_HI() (PORTB |= (1<<3)) +#define DS_PL_LO() (PORTB &= ~(1<<3)) + + +#define CLOCK_PULSE() \ + do { \ + PORTB |= (1<<1); \ + PORTB &= ~(1<<1); \ + } while(0) + +#endif \ No newline at end of file diff --git a/keyboards/ydkb/xikii/xikii_i6x/xikii_i6x.h b/keyboards/ydkb/xikii/xikii_i6x/xikii_i6x.h new file mode 100644 index 00000000000..bd6e6bce6c3 --- /dev/null +++ b/keyboards/ydkb/xikii/xikii_i6x/xikii_i6x.h @@ -0,0 +1,8 @@ +#pragma once + +#include "quantum.h" +#include +#include + +#define XXX KC_NO + diff --git a/keyboards/ydkb/xikii/xikii_i8x/config.h b/keyboards/ydkb/xikii/xikii_i8x/config.h new file mode 100644 index 00000000000..e6b47733510 --- /dev/null +++ b/keyboards/ydkb/xikii/xikii_i8x/config.h @@ -0,0 +1,43 @@ + +#pragma once + +#include "config_common.h" +#include "config_ble51.h" + +/* USB Device descriptor parameter */ +#define FW_VER_DATE DO6M +#define VENDOR_ID 0x9D5B +#define PRODUCT_ID 0x2180 +#define DEVICE_VER 0x0001 +#define MANUFACTURER YDKB +#define PRODUCT Xikii i8x (FW_VER) + + +/* key matrix size */ +#define MATRIX_ROWS 11 //595 +#define MATRIX_COLS 8 + +#define DEFAULT_6KRO // macOS's Capslock switching between Chinese and English has compatibility issues with NKRO + +#define SUSPEND_ACTION + +#define ws2812_PORTREG PORTD +#define ws2812_DDRREG DDRD +#define ws2812_pin PD1 +#define RGBLED_NUM 12 // Number of LEDs + +/* BT Power Control */ +#define BT_POWERED (~PORTD & (1<<5)) +#define bt_power_init() do { DDRD |= (1<<5); PORTD &= ~(1<<5); } while(0) +#define bt_power_reset() do {PORTD |= (1<<5); WAIT_MS(100); PORTD &= ~(1<<5);} while(0) +#define turn_off_bt() do { PORTD |= (1<<5); 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_fn_init(void) { + // led init + DDRD |= (1<<7 | 1<<6 | 1<<4); + PORTD &= ~(1<<7 | 1<<6 | 1<<4); +} + +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; + } + } +} \ No newline at end of file diff --git a/keyboards/ydkb/xikii/xikii_i8x/light_ws2812.c b/keyboards/ydkb/xikii/xikii_i8x/light_ws2812.c new file mode 100644 index 00000000000..739c9ed8776 --- /dev/null +++ b/keyboards/ydkb/xikii/xikii_i8x/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/xikii/xikii_i8x/light_ws2812.h b/keyboards/ydkb/xikii/xikii_i8x/light_ws2812.h new file mode 100644 index 00000000000..08187ac90a9 --- /dev/null +++ b/keyboards/ydkb/xikii/xikii_i8x/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/xikii/xikii_i8x/matrix.c b/keyboards/ydkb/xikii/xikii_i8x/matrix.c new file mode 100644 index 00000000000..e9b916aee5c --- /dev/null +++ b/keyboards/ydkb/xikii/xikii_i8x/matrix.c @@ -0,0 +1,308 @@ +/* +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 "print.h" +#include "debug.h" +#include "util.h" +#include "command.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" +#include "switch_board.h" + +#define DOUBLE_CLICK_FIX_DELAY 10 + +bool is_ble_version = 1; + + +extern debug_config_t debug_config; +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; +static uint8_t matrix_debouncing[MATRIX_ROWS][MATRIX_COLS] = {0}; +static uint8_t matrix_double_click_fix[MATRIX_ROWS][MATRIX_COLS] = {0}; +#ifdef DEFAULT_6KRO +static uint8_t now_debounce_dn_mask = DEBOUNCE_DN_MASK; +#else +static uint8_t now_debounce_dn_mask = DEBOUNCE_NK_MASK; +#endif +static bool matrix_idle = false; +static bool first_key_scan = false; + +static void select_key(uint8_t mode); +static void select_all_keys(void); +static uint8_t get_key(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() +{ + // PB4 for BLE Check; + DDRB &= ~(1<<4); + PORTB |= (1<<4); + WAIT_MS(2); + if (PINB & (1<<4)) { + // USB Only version + is_ble_version = 0; + ble51_boot_on = 0; + // light LED3 + //DDRD |= (1<<4); + //PORTD |= (1<<4); + //_delay_ms(1000); + } else { + is_ble_version = 1; + //DDRD |= (1<<7); + //PORTD |= (1<<7); + //_delay_ms(1000); + // PE2 for BT_SW + DDRE &= ~(1<<2); + PORTE |= (1<<2); + // PB4 for BLE Check; PB5 for BLE Reset + DDRB &= ~(1<<5); + PORTB |= (1<<5); + WAIT_MS(10); // 2ms时似乎有问题,可能一直是 ble51_boot_on = 1 + if (~PINE & (1<<2)) ble51_boot_on = 0; + else ble51_boot_on = 1; + + //BLE Reset + if (ble_reset_key == 0xBBAA) { + ble_reset_key = 0; + if (ble51_boot_on) { + // PB6 for BLE Reset + DDRB |= (1<<5); + PORTB &= ~(1<<5); + bt_power_init(); + // light LED3 + DDRD |= (1<<4); + PORTD |= (1<<4); + _delay_ms(5000); + bootloader_jump(); + } + } + } + // led init + led_fn_init(); + //DDRD |= (1<<7 | 1<<6 | 1<<4); + //PORTD &= ~(1<<7 | 1<<6 | 1<<4); +} + +void matrix_init(void) +{ + init_cols(); + rgblight_init(); +} + +uint8_t matrix_scan(void) +{ + matrix_scan_quantum(); // qmk needs this to run hook_keyboard_loop() + + if (matrix_idle) { + if (get_key() == 0) return 1; + else { + matrix_idle = false; + first_key_scan = true; + } + } + if (!first_key_scan) { + //scan matrix every 1ms + uint16_t time_check = timer_read(); + if (matrix_scan_timestamp == time_check) return 1; + matrix_scan_timestamp = time_check; + } + + select_key(0); + uint8_t *debounce = &matrix_debouncing[0][0]; + uint8_t *double_click_fix = &matrix_double_click_fix[0][0]; + uint8_t one_scan_down = 0; + uint8_t matrix_up_keys = MATRIX_ROWS * MATRIX_COLS; + for (uint8_t row=0; row> 1) | key; + //select next key + select_key(1); + if (1) { + matrix_row_t *p_row = &matrix[row]; + matrix_row_t col_mask = ((matrix_row_t)1 << col); + if (*double_click_fix > 0 && (*p_row & col_mask) == 0) { + (*double_click_fix)--; + } else { + if (*debounce > now_debounce_dn_mask) { //debounce KEY DOWN + *p_row |= col_mask; + *double_click_fix = DOUBLE_CLICK_FIX_DELAY; + } else if (*debounce < DEBOUNCE_UP_MASK) { //debounce KEY UP + *p_row &= ~col_mask; + matrix_up_keys--; + } + } + } + } + } + + // 最终检测一次是不是完全没有按键按下 + if (matrix_up_keys == 0) { + select_all_keys(); + 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; + #if DEBOUNCE_NK > 0 + matrix_scan(); + #endif + } + } + + return 1; +} + + +inline +bool matrix_is_on(uint8_t row, uint8_t col) +{ + return (matrix[row] & ((matrix_row_t)1<= 10) { //lock mode + matrix_scan(); + // K75 F, K55 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(5,5) || i == KP(7,5)) 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 all keys + select_all_keys(); + _delay_us(5); + if (get_key()) { // + return true; + } + } + return false; +} + +void hook_nkro_change(void) { + uint8_t kbd_nkro = (keyboard_protocol & (1<<4)); + 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/xikii/xikii_i8x/rgblight.c b/keyboards/ydkb/xikii/xikii_i8x/rgblight.c new file mode 100644 index 00000000000..04188d2bf43 --- /dev/null +++ b/keyboards/ydkb/xikii/xikii_i8x/rgblight.c @@ -0,0 +1,452 @@ +#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 "led.h" +#include "quantum.h" + +#define rgblight_timer_init() do { DDRD |= (1<<0);} while(0) +#define rgblight_timer_enable() do { PORTD &= ~(1<<0);} while(0) +#define rgblight_timer_disable() do { PORTD |= (1<<0);} while(0) +#define rgblight_timer_enabled (~PORTD & (1<<0)) +#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 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; + 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) +{ + PORTD &= ~(1<<7 | 1<<6 | 1<<4); + rgblight_timer_disable(); //RGB_VCC off + rgb_fading_index = 0; +} + +void suspend_wakeup_init_action(void) +{ + rgblight_init(); +} + +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 (PINC & (1<<7)) { //not charging + rgblight_timer_disable(); + PORTD ^= (1<<4); + } else { + low_battery = 0; + suspend_wakeup_init_action(); + } + } + } else if (display_connection_status_check_times) { + rgblight_timer_enable(); + if (ble51_task_steps == 1) { + PORTD &= ~(1<<6 | 1<<4); + rgblight_clear(); + rgblight_set(); + } else if (ble51_task_steps == 3) { + PORTD |= (1<<4); //led3 on + if (bt_connected) PORTD |= (1<<6); //led2 on too. + 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; + } + } + } +} diff --git a/keyboards/ydkb/xikii/xikii_i8x/rgblight.h b/keyboards/ydkb/xikii/xikii_i8x/rgblight.h new file mode 100644 index 00000000000..4f6e166b1eb --- /dev/null +++ b/keyboards/ydkb/xikii/xikii_i8x/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_clear(void); +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_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/xikii/xikii_i8x/rules.mk b/keyboards/ydkb/xikii/xikii_i8x/rules.mk new file mode 100644 index 00000000000..d943e008707 --- /dev/null +++ b/keyboards/ydkb/xikii/xikii_i8x/rules.mk @@ -0,0 +1,32 @@ +# MCU name +MCU = atmega32u4 + +# Processor frequency +F_CPU = 8000000 + +# Bootloader selection +BOOTLOADER = lufa-ms +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 = no # Enable keyboard backlight functionality +RGBLIGHT_ENABLE = no +LTO_ENABLE = yes + +# project specific files +SRC ?= matrix.c \ + led_fn.c \ + light_ws2812.c \ + rgblight.c + +include $(TMK_DIR)/protocol/ble51.mk diff --git a/keyboards/ydkb/xikii/xikii_i8x/switch_board.h b/keyboards/ydkb/xikii/xikii_i8x/switch_board.h new file mode 100644 index 00000000000..a9af01b320e --- /dev/null +++ b/keyboards/ydkb/xikii/xikii_i8x/switch_board.h @@ -0,0 +1,18 @@ +#ifndef SWITCH_BOARD_H +#define SWITCH_BOARD_H + +#include +#include +#include + +#define DS_PL_HI() (PORTB |= (1<<3)) +#define DS_PL_LO() (PORTB &= ~(1<<3)) + + +#define CLOCK_PULSE() \ + do { \ + PORTB |= (1<<1); \ + PORTB &= ~(1<<1); \ + } while(0) + +#endif \ No newline at end of file diff --git a/keyboards/ydkb/xikii/xikii_i8x/xikii_i8x.h b/keyboards/ydkb/xikii/xikii_i8x/xikii_i8x.h new file mode 100644 index 00000000000..bd6e6bce6c3 --- /dev/null +++ b/keyboards/ydkb/xikii/xikii_i8x/xikii_i8x.h @@ -0,0 +1,8 @@ +#pragma once + +#include "quantum.h" +#include +#include + +#define XXX KC_NO +