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.

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

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

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

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

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

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


The status of the init request

void cyhal_keyscan_free(cyhal_keyscan_t *obj)

Deinitialize the KeyScan object and release the associated hardware resources.


obj[in] 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.

  • obj[in] The KeyScan object

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

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


The status of the read request

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.

  • obj[in] The KeyScan object

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

  • callback_arg[in] 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.

  • obj[in] The KeyScan object

  • event[in] The KeyScan event type

  • intr_priority[in] The priority for NVIC interrupt events

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

struct cyhal_keyscan_action_t
#include <>

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.