KEYSCAN - Keypad Scanner Driver

Description

Keyscan driver.


Introduction

A low-energy keypad scanner (KEYSCAN) which can scan up to a 6x8 matrix of keyboard switches. The KEYSCAN peripheral contains logic for debounce and settling time, allowing it to scan through the switch matrix autonomously in EM0 and EM1, and interrupt the processor when a key press is detected.


Configuration Options

Some properties of the KEYSCAN driver are compile-time configurable. These properties are stored in a file named keyscan_driver_config.h. A template for this file, containing default values, is in the keyscan/config folder. Currently the configuration options are as follows:

  • Number of columns in keyscan.
  • Number of rows in keyscan.
  • Duration of the scan period per column.
  • Duration of debounce period once a key press is detected.
  • Duration of the stable period after the debounce stage.
  • Enable or disable single-press functionality.

To configure KEYSCAN, provide a custom configuration file. This is an example keyscan_driver_config.h file:

#ifndef KEYSCAN_DRIVER_CONFIG_H
#define KEYSCAN_DRIVER_CONFIG_H
// <o SL_KEYSCAN_DRIVER_COLUMN_NUMBER> Number of columns in keyscan <1-8>
// <i> Default: 1
#define SL_KEYSCAN_DRIVER_COLUMN_NUMBER 1
// <o SL_KEYSCAN_DRIVER_ROW_NUMBER> Number of rows in keyscan <3-6>
// <i> Default: 3
#define SL_KEYSCAN_DRIVER_ROW_NUMBER 3
// <o SL_KEYSCAN_DRIVER_SCAN_DELAY_MS> Scan Delay
// <SL_KEYSCAN_DELAY_2MS=> 2ms
// <SL_KEYSCAN_DELAY_4MS=> 4ms
// <SL_KEYSCAN_DELAY_6MS=> 6ms
// <SL_KEYSCAN_DELAY_8MS=> 8ms
// <SL_KEYSCAN_DELAY_10MS=> 10ms
// <SL_KEYSCAN_DELAY_12MS=> 12ms
// <SL_KEYSCAN_DELAY_14MS=> 14ms
// <SL_KEYSCAN_DELAY_16MS=> 16ms
// <SL_KEYSCAN_DELAY_18MS=> 18ms
// <SL_KEYSCAN_DELAY_20MS=> 20ms
// <SL_KEYSCAN_DELAY_22MS=> 22ms
// <SL_KEYSCAN_DELAY_24MS=> 24ms
// <SL_KEYSCAN_DELAY_26MS=> 26ms
// <SL_KEYSCAN_DELAY_28MS=> 28ms
// <SL_KEYSCAN_DELAY_30MS=> 30ms
// <SL_KEYSCAN_DELAY_32MS=> 32ms
// <i> Duration of the scan period per column
// <i> Default: SL_KEYSCAN_DELAY_2MS
#define SL_KEYSCAN_DRIVER_SCAN_DELAY_MS SL_KEYSCAN_DELAY_2MS
// <o SL_KEYSCAN_DRIVER_DEBOUNCE_DELAY_MS> Debounce Delay
// <SL_KEYSCAN_DELAY_2MS=> 2ms
// <SL_KEYSCAN_DELAY_4MS=> 4ms
// <SL_KEYSCAN_DELAY_6MS=> 6ms
// <SL_KEYSCAN_DELAY_8MS=> 8ms
// <SL_KEYSCAN_DELAY_10MS=> 10ms
// <SL_KEYSCAN_DELAY_12MS=> 12ms
// <SL_KEYSCAN_DELAY_14MS=> 14ms
// <SL_KEYSCAN_DELAY_16MS=> 16ms
// <SL_KEYSCAN_DELAY_18MS=> 18ms
// <SL_KEYSCAN_DELAY_20MS=> 20ms
// <SL_KEYSCAN_DELAY_22MS=> 22ms
// <SL_KEYSCAN_DELAY_24MS=> 24ms
// <SL_KEYSCAN_DELAY_26MS=> 26ms
// <SL_KEYSCAN_DELAY_28MS=> 28ms
// <SL_KEYSCAN_DELAY_30MS=> 30ms
// <SL_KEYSCAN_DELAY_32MS=> 32ms
// <i> Duration of debounce period once a key press is detected.
// <i> Default: SL_KEYSCAN_DELAY_2MS
#define SL_KEYSCAN_DRIVER_DEBOUNCE_DELAY_MS SL_KEYSCAN_DELAY_2MS
// <o SL_KEYSCAN_DRIVER_STABLE_DELAY_MS> Stable Delay
// <SL_KEYSCAN_DELAY_2MS=> 2ms
// <SL_KEYSCAN_DELAY_4MS=> 4ms
// <SL_KEYSCAN_DELAY_6MS=> 6ms
// <SL_KEYSCAN_DELAY_8MS=> 8ms
// <SL_KEYSCAN_DELAY_10MS=> 10ms
// <SL_KEYSCAN_DELAY_12MS=> 12ms
// <SL_KEYSCAN_DELAY_14MS=> 14ms
// <SL_KEYSCAN_DELAY_16MS=> 16ms
// <SL_KEYSCAN_DELAY_18MS=> 18ms
// <SL_KEYSCAN_DELAY_20MS=> 20ms
// <SL_KEYSCAN_DELAY_22MS=> 22ms
// <SL_KEYSCAN_DELAY_24MS=> 24ms
// <SL_KEYSCAN_DELAY_26MS=> 26ms
// <SL_KEYSCAN_DELAY_28MS=> 28ms
// <SL_KEYSCAN_DELAY_30MS=> 30ms
// <SL_KEYSCAN_DELAY_32MS=> 32ms
// <i> Duration of the stable period after the debounce stage.
// <i> Default: SL_KEYSCAN_DELAY_2MS
// #define SL_KEYSCAN_DRIVER_STABLE_DELAY_MS SL_KEYSCAN_DELAY_2MS
//
// <q SL_KEYSCAN_DRIVER_SINGLEPRESS> keyscan single-press functionality
// <i> Enable or disable single-press functionality.
// <i> Default: 0
#define SL_KEYSCAN_DRIVER_SINGLEPRESS 0
#endif /* KEYSCAN_DRIVER_CONFIG_H */


