mirror of
				https://github.com/mfulz/qmk_firmware.git
				synced 2025-10-31 05:12:33 +01:00 
			
		
		
		
	Merge remote-tracking branch 'origin/master' into develop
This commit is contained in:
		
						commit
						6f53d10960
					
				
							
								
								
									
										81
									
								
								keyboards/cipulot/ec_typek/config.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								keyboards/cipulot/ec_typek/config.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,81 @@ | |||||||
|  | /* Copyright 2023 Cipulot
 | ||||||
|  |  * | ||||||
|  |  * 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 3 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/>.
 | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #define MATRIX_ROWS 5 | ||||||
|  | #define MATRIX_COLS 15 | ||||||
|  | 
 | ||||||
|  | #define MATRIX_ROW_PINS \ | ||||||
|  |     { B14, B13, B12, A6, A7 } | ||||||
|  | 
 | ||||||
|  | #define AMUX_COUNT 2 | ||||||
|  | #define AMUX_MAX_COLS_COUNT 8 | ||||||
|  | 
 | ||||||
|  | #define AMUX_EN_PINS \ | ||||||
|  |     { B9, B8 } | ||||||
|  | 
 | ||||||
|  | #define AMUX_SEL_PINS \ | ||||||
|  |     { B7, B6, B5 } | ||||||
|  | 
 | ||||||
|  | #define AMUX_COL_CHANNELS_SIZES \ | ||||||
|  |     { 7, 8 } | ||||||
|  | 
 | ||||||
|  | #define AMUX_0_COL_CHANNELS \ | ||||||
|  |     { 3, 0, 1, 2, 4, 6, 7 } | ||||||
|  | 
 | ||||||
|  | #define AMUX_1_COL_CHANNELS \ | ||||||
|  |     { 3, 0, 1, 2, 4, 6, 7, 5 } | ||||||
|  | 
 | ||||||
|  | #define AMUX_COL_CHANNELS AMUX_0_COL_CHANNELS, AMUX_1_COL_CHANNELS | ||||||
|  | 
 | ||||||
|  | #define DISCHARGE_PIN A1 | ||||||
|  | #define ANALOG_PORT A2 | ||||||
|  | 
 | ||||||
|  | #define DEFAULT_ACTUATION_MODE 0 | ||||||
|  | #define DEFAULT_MODE_0_ACTUATION_LEVEL 550 | ||||||
|  | #define DEFAULT_MODE_0_RELEASE_LEVEL 500 | ||||||
|  | #define DEFAULT_MODE_1_INITIAL_DEADZONE_OFFSET DEFAULT_MODE_0_ACTUATION_LEVEL | ||||||
|  | #define DEFAULT_MODE_1_ACTUATION_OFFSET 70 | ||||||
|  | #define DEFAULT_MODE_1_RELEASE_OFFSET 70 | ||||||
|  | #define DEFAULT_EXTREMUM 1023 | ||||||
|  | #define EXPECTED_NOISE_FLOOR 0 | ||||||
|  | #define NOISE_FLOOR_THRESHOLD 50 | ||||||
|  | #define BOTTOMING_CALIBRATION_THRESHOLD 100 | ||||||
|  | #define DEFAULT_NOISE_FLOOR_SAMPLING_COUNT 30 | ||||||
|  | #define DEFAULT_BOTTOMING_READING 1023 | ||||||
|  | #define DEFAULT_CALIBRATION_STARTER true | ||||||
|  | 
 | ||||||
|  | #define DISCHARGE_TIME 10 | ||||||
|  | 
 | ||||||
|  | // #define DEBUG_MATRIX_SCAN_RATE
 | ||||||
|  | 
 | ||||||
|  | #define EECONFIG_KB_DATA_SIZE 171 | ||||||
|  | 
 | ||||||
|  | // RGB & Indicators
 | ||||||
|  | // PWM driver with direct memory access (DMA) support
 | ||||||
|  | #define WS2812_PWM_COMPLEMENTARY_OUTPUT | ||||||
|  | #define WS2812_PWM_DRIVER PWMD1 | ||||||
|  | #define WS2812_PWM_CHANNEL 3 | ||||||
|  | #define WS2812_PWM_PAL_MODE 1 | ||||||
|  | #define WS2812_DMA_STREAM STM32_DMA2_STREAM5 | ||||||
|  | #define WS2812_DMA_CHANNEL 6 | ||||||
|  | #define WS2812_DMAMUX_ID STM32_DMAMUX1_TIM1_UP | ||||||
|  | 
 | ||||||
|  | #define RGBLIGHT_DEFAULT_VAL 200 | ||||||
|  | #define RGBLIGHT_DEFAULT_MODE (RGBLIGHT_MODE_RAINBOW_SWIRL + 5) | ||||||
|  | 
 | ||||||
|  | #define NUM_INDICATOR_INDEX 2 | ||||||
|  | #define CAPS_INDICATOR_INDEX 1 | ||||||
|  | #define SCROLL_INDICATOR_INDEX 0 | ||||||
							
								
								
									
										318
									
								
								keyboards/cipulot/ec_typek/ec_switch_matrix.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										318
									
								
								keyboards/cipulot/ec_typek/ec_switch_matrix.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,318 @@ | |||||||
|  | /* Copyright 2023 Cipulot
 | ||||||
|  |  * | ||||||
|  |  * 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 3 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 "ec_switch_matrix.h" | ||||||
|  | #include "analog.h" | ||||||
|  | #include "atomic_util.h" | ||||||
|  | #include "math.h" | ||||||
|  | #include "print.h" | ||||||
|  | #include "wait.h" | ||||||
|  | 
 | ||||||
|  | #if defined(__AVR__) | ||||||
|  | #    error "AVR platforms not supported due to a variety of reasons. Among them there are limited memory, limited number of pins and ADC not being able to give satisfactory results." | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #define OPEN_DRAIN_SUPPORT defined(PAL_MODE_OUTPUT_OPENDRAIN) | ||||||
|  | 
 | ||||||
|  | eeprom_ec_config_t eeprom_ec_config; | ||||||
|  | ec_config_t        ec_config; | ||||||
|  | 
 | ||||||
|  | // Pin and port array
 | ||||||
|  | const pin_t row_pins[]                                 = MATRIX_ROW_PINS; | ||||||
|  | const pin_t amux_sel_pins[]                            = AMUX_SEL_PINS; | ||||||
|  | const pin_t amux_en_pins[]                             = AMUX_EN_PINS; | ||||||
|  | const pin_t amux_n_col_sizes[]                         = AMUX_COL_CHANNELS_SIZES; | ||||||
|  | const pin_t amux_n_col_channels[][AMUX_MAX_COLS_COUNT] = {AMUX_COL_CHANNELS}; | ||||||
|  | 
 | ||||||
|  | #define AMUX_SEL_PINS_COUNT ARRAY_SIZE(amux_sel_pins) | ||||||
|  | #define EXPECTED_AMUX_SEL_PINS_COUNT ceil(log2(AMUX_MAX_COLS_COUNT) | ||||||
|  | // Checks for the correctness of the configuration
 | ||||||
|  | _Static_assert(ARRAY_SIZE(amux_en_pins) == AMUX_COUNT, "AMUX_EN_PINS doesn't have the minimum number of bits required to enable all the multiplexers available"); | ||||||
|  | // Check that number of select pins is enough to select all the channels
 | ||||||
|  | _Static_assert(AMUX_SEL_PINS_COUNT == EXPECTED_AMUX_SEL_PINS_COUNT), "AMUX_SEL_PINS doesn't have the minimum number of bits required address all the channels"); | ||||||
|  | // Check that number of elements in AMUX_COL_CHANNELS_SIZES is enough to specify the number of channels for all the multiplexers available
 | ||||||
|  | _Static_assert(ARRAY_SIZE(amux_n_col_sizes) == AMUX_COUNT, "AMUX_COL_CHANNELS_SIZES doesn't have the minimum number of elements required to specify the number of channels for all the multiplexers available"); | ||||||
|  | // static ec_config_t config;
 | ||||||
|  | static uint16_t sw_value[MATRIX_ROWS][MATRIX_COLS]; | ||||||
|  | 
 | ||||||
|  | static adc_mux adcMux; | ||||||
|  | 
 | ||||||
|  | // Initialize the row pins
 | ||||||
|  | void init_row(void) { | ||||||
|  |     // Set all row pins as output and low
 | ||||||
|  |     for (uint8_t idx = 0; idx < MATRIX_ROWS; idx++) { | ||||||
|  |         gpio_set_pin_output(row_pins[idx]); | ||||||
|  |         gpio_write_pin_low(row_pins[idx]); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Initialize the multiplexers
 | ||||||
|  | void init_amux(void) { | ||||||
|  |     for (uint8_t idx = 0; idx < AMUX_COUNT; idx++) { | ||||||
|  |         gpio_set_pin_output(amux_en_pins[idx]); | ||||||
|  |         gpio_write_pin_low(amux_en_pins[idx]); | ||||||
|  |     } | ||||||
|  |     for (uint8_t idx = 0; idx < AMUX_SEL_PINS_COUNT; idx++) { | ||||||
|  |         gpio_set_pin_output(amux_sel_pins[idx]); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Select the multiplexer channel of the specified multiplexer
 | ||||||
|  | void select_amux_channel(uint8_t channel, uint8_t col) { | ||||||
|  |     // Get the channel for the specified multiplexer
 | ||||||
|  |     uint8_t ch = amux_n_col_channels[channel][col]; | ||||||
|  |     // momentarily disable specified multiplexer
 | ||||||
|  |     gpio_write_pin_high(amux_en_pins[channel]); | ||||||
|  |     // Select the multiplexer channel
 | ||||||
|  |     for (uint8_t i = 0; i < AMUX_SEL_PINS_COUNT; i++) { | ||||||
|  |         gpio_write_pin(amux_sel_pins[i], ch & (1 << i)); | ||||||
|  |     } | ||||||
|  |     // re enable specified multiplexer
 | ||||||
|  |     gpio_write_pin_low(amux_en_pins[channel]); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Disable all the unused multiplexers
 | ||||||
|  | void disable_unused_amux(uint8_t channel) { | ||||||
|  |     // disable all the other multiplexers apart from the current selected one
 | ||||||
|  |     for (uint8_t idx = 0; idx < AMUX_COUNT; idx++) { | ||||||
|  |         if (idx != channel) { | ||||||
|  |             gpio_write_pin_high(amux_en_pins[idx]); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | // Discharge the peak hold capacitor
 | ||||||
|  | void discharge_capacitor(void) { | ||||||
|  | #ifdef OPEN_DRAIN_SUPPORT | ||||||
|  |     gpio_write_pin_low(DISCHARGE_PIN); | ||||||
|  | #else | ||||||
|  |     gpio_write_pin_low(DISCHARGE_PIN); | ||||||
|  |     gpio_set_pin_output(DISCHARGE_PIN); | ||||||
|  | #endif | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Charge the peak hold capacitor
 | ||||||
|  | void charge_capacitor(uint8_t row) { | ||||||
|  | #ifdef OPEN_DRAIN_SUPPORT | ||||||
|  |     gpio_write_pin_high(DISCHARGE_PIN); | ||||||
|  | #else | ||||||
|  |     gpio_set_pin_input(DISCHARGE_PIN); | ||||||
|  | #endif | ||||||
|  |     gpio_write_pin_high(row_pins[row]); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Initialize the peripherals pins
 | ||||||
|  | int ec_init(void) { | ||||||
|  |     // Initialize ADC
 | ||||||
|  |     palSetLineMode(ANALOG_PORT, PAL_MODE_INPUT_ANALOG); | ||||||
|  |     adcMux = pinToMux(ANALOG_PORT); | ||||||
|  | 
 | ||||||
|  |     // Dummy call to make sure that adcStart() has been called in the appropriate state
 | ||||||
|  |     adc_read(adcMux); | ||||||
|  | 
 | ||||||
|  |     // Initialize discharge pin as discharge mode
 | ||||||
|  |     gpio_write_pin_low(DISCHARGE_PIN); | ||||||
|  | #ifdef OPEN_DRAIN_SUPPORT | ||||||
|  |     gpio_set_pin_output_open_drain(DISCHARGE_PIN); | ||||||
|  | #else | ||||||
|  |     gpio_set_pin_output(DISCHARGE_PIN); | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  |     // Initialize drive lines
 | ||||||
|  |     init_row(); | ||||||
|  | 
 | ||||||
|  |     // Initialize AMUXs
 | ||||||
|  |     init_amux(); | ||||||
|  | 
 | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Get the noise floor
 | ||||||
|  | void ec_noise_floor(void) { | ||||||
|  |     // Initialize the noise floor
 | ||||||
|  |     for (uint8_t row = 0; row < MATRIX_ROWS; row++) { | ||||||
|  |         for (uint8_t col = 0; col < MATRIX_COLS; col++) { | ||||||
|  |             ec_config.noise_floor[row][col] = 0; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // Sample the noise floor
 | ||||||
|  |     for (uint8_t i = 0; i < DEFAULT_NOISE_FLOOR_SAMPLING_COUNT; i++) { | ||||||
|  |         for (uint8_t amux = 0; amux < AMUX_COUNT; amux++) { | ||||||
|  |             disable_unused_amux(amux); | ||||||
|  |             for (uint8_t col = 0; col < amux_n_col_sizes[amux]; col++) { | ||||||
|  |                 uint8_t sum = 0; | ||||||
|  |                 for (uint8_t i = 0; i < (amux > 0 ? amux : 0); i++) | ||||||
|  |                     sum += amux_n_col_sizes[i]; | ||||||
|  |                 uint8_t adjusted_col = col + sum; | ||||||
|  |                 for (uint8_t row = 0; row < MATRIX_ROWS; row++) { | ||||||
|  |                     ec_config.noise_floor[row][adjusted_col] += ec_readkey_raw(amux, row, col); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         wait_ms(5); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // Average the noise floor
 | ||||||
|  |     for (uint8_t row = 0; row < MATRIX_ROWS; row++) { | ||||||
|  |         for (uint8_t col = 0; col < MATRIX_COLS; col++) { | ||||||
|  |             ec_config.noise_floor[row][col] /= DEFAULT_NOISE_FLOOR_SAMPLING_COUNT; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Scan key values and update matrix state
 | ||||||
|  | bool ec_matrix_scan(matrix_row_t current_matrix[]) { | ||||||
|  |     bool updated = false; | ||||||
|  | 
 | ||||||
|  |     for (uint8_t amux = 0; amux < AMUX_COUNT; amux++) { | ||||||
|  |         disable_unused_amux(amux); | ||||||
|  |         for (uint8_t col = 0; col < amux_n_col_sizes[amux]; col++) { | ||||||
|  |             for (uint8_t row = 0; row < MATRIX_ROWS; row++) { | ||||||
|  |                 uint8_t sum = 0; | ||||||
|  |                 for (uint8_t i = 0; i < (amux > 0 ? amux : 0); i++) | ||||||
|  |                     sum += amux_n_col_sizes[i]; | ||||||
|  |                 uint8_t adjusted_col        = col + sum; | ||||||
|  |                 sw_value[row][adjusted_col] = ec_readkey_raw(amux, row, col); | ||||||
|  | 
 | ||||||
|  |                 if (ec_config.bottoming_calibration) { | ||||||
|  |                     if (ec_config.bottoming_calibration_starter[row][adjusted_col]) { | ||||||
|  |                         ec_config.bottoming_reading[row][adjusted_col]             = sw_value[row][adjusted_col]; | ||||||
|  |                         ec_config.bottoming_calibration_starter[row][adjusted_col] = false; | ||||||
|  |                     } else if (sw_value[row][adjusted_col] > ec_config.bottoming_reading[row][adjusted_col]) { | ||||||
|  |                         ec_config.bottoming_reading[row][adjusted_col] = sw_value[row][adjusted_col]; | ||||||
|  |                     } | ||||||
|  |                 } else { | ||||||
|  |                     updated |= ec_update_key(¤t_matrix[row], row, adjusted_col, sw_value[row][adjusted_col]); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return ec_config.bottoming_calibration ? false : updated; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Read the capacitive sensor value
 | ||||||
|  | uint16_t ec_readkey_raw(uint8_t channel, uint8_t row, uint8_t col) { | ||||||
|  |     uint16_t sw_value = 0; | ||||||
|  | 
 | ||||||
|  |     // Select the multiplexer
 | ||||||
|  |     select_amux_channel(channel, col); | ||||||
|  | 
 | ||||||
|  |     // Set the row pin to low state to avoid ghosting
 | ||||||
|  |     gpio_write_pin_low(row_pins[row]); | ||||||
|  | 
 | ||||||
|  |     ATOMIC_BLOCK_FORCEON { | ||||||
|  |         // Set the row pin to high state and have capacitor charge
 | ||||||
|  |         charge_capacitor(row); | ||||||
|  |         // Read the ADC value
 | ||||||
|  |         sw_value = adc_read(adcMux); | ||||||
|  |     } | ||||||
|  |     // Discharge peak hold capacitor
 | ||||||
|  |     discharge_capacitor(); | ||||||
|  |     // Waiting for the ghost capacitor to discharge fully
 | ||||||
|  |     wait_us(DISCHARGE_TIME); | ||||||
|  | 
 | ||||||
|  |     return sw_value; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Update press/release state of key
 | ||||||
|  | bool ec_update_key(matrix_row_t* current_row, uint8_t row, uint8_t col, uint16_t sw_value) { | ||||||
|  |     bool current_state = (*current_row >> col) & 1; | ||||||
|  | 
 | ||||||
|  |     // Real Time Noise Floor Calibration
 | ||||||
|  |     if (sw_value < (ec_config.noise_floor[row][col] - NOISE_FLOOR_THRESHOLD)) { | ||||||
|  |         uprintf("Noise Floor Change: %d, %d, %d\n", row, col, sw_value); | ||||||
|  |         ec_config.noise_floor[row][col]                             = sw_value; | ||||||
|  |         ec_config.rescaled_mode_0_actuation_threshold[row][col]     = rescale(ec_config.mode_0_actuation_threshold, 0, 1023, ec_config.noise_floor[row][col], eeprom_ec_config.bottoming_reading[row][col]); | ||||||
|  |         ec_config.rescaled_mode_0_release_threshold[row][col]       = rescale(ec_config.mode_0_release_threshold, 0, 1023, ec_config.noise_floor[row][col], eeprom_ec_config.bottoming_reading[row][col]); | ||||||
|  |         ec_config.rescaled_mode_1_initial_deadzone_offset[row][col] = rescale(ec_config.mode_1_initial_deadzone_offset, 0, 1023, ec_config.noise_floor[row][col], eeprom_ec_config.bottoming_reading[row][col]); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // Normal board-wide APC
 | ||||||
|  |     if (ec_config.actuation_mode == 0) { | ||||||
|  |         if (current_state && sw_value < ec_config.rescaled_mode_0_release_threshold[row][col]) { | ||||||
|  |             *current_row &= ~(1 << col); | ||||||
|  |             uprintf("Key released: %d, %d, %d\n", row, col, sw_value); | ||||||
|  |             return true; | ||||||
|  |         } | ||||||
|  |         if ((!current_state) && sw_value > ec_config.rescaled_mode_0_actuation_threshold[row][col]) { | ||||||
|  |             *current_row |= (1 << col); | ||||||
|  |             uprintf("Key pressed: %d, %d, %d\n", row, col, sw_value); | ||||||
|  |             return true; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     // Rapid Trigger
 | ||||||
|  |     else if (ec_config.actuation_mode == 1) { | ||||||
|  |         // Is key in active zone?
 | ||||||
|  |         if (sw_value > ec_config.rescaled_mode_1_initial_deadzone_offset[row][col]) { | ||||||
|  |             // Is key pressed while in active zone?
 | ||||||
|  |             if (current_state) { | ||||||
|  |                 // Is the key still moving down?
 | ||||||
|  |                 if (sw_value > ec_config.extremum[row][col]) { | ||||||
|  |                     ec_config.extremum[row][col] = sw_value; | ||||||
|  |                     uprintf("Key pressed: %d, %d, %d\n", row, col, sw_value); | ||||||
|  |                 } | ||||||
|  |                 // Has key moved up enough to be released?
 | ||||||
|  |                 else if (sw_value < ec_config.extremum[row][col] - ec_config.mode_1_release_offset) { | ||||||
|  |                     ec_config.extremum[row][col] = sw_value; | ||||||
|  |                     *current_row &= ~(1 << col); | ||||||
|  |                     uprintf("Key released: %d, %d, %d\n", row, col, sw_value); | ||||||
|  |                     return true; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             // Key is not pressed while in active zone
 | ||||||
|  |             else { | ||||||
|  |                 // Is the key still moving up?
 | ||||||
|  |                 if (sw_value < ec_config.extremum[row][col]) { | ||||||
|  |                     ec_config.extremum[row][col] = sw_value; | ||||||
|  |                 } | ||||||
|  |                 // Has key moved down enough to be pressed?
 | ||||||
|  |                 else if (sw_value > ec_config.extremum[row][col] + ec_config.mode_1_actuation_offset) { | ||||||
|  |                     ec_config.extremum[row][col] = sw_value; | ||||||
|  |                     *current_row |= (1 << col); | ||||||
|  |                     uprintf("Key pressed: %d, %d, %d\n", row, col, sw_value); | ||||||
|  |                     return true; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         // Key is not in active zone
 | ||||||
|  |         else { | ||||||
|  |             // Check to avoid key being stuck in pressed state near the active zone threshold
 | ||||||
|  |             if (sw_value < ec_config.extremum[row][col]) { | ||||||
|  |                 ec_config.extremum[row][col] = sw_value; | ||||||
|  |                 *current_row &= ~(1 << col); | ||||||
|  |                 return true; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     return false; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Print the matrix values
 | ||||||
|  | void ec_print_matrix(void) { | ||||||
|  |     for (uint8_t row = 0; row < MATRIX_ROWS; row++) { | ||||||
|  |         for (uint8_t col = 0; col < MATRIX_COLS - 1; col++) { | ||||||
|  |             uprintf("%4d,", sw_value[row][col]); | ||||||
|  |         } | ||||||
|  |         uprintf("%4d\n", sw_value[row][MATRIX_COLS - 1]); | ||||||
|  |     } | ||||||
|  |     print("\n"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Rescale the value to a different range
 | ||||||
|  | uint16_t rescale(uint16_t x, uint16_t in_min, uint16_t in_max, uint16_t out_min, uint16_t out_max) { | ||||||
|  |     return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; | ||||||
|  | } | ||||||
							
								
								
									
										84
									
								
								keyboards/cipulot/ec_typek/ec_switch_matrix.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								keyboards/cipulot/ec_typek/ec_switch_matrix.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,84 @@ | |||||||
|  | /* Copyright 2023 Cipulot
 | ||||||
|  |  * | ||||||
|  |  * 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 3 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/>.
 | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include <stdint.h> | ||||||
|  | #include <stdbool.h> | ||||||
|  | #include "matrix.h" | ||||||
|  | #include "eeconfig.h" | ||||||
|  | #include "util.h" | ||||||
|  | 
 | ||||||
|  | typedef struct _indicator_config_t { | ||||||
|  |     uint8_t h; | ||||||
|  |     uint8_t s; | ||||||
|  |     uint8_t v; | ||||||
|  |     bool    enabled; | ||||||
|  | } indicator_config; | ||||||
|  | 
 | ||||||
|  | typedef struct PACKED { | ||||||
|  |     indicator_config num; | ||||||
|  |     indicator_config caps; | ||||||
|  |     indicator_config scroll; | ||||||
|  |     uint8_t          actuation_mode;                              // 0: normal board-wide APC, 1: Rapid trigger from specific board-wide actuation point, 2: Rapid trigger from resting point
 | ||||||
|  |     uint16_t         mode_0_actuation_threshold;                  // threshold for key press in mode 0
 | ||||||
|  |     uint16_t         mode_0_release_threshold;                    // threshold for key release in mode 0
 | ||||||
|  |     uint16_t         mode_1_initial_deadzone_offset;              // threshold for key press in mode 1
 | ||||||
|  |     uint8_t          mode_1_actuation_offset;                // offset for key press in mode 1 and 2 (1-255)
 | ||||||
|  |     uint8_t          mode_1_release_offset;                  // offset for key release in mode 1 and 2 (1-255)
 | ||||||
|  |     uint16_t         bottoming_reading[MATRIX_ROWS][MATRIX_COLS]; // bottoming reading
 | ||||||
|  | } eeprom_ec_config_t; | ||||||
|  | 
 | ||||||
|  | typedef struct { | ||||||
|  |     uint8_t  actuation_mode;                                                    // 0: normal board-wide APC, 1: Rapid trigger from specific board-wide actuation point (it can be very near that baseline noise and be "full travel")
 | ||||||
|  |     uint16_t mode_0_actuation_threshold;                                        // threshold for key press in mode 0
 | ||||||
|  |     uint16_t mode_0_release_threshold;                                          // threshold for key release in mode 0
 | ||||||
|  |     uint16_t mode_1_initial_deadzone_offset;                                    // threshold for key press in mode 1 (initial deadzone)
 | ||||||
|  |     uint16_t rescaled_mode_0_actuation_threshold[MATRIX_ROWS][MATRIX_COLS];     // threshold for key press in mode 0 rescaled to actual scale
 | ||||||
|  |     uint16_t rescaled_mode_0_release_threshold[MATRIX_ROWS][MATRIX_COLS];       // threshold for key release in mode 0 rescaled to actual scale
 | ||||||
|  |     uint16_t rescaled_mode_1_initial_deadzone_offset[MATRIX_ROWS][MATRIX_COLS]; // threshold for key press in mode 1 (initial deadzone) rescaled to actual scale
 | ||||||
|  |     uint8_t  mode_1_actuation_offset;                                      // offset for key press in mode 1 (1-255)
 | ||||||
|  |     uint8_t  mode_1_release_offset;                                        // offset for key release in mode 1 (1-255)
 | ||||||
|  |     uint16_t extremum[MATRIX_ROWS][MATRIX_COLS];                                // extremum values for mode 1
 | ||||||
|  |     uint16_t noise_floor[MATRIX_ROWS][MATRIX_COLS];                             // noise floor detected during startup
 | ||||||
|  |     bool     bottoming_calibration;                                             // calibration mode for bottoming out values (true: calibration mode, false: normal mode)
 | ||||||
|  |     bool     bottoming_calibration_starter[MATRIX_ROWS][MATRIX_COLS];           // calibration mode for bottoming out values (true: calibration mode, false: normal mode)
 | ||||||
|  |     uint16_t bottoming_reading[MATRIX_ROWS][MATRIX_COLS];                       // bottoming reading
 | ||||||
|  | } ec_config_t; | ||||||
|  | 
 | ||||||
|  | // Check if the size of the reserved persistent memory is the same as the size of struct eeprom_ec_config_t
 | ||||||
|  | _Static_assert(sizeof(eeprom_ec_config_t) == EECONFIG_KB_DATA_SIZE, "Mismatch in keyboard EECONFIG stored data"); | ||||||
|  | 
 | ||||||
|  | extern eeprom_ec_config_t eeprom_ec_config; | ||||||
|  | 
 | ||||||
|  | extern ec_config_t ec_config; | ||||||
|  | 
 | ||||||
|  | void init_row(void); | ||||||
|  | void init_amux(void); | ||||||
|  | void select_amux_channel(uint8_t channel, uint8_t col); | ||||||
|  | void disable_unused_amux(uint8_t channel); | ||||||
|  | void discharge_capacitor(void); | ||||||
|  | void charge_capacitor(uint8_t row); | ||||||
|  | 
 | ||||||
|  | int      ec_init(void); | ||||||
|  | void     ec_noise_floor(void); | ||||||
|  | bool     ec_matrix_scan(matrix_row_t current_matrix[]); | ||||||
|  | uint16_t ec_readkey_raw(uint8_t channel, uint8_t row, uint8_t col); | ||||||
|  | bool     ec_update_key(matrix_row_t* current_row, uint8_t row, uint8_t col, uint16_t sw_value); | ||||||
|  | void     ec_print_matrix(void); | ||||||
|  | 
 | ||||||
|  | uint16_t rescale(uint16_t x, uint16_t in_min, uint16_t in_max, uint16_t out_min, uint16_t out_max); | ||||||
|  | bool indicators_callback(void); | ||||||
							
								
								
									
										119
									
								
								keyboards/cipulot/ec_typek/ec_typek.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								keyboards/cipulot/ec_typek/ec_typek.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,119 @@ | |||||||
|  | /* Copyright 2023 Cipulot
 | ||||||
|  |  * | ||||||
|  |  * 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 3 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 "ec_switch_matrix.h" | ||||||
|  | #include "quantum.h" | ||||||
|  | 
 | ||||||
|  | void eeconfig_init_kb(void) { | ||||||
|  |     // Default values
 | ||||||
|  |     eeprom_ec_config.num.h                          = 0; | ||||||
|  |     eeprom_ec_config.num.s                          = 0; | ||||||
|  |     eeprom_ec_config.num.v                          = 60; | ||||||
|  |     eeprom_ec_config.num.enabled                    = true; | ||||||
|  |     eeprom_ec_config.caps.h                         = 0; | ||||||
|  |     eeprom_ec_config.caps.s                         = 0; | ||||||
|  |     eeprom_ec_config.caps.v                         = 60; | ||||||
|  |     eeprom_ec_config.caps.enabled                   = true; | ||||||
|  |     eeprom_ec_config.scroll.h                       = 0; | ||||||
|  |     eeprom_ec_config.scroll.s                       = 0; | ||||||
|  |     eeprom_ec_config.scroll.v                       = 60; | ||||||
|  |     eeprom_ec_config.scroll.enabled                 = true; | ||||||
|  |     eeprom_ec_config.actuation_mode                 = DEFAULT_ACTUATION_MODE; | ||||||
|  |     eeprom_ec_config.mode_0_actuation_threshold     = DEFAULT_MODE_0_ACTUATION_LEVEL; | ||||||
|  |     eeprom_ec_config.mode_0_release_threshold       = DEFAULT_MODE_0_RELEASE_LEVEL; | ||||||
|  |     eeprom_ec_config.mode_1_initial_deadzone_offset = DEFAULT_MODE_1_INITIAL_DEADZONE_OFFSET; | ||||||
|  |     eeprom_ec_config.mode_1_actuation_offset   = DEFAULT_MODE_1_ACTUATION_OFFSET; | ||||||
|  |     eeprom_ec_config.mode_1_release_offset     = DEFAULT_MODE_1_RELEASE_OFFSET; | ||||||
|  | 
 | ||||||
|  |     for (uint8_t row = 0; row < MATRIX_ROWS; row++) { | ||||||
|  |         for (uint8_t col = 0; col < MATRIX_COLS; col++) { | ||||||
|  |             eeprom_ec_config.bottoming_reading[row][col] = DEFAULT_BOTTOMING_READING; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     // Write default value to EEPROM now
 | ||||||
|  |     eeconfig_update_kb_datablock(&eeprom_ec_config); | ||||||
|  | 
 | ||||||
|  |     eeconfig_init_user(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // On Keyboard startup
 | ||||||
|  | void keyboard_post_init_kb(void) { | ||||||
|  |     // Read custom menu variables from memory
 | ||||||
|  |     eeconfig_read_kb_datablock(&eeprom_ec_config); | ||||||
|  | 
 | ||||||
|  |     // Set runtime values to EEPROM values
 | ||||||
|  |     ec_config.actuation_mode                 = eeprom_ec_config.actuation_mode; | ||||||
|  |     ec_config.mode_0_actuation_threshold     = eeprom_ec_config.mode_0_actuation_threshold; | ||||||
|  |     ec_config.mode_0_release_threshold       = eeprom_ec_config.mode_0_release_threshold; | ||||||
|  |     ec_config.mode_1_initial_deadzone_offset = eeprom_ec_config.mode_1_initial_deadzone_offset; | ||||||
|  |     ec_config.mode_1_actuation_offset   = eeprom_ec_config.mode_1_actuation_offset; | ||||||
|  |     ec_config.mode_1_release_offset     = eeprom_ec_config.mode_1_release_offset; | ||||||
|  |     ec_config.bottoming_calibration          = false; | ||||||
|  |     for (uint8_t row = 0; row < MATRIX_ROWS; row++) { | ||||||
|  |         for (uint8_t col = 0; col < MATRIX_COLS; col++) { | ||||||
|  |             ec_config.bottoming_calibration_starter[row][col]           = true; | ||||||
|  |             ec_config.bottoming_reading[row][col]                       = eeprom_ec_config.bottoming_reading[row][col]; | ||||||
|  |             ec_config.rescaled_mode_0_actuation_threshold[row][col]     = rescale(ec_config.mode_0_actuation_threshold, 0, 1023, ec_config.noise_floor[row][col], eeprom_ec_config.bottoming_reading[row][col]); | ||||||
|  |             ec_config.rescaled_mode_0_release_threshold[row][col]       = rescale(ec_config.mode_0_release_threshold, 0, 1023, ec_config.noise_floor[row][col], eeprom_ec_config.bottoming_reading[row][col]); | ||||||
|  |             ec_config.rescaled_mode_1_initial_deadzone_offset[row][col] = rescale(ec_config.mode_1_initial_deadzone_offset, 0, 1023, ec_config.noise_floor[row][col], eeprom_ec_config.bottoming_reading[row][col]); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // Set the RGB LEDs range that will be used for the effects
 | ||||||
|  |     rgblight_set_effect_range(3, 66); | ||||||
|  |     // Call the indicator callback to set the indicator color
 | ||||||
|  |     indicators_callback(); | ||||||
|  | 
 | ||||||
|  |     keyboard_post_init_user(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // This function gets called when caps, num, scroll change
 | ||||||
|  | bool led_update_kb(led_t led_state) { | ||||||
|  |     indicators_callback(); | ||||||
|  |     return true; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // This function is called when layers change
 | ||||||
|  | layer_state_t layer_state_set_user(layer_state_t state) { | ||||||
|  |     indicators_callback(); | ||||||
|  |     return state; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // INDICATOR CALLBACK ------------------------------------------------------------------------------
 | ||||||
|  | /* LED index to physical position
 | ||||||
|  |  * | ||||||
|  |  * LED2 | LED1 |  LED0 | ||||||
|  |  * -----+------+-------- | ||||||
|  |  * Num  | Caps | Scroll | | ||||||
|  |  */ | ||||||
|  | bool indicators_callback(void) { | ||||||
|  |     if ((eeprom_ec_config.num.enabled) && (host_keyboard_led_state().num_lock)) | ||||||
|  |         sethsv(eeprom_ec_config.num.h, eeprom_ec_config.num.s, eeprom_ec_config.num.v, (rgb_led_t *)&led[NUM_INDICATOR_INDEX]); | ||||||
|  |     else | ||||||
|  |         sethsv(0, 0, 0, (rgb_led_t *)&led[NUM_INDICATOR_INDEX]); | ||||||
|  | 
 | ||||||
|  |     if ((eeprom_ec_config.caps.enabled) && (host_keyboard_led_state().caps_lock)) | ||||||
|  |         sethsv(eeprom_ec_config.caps.h, eeprom_ec_config.caps.s, eeprom_ec_config.caps.v, (rgb_led_t *)&led[CAPS_INDICATOR_INDEX]); | ||||||
|  |     else | ||||||
|  |         sethsv(0, 0, 0, (rgb_led_t *)&led[CAPS_INDICATOR_INDEX]); | ||||||
|  | 
 | ||||||
|  |     if ((eeprom_ec_config.scroll.enabled) && (host_keyboard_led_state().scroll_lock)) | ||||||
|  |         sethsv(eeprom_ec_config.scroll.h, eeprom_ec_config.scroll.s, eeprom_ec_config.scroll.v, (rgb_led_t *)&led[SCROLL_INDICATOR_INDEX]); | ||||||
|  |     else | ||||||
|  |         sethsv(0, 0, 0, (rgb_led_t *)&led[SCROLL_INDICATOR_INDEX]); | ||||||
|  | 
 | ||||||
|  |     return true; | ||||||
|  | } | ||||||
							
								
								
									
										23
									
								
								keyboards/cipulot/ec_typek/halconf.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								keyboards/cipulot/ec_typek/halconf.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,23 @@ | |||||||
