Simone: a game of visual memory and speed
fsm_keyboard.c File Reference

Keyboard FSM main file. More...

#include <stdlib.h>
#include <stdio.h>
#include "port_system.h"
#include "port_keyboard.h"
#include "fsm.h"
#include "fsm_keyboard.h"
#include "keyboards.h"

Functions

static bool check_row_timeout (fsm_t *p_this)
 Check if the timeout to activate a new row and scan columns has passed. More...
 
static bool check_keyboard_pressed (fsm_t *p_this)
 Check if the keyboard has been pressed. More...
 
static bool check_keyboard_released (fsm_t *p_this)
 Check if the keyboard has been released. More...
 
static bool check_timeout (fsm_t *p_this)
 Check if the debounce-time has passed. More...
 
void do_excite_next_row (fsm_t *p_this)
 Clean the row timeout flag and update the row to be excited. More...
 
static void do_store_tick_pressed (fsm_t *p_this)
 Store the system tick when the keyboard was pressed. More...
 
static void do_set_key_value (fsm_t *p_this)
 Store the key value of the keyboard press. More...
 
static void fsm_keyboard_init (fsm_keyboard_t *p_fsm_keyboard, uint32_t debounce_time, uint8_t keyboard_id)
 Initialize a keyboard FSM. More...
 
fsm_keyboard_tfsm_keyboard_new (uint32_t debounce_time, uint8_t keyboard_id)
 Create a new keyboard FSM. More...
 
void fsm_keyboard_destroy (fsm_keyboard_t *p_fsm)
 Destroy a keyboard FSM. More...
 
void fsm_keyboard_fire (fsm_keyboard_t *p_fsm)
 Fire the keyboard FSM. More...
 
void fsm_keyboard_start_scan (fsm_keyboard_t *p_fsm)
 Start the keyboard scanning. More...
 
void fsm_keyboard_stop_scan (fsm_keyboard_t *p_fsm)
 Stop the keyboard scanning. More...
 
char fsm_keyboard_get_key_value (fsm_keyboard_t *p_fsm)
 Return the key pressed of the last keyboard press. More...
 
bool fsm_keyboard_get_is_valid_key (fsm_keyboard_t *p_fsm)
 Check if the last key pressed is valid. More...
 
void fsm_keyboard_reset_key_value (fsm_keyboard_t *p_fsm)
 Reset the key pressed of the last keyboard press. More...
 
bool fsm_keyboard_check_activity (fsm_keyboard_t *p_fsm)
 Check if the keyboard FSM is active, or not. More...
 

Variables

static fsm_trans_t fsm_trans_keyboard []
 Array representing the transitions table of the FSM keyboard. More...
 

Detailed Description

Keyboard FSM main file.

Author
Sistemas Digitales II
Date
2026-01-01

Function Documentation

◆ check_keyboard_pressed()

static bool check_keyboard_pressed ( fsm_t *  p_this)
static

Check if the keyboard has been pressed.

TODO alumnos:

✅ 1. Call function port_keyboard_get_key_pressed_status() and retrieve the status
✅ 2. Return the status

Parameters
p_thisPointer to an fsm_t struct than contains an fsm_keyboard_t.
Returns
true
false

◆ check_keyboard_released()

static bool check_keyboard_released ( fsm_t *  p_this)
static

Check if the keyboard has been released.

TODO alumnos:

✅ 1. Call function port_keyboard_get_key_pressed_status() and retrieve the status
✅ 2. Return the inverse of the status

Parameters
p_thisPointer to an fsm_t struct than contains an fsm_keyboard_t.
Returns
true
false

◆ check_row_timeout()

static bool check_row_timeout ( fsm_t *  p_this)
static

Check if the timeout to activate a new row and scan columns has passed.

TODO alumnos:

✅ 1. Return the value of the field flag_row_timeout

Parameters
p_thisPointer to an fsm_t struct than contains an fsm_keyboard_t.
Returns
true
false

