matrix.c (4102B)
1 /* Copyright 2023 ArthurCyy <https://github.com/ArthurCyy> 2 * 3 * This program is free software: you can redistribute it and/or modify 4 * it under the terms of the GNU General Public License as published by 5 * the Free Software Foundation, either version 2 of the License, or 6 * (at your option) any later version. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public License 14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 15 */ 16 17 #include "matrix.h" 18 #include "wait.h" 19 #include "common/shift_register.h" 20 21 static uint8_t read_rows(void); 22 static void init_cols(void); 23 static void select_col(uint8_t col); 24 static void unselect_col(uint8_t col); 25 static void unselect_cols(void); 26 27 static const pin_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS; 28 static const pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS; 29 30 #ifdef DIP_SWITCH_PINS 31 # define NUMBER_OF_DIP_SWITCHES (sizeof(dip_switch_pad) / sizeof(pin_t)) 32 static pin_t dip_switch_pad[] = DIP_SWITCH_PINS; 33 #endif 34 35 void matrix_init_custom(void) { 36 for (uint8_t row = 0; row < MATRIX_ROWS; row++) { 37 gpio_set_pin_input_low(row_pins[row]); 38 } 39 40 shift_init(); 41 init_cols(); 42 } 43 44 bool matrix_scan_custom(matrix_row_t current_matrix[]) { 45 bool changed = false; 46 47 for (uint8_t col = 0; col < MATRIX_COLS; col++) { 48 select_col(col); 49 waitInputPinDelay(); 50 uint8_t rows = read_rows(); 51 for (uint8_t row = 0; row < MATRIX_ROWS; row++) { 52 bool prev_bit = ((uint32_t)(current_matrix[row]) & (matrix_row_t)(1UL << col)) ? 1 : 0; 53 bool curr_bit = ((uint32_t)rows & (uint32_t)(1UL << row)) ? 1 : 0; 54 if (prev_bit != curr_bit) { 55 current_matrix[row] = (uint32_t)(current_matrix[row]) ^ (uint32_t)(1UL << col); 56 changed = true; 57 } 58 } 59 unselect_col(col); 60 } 61 62 return changed; 63 } 64 65 void matrix_power_up(void) { 66 for (uint8_t row = 0; row < MATRIX_ROWS; row++) { 67 palDisableLineEvent(row_pins[row]); 68 gpio_set_pin_input_low(row_pins[row]); 69 } 70 init_cols(); 71 #ifdef DIP_SWITCH_PINS 72 for (uint8_t i = 1; i < NUMBER_OF_DIP_SWITCHES; i++) { 73 gpio_set_pin_input_high(dip_switch_pad[i]); 74 } 75 #endif 76 } 77 78 void matrix_power_down(void) { 79 unselect_cols(); 80 for (uint8_t row = 0; row < MATRIX_ROWS; row++) { 81 gpio_set_pin_input_low(row_pins[row]); 82 palEnableLineEvent(row_pins[row], PAL_EVENT_MODE_RISING_EDGE); 83 } 84 #ifdef DIP_SWITCH_PINS 85 for (uint8_t i = 1; i < NUMBER_OF_DIP_SWITCHES; i++) { 86 gpio_set_pin_input_low(dip_switch_pad[i]); 87 } 88 #endif 89 } 90 91 static uint8_t read_rows(void) { 92 uint8_t row_value = 0; 93 for(uint8_t row = 0; row < MATRIX_ROWS; row++) { 94 row_value |= (gpio_read_pin(row_pins[row]) << row); 95 } 96 return row_value; 97 } 98 99 static void init_cols(void) { 100 shift_writeAll(0); 101 for(uint8_t col = 0; col < MATRIX_COLS; col++) { 102 if(col_pins[col] < H0) { 103 gpio_set_pin_output(col_pins[col]); 104 gpio_write_pin_low(col_pins[col]); 105 } 106 } 107 } 108 109 static void select_col(uint8_t col) { 110 if(col_pins[col] < H0){ 111 gpio_write_pin_high(col_pins[col]); 112 waitInputPinDelay(); 113 waitInputPinDelay(); 114 waitInputPinDelay(); 115 waitInputPinDelay(); 116 waitInputPinDelay(); 117 waitInputPinDelay(); 118 }else{ 119 shift_writePin(col_pins[col], 1); 120 } 121 } 122 123 static void unselect_col(uint8_t col) { 124 if(col_pins[col] < H0){ 125 gpio_write_pin_low(col_pins[col]); 126 }else{ 127 shift_writePin(col_pins[col], 0); 128 } 129 } 130 131 static void unselect_cols(void) { 132 shift_writeAll(1); 133 for(uint8_t col = 0; col < MATRIX_COLS; col++) { 134 if(col_pins[col] < H0) { 135 gpio_set_pin_output(col_pins[col]); 136 gpio_write_pin_high(col_pins[col]); 137 } 138 } 139 }