matrix.c (8443B)
1 /* 2 Copyright 2019 Yiancar 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 #include <string.h> 18 #include "timer.h" 19 #include "wait.h" 20 #include "print.h" 21 #include "matrix.h" 22 #include <ch.h> 23 #include <hal.h> 24 25 static matrix_row_t matrix[MATRIX_ROWS]; 26 static matrix_row_t matrix_debouncing[MATRIX_ROWS]; 27 28 volatile uint16_t porta_buffer = 0; 29 volatile uint16_t portb_buffer = 0; 30 31 static uint32_t switch_buffer = 0; 32 33 static void pal_cb(void* unused); 34 35 static void enable_input_events(void) 36 { 37 palDisablePadEventI(GPIOA, 0); 38 palDisablePadEventI(GPIOA, 1); 39 palDisablePadEventI(GPIOA, 2); 40 palDisablePadEventI(GPIOA, 9); 41 palDisablePadEventI(GPIOA, 10); 42 palDisablePadEventI(GPIOB, 12); 43 palDisablePadEventI(GPIOB, 13); 44 palDisablePadEventI(GPIOB, 14); 45 palDisablePadEventI(GPIOB, 15); 46 47 palEnablePadEventI(GPIOA, 0, PAL_EVENT_MODE_FALLING_EDGE); 48 palEnablePadEventI(GPIOA, 1, PAL_EVENT_MODE_FALLING_EDGE); 49 palEnablePadEventI(GPIOA, 2, PAL_EVENT_MODE_FALLING_EDGE); 50 palEnablePadEventI(GPIOA, 9, PAL_EVENT_MODE_FALLING_EDGE); 51 palEnablePadEventI(GPIOA, 10, PAL_EVENT_MODE_FALLING_EDGE); 52 palEnablePadEventI(GPIOB, 12, PAL_EVENT_MODE_FALLING_EDGE); 53 palEnablePadEventI(GPIOB, 13, PAL_EVENT_MODE_FALLING_EDGE); 54 palEnablePadEventI(GPIOB, 14, PAL_EVENT_MODE_FALLING_EDGE); 55 palEnablePadEventI(GPIOB, 15, PAL_EVENT_MODE_FALLING_EDGE); 56 57 palSetPadCallbackI(GPIOA, 0, &pal_cb, 0); 58 palSetPadCallbackI(GPIOA, 1, &pal_cb, 0); 59 palSetPadCallbackI(GPIOA, 2, &pal_cb, 0); 60 palSetPadCallbackI(GPIOA, 9, &pal_cb, 0); 61 palSetPadCallbackI(GPIOA, 10, &pal_cb, 0); 62 palSetPadCallbackI(GPIOB, 12, &pal_cb, 0); 63 palSetPadCallbackI(GPIOB, 13, &pal_cb, 0); 64 palSetPadCallbackI(GPIOB, 14, &pal_cb, 0); 65 palSetPadCallbackI(GPIOB, 15, &pal_cb, 0); 66 } 67 68 // Trigger on negative edge of any of the sense lines. 69 static void pal_cb(void* unused) { 70 71 (void)unused; 72 chSysLockFromISR(); 73 porta_buffer = palReadPort(GPIOA); 74 portb_buffer = palReadPort(GPIOB); 75 //Disable further interrupts that might occur on same button press. 76 enable_input_events(); 77 chSysUnlockFromISR(); 78 } 79 80 void matrix_init(void) { 81 //Set I/O as pull-up inputs to read states 82 gpio_set_pin_input_high(A0); 83 gpio_set_pin_input_high(A1); 84 gpio_set_pin_input_high(A2); 85 gpio_set_pin_input_high(A3); 86 gpio_set_pin_input_high(A4); 87 gpio_set_pin_input_high(A5); 88 gpio_set_pin_input_high(A6); 89 gpio_set_pin_input_high(A7); 90 gpio_set_pin_input_high(A8); 91 gpio_set_pin_input_high(A9); 92 gpio_set_pin_input_high(A10); 93 gpio_set_pin_input_high(B3); 94 gpio_set_pin_input_high(B4); 95 gpio_set_pin_input_high(B5); 96 gpio_set_pin_input_high(B6); 97 gpio_set_pin_input_high(B7); 98 gpio_set_pin_input_high(B8); 99 gpio_set_pin_input_high(B9); 100 gpio_set_pin_input_high(B11); 101 gpio_set_pin_input_high(B12); 102 gpio_set_pin_input_high(B13); 103 gpio_set_pin_input_high(B14); 104 gpio_set_pin_input_high(B15); 105 106 memset(matrix, 0, MATRIX_ROWS * sizeof(matrix_row_t)); 107 memset(matrix_debouncing, 0, MATRIX_ROWS * sizeof(matrix_row_t)); 108 109 matrix_init_kb(); 110 111 osalSysLock(); 112 enable_input_events(); 113 osalSysUnlock(); 114 } 115 116 uint8_t matrix_scan(void) { 117 switch_buffer = ((uint32_t)(porta_buffer & 0x7FF)) | ((uint32_t)(portb_buffer & 0x3F8) << 8); 118 119 switch (switch_buffer) { 120 case 0x1134E: matrix[0] = 0x01; break; 121 case 0x3774D: matrix[0] = 0x02; break; 122 case 0x10BCC: matrix[0] = 0x04; break; 123 case 0x16B4B: matrix[0] = 0x08; break; 124 case 0x167CA: matrix[0] = 0x10; break; 125 case 0x35FC9: matrix[0] = 0x20; break; 126 case 0x15B48: matrix[0] = 0x40; break; 127 case 0x28347: matrix[0] = 0x80; break; 128 case 0x173C6: matrix[0] = 0x100; break; 129 case 0x143CF: matrix[0] = 0x200; break; 130 case 0x3FDC5: matrix[0] = 0x400; break; 131 case 0x3FD21: matrix[0] = 0x800; break; 132 case 0x3FD77: matrix[0] = 0x1000; break; 133 case 0x3FD72: matrix[0] = 0x2000; break; 134 //Special pin 135 case 0x3E7FA: matrix[0] = 0x8000; break; 136 case 0x183EE: matrix[0] = 0x10000; break; 137 case 0x197F3: matrix[0] = 0x20000; break; 138 case 0x1AB7E: matrix[0] = 0x40000; break; 139 140 case 0x107C3: matrix[1] = 0x01; break; 141 case 0x3FD2E: matrix[1] = 0x02; break; 142 case 0x3FD28: matrix[1] = 0x04; break; 143 case 0x3FD3A: matrix[1] = 0x08; break; 144 case 0x3FD2D: matrix[1] = 0x10; break; 145 case 0x3FD2B: matrix[1] = 0x20; break; 146 case 0x3FDA5: matrix[1] = 0x40; break; 147 case 0x3FDAA: matrix[1] = 0x80; break; 148 case 0x3FD36: matrix[1] = 0x100; break; 149 case 0x3FD30: matrix[1] = 0x200; break; 150 case 0x3FDAF: matrix[1] = 0x400; break; 151 case 0x3FD22: matrix[1] = 0x800; break; 152 case 0x157D4: matrix[1] = 0x1000; break; 153 //Does not exist in matrix 154 //Special pin 155 case 0x1C778: matrix[1] = 0x8000; break; 156 case 0x387ED: matrix[1] = 0x10000; break; 157 case 0x19B74: matrix[1] = 0x20000; break; 158 case 0x3FD7D: matrix[1] = 0x40000; break; 159 160 //Special pin 161 case 0x3FDBE: matrix[2] = 0x02; break; 162 case 0x3FDAC: matrix[2] = 0x04; break; 163 case 0x3FDBB: matrix[2] = 0x08; break; 164 case 0x3FD39: matrix[2] = 0x10; break; 165 case 0x3FDB8: matrix[2] = 0x20; break; 166 case 0x3FDB7: matrix[2] = 0x40; break; 167 case 0x3FD35: matrix[2] = 0x80; break; 168 case 0x3FDB4: matrix[2] = 0x100; break; 169 case 0x3FD33: matrix[2] = 0x200; break; 170 case 0x3FDA3: matrix[2] = 0x400; break; 171 case 0x3FD24: matrix[2] = 0x800; break; 172 case 0x0FFDB: matrix[2] = 0x1000; break; 173 case 0x3FDF5: matrix[2] = 0x2000; break; 174 case 0x3FDFF: matrix[2] = 0x4000; break; 175 case 0x3C3E4: matrix[2] = 0x8000; break; 176 case 0x38B6C: matrix[2] = 0x10000; break; 177 case 0x39FF6: matrix[2] = 0x20000; break; 178 case 0x3FDFC: matrix[2] = 0x40000; break; 179 180 //Special pin 181 case 0x3FDA6: matrix[3] = 0x02; break; 182 case 0x3FD27: matrix[3] = 0x04; break; 183 case 0x3FD3C: matrix[3] = 0x08; break; 184 case 0x3FDA9: matrix[3] = 0x10; break; 185 case 0x3FDBD: matrix[3] = 0x20; break; 186 case 0x3FDB1: matrix[3] = 0x40; break; 187 case 0x3FDB2: matrix[3] = 0x80; break; 188 case 0x30353: matrix[3] = 0x100; break; 189 case 0x37BD1: matrix[3] = 0x200; break; 190 case 0x363D2: matrix[3] = 0x400; break; 191 case 0x3FD5F: matrix[3] = 0x800; break; 192 //Does not exist in matrix 193 //Does not exist in matrix 194 //Special pin 195 case 0x1BF00: matrix[3] = 0x8000; break; 196 case 0x18FEB: matrix[3] = 0x10000; break; 197 case 0x3FF69: matrix[3] = 0x20000; break; 198 case 0x3A37B: matrix[3] = 0x40000; break; 199 default: 200 if ((portb_buffer & 0x1000) == 0) { matrix[1] = 0x4000; break; } 201 if ((portb_buffer & 0x2000) == 0) { matrix[3] = 0x4000; break; } 202 if ((portb_buffer & 0x4000) == 0) { matrix[0] = 0x4000; break; } 203 if ((portb_buffer & 0x8000) == 0) { matrix[2] = 0x01; break; } 204 matrix[0] = 0x00; 205 matrix[1] = 0x00; 206 matrix[2] = 0x00; 207 matrix[3] = 0x00; 208 } 209 //Special case for Shift 210 if (gpio_read_pin(B11) == 0) { matrix[3] |= 0x01; } 211 212 porta_buffer = 65535; 213 portb_buffer = 65535; 214 215 matrix_scan_kb(); 216 return 1; 217 } 218 219 matrix_row_t matrix_get_row(uint8_t row) 220 { 221 return matrix[row]; 222 } 223 224 void matrix_print(void) 225 { 226 227 } 228 229 __attribute__ ((weak)) 230 void matrix_init_kb(void) { 231 matrix_init_user(); 232 } 233 234 __attribute__ ((weak)) 235 void matrix_scan_kb(void) { 236 matrix_scan_user(); 237 } 238 239 __attribute__ ((weak)) 240 void matrix_init_user(void) { 241 } 242 243 __attribute__ ((weak)) 244 void matrix_scan_user(void) { 245 } 246