--- /dev/null
+/* Copyright 2017 REPLACE_WITH_YOUR_NAME
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "v60_type_r.h"
+
+#define _____ KC_TRNS
+#define XXXXX KC_NO
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ /* Keymap 0: Default Layer
+ * ,-----------------------------------------------------------.
+ * |Esc| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =| Bs |
+ * |-----------------------------------------------------------|
+ * |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \|
+ * |-----------------------------------------------------------|
+ * |FN0 | A| S| D| F| G| H| J| K| L| ;| '|Return |
+ * |-----------------------------------------------------------|
+ * |LShift | Z| X| C| V| B| N| M| ,| .| /| RShift |
+ * |-----------------------------------------------------------|
+ * |Ctrl|Alt |Gui | Space/L3 |Gui |Alt |Ctrl|Fn1|
+ * `-----------------------------------------------------------'
+ */
+ [0] = KEYMAP(
+ KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, XXXXX, KC_BSPC, \
+ 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, \
+ LT(1, KC_CAPS), 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_LSFT, XXXXX, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, XXXXX, \
+ KC_LCTL, KC_LALT, KC_LGUI, LT(2, KC_SPC), KC_RGUI, KC_RALT, KC_RCTL, MO(3)),
+ /* Keymap 1: FN Layer
+ * ,-----------------------------------------------------------.
+ * |` | F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12| Del |
+ * |-----------------------------------------------------------|
+ * | | | | | | | | | | |PSc|SLk|Pau| Ins |
+ * |-----------------------------------------------------------|
+ * | | | | | | | Lt| Dn| Up| Rt|Hom|PgU| |
+ * |-----------------------------------------------------------|
+ * | | | | | | |Mut|VDn|VUp|End|PgD| |
+ * |-----------------------------------------------------------|
+ * | | | | | | | | |
+ * `-----------------------------------------------------------'
+ */
+ [1] = KEYMAP(
+ KC_GRV, 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_DEL, \
+ _____, _____, _____, _____, _____, _____, _____, _____, _____, _____, KC_PSCR, KC_SLCK, KC_PAUS, KC_INS, \
+ _____, _____, _____, _____, _____, _____, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, KC_HOME, KC_PGUP, _____, \
+ _____, _____, _____, _____, _____, _____, _____, KC_MUTE, KC_VOLD, KC_VOLU, KC_END, KC_PGDN, _____, _____, \
+ _____, _____, _____, _____, _____, _____, _____, _____),
+ /* Keymap 2: Mouse Keys Layer
+ * ,-----------------------------------------------------------.
+ * | | | | | | | | | | | | | | |
+ * |-----------------------------------------------------------|
+ * | | | | | | | |MWU|MWD| | | | | |
+ * |-----------------------------------------------------------|
+ * | | | | | | |MLt|MDn|MUp|MRt| | | |
+ * |-----------------------------------------------------------|
+ * | | | | | |SPC|Ms1|Ms2|Ms3| | | |
+ * |-----------------------------------------------------------|
+ * | | | | | | | | |
+ * `-----------------------------------------------------------'
+ */
+ [2] = KEYMAP(
+ _____, _____, _____, _____, _____, _____, _____, _____, _____, _____, _____, _____, _____, _____, _____, \
+ _____, _____, _____, _____, _____, _____, _____, KC_MS_WH_UP, KC_MS_WH_DOWN, _____, _____, _____, _____, _____, \
+ _____, _____, _____, _____, _____, _____, KC_MS_LEFT, KC_MS_DOWN, KC_MS_UP, KC_MS_RIGHT, _____, _____, _____, \
+ _____, _____, _____, _____, _____, _____, KC_SPC, KC_MS_BTN1, KC_MS_BTN2, KC_MS_BTN3, _____, _____, _____, _____, \
+ _____, _____, _____, _____, _____, _____, _____, _____),
+ /* Keymap 3: LED Modification Layer
+ * ,-----------------------------------------------------------.
+ * | |BLT|BLC|UGT|UGP|UGB|UGR| | | | | | | |
+ * |-----------------------------------------------------------|
+ * | |RD+|GN+|BL+|HU+|SA+|VA+| | | | | | | |
+ * |-----------------------------------------------------------|
+ * | |RD-|GN-|BL-|HU-|SA-|VA-| | | | | | |
+ * |-----------------------------------------------------------|
+ * | | | | | | | | | | | | |
+ * |-----------------------------------------------------------|
+ * | | | | | | | | |
+ * `-----------------------------------------------------------'
+ */
+ [3] = KEYMAP(
+ _____, BL_TOGG, BL_STEP, RGB_TOG, RGB_M_P, RGB_M_B, RGB_M_R, _____, _____, _____, _____, _____, _____, _____, _____, \
+ _____, RGB_RI, RGB_GI, RGB_BI, RGB_HUI, RGB_SAI, RGB_VAI, _____, _____, _____, _____, _____, _____, _____, \
+ _____, RGB_RD, RGB_GD, RGB_BD, RGB_HUD, RGB_SAD, RGB_VAD, _____, _____, _____, _____, _____, _____, \
+ _____, _____, _____, _____, _____, _____, _____, _____, _____, _____, _____, _____, _____, _____, \
+ _____, _____, _____, _____, _____, _____, _____, _____),
+};
+
+const uint16_t PROGMEM fn_actions[] = {
+};
+
+const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
+{
+ // MACRODOWN only works in this function
+ switch(id) {
+ case 0:
+ if (record->event.pressed) {
+ register_code(KC_RSFT);
+ } else {
+ unregister_code(KC_RSFT);
+ }
+ break;
+ }
+ return MACRO_NONE;
+};
+
+
+void led_set_user(uint8_t usb_led) {
+ if (usb_led & (1<<USB_LED_CAPS_LOCK)) {
+ // output low
+ DDRE |= (1<<PE6);
+ PORTE &= ~(1<<PE6);
+ }
+ else {
+ // Hi-Z
+ DDRE &= ~(1<<PE6);
+ PORTE &= ~(1<<PE6);
+ }
+}
-KBParadise V60 Type R
+KBParadise V60 Type R
======================
-Released in 2017, the KBP V60 Type R is KB Paradise's first foray into the world of fully programmable keyboards. It utilizes an atmega32u4, Cherry MX switches, standard layout plate, Cherry style stabilizers, and plastic 60% case.
+Released in 2017, the KBP V60 Type R is KB Paradise's first foray into the world of fully programmable keyboards. It utilizes an atmega32u4, Cherry MX switches, standard layout plate, Cherry style stabilizers, and plastic 60% case.
The keyboard comes in two flavors:
1. V60 Type R
2. V60 Type R Polestar
-The Polestar comes with both in switch and underglow lighting, while the regular Type R has neither.
+The Polestar comes with both in switch and underglow lighting, while the regular Type R has neither.
-Please note that other variants of the KBP V60 are not fully programmable.
+Please note that other variants of the KBP V60 are not fully programmable.
-In switch and underglow lighting is currently not supported, but the hex file generated by QMK can still be used for either type r board.
+Backlight and RGB Underglow are both supported.
-The KB Paradise preferred way of creating the hex file is by using https://tkg.io/, selecting Fantastic60 and then defining your keymap.
+To use the backlight and/or RGB underglow:
+* Create a new keymap
+* Create a rules.mk file in the keymap
+* Add RGBLIGHT_ENABLE = yes and/or BACKLIGHT_ENABLE = yes to the rules.mk
+* Setup your keymap to your preference. Use [the `vimouse` keymap](keymaps/vimouse/keymap.c) as a starting point
+* Some extra keys are defined to allow you to set the red, green and blue values of the underglow directly, rather than using the HSV spectrum. These are RGB_RI, RGB_RD, RGB_GI, RGB_GD, RGB_BI, RGB_BD for increase and decrease of the red, green and blue channels respectively.
+
+The provided `default` keymap pretty closely matches the default V60 Type R keymap, minus the backlight and underglow control keys. The `vimouse` keymap is completely customised and makes use of many of the possibilities, including mouse keys, backlighting, RGB underglow, etc.
+
+Note for those customising: The configuration used in the `vimouse` keymap results in about 93% of the available flash being utilised. Keep that in mind if you're adding functionality.
+
+Note: By default the V60 Type R uses TMK. You should know what you're doing and none of this is guaranteed to work. If you want to stick with the TMK default, then the KB Paradise preferred way of creating the hex file is by using https://tkg.io/, selecting Fantastic60 and then defining your keymap.
You will then have to use tkg-toolkit to finish the flashing
make v60_type_r:default
+or
+
+ make v60_type_r:vimouse
+
See [build environment setup](https://docs.qmk.fm/build_environment_setup.html) then the [make instructions](https://docs.qmk.fm/make_instructions.html) for more information.
*/
#include "v60_type_r.h"
+#include "rgblight.h"
+
+#include <avr/pgmspace.h>
+
+#include "action_layer.h"
+#include "quantum.h"
+
+// if we've got an RGB underglow!
+#ifdef V60_POLESTAR
+#define SOFTPWM_LED_TIMER_TOP F_CPU/(256*64)
+
+extern rgblight_config_t rgblight_config;
+static uint8_t softpwm_buff[3] = {0};
+
+void matrix_init_user(void) {
+ rgb_init();
+}
+
+bool process_record_user(uint16_t keycode, keyrecord_t *record) {
+ uint8_t r = led[0].r, g = led[0].g, b = led[0].b;
+ switch(keycode) {
+ case RGB_RI:
+ if (record->event.pressed) {
+ r += RGB_STEP;
+ if (r < led[0].r) {
+ r = 255;
+ }
+ rgblight_setrgb(r, g, b);
+ }
+
+ return false;
+ case RGB_RD:
+ if (record->event.pressed) {
+ r -= RGB_STEP;
+ if (r > led[0].r) {
+ r = 0;
+ }
+ rgblight_setrgb(r, g, b);
+ }
+
+ return false;
+ case RGB_BI:
+ if (record->event.pressed) {
+ b += RGB_STEP;
+ if (b < led[0].b) {
+ b = 255;
+ }
+ rgblight_setrgb(r, g, b);
+ }
+
+ return false;
+ case RGB_BD:
+ if (record->event.pressed) {
+ b -= RGB_STEP;
+ if (b > led[0].b) {
+ b = 0;
+ }
+ rgblight_setrgb(r, g, b);
+ }
+
+ return false;
+ case RGB_GI:
+ if (record->event.pressed) {
+ g += RGB_STEP;
+ if (g < led[0].g) {
+ g = 255;
+ }
+ rgblight_setrgb(r, g, b);
+ }
+
+ return false;
+ case RGB_GD:
+ if (record->event.pressed) {
+ g -= RGB_STEP;
+ if (g > led[0].g) {
+ g = 0;
+ }
+ rgblight_setrgb(r, g, b);
+ }
+
+ return false;
+ }
+
+ return true;
+}
+
+
+void rgb_timer_init(void) {
+ /* Timer1 setup */
+ /* CTC mode */
+ TCCR1B |= (1<<WGM12);
+ /* Clock selelct: clk/8 */
+ TCCR1B |= (1<<CS10);
+ /* Set TOP value */
+ uint8_t sreg = SREG;
+ cli();
+ OCR1AH = (SOFTPWM_LED_TIMER_TOP >> 8) & 0xff;
+ OCR1AL = SOFTPWM_LED_TIMER_TOP & 0xff;
+ SREG = sreg;
+
+ // Enable the compare match interrupt on timer 1
+ TIMSK1 |= (1<<OCIE1A);
+}
+
+void rgb_init(void) {
+ DDRF |= (1<<PF6 | 1<<PF5 | 1<<PF4);
+ PORTF |= (1<<PF6 | 1<<PF5 | 1<<PF4);
+
+ rgb_timer_init();
+}
+
+void set_rgb_pin_on(uint8_t pin) {
+ PORTF &= ~(1<<pin);
+}
+
+void set_rgb_pin_off(uint8_t pin) {
+ PORTF |= (1<<pin);
+}
+
+void rgblight_set(void) {
+ // xprintf("Setting RGB underglow\n");
+ if (!rgblight_config.enable) {
+ led[0].r = 0;
+ led[0].g = 0;
+ led[0].b = 0;
+ set_rgb_pin_off(RGB_RED_PIN);
+ set_rgb_pin_off(RGB_GREEN_PIN);
+ set_rgb_pin_off(RGB_BLUE_PIN);
+ }
+
+ // //xprintf("Red: %u, Green: %u, Blue: %u\n", led[0].r, led[0].g, led[0].b);
+}
+
+ISR(TIMER1_COMPA_vect)
+{
+ static uint8_t pwm = 0;
+ pwm++;
+
+ // turn the LEDS on
+ if (pwm == 0) {
+ if (softpwm_buff[0]) {
+ set_rgb_pin_on(RGB_RED_PIN);
+ softpwm_buff[0] = led[0].r;
+ }
+
+ if (softpwm_buff[1]) {
+ set_rgb_pin_on(RGB_GREEN_PIN);
+ softpwm_buff[1] = led[0].g;
+ }
+
+ if (softpwm_buff[2]) {
+ set_rgb_pin_on(RGB_BLUE_PIN);
+ softpwm_buff[2] = led[0].b;
+ }
+ }
+
+ // turn em off
+ if (pwm == softpwm_buff[0]) {
+ set_rgb_pin_off(RGB_RED_PIN);
+ softpwm_buff[0] = led[0].r;
+
+ }
+
+ if (pwm == softpwm_buff[1]) {
+ set_rgb_pin_off(RGB_GREEN_PIN);
+ softpwm_buff[1] = led[0].g;
+ }
+
+ if (pwm == softpwm_buff[2]) {
+ set_rgb_pin_off(RGB_BLUE_PIN);
+ softpwm_buff[2] = led[0].b;
+ }
+}
+#else
+
+void matrix_init_user(void) {
+}
+
+bool process_record_user(uint16_t keycode, keyrecord_t *record) {
+ return true;
+}
+
+#endif // V60_POLESTAR
+
+// we need these functions for both versions
+void led_set_kb(uint8_t usb_led) {
+ // put your keyboard LED indicator (ex: Caps Lock LED) toggling code here
+
+ led_set_user(usb_led);
+}
+
+void matrix_scan_user(void) {
+}
+
void matrix_init_kb(void) {
// put your keyboard start-up code here
// runs once when the firmware starts up
return process_record_user(keycode, record);
}
-
-void led_set_kb(uint8_t usb_led) {
- // put your keyboard LED indicator (ex: Caps Lock LED) toggling code here
-
- led_set_user(usb_led);
-}