Enable PWM Support for Planck EZ Indicator Lights (#6473)
* remove led layer code * enable PWM on STM32F303 * Unusable PWM code * Updated PWM Stuff? * PWM Semi-working * Both LEDs working at the same time * Update names * Add led level functions * Add LED levels and persistent settings * Revert change due to issues with timing related code * Review feedback and minor cleanup
This commit is contained in:
		
							parent
							
								
									5004562441
								
							
						
					
					
						commit
						547fbe769c
					
				
					 4 changed files with 164 additions and 30 deletions
				
			
		|  | @ -14,6 +14,10 @@ | ||||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  */ |  */ | ||||||
| #include "ez.h" | #include "ez.h" | ||||||
|  | #include "ch.h" | ||||||
|  | #include "hal.h" | ||||||
|  |  keyboard_config_t keyboard_config; | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| #ifdef RGB_MATRIX_ENABLE | #ifdef RGB_MATRIX_ENABLE | ||||||
| const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { | const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { | ||||||
|  | @ -112,39 +116,148 @@ void suspend_power_down_kb(void) { | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| void matrix_init_kb(void) { | /* Left B9   Right B8 */ | ||||||
|   matrix_init_user(); |  | ||||||
| 
 | 
 | ||||||
|   palSetPadMode(GPIOB, 8, PAL_MODE_OUTPUT_PUSHPULL); | // See http://jared.geek.nz/2013/feb/linear-led-pwm
 | ||||||
|   palSetPadMode(GPIOB, 9, PAL_MODE_OUTPUT_PUSHPULL); | static uint16_t cie_lightness(uint16_t v) { | ||||||
| 
 |   if (v <= 5243) // if below 8% of max
 | ||||||
|   palClearPad(GPIOB, 8); |     return v / 9; // same as dividing by 900%
 | ||||||
|   palClearPad(GPIOB, 9); |   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; | ||||||
|  |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void matrix_scan_kb(void) { | static PWMConfig pwmCFG = { | ||||||
|   matrix_scan_user(); |     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 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 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)); | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint32_t layer_state_set_kb(uint32_t state) { |  | ||||||
| 
 | 
 | ||||||
|   palClearPad(GPIOB, 8); | void planck_ez_right_led_on(void){ | ||||||
|   palClearPad(GPIOB, 9); |     pwmEnableChannel(&PWMD4, 2, PWM_FRACTION_TO_WIDTH(&PWMD4,0xFFFF,planck_ez_right_led_duty)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 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(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | layer_state_t layer_state_set_kb(layer_state_t state) { | ||||||
|  |     planck_ez_left_led_off(); | ||||||
|  |     planck_ez_right_led_off(); | ||||||
|     state = layer_state_set_user(state); |     state = layer_state_set_user(state); | ||||||
|     uint8_t layer = biton32(state); |     uint8_t layer = biton32(state); | ||||||
|     switch (layer) { |     switch (layer) { | ||||||
|         case 3: |         case 3: | ||||||
|         palSetPad(GPIOB, 9); |             planck_ez_left_led_on(); | ||||||
|             break; |             break; | ||||||
|         case 4: |         case 4: | ||||||
|         palSetPad(GPIOB, 8); |             planck_ez_right_led_on(); | ||||||
|             break; |             break; | ||||||
|         case 6: |         case 6: | ||||||
|         palSetPad(GPIOB, 9); |             planck_ez_right_led_on(); | ||||||
|         palSetPad(GPIOB, 8); |             planck_ez_left_led_on(); | ||||||
|             break; |             break; | ||||||
|         default: |         default: | ||||||
|             break; |             break; | ||||||
|     } |     } | ||||||
|     return state; |     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 true; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -50,3 +50,24 @@ LAYOUT_planck_1x2uC( \ | ||||||
| #define KEYMAP LAYOUT_ortho_4x12 | #define KEYMAP LAYOUT_ortho_4x12 | ||||||
| #define LAYOUT_planck_mit LAYOUT_planck_1x2uC | #define LAYOUT_planck_mit LAYOUT_planck_1x2uC | ||||||
| #define LAYOUT_planck_grid LAYOUT_ortho_4x12 | #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; | ||||||
|  |  | ||||||
|  | @ -111,7 +111,7 @@ | ||||||
|  * @brief   Enables the PWM subsystem. |  * @brief   Enables the PWM subsystem. | ||||||
|  */ |  */ | ||||||
| #if !defined(HAL_USE_PWM) || defined(__DOXYGEN__) | #if !defined(HAL_USE_PWM) || defined(__DOXYGEN__) | ||||||
| #define HAL_USE_PWM                 FALSE | #define HAL_USE_PWM                 TRUE | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  |  | ||||||
|  | @ -183,9 +183,9 @@ | ||||||
|  */ |  */ | ||||||
| #define STM32_PWM_USE_ADVANCED              FALSE | #define STM32_PWM_USE_ADVANCED              FALSE | ||||||
| #define STM32_PWM_USE_TIM1                  FALSE | #define STM32_PWM_USE_TIM1                  FALSE | ||||||
| #define STM32_PWM_USE_TIM2                  TRUE | #define STM32_PWM_USE_TIM2                  FALSE | ||||||
| #define STM32_PWM_USE_TIM3                  TRUE | #define STM32_PWM_USE_TIM3                  TRUE | ||||||
| #define STM32_PWM_USE_TIM4                  FALSE | #define STM32_PWM_USE_TIM4                  TRUE | ||||||
| #define STM32_PWM_USE_TIM8                  FALSE | #define STM32_PWM_USE_TIM8                  FALSE | ||||||
| #define STM32_PWM_TIM1_IRQ_PRIORITY         7 | #define STM32_PWM_TIM1_IRQ_PRIORITY         7 | ||||||
| #define STM32_PWM_TIM2_IRQ_PRIORITY         7 | #define STM32_PWM_TIM2_IRQ_PRIORITY         7 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Drashna Jaelre
						Drashna Jaelre