diff options
Diffstat (limited to 'keyboards/massdrop/ctrl/matrix.c')
| -rw-r--r-- | keyboards/massdrop/ctrl/matrix.c | 182 |
1 files changed, 182 insertions, 0 deletions
diff --git a/keyboards/massdrop/ctrl/matrix.c b/keyboards/massdrop/ctrl/matrix.c new file mode 100644 index 000000000..6f306962e --- /dev/null +++ b/keyboards/massdrop/ctrl/matrix.c | |||
| @@ -0,0 +1,182 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2018 Massdrop Inc. | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #include "ctrl.h" | ||
| 19 | |||
| 20 | #include "d51_util.h" | ||
| 21 | #include "debug.h" | ||
| 22 | #include "clks.h" | ||
| 23 | #include <string.h> | ||
| 24 | |||
| 25 | matrix_row_t mlatest[MATRIX_ROWS]; | ||
| 26 | matrix_row_t mlast[MATRIX_ROWS]; | ||
| 27 | matrix_row_t mdebounced[MATRIX_ROWS]; | ||
| 28 | |||
| 29 | uint8_t row_ports[] = { MATRIX_ROW_PORTS }; | ||
| 30 | uint8_t row_pins[] = { MATRIX_ROW_PINS }; | ||
| 31 | uint8_t col_ports[] = { MATRIX_COL_PORTS }; | ||
| 32 | uint8_t col_pins[] = { MATRIX_COL_PINS }; | ||
| 33 | uint32_t row_masks[2]; //NOTE: If more than PA PB used in the future, adjust code to accomodate | ||
| 34 | |||
| 35 | __attribute__ ((weak)) | ||
| 36 | void matrix_init_kb(void) { | ||
| 37 | matrix_init_user(); | ||
| 38 | } | ||
| 39 | |||
| 40 | __attribute__ ((weak)) | ||
| 41 | void matrix_scan_kb(void) { | ||
| 42 | matrix_scan_user(); | ||
| 43 | } | ||
| 44 | |||
| 45 | __attribute__ ((weak)) | ||
| 46 | void matrix_init_user(void) { | ||
| 47 | } | ||
| 48 | |||
| 49 | __attribute__ ((weak)) | ||
| 50 | void matrix_scan_user(void) { | ||
| 51 | } | ||
| 52 | |||
| 53 | void matrix_init(void) | ||
| 54 | { | ||
| 55 | memset(mlatest, 0, MATRIX_ROWS * sizeof(matrix_row_t)); | ||
| 56 | memset(mlast, 0, MATRIX_ROWS * sizeof(matrix_row_t)); | ||
| 57 | memset(mdebounced, 0, MATRIX_ROWS * sizeof(matrix_row_t)); | ||
| 58 | |||
| 59 | row_masks[PA] = 0; | ||
| 60 | row_masks[PB] = 0; | ||
| 61 | |||
| 62 | uint8_t row; | ||
| 63 | for (row = 0; row < MATRIX_ROWS; row++) | ||
| 64 | { | ||
| 65 | PORT->Group[row_ports[row]].DIRCLR.reg = 1 << row_pins[row]; //Input | ||
| 66 | PORT->Group[row_ports[row]].OUTCLR.reg = 1 << row_pins[row]; //Low | ||
| 67 | PORT->Group[row_ports[row]].PINCFG[row_pins[row]].bit.INEN = 1; //Input Enable, | ||
| 68 | PORT->Group[row_ports[row]].PINCFG[row_pins[row]].bit.PULLEN = 1; //Pull Enable | ||
| 69 | row_masks[row_ports[row]] |= 1 << row_pins[row]; //Add pin to proper row mask | ||
| 70 | } | ||
| 71 | |||
| 72 | uint8_t col; | ||
| 73 | for (col = 0; col < MATRIX_COLS; col++) | ||
| 74 | { | ||
| 75 | PORT->Group[col_ports[col]].DIRSET.reg = 1 << col_pins[col]; //Output | ||
| 76 | PORT->Group[col_ports[col]].OUTCLR.reg = 1 << col_pins[col]; //Low | ||
| 77 | } | ||
| 78 | |||
| 79 | matrix_init_quantum(); | ||
| 80 | } | ||
| 81 | |||
| 82 | #define MATRIX_SCAN_DELAY 10 //Delay after setting a col to output (in us) | ||
| 83 | |||
| 84 | uint64_t mdebouncing = 0; | ||
| 85 | uint8_t matrix_scan(void) | ||
| 86 | { | ||
| 87 | uint8_t mchanged; | ||
| 88 | uint8_t row; | ||
| 89 | uint8_t col; | ||
| 90 | uint32_t scans[2]; //PA PB | ||
| 91 | |||
| 92 | if (CLK_get_ms() < mdebouncing) return 1; //mdebouncing == 0 when no debouncing active | ||
| 93 | |||
| 94 | //m15_off; //Profiling scans | ||
| 95 | |||
| 96 | memset(mlatest, 0, MATRIX_ROWS * sizeof(matrix_row_t)); //Zero the result buffer | ||
| 97 | |||
| 98 | for (col = 0; col < MATRIX_COLS; col++) | ||
| 99 | { | ||
| 100 | PORT->Group[col_ports[col]].OUTSET.reg = 1 << col_pins[col]; //Set col output | ||
| 101 | |||
| 102 | CLK_delay_us(MATRIX_SCAN_DELAY); //Delay for output | ||
| 103 | |||
| 104 | scans[PA] = PORT->Group[PA].IN.reg & row_masks[PA]; //Read PA row pins data | ||
| 105 | scans[PB] = PORT->Group[PB].IN.reg & row_masks[PB]; //Read PB row pins data | ||
| 106 | |||
| 107 | PORT->Group[col_ports[col]].OUTCLR.reg = 1 << col_pins[col]; //Clear col output | ||
| 108 | |||
| 109 | for (row = 0; row < MATRIX_ROWS; row++) | ||
| 110 | { | ||
| 111 | //Move scan bits from scans array into proper row bit locations | ||
| 112 | if (scans[row_ports[row]] & (1 << row_pins[row])) | ||
| 113 | mlatest[row] |= 1 << col; | ||
| 114 | } | ||
| 115 | } | ||
| 116 | |||
| 117 | mchanged = 0; //Default to no matrix change since last | ||
| 118 | |||
| 119 | for (row = 0; row < MATRIX_ROWS; row++) | ||
| 120 | { | ||
| 121 | if (mlast[row] != mlatest[row]) | ||
| 122 | mchanged = 1; | ||
| 123 | mlast[row] = mlatest[row]; | ||
| 124 | } | ||
| 125 | |||
| 126 | if (!mchanged) | ||
| 127 | { | ||
| 128 | for (row = 0; row < MATRIX_ROWS; row++) | ||
| 129 | mdebounced[row] = mlatest[row]; | ||
| 130 | mdebouncing = 0; | ||
| 131 | } | ||
| 132 | else | ||
| 133 | { | ||
| 134 | //Begin or extend debounce on change | ||
| 135 | mdebouncing = CLK_get_ms() + DEBOUNCING_DELAY; | ||
| 136 | } | ||
| 137 | |||
| 138 | //m15_on; //Profiling scans | ||
| 139 | |||
| 140 | matrix_scan_quantum(); | ||
| 141 | |||
| 142 | return 1; | ||
| 143 | } | ||
| 144 | |||
| 145 | matrix_row_t matrix_get_row(uint8_t row) | ||
| 146 | { | ||
| 147 | return mdebounced[row]; | ||
| 148 | } | ||
| 149 | |||
| 150 | void matrix_print(void) | ||
| 151 | { | ||
| 152 | char buf[(MATRIX_COLS+8)*(MATRIX_ROWS+1)] = "R C"; | ||
| 153 | char *pbuf = buf+3; | ||
| 154 | uint32_t cols; | ||
| 155 | uint32_t rows; | ||
| 156 | matrix_row_t row; | ||
| 157 | |||
| 158 | for (cols = 1; cols <= MATRIX_COLS; cols++) | ||
| 159 | { | ||
| 160 | *pbuf = (cols%10)+48; | ||
| 161 | pbuf++; | ||
| 162 | } | ||
| 163 | *pbuf = '\r'; pbuf++; | ||
| 164 | *pbuf = '\n'; pbuf++; | ||
| 165 | |||
| 166 | for (rows = 1; rows <= MATRIX_ROWS; rows++) | ||
| 167 | { | ||
| 168 | row = matrix_get_row(rows-1); | ||
| 169 | if (rows < 10) { *pbuf = rows+48; pbuf++; *pbuf = ' '; pbuf++; *pbuf = ' '; pbuf++; } | ||
| 170 | else { *pbuf = (rows/10)+48; pbuf++; *pbuf = (rows%10)+48; pbuf++; *pbuf = ' '; pbuf++; } | ||
| 171 | for (cols = 0; cols < MATRIX_COLS; cols++) | ||
| 172 | { | ||
| 173 | if (row & 1 << cols) *pbuf = 'X'; | ||
| 174 | else *pbuf = '.'; | ||
| 175 | pbuf++; | ||
| 176 | } | ||
| 177 | *pbuf = '\r'; pbuf++; | ||
| 178 | *pbuf = '\n'; pbuf++; | ||
| 179 | } | ||
| 180 | *pbuf = 0; | ||
| 181 | dprint(buf); | ||
| 182 | } | ||
