|
Simone: a game of visual memory and speed
|
Header for the portable functions to interact with the HW of the keyboards. The functions must be implemented in the platform-specific code. More...
#include <stdint.h>#include <stdbool.h>Macros | |
| #define | PORT_KEYBOARD_MAIN_ID |
| #define | PORT_KEYBOARDS_TIMEOUT_MS |
| #define | PORT_KEYBOARD_MAIN_DEBOUNCE_TIME_MS |
Enumerations | |
| enum | PORT_KEYBOARD_COL_IDS { PORT_KEYBOARD_COL_0, PORT_KEYBOARD_COL_1, PORT_KEYBOARD_COL_2, PORT_KEYBOARD_COL_3 } |
| Enumeration to define the columns indexes of the keyboard. This enumeration is used to identify the columns when handling the interrupts. More... | |
Functions | |
| void | port_keyboard_init (uint8_t keyboard_id) |
| Configure the HW specifications of a given keyboard. More... | |
| void | port_keyboard_excite_row (uint8_t keyboard_id, uint8_t row_idx) |
| Set the given row to high and lower the others. More... | |
| void | port_keyboard_start_scan (uint8_t keyboard_id) |
| Start the scanning of a keyboard. More... | |
| void | port_keyboard_stop_scan (uint8_t keyboard_id) |
| Stop the scanning of a keyboard. More... | |
| void | port_keyboard_excite_next_row (uint8_t keyboard_id) |
| Update the row to be excited. More... | |
| bool | port_keyboard_get_key_pressed_status (uint8_t keyboard_id) |
| Return the status of the keyboard (pressed or not). More... | |
| void | port_keyboard_set_key_pressed_status (uint8_t keyboard_id, bool status) |
| Set the status of the keyboard (pressed or not). More... | |
| bool | port_keyboard_get_row_timeout_status (uint8_t keyboard_id) |
| Return the status of the column timeout flag. More... | |
| void | port_keyboard_set_row_timeout_status (uint8_t keyboard_id, bool status) |
| Set the status of the row timeout flag. More... | |
| char | port_keyboard_get_key_value (uint8_t keyboard_id) |
| Return the char representing the key pressed of a given keyboard based on its row that is being excited. This assumes that the matrix of chars is flattened (i.e., it is not a 2D array, but all rows are in a single array), thus it is necessary to calculate only one index. More... | |
| char | port_keyboard_get_invalid_key_value (uint8_t keyboard_id) |
| Return the null key value of a given keyboard. More... | |
Header for the portable functions to interact with the HW of the keyboards. The functions must be implemented in the platform-specific code.
| #define PORT_KEYBOARD_MAIN_DEBOUNCE_TIME_MS |
Keyboard's keys debounce time in milliseconds
| #define PORT_KEYBOARD_MAIN_ID |
Keyboard identifier that represents the keyboard of the system
| #define PORT_KEYBOARDS_TIMEOUT_MS |
Keyboard scanning timeout in milliseconds
Enumeration to define the columns indexes of the keyboard. This enumeration is used to identify the columns when handling the interrupts.
| void port_keyboard_excite_next_row | ( | uint8_t | keyboard_id | ) |
Update the row to be excited.
✅ 1. Update the
current_excited_rowto move to the next row. If the index equals or greater than the number of rows indicated in the layout, move to the first row.
💡 You can use the%(modulo) operator to get the remainder of the division
✅ 2. Call the functionport_keyboard_excite_row()to excite the new row.
| keyboard_id | Keyboard ID. This index is used to get the correct keyboard status struct. |
| void port_keyboard_excite_row | ( | uint8_t | keyboard_id, |
| uint8_t | row_idx | ||
| ) |
Set the given row to high and lower the others.
TODO alumnos:
✅ 1. Retrieve the keyboard configuration struct calling
_stm32f4_keyboard_get()
✅ 2. Iterate through all the rows indexes (you can get the number of rows from the keyboard's layout) and set them to LOW to ensure that only one row is excited at the same time.
✅ 3. Set the given row to HIGH.
💡 You can use theBSRRor call thestm32f4_system_gpio_write()function.
| keyboard_id | ID of the keyboard to be scanned. |
| row_idx | Index of the row to be excited. |
| char port_keyboard_get_invalid_key_value | ( | uint8_t | keyboard_id | ) |
Return the null key value of a given keyboard.
This function retrieves the null key value defined in the keyboard layout.
TODO alumnos:
✅ 1. Retrieve and return the
null_keyfield from the keyboard layout. Call the function_stm32f4_keyboard_get()to get the keyboard struct.
| keyboard_id |
| bool port_keyboard_get_key_pressed_status | ( | uint8_t | keyboard_id | ) |
Return the status of the keyboard (pressed or not).
TODO alumnos:
✅ 1. Return the value of the field
flag_key_pressed. Call the function_stm32f4_keyboard_get()to get the keyboard struct.
| keyboard_id | Keyboard ID. This index is used to get the correct keyboard status struct. |
| char port_keyboard_get_key_value | ( | uint8_t | keyboard_id | ) |
Return the char representing the key pressed of a given keyboard based on its row that is being excited. This assumes that the matrix of chars is flattened (i.e., it is not a 2D array, but all rows are in a single array), thus it is necessary to calculate only one index.
✅ 1. Determine the value (char) of the key pressed based on the index of the current scanned row and the index of the column that provoked the interrupt, and return it.
💡 You can calculate the key index as:key index = (excited row * num columns) + column interrupting.
| keyboard_id | Keyboard ID. This index is used to get the correct keyboard status struct. |
| bool port_keyboard_get_row_timeout_status | ( | uint8_t | keyboard_id | ) |
Return the status of the column timeout flag.
TODO alumnos:
✅ 1. Return the value of the field
flag_row_timeout. Call the function_stm32f4_keyboard_get()to get the keyboard struct.
| keyboard_id | Keyboard ID. This index is used to get the correct keyboard status struct. |
| void port_keyboard_init | ( | uint8_t | keyboard_id | ) |
Configure the HW specifications of a given keyboard.
Assuming we are using an STM32F4-based platform, this function must call the following functions:
TODO alumnos:
✅ 1. Retrieve the keyboard configuration struct calling
_stm32f4_keyboard_get()
✅ 2. Call functionstm32f4_system_gpio_config()with the right arguments to configure the rows as outputs with no pull up neither pull down connections (you can get the number of rows from the keyboard's layout).
✅ 3. Call functionstm32f4_system_gpio_config()with the right arguments to configure the columns as inputs with pull down connections. Call also functionstm32f4_system_gpio_config_exti()with the right parameters to to configure interruption mode in rising and falling edges and enabling the interrupt line for each column. Finally, call functionstm32f4_system_gpio_exti_enable()with priority level to1and the subpriority level to1for all columns. All keyboards will have the same priority levels for their columns in the basic implementation. You can get the number of columns from the keyboard's layout.
✅ 4. Clean/set all the fields of the keyboard struct to their initial values. Set the value ofcurrent_excited_rowto-1to indicate that no row is being excited at the beginning.
✅ 5. Configure the timer that controls the duration of the column scanning by calling the function_timer_scan_column_config()
💡 If any of the IRQs associated with the EXTI lines of the columns coincides with other IRQs in the system, the priority levels of this IRQ will be equal to the priority levels of the other peripheral.
| keyboard_id | Keyboard ID. This index is used to select the element of the keyboards_arr[] array |
| void port_keyboard_set_key_pressed_status | ( | uint8_t | keyboard_id, |
| bool | status | ||
| ) |
Set the status of the keyboard (pressed or not).
This function is used to update the status of the keyboard when a key press is detected or cleared.
TODO alumnos:
✅ 1. Set the value of the field
flag_key_pressedto the given status. Call the function_stm32f4_keyboard_get()to get the keyboard struct.
| keyboard_id | |
| status |
| void port_keyboard_set_row_timeout_status | ( | uint8_t | keyboard_id, |
| bool | status | ||
| ) |
Set the status of the row timeout flag.
This function is used to update the status of the row timeout flag when a timeout occurs or is cleared.
TODO alumnos:
✅ 1. Set the value of the field
flag_row_timeoutto the given status. Call the function_stm32f4_keyboard_get()to get the keyboard struct.
| keyboard_id | Keyboard ID. This index is used to get the correct keyboard status struct. |
| status | New status of the row timeout flag. |
| void port_keyboard_start_scan | ( | uint8_t | keyboard_id | ) |
Start the scanning of a keyboard.
This function starts the scanning of a keyboard by enabling the timer that controls the duration of the column scanning and setting the first row to HIGH.
TODO alumnos:
✅ 1. Reset the
flag_row_timeoutto indicate that a new scan is starting.
✅ 2. Reset the counter (CNT) of the timer.
✅ 3. Set the first row to be excited to HIGH and the others to LOW. You must use the appropiate function to do it.
✅ 4. Enable the timer interrupt in the NVIC using theNVIC_EnableIRQ()function and theTIMx_IRQninterrupt. ✅ 5. Enable the counter of the timer (registerCR1of the timer) to start the column scanning.
| keyboard_id | Keyboard ID. This index is used to get the correct keyboard status struct. |
| void port_keyboard_stop_scan | ( | uint8_t | keyboard_id | ) |
Stop the scanning of a keyboard.
TODO alumnos:
✅ 1. Disable the counter of the timer (register
CR1of the timer) to stop the column scanning.
✅ 2. Disable the timer interrupt in the NVIC using theNVIC_DisableIRQ()function and theTIMx_IRQninterrupt.
✅ 3. Set all rows to LOW.
| keyboard_id | Keyboard ID. This index is used to get the correct keyboard status struct. |