|  | /* Copyright 2023 Cipulot
 | ||||||
|  |  * | ||||||
|  |  * 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 3 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/>.
 | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #define HAL_USE_ADC TRUE | ||||||
|  | #define HAL_USE_PWM TRUE | ||||||
|  | #define HAL_USE_PAL TRUE | ||||||
|  | 
 | ||||||
|  | #include_next <halconf.h> | ||||||
							
								
								
									
										133
									
								
								keyboards/cipulot/ec_typek/info.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								keyboards/cipulot/ec_typek/info.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,133 @@ | |||||||
|  | { | ||||||
|  |     "manufacturer": "Cipulot", | ||||||
|  |     "keyboard_name": "EC Type-K", | ||||||
|  |     "maintainer": "Cipulot", | ||||||
|  |     "bootloader": "stm32-dfu", | ||||||
|  |     "build": { | ||||||
|  |         "lto": true | ||||||
|  |     }, | ||||||
|  |     "diode_direction": "COL2ROW", | ||||||
|  |     "eeprom": { | ||||||
|  |         "wear_leveling": { | ||||||
|  |             "backing_size": 4096 | ||||||
|  |         } | ||||||
|  |     }, | ||||||
|  |     "features": { | ||||||
|  |         "bootmagic": false, | ||||||
|  |         "console": true, | ||||||
|  |         "extrakey": true, | ||||||
|  |         "mousekey": true, | ||||||
|  |         "nkro": true, | ||||||
|  |         "rgblight": true | ||||||
|  |     }, | ||||||
|  |     "processor": "STM32F411", | ||||||
|  |     "qmk": { | ||||||
|  |         "locking": { | ||||||
|  |             "enabled": true, | ||||||
|  |             "resync": true | ||||||
|  |         } | ||||||
|  |     }, | ||||||
|  |     "rgblight": { | ||||||
|  |         "animations": { | ||||||
|  |             "alternating": true, | ||||||
|  |             "breathing": true, | ||||||
|  |             "christmas": true, | ||||||
|  |             "knight": true, | ||||||
|  |             "rainbow_mood": true, | ||||||
|  |             "rainbow_swirl": true, | ||||||
|  |             "rgb_test": true, | ||||||
|  |             "snake": true, | ||||||
|  |             "static_gradient": true, | ||||||
|  |             "twinkle": true | ||||||
|  |         }, | ||||||
|  |         "led_count": 69, | ||||||
|  |         "led_map": [0, 1, 2, 3, 4, 5, 66, 67, 68, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65], | ||||||
|  |         "max_brightness": 200 | ||||||
|  |     }, | ||||||
|  |     "usb": { | ||||||
|  |         "device_version": "0.0.1", | ||||||
|  |         "pid": "0x6BB4", | ||||||
|  |         "shared_endpoint": { | ||||||
|  |             "keyboard": true | ||||||
|  |         }, | ||||||
|  |         "vid": "0x6369" | ||||||
|  |     }, | ||||||
|  |     "ws2812": { | ||||||
|  |         "driver": "pwm", | ||||||
|  |         "pin": "B15" | ||||||
|  |     }, | ||||||
|  |     "layouts": { | ||||||
|  |         "LAYOUT": { | ||||||
|  |             "layout": [ | ||||||
|  |                 {"matrix": [1, 0], "x": 0.75, "y": 0}, | ||||||
|  |                 {"matrix": [0, 0], "x": 2.5, "y": 0}, | ||||||
|  |                 {"matrix": [0, 1], "x": 3.5, "y": 0}, | ||||||
|  |                 {"matrix": [0, 2], "x": 4.5, "y": 0}, | ||||||
|  |                 {"matrix": [0, 3], "x": 5.5, "y": 0}, | ||||||
|  |                 {"matrix": [0, 4], "x": 6.5, "y": 0}, | ||||||
|  |                 {"matrix": [0, 5], "x": 7.5, "y": 0}, | ||||||
|  |                 {"matrix": [0, 6], "x": 8.5, "y": 0}, | ||||||
|  |                 {"matrix": [0, 7], "x": 10.5, "y": 0}, | ||||||
|  |                 {"matrix": [0, 8], "x": 11.5, "y": 0}, | ||||||
|  |                 {"matrix": [0, 9], "x": 12.5, "y": 0}, | ||||||
|  |                 {"matrix": [0, 10], "x": 13.5, "y": 0}, | ||||||
|  |                 {"matrix": [0, 11], "x": 14.5, "y": 0}, | ||||||
|  |                 {"matrix": [0, 12], "x": 15.5, "y": 0}, | ||||||
|  |                 {"matrix": [0, 13], "x": 16.5, "y": 0}, | ||||||
|  |                 {"matrix": [0, 14], "x": 17.5, "y": 0}, | ||||||
|  |                 {"matrix": [2, 0], "x": 0.5, "y": 1}, | ||||||
|  |                 {"matrix": [1, 1], "x": 2.25, "y": 1, "w": 1.5}, | ||||||
|  |                 {"matrix": [1, 2], "x": 3.75, "y": 1}, | ||||||
|  |                 {"matrix": [1, 3], "x": 4.75, "y": 1}, | ||||||
|  |                 {"matrix": [1, 4], "x": 5.75, "y": 1}, | ||||||
|  |                 {"matrix": [1, 5], "x": 6.75, "y": 1}, | ||||||
|  |                 {"matrix": [1, 6], "x": 7.75, "y": 1}, | ||||||
|  |                 {"matrix": [1, 7], "x": 10.25, "y": 1}, | ||||||
|  |                 {"matrix": [1, 8], "x": 11.25, "y": 1}, | ||||||
|  |                 {"matrix": [1, 9], "x": 12.25, "y": 1}, | ||||||
|  |                 {"matrix": [1, 10], "x": 13.25, "y": 1}, | ||||||
|  |                 {"matrix": [1, 11], "x": 14.25, "y": 1}, | ||||||
|  |                 {"matrix": [1, 12], "x": 15.25, "y": 1}, | ||||||
|  |                 {"matrix": [1, 13], "x": 16.25, "y": 1}, | ||||||
|  |                 {"matrix": [1, 14], "x": 17.25, "y": 1, "w": 1.5}, | ||||||
|  |                 {"matrix": [3, 0], "x": 0.25, "y": 2}, | ||||||
|  |                 {"matrix": [2, 1], "x": 2, "y": 2, "w": 1.75}, | ||||||
|  |                 {"matrix": [2, 2], "x": 3.75, "y": 2}, | ||||||
|  |                 {"matrix": [2, 3], "x": 4.75, "y": 2}, | ||||||
|  |                 {"matrix": [2, 4], "x": 5.75, "y": 2}, | ||||||
|  |                 {"matrix": [2, 5], "x": 6.75, "y": 2}, | ||||||
|  |                 {"matrix": [2, 6], "x": 7.75, "y": 2}, | ||||||
|  |                 {"matrix": [2, 7], "x": 10.75, "y": 2}, | ||||||
|  |                 {"matrix": [2, 8], "x": 11.75, "y": 2}, | ||||||
|  |                 {"matrix": [2, 9], "x": 12.75, "y": 2}, | ||||||
|  |                 {"matrix": [2, 10], "x": 13.75, "y": 2}, | ||||||
|  |                 {"matrix": [2, 11], "x": 14.75, "y": 2}, | ||||||
|  |                 {"matrix": [2, 12], "x": 15.75, "y": 2}, | ||||||
|  |                 {"matrix": [2, 14], "x": 16.75, "y": 2, "w": 2.25}, | ||||||
|  |                 {"matrix": [4, 0], "x": 0, "y": 3}, | ||||||
|  |                 {"matrix": [3, 1], "x": 1.75, "y": 3, "w": 2.25}, | ||||||
|  |                 {"matrix": [3, 2], "x": 4, "y": 3}, | ||||||
|  |                 {"matrix": [3, 3], "x": 5, "y": 3}, | ||||||
|  |                 {"matrix": [3, 4], "x": 6, "y": 3}, | ||||||
|  |                 {"matrix": [3, 5], "x": 7, "y": 3}, | ||||||
|  |                 {"matrix": [3, 6], "x": 8, "y": 3}, | ||||||
|  |                 {"matrix": [3, 7], "x": 10.5, "y": 3}, | ||||||
|  |                 {"matrix": [3, 8], "x": 11.5, "y": 3}, | ||||||
|  |                 {"matrix": [3, 9], "x": 12.5, "y": 3}, | ||||||
|  |                 {"matrix": [3, 10], "x": 13.5, "y": 3}, | ||||||
|  |                 {"matrix": [3, 11], "x": 14.5, "y": 3}, | ||||||
|  |                 {"matrix": [3, 12], "x": 15.5, "y": 3}, | ||||||
|  |                 {"matrix": [3, 13], "x": 16.5, "y": 3, "w": 1.25}, | ||||||
|  |                 {"matrix": [3, 14], "x": 17.75, "y": 3}, | ||||||
|  |                 {"matrix": [4, 1], "x": 1.75, "y": 4, "w": 1.5}, | ||||||
|  |                 {"matrix": [4, 3], "x": 5, "y": 4, "w": 1.5}, | ||||||
|  |                 {"matrix": [4, 5], "x": 6.5, "y": 4, "w": 2}, | ||||||
|  |                 {"matrix": [4, 6], "x": 8.5, "y": 4}, | ||||||
|  |                 {"matrix": [4, 7], "x": 10, "y": 4}, | ||||||
|  |                 {"matrix": [4, 8], "x": 11, "y": 4, "w": 2}, | ||||||
|  |                 {"matrix": [4, 10], "x": 13, "y": 4, "w": 1.5}, | ||||||
|  |                 {"matrix": [4, 13], "x": 16.75, "y": 4, "w": 1.5} | ||||||
|  |             ] | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										41
									
								
								keyboards/cipulot/ec_typek/keymaps/default/keymap.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								keyboards/cipulot/ec_typek/keymaps/default/keymap.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,41 @@ | |||||||
|  | /* Copyright 2023 Cipulot
 | ||||||
|  |  * | ||||||
|  |  * 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 3 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 QMK_KEYBOARD_H | ||||||
|  | 
 | ||||||
|  | const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | ||||||
|  |     // clang-format off
 | ||||||
|  |     [0] = LAYOUT( | ||||||
|  |         KC_ESC,   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_BSLS,   KC_DEL, | ||||||
|  |         KC_PGUP,  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_BSPC, | ||||||
|  |         KC_PGDN,  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_ENTER, | ||||||
|  |         KC_LGUI,  KC_LSFT,  KC_Z,  KC_X,  KC_C,     KC_V,    KC_B,              KC_B,     KC_N,    KC_M,     KC_COMM,  KC_DOT,   KC_SLSH,  KC_RSFT,   MO(1), | ||||||
|  |         KC_LCTL,                          KC_LALT,  KC_SPC,  KC_LGUI,           KC_RGUI,  KC_SPC,  KC_RALT,                                           MO(1) | ||||||
|  |     ), | ||||||
|  |     [1] = LAYOUT( | ||||||
|  |         _______,  _______,  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_HOME,  _______,  _______,  KC_UP,    _______,   _______,  _______,            _______,  _______,  KC_PSCR,  KC_SCRL,  KC_PAUSE,  _______,  _______,  _______, | ||||||
|  |         KC_END,   _______,  KC_LEFT,  KC_DOWN,  KC_RIGHT,  _______,  _______,            _______,  _______,  _______,  _______,  _______,   _______,  _______, | ||||||
|  |         _______,  _______,  _______,  _______,  _______,   _______,  _______,            _______,  _______,  _______,  _______,  _______,   _______,  _______,  _______, | ||||||
|  |         _______,                                _______,   _______,  _______,            _______,  _______,  MO(2),                                             _______ | ||||||
|  |     ), | ||||||
|  |     [2] = LAYOUT( | ||||||
|  |         QK_BOOT,  _______,  _______,  _______,  _______,  _______,  _______,  _______,    _______,  _______,  _______,  _______,  _______,  _______,  _______,  _______, | ||||||
|  |         NK_TOGG,  _______,  _______,  _______,  _______,  _______,  _______,              _______,  _______,  _______,  _______,  _______,  _______,  _______,  _______, | ||||||
|  |         _______,  _______,  _______,  _______,  _______,  _______,  _______,              _______,  _______,  _______,  _______,  _______,  _______,  _______, | ||||||
|  |         _______,  _______,  _______,  _______,  _______,  _______,  _______,              _______,  _______,  _______,  _______,  _______,  _______,  _______,  _______, | ||||||
|  |         _______,                                _______,  _______,  _______,              _______,  _______,  _______,                                          _______) | ||||||
|  | }; | ||||||
							
								
								
									
										41
									
								
								keyboards/cipulot/ec_typek/keymaps/via/keymap.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								keyboards/cipulot/ec_typek/keymaps/via/keymap.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,41 @@ | |||||||
|  | /* Copyright 2023 Cipulot
 | ||||||
|  |  * | ||||||
|  |  * 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 3 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 QMK_KEYBOARD_H | ||||||
|  | 
 | ||||||
|  | const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | ||||||
|  |     // clang-format off
 | ||||||
|  |     [0] = LAYOUT( | ||||||
|  |         KC_ESC,   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_BSLS,   KC_DEL, | ||||||
|  |         KC_PGUP,  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_BSPC, | ||||||
|  |         KC_PGDN,  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_ENTER, | ||||||
|  |         KC_LGUI,  KC_LSFT,  KC_Z,  KC_X,  KC_C,     KC_V,    KC_B,              KC_B,     KC_N,    KC_M,     KC_COMM,  KC_DOT,   KC_SLSH,  KC_RSFT,   MO(1), | ||||||
|  |         KC_LCTL,                          KC_LALT,  KC_SPC,  KC_LGUI,           KC_RGUI,  KC_SPC,  KC_RALT,                                           MO(1) | ||||||
|  |     ), | ||||||
|  |     [1] = LAYOUT( | ||||||
|  |         _______,  _______,  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_HOME,  _______,  _______,  KC_UP,    _______,   _______,  _______,            _______,  _______,  KC_PSCR,  KC_SCRL,  KC_PAUSE,  _______,  _______,  _______, | ||||||
|  |         KC_END,   _______,  KC_LEFT,  KC_DOWN,  KC_RIGHT,  _______,  _______,            _______,  _______,  _______,  _______,  _______,   _______,  _______, | ||||||
|  |         _______,  _______,  _______,  _______,  _______,   _______,  _______,            _______,  _______,  _______,  _______,  _______,   _______,  _______,  _______, | ||||||
|  |         _______,                                _______,   _______,  _______,            _______,  _______,  MO(2),                                             _______ | ||||||
|  |     ), | ||||||
|  |     [2] = LAYOUT( | ||||||
|  |         QK_BOOT,  _______,  _______,  _______,  _______,  _______,  _______,  _______,    _______,  _______,  _______,  _______,  _______,  _______,  _______,  _______, | ||||||
|  |         NK_TOGG,  _______,  _______,  _______,  _______,  _______,  _______,              _______,  _______,  _______,  _______,  _______,  _______,  _______,  _______, | ||||||
|  |         _______,  _______,  _______,  _______,  _______,  _______,  _______,              _______,  _______,  _______,  _______,  _______,  _______,  _______, | ||||||
|  |         _______,  _______,  _______,  _______,  _______,  _______,  _______,              _______,  _______,  _______,  _______,  _______,  _______,  _______,  _______, | ||||||
|  |         _______,                                _______,  _______,  _______,              _______,  _______,  _______,                                          _______) | ||||||
|  | }; | ||||||
							
								
								
									
										3
									
								
								keyboards/cipulot/ec_typek/keymaps/via/rules.mk
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								keyboards/cipulot/ec_typek/keymaps/via/rules.mk
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | |||||||
|  | VIA_ENABLE = yes | ||||||
|  | 
 | ||||||
|  | SRC += via_ec_indicators.c | ||||||
							
								
								
									
										502
									
								
								keyboards/cipulot/ec_typek/keymaps/via/via_ec_indicators.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										502
									
								
								keyboards/cipulot/ec_typek/keymaps/via/via_ec_indicators.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,502 @@ | |||||||
|  | /* Copyright 2023 Cipulot
 | ||||||
|  |  * | ||||||
|  |  * 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 3 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 "keyboards/cipulot/common/eeprom_tools.h" | ||||||
|  | #include "ec_switch_matrix.h" | ||||||
|  | #include "action.h" | ||||||
|  | #include "print.h" | ||||||
|  | #include "via.h" | ||||||
|  | 
 | ||||||
|  | #ifdef VIA_ENABLE | ||||||
|  | 
 | ||||||
|  | void ec_rescale_values(uint8_t item); | ||||||
|  | void ec_save_threshold_data(uint8_t option); | ||||||
|  | void ec_save_bottoming_reading(void); | ||||||
|  | void ec_show_calibration_data(void); | ||||||
|  | void ec_clear_bottoming_calibration_data(void); | ||||||
|  | 
 | ||||||
|  | // Declaring enums for VIA config menu
 | ||||||
|  | enum via_enums { | ||||||
|  |     // clang-format off
 | ||||||
|  |     id_num_indicator_enabled    = 1, | ||||||
|  |     id_num_indicator_brightness = 2, | ||||||
|  |     id_num_indicator_color      = 3, | ||||||
|  |     id_caps_indicator_enabled    = 4, | ||||||
|  |     id_caps_indicator_brightness = 5, | ||||||
|  |     id_caps_indicator_color      = 6, | ||||||
|  |     id_scroll_indicator_enabled    = 7, | ||||||
|  |     id_scroll_indicator_brightness = 8, | ||||||
|  |     id_scroll_indicator_color      = 9, | ||||||
|  |     id_actuation_mode = 10, | ||||||
|  |     id_mode_0_actuation_threshold = 11, | ||||||
|  |     id_mode_0_release_threshold = 12, | ||||||
|  |     id_save_threshold_data = 13, | ||||||
|  |     id_mode_1_initial_deadzone_offset = 14, | ||||||
|  |     id_mode_1_actuation_offset = 15, | ||||||
|  |     id_mode_1_release_offset = 16, | ||||||
|  |     id_bottoming_calibration = 17, | ||||||
|  |     id_noise_floor_calibration = 18, | ||||||
|  |     id_show_calibration_data = 19, | ||||||
|  |     id_clear_bottoming_calibration_data = 20 | ||||||
|  |     // clang-format on
 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | // Handle the data received by the keyboard from the VIA menus
 | ||||||
|  | void via_config_set_value(uint8_t *data) { | ||||||
|  |     // data = [ value_id, value_data ]
 | ||||||
|  |     uint8_t *value_id   = &(data[0]); | ||||||
|  |     uint8_t *value_data = &(data[1]); | ||||||
|  | 
 | ||||||
|  |     switch (*value_id) { | ||||||
|  |         case id_num_indicator_enabled: { | ||||||
|  |             if (value_data[0] == 1) { | ||||||
|  |                 eeprom_ec_config.num.enabled = true; | ||||||
|  |                 uprintf("#########################\n"); | ||||||
|  |                 uprintf("# Num indicator enabled #\n"); | ||||||
|  |                 uprintf("#########################\n"); | ||||||
|  |             } else { | ||||||
|  |                 eeprom_ec_config.num.enabled = false; | ||||||
|  |                 uprintf("##########################\n"); | ||||||
|  |                 uprintf("# Num indicator disabled #\n"); | ||||||
|  |                 uprintf("##########################\n"); | ||||||
|  |             } | ||||||
|  |             EEPROM_KB_PARTIAL_UPDATE(eeprom_ec_config, num.enabled); | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |         case id_num_indicator_brightness: { | ||||||
|  |             eeprom_ec_config.num.v = value_data[0]; | ||||||
|  |             uprintf("Num indicator brightness: %d\n", eeprom_ec_config.num.v); | ||||||
|  |             EEPROM_KB_PARTIAL_UPDATE(eeprom_ec_config, num.v); | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |         case id_num_indicator_color: { | ||||||
|  |             eeprom_ec_config.num.h = value_data[0]; | ||||||
|  |             eeprom_ec_config.num.s = value_data[1]; | ||||||
|  |             uprintf("Num indicator color: %d, %d\n", eeprom_ec_config.num.h, eeprom_ec_config.num.s); | ||||||
|  |             EEPROM_KB_PARTIAL_UPDATE(eeprom_ec_config, num.h); | ||||||
|  |             EEPROM_KB_PARTIAL_UPDATE(eeprom_ec_config, num.s); | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |         case id_caps_indicator_enabled: { | ||||||
|  |             if (value_data[0] == 1) { | ||||||
|  |                 eeprom_ec_config.caps.enabled = true; | ||||||
|  |                 uprintf("##########################\n"); | ||||||
|  |                 uprintf("# Caps indicator enabled #\n"); | ||||||
|  |                 uprintf("##########################\n"); | ||||||
|  |             } else { | ||||||
|  |                 eeprom_ec_config.caps.enabled = false; | ||||||
|  |                 uprintf("###########################\n"); | ||||||
|  |                 uprintf("# Caps indicator disabled #\n"); | ||||||
|  |                 uprintf("###########################\n"); | ||||||
|  |             } | ||||||
|  |             EEPROM_KB_PARTIAL_UPDATE(eeprom_ec_config, caps.enabled); | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |         case id_caps_indicator_brightness: { | ||||||
|  |             eeprom_ec_config.caps.v = value_data[0]; | ||||||
|  |             uprintf("Caps indicator brightness: %d\n", eeprom_ec_config.caps.v); | ||||||
|  |             EEPROM_KB_PARTIAL_UPDATE(eeprom_ec_config, caps.v); | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |         case id_caps_indicator_color: { | ||||||
|  |             eeprom_ec_config.caps.h = value_data[0]; | ||||||
|  |             eeprom_ec_config.caps.s = value_data[1]; | ||||||
|  |             uprintf("Caps indicator color: %d, %d\n", eeprom_ec_config.caps.h, eeprom_ec_config.caps.s); | ||||||
|  |             EEPROM_KB_PARTIAL_UPDATE(eeprom_ec_config, caps.h); | ||||||
|  |             EEPROM_KB_PARTIAL_UPDATE(eeprom_ec_config, caps.s); | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |         case id_scroll_indicator_enabled: { | ||||||
|  |             if (value_data[0] == 1) { | ||||||
|  |                 eeprom_ec_config.scroll.enabled = true; | ||||||
|  |                 uprintf("############################\n"); | ||||||
|  |                 uprintf("# Scroll indicator enabled #\n"); | ||||||
|  |                 uprintf("############################\n"); | ||||||
|  |             } else { | ||||||
|  |                 eeprom_ec_config.scroll.enabled = false; | ||||||
|  |                 uprintf("#############################\n"); | ||||||
|  |                 uprintf("# Scroll indicator disabled #\n"); | ||||||
|  |                 uprintf("#############################\n"); | ||||||
|  |             } | ||||||
|  |             EEPROM_KB_PARTIAL_UPDATE(eeprom_ec_config, scroll.enabled); | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |         case id_scroll_indicator_brightness: { | ||||||
|  |             eeprom_ec_config.scroll.v = value_data[0]; | ||||||
|  |             uprintf("Scroll indicator brightness: %d\n", eeprom_ec_config.scroll.v); | ||||||
|  |             EEPROM_KB_PARTIAL_UPDATE(eeprom_ec_config, scroll.v); | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |         case id_scroll_indicator_color: { | ||||||
|  |             eeprom_ec_config.scroll.h = value_data[0]; | ||||||
|  |             eeprom_ec_config.scroll.s = value_data[1]; | ||||||
|  |             uprintf("Scroll indicator color: %d, %d\n", eeprom_ec_config.scroll.h, eeprom_ec_config.scroll.s); | ||||||
|  |             EEPROM_KB_PARTIAL_UPDATE(eeprom_ec_config, scroll.h); | ||||||
|  |             EEPROM_KB_PARTIAL_UPDATE(eeprom_ec_config, scroll.s); | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |         case id_actuation_mode: { | ||||||
|  |             eeprom_ec_config.actuation_mode = value_data[0]; | ||||||
|  |             ec_config.actuation_mode        = eeprom_ec_config.actuation_mode; | ||||||
|  |             if (ec_config.actuation_mode == 0) { | ||||||
|  |                 uprintf("#########################\n"); | ||||||
|  |                 uprintf("#  Actuation Mode: APC  #\n"); | ||||||
|  |                 uprintf("#########################\n"); | ||||||
|  |             } else if (ec_config.actuation_mode == 1) { | ||||||
|  |                 uprintf("#################################\n"); | ||||||
|  |                 uprintf("# Actuation Mode: Rapid Trigger #\n"); | ||||||
|  |                 uprintf("#################################\n"); | ||||||
|  |             } | ||||||
|  |             EEPROM_KB_PARTIAL_UPDATE(eeprom_ec_config, actuation_mode); | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |         case id_mode_0_actuation_threshold: { | ||||||
|  |             ec_config.mode_0_actuation_threshold = value_data[1] | (value_data[0] << 8); | ||||||
|  |             uprintf("APC Mode Actuation Threshold: %d\n", ec_config.mode_0_actuation_threshold); | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |         case id_mode_0_release_threshold: { | ||||||
|  |             eeprom_ec_config.mode_0_release_threshold = value_data[1] | (value_data[0] << 8); | ||||||
|  |             ec_config.mode_0_release_threshold        = eeprom_ec_config.mode_0_release_threshold; | ||||||
|  |             uprintf("APC Mode Release Threshold: %d\n", ec_config.mode_0_release_threshold); | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |         case id_mode_1_initial_deadzone_offset: { | ||||||
|  |             ec_config.mode_1_initial_deadzone_offset = value_data[1] | (value_data[0] << 8); | ||||||
|  |             uprintf("Rapid Trigger Mode Initial Deadzone Offset: %d\n", ec_config.mode_1_initial_deadzone_offset); | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |         case id_mode_1_actuation_offset: { | ||||||
|  |             ec_config.mode_1_actuation_offset = value_data[0]; | ||||||
|  |             uprintf("Rapid Trigger Mode Actuation Sensitivity: %d\n", ec_config.mode_1_actuation_offset); | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |         case id_mode_1_release_offset: { | ||||||
|  |             ec_config.mode_1_release_offset = value_data[0]; | ||||||
|  |             uprintf("Rapid Trigger Mode Release Sensitivity: %d\n", ec_config.mode_1_release_offset); | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |         case id_bottoming_calibration: { | ||||||
|  |             if (value_data[0] == 1) { | ||||||
|  |                 ec_config.bottoming_calibration = true; | ||||||
|  |                 uprintf("##############################\n"); | ||||||
|  |                 uprintf("# Bottoming calibration mode #\n"); | ||||||
|  |                 uprintf("##############################\n"); | ||||||
|  |             } else { | ||||||
|  |                 ec_config.bottoming_calibration = false; | ||||||
|  |                 ec_save_bottoming_reading(); | ||||||
|  |                 uprintf("## Bottoming calibration done ##\n"); | ||||||
|  |                 ec_show_calibration_data(); | ||||||
|  |             } | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |         case id_save_threshold_data: { | ||||||
|  |             ec_save_threshold_data(value_data[0]); | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |         case id_noise_floor_calibration: { | ||||||
|  |             if (value_data[0] == 0) { | ||||||
|  |                 ec_noise_floor(); | ||||||
|  |                 ec_rescale_values(0); | ||||||
|  |                 ec_rescale_values(1); | ||||||
|  |                 ec_rescale_values(2); | ||||||
|  |                 uprintf("#############################\n"); | ||||||
|  |                 uprintf("# Noise floor data acquired #\n"); | ||||||
|  |                 uprintf("#############################\n"); | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         case id_show_calibration_data: { | ||||||
|  |             // Show calibration data once if the user toggle the switch
 | ||||||
|  |             if (value_data[0] == 0) { | ||||||
|  |                 ec_show_calibration_data(); | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         case id_clear_bottoming_calibration_data: { | ||||||
|  |             if (value_data[0] == 0) { | ||||||
|  |                 ec_clear_bottoming_calibration_data(); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         default: { | ||||||
|  |             // Unhandled value.
 | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // Call the indicator callback to set the indicator color
 | ||||||
|  |     indicators_callback(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Handle the data sent by the keyboard to the VIA menus
 | ||||||
|  | void via_config_get_value(uint8_t *data) { | ||||||
|  |     // data = [ value_id, value_data ]
 | ||||||
|  |     uint8_t *value_id   = &(data[0]); | ||||||
|  |     uint8_t *value_data = &(data[1]); | ||||||
|  | 
 | ||||||
|  |     switch (*value_id) { | ||||||
|  |         case id_num_indicator_enabled: { | ||||||
|  |             value_data[0] = eeprom_ec_config.num.enabled; | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |         case id_num_indicator_brightness: { | ||||||
|  |             value_data[0] = eeprom_ec_config.num.v; | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |         case id_num_indicator_color: { | ||||||
|  |             value_data[0] = eeprom_ec_config.num.h; | ||||||
|  |             value_data[1] = eeprom_ec_config.num.s; | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |         case id_caps_indicator_enabled: { | ||||||
|  |             value_data[0] = eeprom_ec_config.caps.enabled; | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |         case id_caps_indicator_brightness: { | ||||||
|  |             value_data[0] = eeprom_ec_config.caps.v; | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |         case id_caps_indicator_color: { | ||||||
|  |             value_data[0] = eeprom_ec_config.caps.h; | ||||||
|  |             value_data[1] = eeprom_ec_config.caps.s; | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |         case id_scroll_indicator_enabled: { | ||||||
|  |             value_data[0] = eeprom_ec_config.scroll.enabled; | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |         case id_scroll_indicator_brightness: { | ||||||
|  |             value_data[0] = eeprom_ec_config.scroll.v; | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |         case id_scroll_indicator_color: { | ||||||
|  |             value_data[0] = eeprom_ec_config.scroll.h; | ||||||
|  |             value_data[1] = eeprom_ec_config.scroll.s; | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |         case id_actuation_mode: { | ||||||
|  |             value_data[0] = eeprom_ec_config.actuation_mode; | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |         case id_mode_0_actuation_threshold: { | ||||||
|  |             value_data[0] = eeprom_ec_config.mode_0_actuation_threshold >> 8; | ||||||
|  |             value_data[1] = eeprom_ec_config.mode_0_actuation_threshold & 0xFF; | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |         case id_mode_0_release_threshold: { | ||||||
|  |             value_data[0] = eeprom_ec_config.mode_0_release_threshold >> 8; | ||||||
|  |             value_data[1] = eeprom_ec_config.mode_0_release_threshold & 0xFF; | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |         case id_mode_1_initial_deadzone_offset: { | ||||||
|  |             value_data[0] = eeprom_ec_config.mode_1_initial_deadzone_offset >> 8; | ||||||
|  |             value_data[1] = eeprom_ec_config.mode_1_initial_deadzone_offset & 0xFF; | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |         case id_mode_1_actuation_offset: { | ||||||
|  |             value_data[0] = eeprom_ec_config.mode_1_actuation_offset; | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |         case id_mode_1_release_offset: { | ||||||
|  |             value_data[0] = eeprom_ec_config.mode_1_release_offset; | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |         default: { | ||||||
|  |             // Unhandled value.
 | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Handle the commands sent and received by the keyboard with VIA
 | ||||||
|  | void via_custom_value_command_kb(uint8_t *data, uint8_t length) { | ||||||
|  |     // data = [ command_id, channel_id, value_id, value_data ]
 | ||||||
|  |     uint8_t *command_id        = &(data[0]); | ||||||
|  |     uint8_t *channel_id        = &(data[1]); | ||||||
|  |     uint8_t *value_id_and_data = &(data[2]); | ||||||
|  | 
 | ||||||
|  |     if (*channel_id == id_custom_channel) { | ||||||
|  |         switch (*command_id) { | ||||||
|  |             case id_custom_set_value: { | ||||||
|  |                 via_config_set_value(value_id_and_data); | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  |             case id_custom_get_value: { | ||||||
|  |                 via_config_get_value(value_id_and_data); | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  |             case id_custom_save: { | ||||||
|  |                 // Bypass the save function in favor of pinpointed saves
 | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  |             default: { | ||||||
|  |                 // Unhandled message.
 | ||||||
|  |                 *command_id = id_unhandled; | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     *command_id = id_unhandled; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Rescale the values received by VIA to fit the new range
 | ||||||
|  | void ec_rescale_values(uint8_t item) { | ||||||
|  |     switch (item) { | ||||||
|  |         // Rescale the APC mode actuation thresholds
 | ||||||
|  |         case 0: | ||||||
|  |             for (uint8_t row = 0; row < MATRIX_ROWS; row++) { | ||||||
|  |                 for (uint8_t col = 0; col < MATRIX_COLS; col++) { | ||||||
|  |                     ec_config.rescaled_mode_0_actuation_threshold[row][col] = rescale(ec_config.mode_0_actuation_threshold, 0, 1023, ec_config.noise_floor[row][col], eeprom_ec_config.bottoming_reading[row][col]); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             break; | ||||||
|  |         // Rescale the APC mode release thresholds
 | ||||||
|  |         case 1: | ||||||
|  |             for (uint8_t row = 0; row < MATRIX_ROWS; row++) { | ||||||
|  |                 for (uint8_t col = 0; col < MATRIX_COLS; col++) { | ||||||
|  |                     ec_config.rescaled_mode_0_release_threshold[row][col] = rescale(ec_config.mode_0_release_threshold, 0, 1023, ec_config.noise_floor[row][col], eeprom_ec_config.bottoming_reading[row][col]); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             break; | ||||||
|  |         // Rescale the Rapid Trigger mode initial deadzone offsets
 | ||||||
|  |         case 2: | ||||||
|  |             for (uint8_t row = 0; row < MATRIX_ROWS; row++) { | ||||||
|  |                 for (uint8_t col = 0; col < MATRIX_COLS; col++) { | ||||||
|  |                     ec_config.rescaled_mode_1_initial_deadzone_offset[row][col] = rescale(ec_config.mode_1_initial_deadzone_offset, 0, 1023, ec_config.noise_floor[row][col], eeprom_ec_config.bottoming_reading[row][col]); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             break; | ||||||
|  | 
 | ||||||
|  |         default: | ||||||
|  |             // Unhandled item.
 | ||||||
|  |             break; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void ec_save_threshold_data(uint8_t option) { | ||||||
|  |     // Save APC mode thresholds and rescale them for runtime usage
 | ||||||
|  |     if (option == 0) { | ||||||
|  |         eeprom_ec_config.mode_0_actuation_threshold = ec_config.mode_0_actuation_threshold; | ||||||
|  |         eeprom_ec_config.mode_0_release_threshold   = ec_config.mode_0_release_threshold; | ||||||
|  |         ec_rescale_values(0); | ||||||
|  |         ec_rescale_values(1); | ||||||
|  |     } | ||||||
|  |     // Save Rapid Trigger mode thresholds and rescale them for runtime usage
 | ||||||
|  |     else if (option == 1) { | ||||||
|  |         eeprom_ec_config.mode_1_initial_deadzone_offset = ec_config.mode_1_initial_deadzone_offset; | ||||||
|  |         ec_rescale_values(2); | ||||||
|  |     } | ||||||
|  |     eeconfig_update_kb_datablock(&eeprom_ec_config); | ||||||
|  |     uprintf("####################################\n"); | ||||||
|  |     uprintf("# New thresholds applied and saved #\n"); | ||||||
|  |     uprintf("####################################\n"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Save the bottoming reading
 | ||||||
|  | void ec_save_bottoming_reading(void) { | ||||||
|  |     for (uint8_t row = 0; row < MATRIX_ROWS; row++) { | ||||||
|  |         for (uint8_t col = 0; col < MATRIX_COLS; col++) { | ||||||
|  |             // If the bottom reading doesn't go over the noise floor by 100, it is likely that:
 | ||||||
|  |             // 1. The key is not actually in the matrix
 | ||||||
|  |             // 2. The key is on an alternative layout, therefore not being pressed
 | ||||||
|  |             // 3. The key in in the current layout but not being pressed
 | ||||||
|  |             if (ec_config.bottoming_reading[row][col] < (ec_config.noise_floor[row][col] + 100)) { | ||||||
|  |                 eeprom_ec_config.bottoming_reading[row][col] = 1023; | ||||||
|  |             } else { | ||||||
|  |                 eeprom_ec_config.bottoming_reading[row][col] = ec_config.bottoming_reading[row][col]; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     // Rescale the values to fit the new range for runtime usage
 | ||||||
|  |     ec_rescale_values(0); | ||||||
|  |     ec_rescale_values(1); | ||||||
|  |     ec_rescale_values(2); | ||||||
|  |     eeconfig_update_kb_datablock(&eeprom_ec_config); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Show the calibration data
 | ||||||
|  | void ec_show_calibration_data(void) { | ||||||
|  |     uprintf("\n###############\n"); | ||||||
|  |     uprintf("# Noise Floor #\n"); | ||||||
|  |     uprintf("###############\n"); | ||||||
|  |     for (uint8_t row = 0; row < MATRIX_ROWS; row++) { | ||||||
|  |         for (uint8_t col = 0; col < MATRIX_COLS - 1; col++) { | ||||||
|  |             uprintf("%4d,", ec_config.noise_floor[row][col]); | ||||||
|  |         } | ||||||
|  |         uprintf("%4d\n", ec_config.noise_floor[row][MATRIX_COLS - 1]); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     uprintf("\n######################\n"); | ||||||
|  |     uprintf("# Bottoming Readings #\n"); | ||||||
|  |     uprintf("######################\n"); | ||||||
|  |     for (uint8_t row = 0; row < MATRIX_ROWS; row++) { | ||||||
|  |         for (uint8_t col = 0; col < MATRIX_COLS - 1; col++) { | ||||||
|  |             uprintf("%4d,", eeprom_ec_config.bottoming_reading[row][col]); | ||||||
|  |         } | ||||||
|  |         uprintf("%4d\n", eeprom_ec_config.bottoming_reading[row][MATRIX_COLS - 1]); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     uprintf("\n######################################\n"); | ||||||
|  |     uprintf("# Rescaled APC Mode Actuation Points #\n"); | ||||||
|  |     uprintf("######################################\n"); | ||||||
|  |     uprintf("Original APC Mode Actuation Point: %4d\n", ec_config.mode_0_actuation_threshold); | ||||||
|  |     for (uint8_t row = 0; row < MATRIX_ROWS; row++) { | ||||||
|  |         for (uint8_t col = 0; col < MATRIX_COLS - 1; col++) { | ||||||
|  |             uprintf("%4d,", ec_config.rescaled_mode_0_actuation_threshold[row][col]); | ||||||
|  |         } | ||||||
|  |         uprintf("%4d\n", ec_config.rescaled_mode_0_actuation_threshold[row][MATRIX_COLS - 1]); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     uprintf("\n######################################\n"); | ||||||
|  |     uprintf("# Rescaled APC Mode Release Points   #\n"); | ||||||
|  |     uprintf("######################################\n"); | ||||||
|  |     uprintf("Original APC Mode Release Point: %4d\n", ec_config.mode_0_release_threshold); | ||||||
|  |     for (uint8_t row = 0; row < MATRIX_ROWS; row++) { | ||||||
|  |         for (uint8_t col = 0; col < MATRIX_COLS - 1; col++) { | ||||||
|  |             uprintf("%4d,", ec_config.rescaled_mode_0_release_threshold[row][col]); | ||||||
|  |         } | ||||||
|  |         uprintf("%4d\n", ec_config.rescaled_mode_0_release_threshold[row][MATRIX_COLS - 1]); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     uprintf("\n#######################################################\n"); | ||||||
|  |     uprintf("# Rescaled Rapid Trigger Mode Initial Deadzone Offset #\n"); | ||||||
|  |     uprintf("#######################################################\n"); | ||||||
|  |     uprintf("Original Rapid Trigger Mode Initial Deadzone Offset: %4d\n", ec_config.mode_1_initial_deadzone_offset); | ||||||
|  |     for (uint8_t row = 0; row < MATRIX_ROWS; row++) { | ||||||
|  |         for (uint8_t col = 0; col < MATRIX_COLS - 1; col++) { | ||||||
|  |             uprintf("%4d,", ec_config.rescaled_mode_1_initial_deadzone_offset[row][col]); | ||||||
|  |         } | ||||||
|  |         uprintf("%4d\n", ec_config.rescaled_mode_1_initial_deadzone_offset[row][MATRIX_COLS - 1]); | ||||||
|  |     } | ||||||
|  |     print("\n"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Clear the calibration data
 | ||||||
|  | void ec_clear_bottoming_calibration_data(void) { | ||||||
|  |     // Clear the EEPROM data
 | ||||||
|  |     eeconfig_init_kb(); | ||||||
|  | 
 | ||||||
|  |     // Reset the runtime values to the EEPROM values
 | ||||||
|  |     keyboard_post_init_kb(); | ||||||
|  | 
 | ||||||
|  |     uprintf("######################################\n"); | ||||||
|  |     uprintf("# Bottoming calibration data cleared #\n"); | ||||||
|  |     uprintf("######################################\n"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #endif // VIA_ENABLE
 | ||||||
							
								
								
									
										42
									
								
								keyboards/cipulot/ec_typek/matrix.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								keyboards/cipulot/ec_typek/matrix.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,42 @@ | |||||||
|  | /* Copyright 2023 Cipulot
 | ||||||
|  |  * | ||||||
|  |  * 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 3 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 "ec_switch_matrix.h" | ||||||
|  | #include "matrix.h" | ||||||
|  | 
 | ||||||
|  | extern matrix_row_t raw_matrix[MATRIX_ROWS]; // raw values
 | ||||||
|  | extern matrix_row_t matrix[MATRIX_ROWS];     // debounced values
 | ||||||
|  | 
 | ||||||
|  | // Custom matrix init function
 | ||||||
|  | void matrix_init_custom(void) { | ||||||
|  |     // Initialize EC
 | ||||||
|  |     ec_init(); | ||||||
|  | 
 | ||||||
|  |     // Get the noise floor at boot
 | ||||||
|  |     ec_noise_floor(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Custom matrix scan function
 | ||||||
|  | bool matrix_scan_custom(matrix_row_t current_matrix[]) { | ||||||
|  |     bool updated = ec_matrix_scan(current_matrix); | ||||||
|  | 
 | ||||||
|  |     return updated; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Bootmagic overriden to avoid conflicts with EC
 | ||||||
|  | void bootmagic_scan(void) { | ||||||
|  |     ; | ||||||
|  | } | ||||||
							
								
								
									
										28
									
								
								keyboards/cipulot/ec_typek/mcuconf.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								keyboards/cipulot/ec_typek/mcuconf.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,28 @@ | |||||||
|  | /* Copyright 2023 Cipulot
 | ||||||
|  |  * | ||||||
|  |  * 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 3 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/>.
 | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include_next <mcuconf.h> | ||||||
|  | 
 | ||||||
|  | #undef STM32_ADC_USE_ADC1 | ||||||
|  | #define STM32_ADC_USE_ADC1 TRUE | ||||||
|  | 
 | ||||||
|  | #undef STM32_PWM_USE_ADVANCED | ||||||
|  | #define STM32_PWM_USE_ADVANCED TRUE | ||||||
|  | 
 | ||||||
|  | #undef STM32_PWM_USE_TIM1 | ||||||
|  | #define STM32_PWM_USE_TIM1 TRUE | ||||||
							
								
								
									
										26
									
								
								keyboards/cipulot/ec_typek/readme.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								keyboards/cipulot/ec_typek/readme.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,26 @@ | |||||||
|  | # EC Type-K | ||||||
|  | 
 | ||||||
|  |  | ||||||
|  | 
 | ||||||
|  | EC Type-K Keyboard by gok. | ||||||
|  | 
 | ||||||
|  | * Keyboard Maintainer: [cipulot](https://github.com/cipulot) | ||||||
|  | * Hardware Supported: EC Type-K | ||||||
|  | * Hardware Availability: [gok](https://www.gok.design/) | ||||||
|  | 
 | ||||||
|  | Make example for this keyboard (after setting up your build environment): | ||||||
|  | 
 | ||||||
|  |     make cipulot/ec_typek:default | ||||||
|  | 
 | ||||||
|  | Flashing example for this keyboard: | ||||||
|  | 
 | ||||||
|  |     make cipulot/ec_typek:default:flash | ||||||
|  | 
 | ||||||
|  | See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs). | ||||||
|  | 
 | ||||||
|  | ## Bootloader | ||||||
|  | 
 | ||||||
|  | Enter the bootloader in 2 ways: | ||||||
|  | 
 | ||||||
|  | * **Physical Boot0 pins**: Short the Boot0 pins on the back of the PCB while plugging in the keyboard | ||||||
|  | * **Keycode in layout**: Press the key mapped to `QK_BOOT` if it is available | ||||||
							
								
								
									
										4
									
								
								keyboards/cipulot/ec_typek/rules.mk
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								keyboards/cipulot/ec_typek/rules.mk
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,4 @@ | |||||||
|  | CUSTOM_MATRIX = lite | ||||||
|  | ANALOG_DRIVER_REQUIRED = yes | ||||||
|  | SRC += matrix.c ec_switch_matrix.c | ||||||
|  | OPT = 2 | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 QMK Bot
						QMK Bot