diff --git a/docs/_summary.md b/docs/_summary.md index f6b03867f..de8148138 100644 --- a/docs/_summary.md +++ b/docs/_summary.md @@ -105,6 +105,7 @@ * [I2C Driver](i2c_driver.md) * [WS2812 Driver](ws2812_driver.md) * [GPIO Controls](internals_gpio_control.md) + * [Custom Matrix](custom_matrix.md) * [Proton C Conversion](proton_c_conversion.md) * For a Deeper Understanding diff --git a/docs/custom_matrix.md b/docs/custom_matrix.md new file mode 100644 index 000000000..cfa900a33 --- /dev/null +++ b/docs/custom_matrix.md @@ -0,0 +1,108 @@ +# 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: +```text +keyboards//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_quantum(); +} + +uint8_t matrix_scan(void) { + bool matrix_has_changed = false; + + // TODO: add matrix scanning routine here + + // Unless hardware debouncing - use the configured debounce routine + debounce(raw_matrix, matrix, MATRIX_ROWS, changed); + + // This *must* be called for correct keyboard behavior + matrix_scan_quantum(); + + return matrix_has_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) {} +``` diff --git a/docs/getting_started_make_guide.md b/docs/getting_started_make_guide.md index bf8d472d0..df82a001f 100644 --- a/docs/getting_started_make_guide.md +++ b/docs/getting_started_make_guide.md @@ -135,7 +135,7 @@ As there is no standard split communication driver for ARM-based split keyboards `CUSTOM_MATRIX` -Lets you replace the default matrix scanning routine with your own code. You will need to provide your own implementations of matrix_init() and matrix_scan(). +Lets you replace the default matrix scanning routine with your own code. For further details, see the [Custom Matrix page](custom_matrix.md). `DEBOUNCE_TYPE`