group group_hal_keyscan

High level interface for interacting with the KeyScan.

The KeyScan driver monitors a key matrix for actions and provides keycodes to the application for processing.


  • Configurable number of rows and columns

  • Detection of press, double press, triple press, and release actions

  • Buffering of multiple key actions without application intervention

  • Configurable callback for event-driven response to key actions

See the implementation-specific documentation for information about device-specific limits on row count, column count, and buffer depth.

Quick Start

Initialize a KeyScan instance using cyhal_keyscan_init, providing the pins that should be used for the rows and columns of the key matrix. Use cyhal_keyscan_read to read key actions.

See Snippet 1: KeyScan initialization for an example initialization.


The clock parameter (const cyhal_clock_t *clk) is optional and can be set to NULL to automatically configure and use an available clock resource with a default frequency.

Code Snippets


Error handling is omitted for clarity

Snippet 1: KeyScan initialization

This snippet initializes a KeyScan resource to scan a matrix of pins.

    const cyhal_gpio_t rows[]    = { P0_0, P0_1, P0_2 };
    const cyhal_gpio_t columns[] = { P1_0, P1_1, P1_2 };
    cyhal_keyscan_t    keyscan;

    cy_rslt_t result = cyhal_keyscan_init(&keyscan, sizeof(rows)/sizeof(rows[0]), rows,
                                          sizeof(columns)/sizeof(columns[0]), columns, NULL);

Snippet 2: Polling

This snippet illustrates periodic polling for key actions

    #define MAX_KEYS (20u)
    cyhal_keyscan_action_t key_actions[MAX_KEYS];

    cyhal_keyscan_t keyscan;
    // Initialize keyscan object as shown in snippet 1

    while (true)
        uint8_t   num_keys = MAX_KEYS;
        cy_rslt_t result   = cyhal_keyscan_read(&keyscan, &num_keys, key_actions);
        CY_ASSERT(CY_RSLT_SUCCESS == result);
        for (int i = 0; i < num_keys; ++i)
            // process key_actions[i]

        // Perform other application processing while waiting for further key actions

Snippet 3: Event Handling

This snippet shows how to register a callback which is invoked when a key action occurs.

static void keyscan_event_handler(void* arg, cyhal_keyscan_event_t event)
    cyhal_keyscan_action_t key_actions[MAX_KEYS];
    uint8_t                num_keys = MAX_KEYS;

    // When we registered the callback, we set 'arg' to point to the keyscan object
    cyhal_keyscan_t* keyscan = (cyhal_keyscan_t*)arg;
    cy_rslt_t        result  = cyhal_keyscan_read(keyscan, &num_keys, key_actions);
    CY_ASSERT(num_keys > 0);

    for (int i = 0; i < num_keys; ++i)
        // process key_actions[i]

// snippet_cyhal_keyscan_event
static void snippet_cyhal_keyscan_event()
    cyhal_keyscan_t keyscan;
    // Initialize keyscan object as shown in snippet 1

    // Register a callback and set the callback argument to be a pointer to the keyscan object, so
    // that we can easily reference it from the callback handler.
    cyhal_keyscan_register_callback(&keyscan, &keyscan_event_handler, &keyscan);

    // Subscribe to the action detected event so that we can respond to new key actions
    cyhal_keyscan_enable_event(&keyscan, CYHAL_KEYSCAN_EVENT_ACTION_DETECTED,
                               CYHAL_ISR_PRIORITY_DEFAULT, true);



An invalid pin location was specified.


An invalid argument was provided.


Initialization of the KeyScan hardware failed.


typedef void (*cyhal_keyscan_event_callback_t)(void *callback_arg, cyhal_keyscan_event_t event)

Handler for KeyScan event callbacks.


enum cyhal_keyscan_event_t

cyhal_keyscan_event_t: KeyScan events.



No interrupt.


Key action detected.


Keycode buffer is full.

enum cyhal_keyscan_action_type_t

cyhal_keyscan_action_type_t: Key action types.




cy_rslt_t cyhal_keyscan_init(cyhal_keyscan_t *obj, uint8_t num_rows, const cyhal_gpio_t *rows, uint8_t num_columns, const cyhal_gpio_t *columns, const cyhal_clock_t *clock)

Initialize the KeyScan peripheral.


The status of the init request

  • [out] obj: Pointer to a KeyScan object. The caller must allocate the memory for this object but the init function will initialize its contents.

  • [in] num_rows: The number of rows in the key matrix

  • [in] rows: Array of pins corresponding to the key matrix rows

  • [in] num_columns: The number of columns in the key matrix

  • [in] columns: Array of pins corresponding to the key matrix columns

  • [in] clock: Clock source to use for this instance. If NULL, a dedicated clock will be automatically allocated for this instance.

void cyhal_keyscan_free(cyhal_keyscan_t *obj)

Deinitialize the KeyScan object and release the associated hardware resources.

  • [in] obj: The KeyScan object

cy_rslt_t cyhal_keyscan_read(cyhal_keyscan_t *obj, uint8_t *count, cyhal_keyscan_action_t *keys)

Reads up to the specified number of key actions.


If an error code is returned, this function will contain partial information up to the number of keys read.


The status of the read request

  • [in] obj: The KeyScan object

  • [inout] count: The number of key action to read. Updated with the number of keys actually read.

  • [out] keys: The array into which key action descriptions should be written, starting from the least recent key action at index 0.

void cyhal_keyscan_register_callback(cyhal_keyscan_t *obj, cyhal_keyscan_event_callback_t callback, void *callback_arg)

Register a keyscan callback handler.

This function will be called when one of the events enabled by cyhal_keyscan_enable_event occurs.

  • [in] obj: The KeyScan object

  • [in] callback: The callback handler which will be invoked when the event occurs

  • [in] callback_arg: Generic argument that will be provided to the callback when called

void cyhal_keyscan_enable_event(cyhal_keyscan_t *obj, cyhal_keyscan_event_t event, uint8_t intr_priority, bool enable)

Configure KeyScan events.

When an enabled event occurs, the function specified by cyhal_keyscan_register_callback will be called.

  • [in] obj: The KeyScan object

  • [in] event: The KeyScan event type

  • [in] intr_priority: The priority for NVIC interrupt events

  • [in] enable: True to turn on the specified event, False to turn off

struct cyhal_keyscan_action_t
#include <cyhal_keyscan.h>

Key action description.

Public Members

uint8_t keycode

Code indicating which key the action applies to.

Keycodes are assigned sequentially in column order. For example, in a key matrix with five rows and two columns, column 0 would be represented by keycode 0 - 4, and column 1 by keycode 5-9.

cyhal_keyscan_action_type_t action

The type of key action that was performd.