planck_ez.c (8991B)
1 /* Copyright 2018 Jack Humbert <jack.humb@gmail.com> 2 * Copyright 2015 ZSA Technology Labs Inc (@zsa) 3 * Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com> 4 * 5 * This program is free software: you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation, either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 */ 18 #include "planck_ez.h" 19 #include <ch.h> 20 #include <hal.h> 21 #include "keycodes.h" 22 23 keyboard_config_t keyboard_config; 24 25 26 /* Left B9 Right B8 */ 27 28 // See http://jared.geek.nz/2013/feb/linear-led-pwm 29 static uint16_t cie_lightness(uint16_t v) { 30 if (v <= 5243) // if below 8% of max 31 return v / 9; // same as dividing by 900% 32 else { 33 uint32_t y = (((uint32_t) v + 10486) << 8) / (10486 + 0xFFFFUL); // add 16% of max and compare 34 // to get a useful result with integer division, we shift left in the expression above 35 // and revert what we've done again after squaring. 36 y = y * y * y >> 8; 37 if (y > 0xFFFFUL) // prevent overflow 38 return 0xFFFFU; 39 else 40 return (uint16_t) y; 41 } 42 } 43 44 static PWMConfig pwmCFG = { 45 0xFFFF,/* PWM clock frequency */ 46 256,/* initial PWM period (in ticks) 1S (1/10kHz=0.1mS 0.1ms*10000 ticks=1S) */ 47 NULL, 48 { 49 {PWM_OUTPUT_DISABLED, NULL}, /* channel 0 -> TIM1-CH1 = PA8 */ 50 {PWM_OUTPUT_DISABLED, NULL}, /* channel 1 -> TIM1-CH2 = PA9 */ 51 {PWM_OUTPUT_ACTIVE_HIGH, NULL}, 52 {PWM_OUTPUT_ACTIVE_HIGH, NULL} 53 }, 54 0, /* HW dependent part.*/ 55 0 56 }; 57 58 static uint32_t planck_ez_right_led_duty; 59 static uint32_t planck_ez_left_led_duty; 60 61 void planck_ez_right_led_level(uint8_t level) { 62 planck_ez_right_led_duty = (uint32_t)(cie_lightness(0xFFFF * (uint32_t) level / 255)); 63 if (level == 0) { 64 // Turn backlight off 65 pwmDisableChannel(&PWMD4, 2); 66 } else { 67 // Turn backlight on 68 pwmEnableChannel(&PWMD4, 2, PWM_FRACTION_TO_WIDTH(&PWMD4,0xFFFF,planck_ez_right_led_duty)); 69 } 70 } 71 72 73 void planck_ez_right_led_on(void){ 74 pwmEnableChannel(&PWMD4, 2, PWM_FRACTION_TO_WIDTH(&PWMD4,0xFFFF,planck_ez_right_led_duty)); 75 } 76 77 void planck_ez_right_led_off(void){ 78 pwmDisableChannel(&PWMD4, 2); 79 } 80 81 void planck_ez_left_led_level(uint8_t level) { 82 planck_ez_left_led_duty = (uint32_t)(cie_lightness(0xFFFF * (uint32_t) level / 255)); 83 if (level == 0) { 84 // Turn backlight off 85 pwmDisableChannel(&PWMD4, 3); 86 } else { 87 // Turn backlight on 88 pwmEnableChannel(&PWMD4, 3, PWM_FRACTION_TO_WIDTH(&PWMD4,0xFFFF,planck_ez_left_led_duty)); 89 } 90 } 91 92 void planck_ez_left_led_on(void){ 93 pwmEnableChannel(&PWMD4, 3, PWM_FRACTION_TO_WIDTH(&PWMD4,0xFFFF,planck_ez_left_led_duty)); 94 } 95 96 void planck_ez_left_led_off(void){ 97 pwmDisableChannel(&PWMD4, 3); 98 } 99 100 101 void led_initialize_hardware(void) { 102 pwmStart(&PWMD4, &pwmCFG); 103 104 // set up defaults 105 planck_ez_right_led_level((uint8_t)keyboard_config.led_level * 255 / 4 ); 106 palSetPadMode(GPIOB, 8, PAL_MODE_ALTERNATE(2)); 107 planck_ez_left_led_level((uint8_t)keyboard_config.led_level * 255 / 4 ); 108 palSetPadMode(GPIOB, 9, PAL_MODE_ALTERNATE(2)); 109 110 111 // turn LEDs off by default 112 planck_ez_left_led_off(); 113 planck_ez_right_led_off(); 114 } 115 116 void keyboard_pre_init_kb(void) { 117 if (!eeconfig_is_enabled()) { 118 eeconfig_init(); 119 } 120 // read kb settings from eeprom 121 keyboard_config.raw = eeconfig_read_kb(); 122 #if defined(RGB_MATRIX_ENABLE) && defined(ORYX_CONFIGURATOR) 123 if (keyboard_config.rgb_matrix_enable) { 124 rgb_matrix_set_flags(LED_FLAG_ALL); 125 } else { 126 rgb_matrix_set_flags(LED_FLAG_NONE); 127 } 128 #endif 129 led_initialize_hardware(); 130 keyboard_pre_init_user(); 131 } 132 133 #if defined(RGB_MATRIX_ENABLE) && defined(ORYX_CONFIGURATOR) 134 void keyboard_post_init_kb(void) { 135 rgb_matrix_enable_noeeprom(); 136 keyboard_post_init_user(); 137 } 138 #endif 139 140 void eeconfig_init_kb(void) { // EEPROM is getting reset! 141 keyboard_config.raw = 0; 142 keyboard_config.rgb_matrix_enable = true; 143 keyboard_config.led_level = 4; 144 eeconfig_update_kb(keyboard_config.raw); 145 eeconfig_init_user(); 146 } 147 148 149 #ifdef ORYX_CONFIGURATOR 150 151 #ifndef PLANCK_EZ_USER_LEDS 152 153 #ifndef PLANCK_EZ_LED_LOWER 154 # define PLANCK_EZ_LED_LOWER 1 155 #endif 156 #ifndef PLANCK_EZ_LED_RAISE 157 # define PLANCK_EZ_LED_RAISE 2 158 #endif 159 #ifndef PLANCK_EZ_LED_ADJUST 160 # define PLANCK_EZ_LED_ADJUST 3 161 #endif 162 163 layer_state_t layer_state_set_kb(layer_state_t state) { 164 planck_ez_left_led_off(); 165 planck_ez_right_led_off(); 166 state = layer_state_set_user(state); 167 uint8_t layer = get_highest_layer(state); 168 switch (layer) { 169 case PLANCK_EZ_LED_LOWER: 170 planck_ez_left_led_on(); 171 break; 172 case PLANCK_EZ_LED_RAISE: 173 planck_ez_right_led_on(); 174 break; 175 case PLANCK_EZ_LED_ADJUST: 176 planck_ez_right_led_on(); 177 planck_ez_left_led_on(); 178 break; 179 default: 180 break; 181 } 182 return state; 183 } 184 #endif 185 186 bool process_record_kb(uint16_t keycode, keyrecord_t *record) { 187 switch (keycode) { 188 case LED_LEVEL: 189 if (record->event.pressed) { 190 keyboard_config.led_level++; 191 if (keyboard_config.led_level > 4) { 192 keyboard_config.led_level = 0; 193 } 194 planck_ez_right_led_level((uint8_t)keyboard_config.led_level * 255 / 4 ); 195 planck_ez_left_led_level((uint8_t)keyboard_config.led_level * 255 / 4 ); 196 eeconfig_update_kb(keyboard_config.raw); 197 layer_state_set_kb(layer_state); 198 } 199 break; 200 #ifdef RGB_MATRIX_ENABLE 201 case TOGGLE_LAYER_COLOR: 202 if (record->event.pressed) { 203 keyboard_config.disable_layer_led ^= 1; 204 if (keyboard_config.disable_layer_led) 205 rgb_matrix_set_color_all(0, 0, 0); 206 eeconfig_update_kb(keyboard_config.raw); 207 } 208 break; 209 case QK_RGB_MATRIX_TOGGLE: 210 if (record->event.pressed) { 211 switch (rgb_matrix_get_flags()) { 212 case LED_FLAG_ALL: { 213 rgb_matrix_set_flags(LED_FLAG_NONE); 214 keyboard_config.rgb_matrix_enable = false; 215 rgb_matrix_set_color_all(0, 0, 0); 216 } 217 break; 218 default: { 219 rgb_matrix_set_flags(LED_FLAG_ALL); 220 keyboard_config.rgb_matrix_enable = true; 221 } 222 break; 223 } 224 eeconfig_update_kb(keyboard_config.raw); 225 } 226 return false; 227 #endif 228 } 229 return process_record_user(keycode, record); 230 } 231 #endif 232 233 #ifdef AUDIO_ENABLE 234 bool music_mask_kb(uint16_t keycode) { 235 switch (keycode) { 236 case QK_LAYER_TAP ... QK_LAYER_TAP_MAX: 237 case QK_TO ... QK_TO_MAX: 238 case QK_MOMENTARY ... QK_MOMENTARY_MAX: 239 case QK_DEF_LAYER ... QK_DEF_LAYER_MAX: 240 case QK_PERSISTENT_DEF_LAYER ... QK_PERSISTENT_DEF_LAYER_MAX: 241 case QK_TOGGLE_LAYER ... QK_TOGGLE_LAYER_MAX: 242 case QK_ONE_SHOT_LAYER ... QK_ONE_SHOT_LAYER_MAX: 243 case QK_LAYER_TAP_TOGGLE ... QK_LAYER_TAP_TOGGLE_MAX: 244 case QK_LAYER_MOD ... QK_LAYER_MOD_MAX: 245 case QK_ONE_SHOT_MOD ... QK_ONE_SHOT_MOD_MAX: 246 case QK_MOD_TAP ... QK_MOD_TAP_MAX: 247 case AU_ON ... AU_PREV: 248 case QK_BOOT: 249 case QK_CLEAR_EEPROM: 250 case QK_TRI_LAYER_LOWER: 251 case QK_TRI_LAYER_UPPER: 252 return false; 253 default: 254 return music_mask_user(keycode); 255 } 256 } 257 #endif 258 259 #ifdef SWAP_HANDS_ENABLE 260 __attribute__ ((weak)) 261 const keypos_t PROGMEM hand_swap_config[MATRIX_ROWS][MATRIX_COLS] = { 262 {{5, 4}, {4, 4}, {3, 4}, {2, 4}, {1, 4}, {0, 4}}, 263 {{5, 5}, {4, 5}, {3, 5}, {2, 5}, {1, 5}, {0, 5}}, 264 {{5, 6}, {4, 6}, {3, 6}, {2, 6}, {1, 6}, {0, 6}}, 265 {{5, 3}, {4, 3}, {3, 3}, {2, 3}, {1, 3}, {0, 3}}, 266 267 {{5, 0}, {4, 0}, {3, 0}, {2, 0}, {1, 0}, {0, 0}}, 268 {{5, 1}, {4, 1}, {3, 1}, {2, 1}, {1, 1}, {0, 1}}, 269 {{5, 2}, {4, 2}, {3, 2}, {2, 2}, {1, 2}, {0, 2}}, 270 {{5, 7}, {4, 7}, {3, 7}, {2, 7}, {1, 7}, {0, 7}}, 271 }; 272 273 # ifdef ENCODER_MAP_ENABLE 274 const uint8_t PROGMEM encoder_hand_swap_config[NUM_ENCODERS] = {0}; 275 # endif 276 #endif 277 278 const uint8_t music_map[MATRIX_ROWS][MATRIX_COLS] = { 279 {36, 37, 38, 39, 40, 41}, 280 {24, 25, 26, 27, 28, 29}, 281 {12, 13, 14, 15, 16, 17}, 282 { 0, 1, 2, 10, 11, 6}, 283 {42, 43, 44, 45, 46, 47}, 284 {30, 31, 32, 33, 34, 35}, 285 {18, 19, 20, 21, 22, 23}, 286 { 7, 8, 9, 3, 4, 5} 287 };