diff --git a/keyboards/lightsaver/config.h b/keyboards/lightsaver/config.h new file mode 100644 index 00000000..bc984c7e --- /dev/null +++ b/keyboards/lightsaver/config.h @@ -0,0 +1,54 @@ +/* +Copyright 2017 Rasmus Schults + +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 CONFIG_H +#define CONFIG_H + +#include "config_common.h" + +/* USB Device descriptor parameter */ +#define VENDOR_ID 0xFEED +#define PRODUCT_ID 0x1337 +#define DEVICE_VER 0x0003 +#define MANUFACTURER Duck +#define PRODUCT Lightsaver V3 +#define DESCRIPTION Duck Lightsaver V3 + +/* key matrix size */ +#define MATRIX_ROWS 6 +#define MATRIX_COLS 19 + +#define DIODE_DIRECTION COL2ROW + +/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */ +#define DEBOUNCING_DELAY 5 + +/* number of backlight levels */ +#define BACKLIGHT_LEVELS 1 + +/* key combination for magic key command */ +#define IS_COMMAND() ( \ + keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \ +) + +#define RGBLIGHT_ANIMATIONS +#define RGB_DI_PIN D6 +#define RGBLED_NUM 17 + +#define TAPPING_TERM 200 + +#endif diff --git a/keyboards/lightsaver/indicator_leds.c b/keyboards/lightsaver/indicator_leds.c new file mode 100644 index 00000000..0a54e151 --- /dev/null +++ b/keyboards/lightsaver/indicator_leds.c @@ -0,0 +1,91 @@ +/* +Copyright 2016-2017 Ralf Schmitt Rasmus Schults + +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 + +#define T1H 900 +#define T1L 600 +#define T0H 400 +#define T0L 900 +#define RES 6000 + +#define NS_PER_SEC (1000000000L) +#define CYCLES_PER_SEC (F_CPU) +#define NS_PER_CYCLE (NS_PER_SEC / CYCLES_PER_SEC) +#define NS_TO_CYCLES(n) ((n) / NS_PER_CYCLE) + +void send_bit_d4(bool bitVal) { + if(bitVal) { + asm volatile ( + "sbi %[port], %[bit] \n\t" + ".rept %[onCycles] \n\t" + "nop \n\t" + ".endr \n\t" + "cbi %[port], %[bit] \n\t" + ".rept %[offCycles] \n\t" + "nop \n\t" + ".endr \n\t" + :: + [port] "I" (_SFR_IO_ADDR(PORTD)), + [bit] "I" (4), + [onCycles] "I" (NS_TO_CYCLES(T1H) - 2), + [offCycles] "I" (NS_TO_CYCLES(T1L) - 2)); + } else { + asm volatile ( + "sbi %[port], %[bit] \n\t" + ".rept %[onCycles] \n\t" + "nop \n\t" + ".endr \n\t" + "cbi %[port], %[bit] \n\t" + ".rept %[offCycles] \n\t" + "nop \n\t" + ".endr \n\t" + :: + [port] "I" (_SFR_IO_ADDR(PORTD)), + [bit] "I" (4), + [onCycles] "I" (NS_TO_CYCLES(T0H) - 2), + [offCycles] "I" (NS_TO_CYCLES(T0L) - 2)); + } +} + +void show(void) { + _delay_us((RES / 1000UL) + 1); +} + +void send_value(uint8_t byte) { + for(uint8_t b = 0; b < 8; b++) { + send_bit_d4(byte & 0b10000000); + byte <<= 1; + } +} + +void send_color(uint8_t r, uint8_t g, uint8_t b) { + send_value(g); + send_value(r); + send_value(b); +} + +void indicator_leds_set(bool leds[8]) { + cli(); + send_color(leds[1] ? 255 : 0, leds[2] ? 255 : 0, leds[0] ? 255 : 0); + send_color(leds[4] ? 255 : 0, leds[5] ? 255 : 0, leds[3] ? 255 : 0); + send_color(leds[6] ? 255 : 0, leds[7] ? 255 : 0, 0); + sei(); + show(); +} diff --git a/keyboards/lightsaver/indicator_leds.h b/keyboards/lightsaver/indicator_leds.h new file mode 100644 index 00000000..fe66eef6 --- /dev/null +++ b/keyboards/lightsaver/indicator_leds.h @@ -0,0 +1 @@ +void indicator_leds_set(bool leds[8]); diff --git a/keyboards/lightsaver/keymaps/default/keymap.c b/keyboards/lightsaver/keymaps/default/keymap.c new file mode 100644 index 00000000..fd188bd3 --- /dev/null +++ b/keyboards/lightsaver/keymaps/default/keymap.c @@ -0,0 +1,48 @@ +/* Copyright 2017 Rasmus Schults + * + * + * 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 "lightsaver.h" + +#define KC_F1GL TD(TD_F1_GAME) +#define KC_CLFN TD(TD_CAPS_FN) + +enum custom_layers { + BASE, // Base QWERTY layer + FN = 5, // Function layer +}; + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { +[BASE] = KEYMAP(\ + KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_PSCR, KC_NLCK, KC_INS, KC_HOME, KC_PGUP, KC_PSLS, \ + KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_DEL, KC_END, KC_PGDN, KC_PAST, \ + KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_P7, KC_P8, KC_P9, KC_PMNS, \ + MO(FN), KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_P4, KC_P5, KC_P6, KC_PPLS, \ + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, KC_P1, KC_P2, KC_P3, KC_PENT, \ + KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT, KC_P0, KC_PDOT), \ + +[FN] = KEYMAP(\ + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_PAUS, KC_SLCK, RGB_TOG, RGB_MOD, _______, _______, \ + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_CAPS, BL_TOGG, _______, _______, _______, \ + _______, _______, _______, _______, _______, _______, KC_HOME, KC_PGDN, KC_PGUP, KC_END, _______, _______, _______, _______, _______, _______, _______, _______, \ + _______, _______, _______, _______, _______, _______, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, _______, _______, _______, _______, _______, _______, _______, \ + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, RESET, \ + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ ), \ + +}; + +const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) { + return MACRO_NONE; +}; diff --git a/keyboards/lightsaver/keymaps/default/readme.md b/keyboards/lightsaver/keymaps/default/readme.md new file mode 100644 index 00000000..3e02a29c --- /dev/null +++ b/keyboards/lightsaver/keymaps/default/readme.md @@ -0,0 +1,9 @@ +![Lightsaver Layout Image](https://i.imgur.com/kSyGao4.png) + +# Default Lightsaver Layout + +This is the default implement layout for Duck Lightsaver V3. + +## FN layer + +![Lightsaver Layout Image](https://i.imgur.com/8jIGy6o.png) diff --git a/keyboards/lightsaver/lightsaver.c b/keyboards/lightsaver/lightsaver.c new file mode 100644 index 00000000..75e35b28 --- /dev/null +++ b/keyboards/lightsaver/lightsaver.c @@ -0,0 +1,60 @@ +/* Copyright 2017 Rasmus Schults + * + * 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 "lightsaver.h" +#include "indicator_leds.h" + +enum BACKLIGHT_AREAS { + BACKLIGHT_ALPHAS = 0b00000010, // Alpha keys + BACKLIGHT_FKEYS = 0b00000100, // Function row keys + BACKLIGHT_MODNUM = 0b00001000, // Modifiers and number row + BACKLIGHT_NUMPAD = 0b01000000 // Numpad area +}; + +void backlight_set(uint8_t level) { + if (level > 0) { + // Turn on leds + PORTB &= ~BACKLIGHT_ALPHAS; + PORTB &= ~BACKLIGHT_FKEYS; + PORTB &= ~BACKLIGHT_MODNUM; + PORTE &= ~BACKLIGHT_NUMPAD; + } else { + // Turn off leds + PORTB |= BACKLIGHT_ALPHAS; + PORTB |= BACKLIGHT_FKEYS; + PORTB |= BACKLIGHT_MODNUM; + PORTE |= BACKLIGHT_NUMPAD; + } +} + +void led_set_kb(uint8_t usb_led) { + bool leds[8] = { + usb_led & (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 . + */ +#ifndef LIGHTSAVER_H +#define LIGHTSAVER_H + +#include "quantum.h" + +#define NO KC_NO + +#define KEYMAP( \ + K5A, K5B, K5C, K5D, K5E, K5F, K5G, K5H, K5I, K5J, K5K, K5L, K5M, K5N, K5O, K5P, K5Q, K5R, K5S, \ + K4A, K4B, K4C, K4D, K4E, K4F, K4G, K4H, K4I, K4J, K4K, K4L, K4M, K4O, K4P, K4Q, K4R, K4S, \ + K3A, K3B, K3C, K3D, K3E, K3F, K3G, K3H, K3I, K3J, K3K, K3L, K3M, K3O, K3P, K3Q, K3R, K3S, \ + K2A, K2B, K2C, K2D, K2E, K2F, K2G, K2H, K2I, K2J, K2K, K2L, K2O, K2P, K2Q, K2R, K2S, \ + K1A, K1C, K1D, K1E, K1F, K1G, K1H, K1I, K1J, K1K, K1M, K1N, K1O, K1P, K1Q, K1R, K1S, \ + K0A, K0B, K0C, K0I, K0K, K0M, K0N, K0O, K0P, K0Q, K0R \ +) { \ +/* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 */ \ +/* 0 */ { K5A, K5B, K5C, K5D, K5E, K5F, K5G, K5H, K5I, K5J, K5K, K5L, K5M, K5N, K5O, K5P, K5Q, K5R, K5S, }, \ +/* 1 */ { K4A, K4B, K4C, K4D, K4E, K4F, K4G, K4H, K4I, K4J, K4K, K4L, K4M, NO, K4O, K4P, K4Q, K4R, K4S, }, \ +/* 2 */ { K3A, K3B, K3C, K3D, K3E, K3F, K3G, K3H, K3I, K3J, K3K, K3L, K3M, NO, K3O, K3P, K3Q, K3R, K3S, }, \ +/* 3 */ { K2A, K2B, K2C, K2D, K2E, K2F, K2G, K2H, K2I, K2J, K2K, K2L, NO, NO, K2O, K2P, K2Q, K2R, K2S, }, \ +/* 4 */ { K1A, NO, K1C, K1D, K1E, K1F, K1G, K1H, K1I, K1J, K1K, NO, K1M, K1N, K1O, K1P, K1Q, K1R, K1S, }, \ +/* 5 */ { K0A, K0B, K0C, NO, NO, NO, NO, NO, K0I, NO, K0K, NO, K0M, K0N, K0O, K0P, K0Q, K0R } \ +} + +#endif diff --git a/keyboards/lightsaver/matrix.c b/keyboards/lightsaver/matrix.c new file mode 100644 index 00000000..cb7b38fd --- /dev/null +++ b/keyboards/lightsaver/matrix.c @@ -0,0 +1,284 @@ +/* +Copyright 2016-2017 Ralf Schmitt Rasmus Schults +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 "matrix.h" +#include "util.h" +#include "print.h" +#include "debug.h" + +static uint8_t debouncing = DEBOUNCING_DELAY; + +/* matrix state(1:on, 0:off) */ +static matrix_row_t matrix[MATRIX_ROWS]; +static matrix_row_t matrix_debouncing[MATRIX_ROWS]; + +static uint8_t read_rows(void); +static uint8_t read_fwkey(void); +static void init_rows(void); +static void unselect_cols(void); +static void select_col(uint8_t col); + +__attribute__ ((weak)) +void matrix_init_quantum(void) { + matrix_init_kb(); +} + +__attribute__ ((weak)) +void matrix_scan_quantum(void) { + matrix_scan_kb(); +} + +__attribute__ ((weak)) +void matrix_init_kb(void) { + matrix_init_user(); +} + +__attribute__ ((weak)) +void matrix_scan_kb(void) { + matrix_scan_user(); +} + +__attribute__ ((weak)) +void matrix_init_user(void) { +} + +__attribute__ ((weak)) +void matrix_scan_user(void) { +} + +void matrix_init(void) { + DDRD |= 0b11010000; + PORTD &= ~0b01010000; + DDRB |= 0b00011111; + PORTB &= ~0b00001110; + PORTB |= 0b00010001; + DDRE |= 0b01000000; + PORTE &= ~0b01000000; + + unselect_cols(); + init_rows(); + + for (uint8_t i=0; i < MATRIX_ROWS; i++) { + matrix[i] = 0; + matrix_debouncing[i] = 0; + } + + matrix_init_quantum(); +} + +uint8_t matrix_scan(void) { + for (uint8_t col = 0; col < MATRIX_COLS; col++) { + select_col(col); + _delay_us(3); + + uint8_t rows = read_rows(); + if(col == 0) { + rows |= read_fwkey(); + } + for (uint8_t row = 0; row < MATRIX_ROWS; row++) { + bool prev_bit = matrix_debouncing[row] & ((matrix_row_t)1<