I'm writing a bit of code for a keyboard. I've written this before, but it was inefficient and I figured as I was learning bare metal, I'd rewrite the code again. However, the said code wasn't working, so I've written the main in C to see what went wrong. My output pins (columns) are connected to pins PC0 - PC8 and input pins (rows) are connected to PD0 - PD6.
Initialization code:
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN | RCC_AHB1ENR_GPIODEN; GPIOC->MODER |= GPIO_MODER_MODER0_0 | GPIO_MODER_MODER1_0 | GPIO_MODER_MODER2_0 | GPIO_MODER_MODER3_0 | GPIO_MODER_MODER4_0 | GPIO_MODER_MODER5_0 | GPIO_MODER_MODER6_0 | GPIO_MODER_MODER7_0 | GPIO_MODER_MODER8_0; GPIOD->PUPDR |= GPIO_PUPDR_PUPDR0_1 | GPIO_PUPDR_PUPDR1_1 | GPIO_PUPDR_PUPDR2_1 | GPIO_PUPDR_PUPDR3_1 | GPIO_PUPDR_PUPDR4_1 | GPIO_PUPDR_PUPDR5_1 | GPIO_PUPDR_PUPDR6_1; Definitions, structures, typedefs, variables
typedef enum { KEY_UP, KEY_DOWN } keystate_t; #define NUM_COLS 9 #define NUM_ROWS 7 #define NUM_KEYS (NUM_COLS * NUM_ROWS) keystate_t key_state [NUM_KEYS] = {KEY_UP}; static const struct { GPIO_TypeDef* port ; uint16_t pin ; } keyscan_col_io[NUM_COLS] = { {GPIOC, 0}, {GPIOC, 1}, {GPIOC, 2}, {GPIOC, 3}, {GPIOC, 4}, {GPIOC, 5}, {GPIOC, 6}, {GPIOC, 7}, {GPIOC, 8} }; static const struct { GPIO_TypeDef* port ; uint16_t pin ; } keyscan_row_io[NUM_ROWS] = { {GPIOD, 0}, {GPIOD, 1}, {GPIOD, 2}, {GPIOD, 3}, {GPIOD, 4}, {GPIOD, 5}, {GPIOD, 6} }; While Loop
while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ for (int cols = 0; cols < NUM_COLS; cols++) { for (int c = 0; c < NUM_COLS; c++) { if (c == cols) HAL_GPIO_WritePin(GPIOC, keyscan_col_io[c].pin, GPIO_PIN_SET); else HAL_GPIO_WritePin(GPIOC, keyscan_col_io[c].pin, GPIO_PIN_RESET); } for (int rows = 0; rows < NUM_ROWS; rows++) { if (HAL_GPIO_ReadPin(GPIOD, keyscan_row_io[rows].pin)) key_state [rows * NUM_ROWS + cols] = KEY_DOWN; else key_state [rows * NUM_ROWS + cols] = KEY_UP; } } } Like I said, I initially tried writing the while loop section in bare metal but the code didn't work as expected, so I wrote it in HAL to see if it would.
On checking the status registers, all the bits are set as expected. I set key_state as a live expression, so that I could view the states of all the keys. However, the keys won't trigger the right variables. I checked the connections and can confirm they're connected properly. Also, on checking with the previous, program I wrote, the keys trigger the right variables and I cannot see any difference between the code.
Where am I going wrong?