KEYSCAN - Keypad Scanner Driver#

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_HAL_KEYSCAN_DELAY_2MS=>     2ms
//    <SL_HAL_KEYSCAN_DELAY_4MS=>     4ms
//    <SL_HAL_KEYSCAN_DELAY_6MS=>     6ms
//    <SL_HAL_KEYSCAN_DELAY_8MS=>     8ms
//    <SL_HAL_KEYSCAN_DELAY_10MS=>    10ms
//    <SL_HAL_KEYSCAN_DELAY_12MS=>    12ms
//    <SL_HAL_KEYSCAN_DELAY_14MS=>    14ms
//    <SL_HAL_KEYSCAN_DELAY_16MS=>    16ms
//    <SL_HAL_KEYSCAN_DELAY_18MS=>    18ms
//    <SL_HAL_KEYSCAN_DELAY_20MS=>    20ms
//    <SL_HAL_KEYSCAN_DELAY_22MS=>    22ms
//    <SL_HAL_KEYSCAN_DELAY_24MS=>    24ms
//    <SL_HAL_KEYSCAN_DELAY_26MS=>    26ms
//    <SL_HAL_KEYSCAN_DELAY_28MS=>    28ms
//    <SL_HAL_KEYSCAN_DELAY_30MS=>    30ms
//    <SL_HAL_KEYSCAN_DELAY_32MS=>    32ms
// <i> Duration of the scan period per column
// <i> Default: SL_HAL_KEYSCAN_DELAY_2MS
#define SL_KEYSCAN_DRIVER_SCAN_DELAY_MS    SL_HAL_KEYSCAN_DELAY_2MS

// <o SL_KEYSCAN_DRIVER_DEBOUNCE_DELAY_MS> Debounce Delay
//    <SL_HAL_KEYSCAN_DELAY_2MS=>     2ms
//    <SL_HAL_KEYSCAN_DELAY_4MS=>     4ms
//    <SL_HAL_KEYSCAN_DELAY_6MS=>     6ms
//    <SL_HAL_KEYSCAN_DELAY_8MS=>     8ms
//    <SL_HAL_KEYSCAN_DELAY_10MS=>    10ms
//    <SL_HAL_KEYSCAN_DELAY_12MS=>    12ms
//    <SL_HAL_KEYSCAN_DELAY_14MS=>    14ms
//    <SL_HAL_KEYSCAN_DELAY_16MS=>    16ms
//    <SL_HAL_KEYSCAN_DELAY_18MS=>    18ms
//    <SL_HAL_KEYSCAN_DELAY_20MS=>    20ms
//    <SL_HAL_KEYSCAN_DELAY_22MS=>    22ms
//    <SL_HAL_KEYSCAN_DELAY_24MS=>    24ms
//    <SL_HAL_KEYSCAN_DELAY_26MS=>    26ms
//    <SL_HAL_KEYSCAN_DELAY_28MS=>    28ms
//    <SL_HAL_KEYSCAN_DELAY_30MS=>    30ms
//    <SL_HAL_KEYSCAN_DELAY_32MS=>    32ms
// <i> Duration of debounce period once a key press is detected.
// <i> Default: SL_HAL_KEYSCAN_DELAY_2MS
#define SL_KEYSCAN_DRIVER_DEBOUNCE_DELAY_MS    SL_HAL_KEYSCAN_DELAY_2MS

// <o SL_KEYSCAN_DRIVER_STABLE_DELAY_MS> Stable Delay
//    <SL_HAL_KEYSCAN_DELAY_2MS=>     2ms
//    <SL_HAL_KEYSCAN_DELAY_4MS=>     4ms
//    <SL_HAL_KEYSCAN_DELAY_6MS=>     6ms
//    <SL_HAL_KEYSCAN_DELAY_8MS=>     8ms
//    <SL_HAL_KEYSCAN_DELAY_10MS=>    10ms
//    <SL_HAL_KEYSCAN_DELAY_12MS=>    12ms
//    <SL_HAL_KEYSCAN_DELAY_14MS=>    14ms
//    <SL_HAL_KEYSCAN_DELAY_16MS=>    16ms
//    <SL_HAL_KEYSCAN_DELAY_18MS=>    18ms
//    <SL_HAL_KEYSCAN_DELAY_20MS=>    20ms
//    <SL_HAL_KEYSCAN_DELAY_22MS=>    22ms
//    <SL_HAL_KEYSCAN_DELAY_24MS=>    24ms
//    <SL_HAL_KEYSCAN_DELAY_26MS=>    26ms
//    <SL_HAL_KEYSCAN_DELAY_28MS=>    28ms
//    <SL_HAL_KEYSCAN_DELAY_30MS=>    30ms
//    <SL_HAL_KEYSCAN_DELAY_32MS=>    32ms
// <i> Duration of the stable period after the debounce stage.
// <i> Default: SL_HAL_KEYSCAN_DELAY_2MS
// #define SL_KEYSCAN_DRIVER_STABLE_DELAY_MS    SL_HAL_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);
static sl_keyscan_driver_process_keyscan_event_handle_t handle =
{
  .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.
  sl_keyscan_driver_init();
  // Set callback to be called when processing interrupt
  sl_keyscan_driver_subscribe_event(&handle);
  // Start the keypad scanner.
  sl_keyscan_driver_start_scan();

  return 0;
}

Modules#

sl_keyscan_driver_process_keyscan_event_handle_t

Enumerations#

enum
SL_KEYSCAN_STATUS_KEYPRESS_VALID = 0
SL_KEYSCAN_STATUS_KEYPRESS_INVALID
SL_KEYSCAN_STATUS_KEYPRESS_RELEASED
}

KEYSCAN status values.

Typedefs#

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

A Keyscan event handler.

Functions#

sl_status_t

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

Starts the keyscan scan.

sl_status_t

Stops the keyscan scan.

Enumeration Documentation#

sl_keyscan_driver_status_t#

sl_keyscan_driver_status_t

KEYSCAN status values.

Enumerator
SL_KEYSCAN_STATUS_KEYPRESS_VALID
SL_KEYSCAN_STATUS_KEYPRESS_INVALID
SL_KEYSCAN_STATUS_KEYPRESS_RELEASED

Definition at line 60 of file platform/driver/keyscan/inc/keyscan_driver.h

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) )(uint8_t *p_keyscan_matrix, sl_keyscan_driver_status_t status)

A Keyscan event handler.


Definition at line 71 of file platform/driver/keyscan/inc/keyscan_driver.h

Function Documentation#

sl_keyscan_driver_init#

sl_status_t sl_keyscan_driver_init (void )

Initializes the keyscan driver.

Parameters
N/A

Returns

  • 0 if successful. Error code otherwise.


Definition at line 87 of file platform/driver/keyscan/inc/keyscan_driver.h

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.


Definition at line 101 of file platform/driver/keyscan/inc/keyscan_driver.h

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.


Definition at line 114 of file platform/driver/keyscan/inc/keyscan_driver.h

sl_keyscan_driver_start_scan#

sl_status_t sl_keyscan_driver_start_scan (void )

Starts the keyscan scan.

Parameters
N/A

Returns

  • 0 if successful. Error code otherwise.


Definition at line 123 of file platform/driver/keyscan/inc/keyscan_driver.h

sl_keyscan_driver_stop_scan#

sl_status_t sl_keyscan_driver_stop_scan (void )

Stops the keyscan scan.

Parameters
N/A

Returns

  • 0 if successful. Error code otherwise.


Definition at line 132 of file platform/driver/keyscan/inc/keyscan_driver.h