◆ check_timeout()

static bool check_timeout ( fsm_t *  p_this)
static

Check if the debounce-time has passed.

TODO alumnos:

✅ 1. Call function port_system_get_millis() and retrieve the current system tick
✅ 2. Check if the current system tick is higher than the field next_timeout
✅ 3. Return true if it is higher, otherwise return false

Parameters
p_thisPointer to an fsm_t struct than contains an fsm_keyboard_t.
Returns
true
false

◆ do_excite_next_row()

void do_excite_next_row ( fsm_t *  p_this)

Clean the row timeout flag and update the row to be excited.

TODO alumnos:

✅ 1. Clear the flag that indicates the row timeout with port_keyboard_set_row_timeout_status().
✅ 2. Excite the the next row by calling port_keyboard_excite_next_row() function.

Parameters
p_thisPointer to an fsm_t struct than contains an fsm_keyboard_t.

◆ do_set_key_value()

static void do_set_key_value ( fsm_t *  p_this)
static

Store the key value of the keyboard press.

TODO alumnos:

✅ 1. Call function port_system_get_millis() and retrieve the current system tick
✅ 2. Update the field next_timeout considering the current tick and the field debounce_time_ms
✅ 3. Save the key_value of key pressed calling the appropriate port function.

Parameters
p_thisPointer to an fsm_t struct than contains an fsm_keyboard_t.

◆ do_store_tick_pressed()

static void do_store_tick_pressed ( fsm_t *  p_this)
static

Store the system tick when the keyboard was pressed.

TODO alumnos:

✅ 1. Call function port_system_get_millis() and retrieve the current system tick
✅ 2. Store it in the field tick_pressed
✅ 3. Update the field next_timeout considering the current tick and the field debounce_time_ms

Parameters
p_thisPointer to an fsm_t struct than contains an fsm_keyboard_t.

◆ fsm_keyboard_check_activity()

bool fsm_keyboard_check_activity ( fsm_keyboard_t p_fsm)

Check if the keyboard FSM is active, or not.

The keyboard is always inactive because it works with events.

TODO alumnos Version 4:

✅ 1. Return false always.

Parameters
p_fsmPointer to an fsm_keyboard_t struct.
Returns
true
false

◆ fsm_keyboard_destroy()

void fsm_keyboard_destroy ( fsm_keyboard_t p_fsm)

Destroy a keyboard FSM.

This function destroys a keyboard FSM and frees the memory.

Parameters
p_fsmPointer to an fsm_keyboard_t struct.

◆ fsm_keyboard_fire()

void fsm_keyboard_fire ( fsm_keyboard_t p_fsm)

Fire the keyboard FSM.

This function is used to fire the keyboard FSM. It is used to check the transitions and execute the actions of the keyboard FSM.

TODO alumnos:

✅ 1. Call the fsm_fire() function. Pass the address of the fsm_t struct.

Parameters
p_fsmPointer to an fsm_keyboard_t struct.

◆ fsm_keyboard_get_is_valid_key()

bool fsm_keyboard_get_is_valid_key ( fsm_keyboard_t p_fsm)

Check if the last key pressed is valid.

This function checks if the last key pressed is valid by comparing it with the invalid key value.

TODO alumnos:

✅ 1. Return true if the field key_pressed is different from invalid_key, otherwise return false.

Parameters
p_fsmPointer to an fsm_keyboard_t struct.
Returns
true
false

◆ fsm_keyboard_get_key_value()

char fsm_keyboard_get_key_value ( fsm_keyboard_t p_fsm)

Return the key pressed of the last keyboard press.

TODO alumnos:

✅ 1. Retrieve and return the field key_pressed

Parameters
p_fsmPointer to an fsm_keyboard_t struct.
Returns
char Key pressed of the last keyboard press.

◆ fsm_keyboard_init()