Usage

The expected flow of execution is:

  • Initialize the driver.
  • Register an event callback to be called on Keyscan event.
  • Start the scan.
  • Interrupt-based event to read the keypresses.

Initialization is done by calling sl_keyscan_driver_init() . It will prepare the internal structure and GPIO configuration.

When initialization is done successfully, scanning can be started by calling sl_keyscan_driver_start_scan() .

Here is a complete example:

#include "keyscan_driver.h"
/*******************************************************************************
********************* LOCAL FUNCTION PROTOTYPES ***************************
******************************************************************************/
static void on_event(uint8_t *p_keyscan_matrix, sl_keyscan_driver_status_t status);
{
. on_event = on_event,
};
/*******************************************************************************
************************** GLOBAL FUNCTIONS *******************************
******************************************************************************/
static void on_event(uint8_t *p_keyscan_matrix, sl_keyscan_driver_status_t status)
{
(void)p_keyscan_matrix;
switch (status) {
// Singlepress mode: key press detected.
case SL_KEYSCAN_STATUS_KEYPRESS_VALID:
break ;
// Multipress mode: all keys are released.
case SL_KEYSCAN_STATUS_KEYPRESS_RELEASED:
break ;
default :
EFM_ASSERT( false );
break ;
}
}
int main( void )
{
// Initialize KEYSCAN.
// Set callback to be called when processing interrupt
// Start the keypad scanner.
return 0;
}

Data Structures

struct sl_keyscan_driver_process_keyscan_event_handle_t
An Event Handle.

Functions

sl_status_t sl_keyscan_driver_init (void)
Initializes the keyscan driver.
void sl_keyscan_driver_subscribe_event ( sl_keyscan_driver_process_keyscan_event_handle_t *event_handle)
Registers an event callback to be called on Keyscan event.
void sl_keyscan_driver_unsubscribe_event ( sl_keyscan_driver_process_keyscan_event_handle_t *event_handle)
Unregisters an event callback to be called on Keyscan event.
sl_status_t sl_keyscan_driver_start_scan (void)
Starts the keyscan scan.
sl_status_t sl_keyscan_driver_stop_scan (void)
Stops the keyscan scan.

Typedefs

typedef void(* sl_keyscan_driver_process_keyscan_event ) (uint8_t *p_keyscan_matrix, sl_keyscan_driver_status_t status)
A Keyscan event handler.

Enumerations

enum sl_keyscan_driver_status_t {
SL_KEYSCAN_STATUS_KEYPRESS_VALID = 0,
SL_KEYSCAN_STATUS_KEYPRESS_INVALID ,
SL_KEYSCAN_STATUS_KEYPRESS_RELEASED
}
KEYSCAN status values.

Function Documentation

sl_keyscan_driver_init()

sl_status_t sl_keyscan_driver_init ( void )

Initializes the keyscan driver.

Returns
0 if successful. Error code otherwise.

sl_keyscan_driver_subscribe_event()

void sl_keyscan_driver_subscribe_event ( sl_keyscan_driver_process_keyscan_event_handle_t * event_handle )

Registers an event callback to be called on Keyscan event.

Parameters
[in] event_handle Event handle to register
Note
An EFM_ASSERT is thrown if the handle is NULL.
Must be called before init function.

Registers an event callback to be called on Keyscan event.

sl_keyscan_driver_unsubscribe_event()

void sl_keyscan_driver_unsubscribe_event ( sl_keyscan_driver_process_keyscan_event_handle_t * event_handle )

Unregisters an event callback to be called on Keyscan event.

Parameters
[in] event_handle Event handle which must be unregistered (must have been registered previously).
Note
An EFM_ASSERT is thrown if the handle is not found or is NULL.

Unregisters an event callback to be called on Keyscan event.

sl_keyscan_driver_start_scan()

sl_status_t sl_keyscan_driver_start_scan ( void )

Starts the keyscan scan.

Returns
0 if successful. Error code otherwise.

sl_keyscan_driver_stop_scan()

sl_status_t sl_keyscan_driver_stop_scan ( void )

Stops the keyscan scan.

Returns
0 if successful. Error code otherwise.

Typedef Documentation

sl_keyscan_driver_process_keyscan_event

typedef void(* sl_keyscan_driver_process_keyscan_event) (uint8_t *p_keyscan_matrix, sl_keyscan_driver_status_t status)

A Keyscan event handler.

Enumeration Type Documentation

sl_keyscan_driver_status_t

KEYSCAN status values.