matrix.c (3663B)
1 // Copyright 2023 David Hoelscher (@customMK) 2 // SPDX-License-Identifier: GPL-2.0-or-later 3 #include "matrix.h" 4 #include <string.h> 5 6 // Pin definitions 7 static const pin_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS; 8 9 void matrix_wait_for_pin(pin_t pin, uint8_t target_state) { 10 rtcnt_t start = chSysGetRealtimeCounterX(); 11 rtcnt_t end = start + 5000; 12 while (chSysIsCounterWithinX(chSysGetRealtimeCounterX(), start, end)) { 13 if (gpio_read_pin(pin) == target_state) { 14 break; 15 } 16 } 17 } 18 19 void matrix_wait_for_port(stm32_gpio_t *port, uint32_t target_bitmask) { 20 rtcnt_t start = chSysGetRealtimeCounterX(); 21 rtcnt_t end = start + 5000; 22 while (chSysIsCounterWithinX(chSysGetRealtimeCounterX(), start, end)) { 23 if ((palReadPort(port) & target_bitmask) == target_bitmask) { 24 break; 25 } 26 } 27 } 28 29 void shift_pulse_clock(void) { 30 gpio_write_pin_high(COL_SHIFT_CLK_PIN); 31 matrix_wait_for_pin(COL_SHIFT_CLK_PIN, 1); 32 gpio_write_pin_low(COL_SHIFT_CLK_PIN); 33 } 34 35 void matrix_init_custom(void) { 36 //set all row pins as input with pullups 37 for (int i = 0; i < MATRIX_ROWS; ++i) { 38 gpio_write_pin_high(row_pins[i]); 39 gpio_set_pin_input_high(row_pins[i]); 40 } 41 42 //set all column pins high in ROW2COL matrix 43 gpio_set_pin_output(COL_SHIFT_IN_PIN); 44 gpio_set_pin_output(COL_SHIFT_CLK_PIN); 45 gpio_write_pin_high(COL_SHIFT_IN_PIN); 46 matrix_wait_for_pin(COL_SHIFT_IN_PIN, 1); 47 48 for (int i = 0; i < MATRIX_COLS; ++i) { 49 shift_pulse_clock(); 50 } 51 52 } 53 54 bool matrix_scan_custom(matrix_row_t current_matrix[]) { 55 static matrix_row_t temp_matrix[MATRIX_ROWS] = {0}; 56 57 gpio_write_pin_low(COL_SHIFT_IN_PIN); 58 matrix_wait_for_pin(COL_SHIFT_IN_PIN, 0); 59 60 // Setup the output column pin 61 shift_pulse_clock(); 62 63 gpio_write_pin_high(COL_SHIFT_IN_PIN); 64 for (int current_col = 0; current_col < MATRIX_COLS; ++current_col) { 65 66 // Read the column ports 67 uint32_t gpio_a = palReadPort(GPIOA); 68 uint32_t gpio_b = palReadPort(GPIOB); 69 70 // row 0, pin A8 71 int current_row = 0; 72 if ((gpio_a & (1 << 8)) >> 8) { 73 temp_matrix[current_row] &= ~(1ul << current_col); 74 } else { 75 temp_matrix[current_row] |= (1ul << current_col); 76 } 77 // row 1, pin A1 78 current_row = 1; 79 if ((gpio_a & (1 << 1)) >> 1) { 80 temp_matrix[current_row] &= ~(1ul << current_col); 81 } else { 82 temp_matrix[current_row] |= (1ul << current_col); 83 } 84 // row 2, pin A2 85 current_row = 2; 86 if ((gpio_a & (1 << 2)) >> 2) { 87 temp_matrix[current_row] &= ~(1ul << current_col); 88 } else { 89 temp_matrix[current_row] |= (1ul << current_col); 90 } 91 // row 3, pin B3 92 current_row = 3; 93 if ((gpio_b & (1 << 1)) >> 1) { 94 temp_matrix[current_row] &= ~(1ul << current_col); 95 } else { 96 temp_matrix[current_row] |= (1ul << current_col); 97 } 98 // row 4, pin A7 99 current_row = 4; 100 if ((gpio_a & (1 << 7)) >> 7) { 101 temp_matrix[current_row] &= ~(1ul << current_col); 102 } else { 103 temp_matrix[current_row] |= (1ul << current_col); 104 } 105 106 // Setup the output column pin 107 shift_pulse_clock(); 108 109 } 110 111 // Check if matrix has changed, return the last-read data 112 bool changed = memcmp(current_matrix, temp_matrix, sizeof(temp_matrix)) != 0; 113 if (changed) { 114 memcpy(current_matrix, temp_matrix, sizeof(temp_matrix)); 115 } 116 shift_pulse_clock(); 117 return changed; 118 }