static void fsm_keyboard_init ( fsm_keyboard_t p_fsm_keyboard,
uint32_t  debounce_time,
uint8_t  keyboard_id 
)
static

Initialize a keyboard FSM.

This function initializes the default values of the FSM struct and calls to the port to initialize the associated HW given the ID.

This FSM implements an anti-debounce mechanism. Debounces (or very fast keyboard presses) lasting less than the debounce_time_ms are filtered out.

The FSM stores the key_value of the last keyboard press. The user should ask for it using the function fsm_keyboard_get_key_value().

At start and reset, the key value value must be 0 ms. A value of 0 ms means that there has not been a new keyboard press.

Attention
The user is required to reset the key value value once it has been read. Otherwise, this value may be misinterpreted by the user, if successive calls are made without having pressed the keyboard. In such a case we would be reading past information. In order to reset the value, the function fsm_keyboard_reset_key_value() must be called.

In other words, the status flag of this FSM is the variable key_value. A key_value of null key means that no new keyboard has been pressed, a value other than null key means that it has been pressed and the value is the key pressed, so it is the user's responsibility to clear this status flag.

The FSM contains information of the keyboard ID. This ID is a unique identifier that is managed by the user in the port. That is where the user provides identifiers and HW information for all the keyboards on his system. The FSM does not have to know anything of the underlying HW.

Note
Both unit and integration tests (example) are provided for this keyboard library are available in this GitHub repository: https://github.com/sdg2DieUpm/simone/tree/simone_v1_test

TODO alumnos:

✅ 1. Call the fsm_init() to initialize the FSM. Pass the address of the fsm_t struct and the transition table
✅ 2. Initialize the fields debounce_time_ms, keyboard_id of p_fsm_keyboard with the received values
✅ 3. Initialize the fields tick_pressed and invalid_key of p_fsm_keyboard properly. Initialize the ID as well.
✅ 4. Call the function port_keyboard_init() ✅ 5. Call the function port_keyboard_get_invalid_key_value() to get the null key value of the keyboard and store it in the field invalid_key and key_value as initial value.

Parameters
p_fsm_keyboardPointer to the keyboard FSM.
debounce_timeAnti-debounce time in milliseconds
keyboard_idUnique keyboard identifier number

◆ fsm_keyboard_new()

fsm_keyboard_t* fsm_keyboard_new ( uint32_t  debounce_time_ms,
uint8_t  keyboard_id 
)

Create a new keyboard FSM.

This function creates a new keyboard FSM with the given debounce time for all keys and keyboard ID.

Parameters
debounce_time_msDebounce time in milliseconds for all keys.
keyboard_idKeyboard ID. Must be unique.
Returns
fsm_keyboard_t* Pointer to the keyboard FSM.

◆ fsm_keyboard_reset_key_value()

void fsm_keyboard_reset_key_value ( fsm_keyboard_t p_fsm)

Reset the key pressed of the last keyboard press.

TODO alumnos:

✅ 1. Set the field key_value to invalid_key

Parameters
p_fsmPointer to an fsm_keyboard_t struct.

◆ fsm_keyboard_start_scan()

void fsm_keyboard_start_scan ( fsm_keyboard_t p_fsm)

Start the keyboard scanning.

This function starts the keyboard scanning by calling the appropriate port function.

TODO alumnos:

✅ 1. Call the appropriate port function passing the keyboard ID

Parameters
p_fsmPointer to an fsm_keyboard_t struct.

◆ fsm_keyboard_stop_scan()

void fsm_keyboard_stop_scan ( fsm_keyboard_t p_fsm)

Stop the keyboard scanning.

This function stops the keyboard scanning by calling the appropriate port function.

TODO alumnos:

✅ 1. Call the appropriate port function passing the keyboard ID

Parameters
p_fsmPointer to an fsm_keyboard_t struct.

Variable Documentation

◆ fsm_trans_keyboard

fsm_trans_t fsm_trans_keyboard[]
static

Array representing the transitions table of the FSM keyboard.