aboutsummaryrefslogtreecommitdiffstats
path: root/docs/custom_matrix.md
blob: cfa900a33d3a6b53434df06ca77ec51b3de98e0a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
pre { line-height: 125%; margin: 0; }
td.linenos pre { color: #000000; background-color: #f0f0f0; padding: 0 5px 0 5px; }
span.linenos { color: #000000; background-color: #f0f0f0; padding: 0 5px 0 5px; }
td.linenos pre.special { color: #000000; background-color: #ffffc0; padding: 0 5px 0 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding: 0 5px 0 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight { background: #ffffff; }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Singl
# 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/<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_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) {}
```