mirror of
				https://github.com/mfulz/qmk_firmware.git
				synced 2025-10-31 05:12:33 +01:00 
			
		
		
		
	Add SN74x154 driver and convert AL1 custom matrix (#16331)
This commit is contained in:
		
							parent
							
								
									588abd24b5
								
							
						
					
					
						commit
						2d9c3f9a89
					
				
							
								
								
									
										58
									
								
								drivers/gpio/sn74x154.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								drivers/gpio/sn74x154.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,58 @@ | |||||||
|  | /* Copyright 2022
 | ||||||
|  |  * | ||||||
|  |  * This program is free software: you can redistribute it and/or modify | ||||||
|  |  * it under the terms of the GNU General Public License as published by | ||||||
|  |  * the Free Software Foundation, either version 2 of the License, or | ||||||
|  |  * (at your option) any later version. | ||||||
|  |  * | ||||||
|  |  * This program is distributed in the hope that it will be useful, | ||||||
|  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |  * GNU General Public License for more details. | ||||||
|  |  * | ||||||
|  |  * You should have received a copy of the GNU General Public License | ||||||
|  |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #include "sn74x154.h" | ||||||
|  | #include "gpio.h" | ||||||
|  | 
 | ||||||
|  | #define ADDRESS_PIN_COUNT 4 | ||||||
|  | 
 | ||||||
|  | #ifndef SN74X154_ADDRESS_PINS | ||||||
|  | #    error sn74x154: no address pins defined! | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | static const pin_t address_pins[ADDRESS_PIN_COUNT] = SN74X154_ADDRESS_PINS; | ||||||
|  | 
 | ||||||
|  | void sn74x154_init(void) { | ||||||
|  |     for (int i = 0; i < ADDRESS_PIN_COUNT; i++) { | ||||||
|  |         setPinOutput(address_pins[i]); | ||||||
|  |         writePinLow(address_pins[i]); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | #if defined(SN74X154_E0_PIN) | ||||||
|  |     setPinOutput(SN74X154_E0_PIN); | ||||||
|  |     writePinHigh(SN74X154_E0_PIN); | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #if defined(SN74X154_E1_PIN) | ||||||
|  |     setPinOutput(SN74X154_E1_PIN); | ||||||
|  |     writePinHigh(SN74X154_E1_PIN); | ||||||
|  | #endif | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void sn74x154_set_enabled(bool enabled) { | ||||||
|  | #if defined(SN74X154_E0_PIN) | ||||||
|  |     writePin(SN74X154_E0_PIN, !enabled); | ||||||
|  | #endif | ||||||
|  | #if defined(SN74X154_E1_PIN) | ||||||
|  |     writePin(SN74X154_E1_PIN, !enabled); | ||||||
|  | #endif | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void sn74x154_set_addr(uint8_t address) { | ||||||
|  |     for (int i = 0; i < ADDRESS_PIN_COUNT; i++) { | ||||||
|  |         writePin(address_pins[i], address & (1 << i)); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										48
									
								
								drivers/gpio/sn74x154.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								drivers/gpio/sn74x154.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,48 @@ | |||||||
|  | /* Copyright 2022
 | ||||||
|  |  * | ||||||
|  |  * This program is free software: you can redistribute it and/or modify | ||||||
|  |  * it under the terms of the GNU General Public License as published by | ||||||
|  |  * the Free Software Foundation, either version 2 of the License, or | ||||||
|  |  * (at your option) any later version. | ||||||
|  |  * | ||||||
|  |  * This program is distributed in the hope that it will be useful, | ||||||
|  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |  * GNU General Public License for more details. | ||||||
|  |  * | ||||||
|  |  * You should have received a copy of the GNU General Public License | ||||||
|  |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include <stdint.h> | ||||||
|  | #include <stdbool.h> | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Driver for 74x154 4-to-16 decoder/demultiplexer with inverting outputs | ||||||
|  |  * https://assets.nexperia.com/documents/data-sheet/74HC_HCT154.pdf
 | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Initialize the address and output enable pins. | ||||||
|  |  */ | ||||||
|  | void sn74x154_init(void); | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Set the enabled state. | ||||||
|  |  * | ||||||
|  |  * When enabled is true, pulls the E0 and E1 pins low. | ||||||
|  |  * | ||||||
|  |  * \param enabled The enable state to set. | ||||||
|  |  */ | ||||||
|  | void sn74x154_set_enabled(bool enabled); | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Set the output pin address. | ||||||
|  |  * | ||||||
|  |  * The selected output pin will be pulled low, while the remaining output pins will be high. | ||||||
|  |  * | ||||||
|  |  * \param address The address to set, from 0 to 15. | ||||||
|  |  */ | ||||||
|  | void sn74x154_set_addr(uint8_t address); | ||||||
| @ -30,6 +30,11 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>. | |||||||
| #define MATRIX_ROWS 6 | #define MATRIX_ROWS 6 | ||||||
| #define MATRIX_COLS 16 | #define MATRIX_COLS 16 | ||||||
| 
 | 
 | ||||||
|  | #define MATRIX_ROW_PINS { C7, B1, B2, C6, B4, B5 } | ||||||
|  | 
 | ||||||
|  | #define SN74X154_ADDRESS_PINS { D4, D5, D6, D7 } | ||||||
|  | #define SN74X154_E1_PIN D3 | ||||||
|  | 
 | ||||||
| #define LED_NUM_LOCK_PIN D0 | #define LED_NUM_LOCK_PIN D0 | ||||||
| #define LED_CAPS_LOCK_PIN B7 | #define LED_CAPS_LOCK_PIN B7 | ||||||
| #define LED_SCROLL_LOCK_PIN D1 | #define LED_SCROLL_LOCK_PIN D1 | ||||||
|  | |||||||
| @ -1,91 +1,101 @@ | |||||||
|  | /* Copyright 2022
 | ||||||
|  |  * | ||||||
|  |  * This program is free software: you can redistribute it and/or modify | ||||||
|  |  * it under the terms of the GNU General Public License as published by | ||||||
|  |  * the Free Software Foundation, either version 2 of the License, or | ||||||
|  |  * (at your option) any later version. | ||||||
|  |  * | ||||||
|  |  * This program is distributed in the hope that it will be useful, | ||||||
|  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |  * GNU General Public License for more details. | ||||||
|  |  * | ||||||
|  |  * You should have received a copy of the GNU General Public License | ||||||
|  |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
| #include "matrix.h" | #include "matrix.h" | ||||||
| 
 |  | ||||||
| #include "gpio.h" | #include "gpio.h" | ||||||
|  | #include "sn74x154.h" | ||||||
| 
 | 
 | ||||||
| static uint8_t read_rows(void) { | static const pin_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS; | ||||||
|     return (readPin(C7) ? 0 : 1) | |  | ||||||
|            (readPin(B1) ? 0 : 2) | |  | ||||||
|            (readPin(B2) ? 0 : 4) | |  | ||||||
|            (readPin(C6) ? 0 : 8) | |  | ||||||
|            (readPin(B4) ? 0 : 16) | |  | ||||||
|            (readPin(B5) ? 0 : 32); |  | ||||||
| } |  | ||||||
| 
 | 
 | ||||||
|  | /* All columns use a 74HC154 4-to-16 demultiplexer.
 | ||||||
|  |  * D3 is the enable pin, must be set high to use it. | ||||||
|  |  * | ||||||
|  |  *     A3   A2   A1   A0 | ||||||
|  |  *     D7   D6   D5   D4 | ||||||
|  |  * 0:   0    0    0    0 | ||||||
|  |  * 1:   0    0    0    1 | ||||||
|  |  * 2:   0    0    1    0 | ||||||
|  |  * 3:   0    0    1    1 | ||||||
|  |  * 4:   0    1    0    0 | ||||||
|  |  * 5:   0    1    0    1 | ||||||
|  |  * 6:   0    1    1    0 | ||||||
|  |  * 7:   0    1    1    1 | ||||||
|  |  * 8:   1    0    0    0 | ||||||
|  |  * 9:   1    0    0    1 | ||||||
|  |  * 10:  1    0    1    0 | ||||||
|  |  * 11:  1    0    1    1 | ||||||
|  |  * 12:  1    1    0    0 | ||||||
|  |  * 13:  1    1    0    1 | ||||||
|  |  * 14:  1    1    1    0 | ||||||
|  |  * 15:  1    1    1    1 | ||||||
|  |  */ | ||||||
| static void select_col(uint8_t col) { | static void select_col(uint8_t col) { | ||||||
|     writePinLow(D3); |     sn74x154_set_addr(col); | ||||||
| 
 |  | ||||||
|     writePin(D4, (col & 1)); |  | ||||||
|     writePin(D5, (col & 2)); |  | ||||||
|     writePin(D6, (col & 4)); |  | ||||||
|     writePin(D7, (col & 8)); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void  unselect_cols(void) { | static void init_pins(void) { | ||||||
|     writePinHigh(D3); |     for (uint8_t x = 0; x < MATRIX_ROWS; x++) { | ||||||
|  |         setPinInputHigh(row_pins[x]); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col) { | ||||||
|  |     bool matrix_changed = false; | ||||||
|  | 
 | ||||||
|  |     // Select col and wait for col seleciton to stabilize
 | ||||||
|  |     select_col(current_col); | ||||||
|  |     matrix_io_delay(); | ||||||
|  | 
 | ||||||
|  |     // For each row...
 | ||||||
|  |     for (uint8_t row_index = 0; row_index < MATRIX_ROWS; row_index++) { | ||||||
|  |         // Store last value of row prior to reading
 | ||||||
|  |         matrix_row_t last_row_value = current_matrix[row_index]; | ||||||
|  | 
 | ||||||
|  |         // Check row pin state
 | ||||||
|  |         if (readPin(row_pins[row_index]) == 0) { | ||||||
|  |             // Pin LO, set col bit
 | ||||||
|  |             current_matrix[row_index] |= (MATRIX_ROW_SHIFTER << current_col); | ||||||
|  |         } else { | ||||||
|  |             // Pin HI, clear col bit
 | ||||||
|  |             current_matrix[row_index] &= ~(MATRIX_ROW_SHIFTER << current_col); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // Determine if the matrix changed state
 | ||||||
|  |         if ((last_row_value != current_matrix[row_index]) && !(matrix_changed)) { | ||||||
|  |             matrix_changed = true; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return matrix_changed; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void matrix_init_custom(void) { | void matrix_init_custom(void) { | ||||||
|     /* 74HC154 col pin configuration
 |     // initialize demultiplexer
 | ||||||
|      * pin:     D3  D7  D6  D5  D4 |     sn74x154_init(); | ||||||
|      * row: off  0   x   x   x   x |     sn74x154_set_enabled(true); | ||||||
|      *      0    1   0   0   0   0 |     // initialize key pins
 | ||||||
|      *      1    1   0   0   0   1 |     init_pins(); | ||||||
|      *      2    1   0   0   1   0 |  | ||||||
|      *      3    1   0   0   1   1 |  | ||||||
|      *      4    1   0   1   0   0 |  | ||||||
|      *      5    1   0   1   0   1 |  | ||||||
|      *      6    1   0   1   1   0 |  | ||||||
|      *      7    1   0   1   1   1 |  | ||||||
|      *      8    1   1   0   0   0 |  | ||||||
|      *      9    1   1   0   0   1 |  | ||||||
|      *      10   1   1   0   1   0 |  | ||||||
|      *      11   1   1   0   1   1 |  | ||||||
|      *      12   1   1   1   0   0 |  | ||||||
|      *      13   1   1   1   0   1 |  | ||||||
|      *      14   1   1   1   1   0 |  | ||||||
|      *      15   1   1   1   1   1 |  | ||||||
|      */ |  | ||||||
|     setPinOutput(D3); |  | ||||||
|     writePinHigh(D3); |  | ||||||
| 
 |  | ||||||
|     setPinOutput(D4); |  | ||||||
|     setPinOutput(D5); |  | ||||||
|     setPinOutput(D6); |  | ||||||
|     setPinOutput(D7); |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|     /* Row pin configuration
 |  | ||||||
|      * |  | ||||||
|      * row:  0  1  2  3  4  5 |  | ||||||
|      * pin: C7 B1 B2 C6 B4 B5 |  | ||||||
|      * |  | ||||||
|      */ |  | ||||||
|     setPinInputHigh(C7); |  | ||||||
|     setPinInputHigh(B1); |  | ||||||
|     setPinInputHigh(B2); |  | ||||||
|     setPinInputHigh(C6); |  | ||||||
|     setPinInputHigh(B4); |  | ||||||
|     setPinInputHigh(B5); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool matrix_scan_custom(matrix_row_t current_matrix[]) { | bool matrix_scan_custom(matrix_row_t current_matrix[]) { | ||||||
|     bool changed = false; |     bool changed = false; | ||||||
| 
 | 
 | ||||||
|     for (uint8_t col = 0; col < MATRIX_COLS; col++) { |     // Set col, read rows
 | ||||||
|         select_col(col); |     for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++) { | ||||||
|         matrix_io_delay(); |         changed |= read_rows_on_col(current_matrix, current_col); | ||||||
|         uint8_t rows = read_rows(); |  | ||||||
| 
 |  | ||||||
|         for (uint8_t row = 0; row < MATRIX_ROWS; row++) { |  | ||||||
|             bool prev_bit = current_matrix[row] & ((matrix_row_t)1 << col); |  | ||||||
|             bool curr_bit = rows & (1 << row); |  | ||||||
| 
 |  | ||||||
|             if (prev_bit != curr_bit) { |  | ||||||
|                 current_matrix[row] ^= ((matrix_row_t)1 << col); |  | ||||||
|                 changed = true; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         unselect_cols(); |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     return changed; |     return changed; | ||||||
|  | |||||||
| @ -18,4 +18,5 @@ RGBLIGHT_ENABLE = no        # Enable keyboard RGB underglow | |||||||
| AUDIO_ENABLE = no           # Audio output | AUDIO_ENABLE = no           # Audio output | ||||||
| 
 | 
 | ||||||
| CUSTOM_MATRIX = lite | CUSTOM_MATRIX = lite | ||||||
| SRC += matrix.c | VPATH += drivers/gpio | ||||||
|  | SRC += matrix.c sn74x154.c | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Ryan
						Ryan