diff options
author | Drashna Jael're <drashna@live.com> | 2019-08-02 12:24:32 -0700 |
---|---|---|
committer | Florian Didron <fdidron@users.noreply.github.com> | 2019-08-05 09:36:26 +0900 |
commit | d2100ba45d0c0bf5258dcab2f503aa350f423120 (patch) | |
tree | 55bfc7ddc8ee593879f002ece185205e9409ce08 /keyboards/planck | |
parent | 4a5b36ec4c07cd5f84e3c76745646af9e3e14a42 (diff) |
Enable PWM support for Planck EZ Indicator LEDs
Diffstat (limited to 'keyboards/planck')
-rw-r--r-- | keyboards/planck/ez/ez.c | 167 | ||||
-rw-r--r-- | keyboards/planck/ez/ez.h | 21 |
2 files changed, 160 insertions, 28 deletions
diff --git a/keyboards/planck/ez/ez.c b/keyboards/planck/ez/ez.c index 6e250d4d76..fa169f4528 100644 --- a/keyboards/planck/ez/ez.c +++ b/keyboards/planck/ez/ez.c @@ -14,9 +14,13 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include "ez.h" +#include "ch.h" +#include "hal.h" + +keyboard_config_t keyboard_config; -#ifdef RGB_MATRIX_ENABLE +#ifdef RGB_MATRIX_ENABLE void suspend_power_down_kb(void) { rgb_matrix_set_suspend_state(true); suspend_power_down_user(); @@ -114,43 +118,150 @@ led_config_t g_led_config = { { #endif -void matrix_init_kb(void) { - matrix_init_user(); +// See http://jared.geek.nz/2013/feb/linear-led-pwm +static uint16_t cie_lightness(uint16_t v) { + if (v <= 5243) // if below 8% of max + return v / 9; // same as dividing by 900% + else { + uint32_t y = (((uint32_t) v + 10486) << 8) / (10486 + 0xFFFFUL); // add 16% of max and compare + // to get a useful result with integer division, we shift left in the expression above + // and revert what we've done again after squaring. + y = y * y * y >> 8; + if (y > 0xFFFFUL) // prevent overflow + return 0xFFFFU; + else + return (uint16_t) y; + } +} - palSetPadMode(GPIOB, 8, PAL_MODE_OUTPUT_PUSHPULL); - palSetPadMode(GPIOB, 9, PAL_MODE_OUTPUT_PUSHPULL); + static PWMConfig pwmCFG = { + 0xFFFF,/* PWM clock frequency */ + 256,/* initial PWM period (in ticks) 1S (1/10kHz=0.1mS 0.1ms*10000 ticks=1S) */ + NULL, + { + {PWM_OUTPUT_DISABLED, NULL}, /* channel 0 -> TIM1-CH1 = PA8 */ + {PWM_OUTPUT_DISABLED, NULL}, /* channel 1 -> TIM1-CH2 = PA9 */ + {PWM_OUTPUT_ACTIVE_HIGH, NULL}, + {PWM_OUTPUT_ACTIVE_HIGH, NULL} + }, + 0, /* HW dependent part.*/ + 0 +}; - palClearPad(GPIOB, 8); - palClearPad(GPIOB, 9); +static uint32_t planck_ez_right_led_duty; +static uint32_t planck_ez_left_led_duty; + +void planck_ez_right_led_level(uint8_t level) { + planck_ez_right_led_duty = (uint32_t)(cie_lightness(0xFFFF * (uint32_t) level / 255)); + if (level == 0) { + // Turn backlight off + pwmDisableChannel(&PWMD4, 2); + } else { + // Turn backlight on + pwmEnableChannel(&PWMD4, 2, PWM_FRACTION_TO_WIDTH(&PWMD4,0xFFFF,planck_ez_right_led_duty)); + } } -void matrix_scan_kb(void) { - matrix_scan_user(); + +void planck_ez_right_led_on(void){ + pwmEnableChannel(&PWMD4, 2, PWM_FRACTION_TO_WIDTH(&PWMD4,0xFFFF,planck_ez_right_led_duty)); } -layer_state_t layer_state_set_kb(layer_state_t state) { - - palClearPad(GPIOB, 8); - palClearPad(GPIOB, 9); - state = layer_state_set_user(state); - uint8_t layer = biton32(state); - switch (layer) { - case 3: - palSetPad(GPIOB, 9); - break; - case 4: - palSetPad(GPIOB, 8); - break; - case 6: - palSetPad(GPIOB, 9); - palSetPad(GPIOB, 8); - break; - default: - break; +void planck_ez_right_led_off(void){ + pwmDisableChannel(&PWMD4, 2); +} + +void planck_ez_left_led_level(uint8_t level) { + planck_ez_left_led_duty = (uint32_t)(cie_lightness(0xFFFF * (uint32_t) level / 255)); + if (level == 0) { + // Turn backlight off + pwmDisableChannel(&PWMD4, 3); + } else { + // Turn backlight on + pwmEnableChannel(&PWMD4, 3, PWM_FRACTION_TO_WIDTH(&PWMD4,0xFFFF,planck_ez_left_led_duty)); + } +} + +void planck_ez_left_led_on(void){ + pwmEnableChannel(&PWMD4, 3, PWM_FRACTION_TO_WIDTH(&PWMD4,0xFFFF,planck_ez_left_led_duty)); +} + +void planck_ez_left_led_off(void){ + pwmDisableChannel(&PWMD4, 3); +} + + +void led_initialize_hardware(void) { + pwmStart(&PWMD4, &pwmCFG); + + // set up defaults + planck_ez_right_led_level((uint8_t)keyboard_config.led_level * 255 / 4 ); + palSetPadMode(GPIOB, 8, PAL_MODE_ALTERNATE(2)); + planck_ez_left_led_level((uint8_t)keyboard_config.led_level * 255 / 4 ); + palSetPadMode(GPIOB, 9, PAL_MODE_ALTERNATE(2)); + + + // turn LEDs off by default + planck_ez_left_led_off(); + planck_ez_right_led_off(); +} + +void keyboard_pre_init_kb(void) { + // read kb settings from eeprom + keyboard_config.raw = eeconfig_read_kb(); + + // initialize settings for front LEDs + led_initialize_hardware(); +} + +void eeconfig_init_kb(void) { // EEPROM is getting reset! + keyboard_config.raw = 0; + keyboard_config.led_level = 4; + eeconfig_update_kb(keyboard_config.raw); + eeconfig_init_user(); +} + + +uint32_t layer_state_set_kb(uint32_t state) { + planck_ez_left_led_off(); + planck_ez_right_led_off(); + state = layer_state_set_user(state); + uint8_t layer = biton32(state); + switch (layer) { + case 3: + planck_ez_left_led_on(); + break; + case 4: + planck_ez_right_led_on(); + break; + case 6: + planck_ez_right_led_on(); + planck_ez_left_led_on(); + break; + default: + break; } return state; } +bool process_record_kb(uint16_t keycode, keyrecord_t *record) { + switch (keycode) { + case LED_LEVEL: + if (record->event.pressed) { + keyboard_config.led_level++; + if (keyboard_config.led_level > 4) { + keyboard_config.led_level = 0; + } + planck_ez_right_led_level((uint8_t)keyboard_config.led_level * 255 / 4 ); + planck_ez_left_led_level((uint8_t)keyboard_config.led_level * 255 / 4 ); + eeconfig_update_kb(keyboard_config.raw); + layer_state_set_kb(layer_state); + } + break; + } + return process_record_user(keycode, record); +} + #ifdef AUDIO_ENABLE bool music_mask_kb(uint16_t keycode) { switch (keycode) { diff --git a/keyboards/planck/ez/ez.h b/keyboards/planck/ez/ez.h index 55c4032422..e2ddaf3cec 100644 --- a/keyboards/planck/ez/ez.h +++ b/keyboards/planck/ez/ez.h @@ -50,3 +50,24 @@ LAYOUT_planck_1x2uC( \ #define KEYMAP LAYOUT_ortho_4x12 #define LAYOUT_planck_mit LAYOUT_planck_1x2uC #define LAYOUT_planck_grid LAYOUT_ortho_4x12 + +void planck_ez_right_led_on(void); +void planck_ez_right_led_off(void); +void planck_ez_right_led_level(uint8_t level); +void planck_ez_left_led_on(void); +void planck_ez_left_led_off(void); +void planck_ez_left_led_level(uint8_t level); + +enum planck_ez_keycodes { + LED_LEVEL = SAFE_RANGE, + EZ_SAFE_RANGE, +}; + +typedef union { + uint32_t raw; + struct { + uint8_t led_level :3; + }; +} keyboard_config_t; + +extern keyboard_config_t keyboard_config; |