109 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			109 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| # Custom Matrix
 | |
| 
 | |
| QMK provides a mechanism to supplement or replace the default matrix scanning routine with your own code.
 | |
| 
 | |
| The reasons to use this feature include:
 | |
| 
 | |
| * Extra hardware between the keyboard's switches and MCU pins
 | |
|   * I/O multiplexer
 | |
|   * Line decoder
 | |
| * Irregular switch matrix
 | |
|   * Simultaneous use of `COL2ROW` and `ROW2COL`
 | |
| 
 | |
| ## Prerequisites
 | |
| 
 | |
| Implementing custom matrix usually involves compilation of an additional source file. It is recommended that for consistency, this file is called `matrix.c`.
 | |
| 
 | |
| Add a new file to your keyboard directory:
 | |
| ```
 | |
| keyboards/<keyboard>/matrix.c
 | |
| ```
 | |
| 
 | |
| And to configure compilation for the new file, add this to your `rules.mk`:
 | |
| ```make
 | |
| SRC += matrix.c
 | |
| ```
 | |
| 
 | |
| ## 'lite'
 | |
| 
 | |
| Provides a default implementation for various scanning functions, reducing the boilerplate code when implementing custom matrix.
 | |
| To configure it, add this to your `rules.mk`:
 | |
| 
 | |
| ```make
 | |
| CUSTOM_MATRIX = lite
 | |
| ```
 | |
| 
 | |
| And implement the following functions in a `matrix.c` file in your keyboard folder:
 | |
| 
 | |
| ```c
 | |
| void matrix_init_custom(void) {
 | |
|     // TODO: initialize hardware here
 | |
| }
 | |
| 
 | |
| bool matrix_scan_custom(matrix_row_t current_matrix[]) {
 | |
|     bool matrix_has_changed = false;
 | |
| 
 | |
|     // TODO: add matrix scanning routine here
 | |
| 
 | |
|     return matrix_has_changed;
 | |
| }
 | |
| ```
 | |
| 
 | |
| 
 | |
| ## Full Replacement
 | |
| 
 | |
| When more control over the scanning routine is required, you can choose to implement the full scanning routine.
 | |
| To configure it, add this to your rules.mk:
 | |
| 
 | |
| ```make
 | |
| CUSTOM_MATRIX = yes
 | |
| ```
 | |
| 
 | |
| And implement the following functions in a `matrix.c` file in your keyboard folder:
 | |
| 
 | |
| ```c
 | |
| matrix_row_t matrix_get_row(uint8_t row) {
 | |
|     // TODO: return the requested row data
 | |
| }
 | |
| 
 | |
| void matrix_print(void) {
 | |
|     // TODO: use print() to dump the current matrix state to console
 | |
| }
 | |
| 
 | |
| void matrix_init(void) {
 | |
|     // TODO: initialize hardware and global matrix state here
 | |
| 
 | |
|     // Unless hardware debouncing - Init the configured debounce routine
 | |
|     debounce_init(MATRIX_ROWS);
 | |
| 
 | |
|     // This *must* be called for correct keyboard behavior
 | |
|     matrix_init_kb();
 | |
| }
 | |
| 
 | |
| uint8_t matrix_scan(void) {
 | |
|     bool changed = false;
 | |
| 
 | |
|     // TODO: add matrix scanning routine here
 | |
| 
 | |
|     // Unless hardware debouncing - use the configured debounce routine
 | |
|     changed = debounce(raw_matrix, matrix, MATRIX_ROWS, changed);
 | |
| 
 | |
|     // This *must* be called for correct keyboard behavior
 | |
|     matrix_scan_kb();
 | |
| 
 | |
|     return changed;
 | |
| }
 | |
| ```
 | |
| 
 | |
| And also provide defaults for the following callbacks:
 | |
| 
 | |
| ```c
 | |
| __attribute__((weak)) void matrix_init_kb(void) { matrix_init_user(); }
 | |
| 
 | |
| __attribute__((weak)) void matrix_scan_kb(void) { matrix_scan_user(); }
 | |
| 
 | |
| __attribute__((weak)) void matrix_init_user(void) {}
 | |
| 
 | |
| __attribute__((weak)) void matrix_scan_user(void) {}
 | |
| ```
 |