1 /***************************************************************************//** 2 * \file cyhal_keyscan.h 3 * 4 * \brief 5 * Provides a high level interface for interacting with the Infineon KeyScan. 6 * This interface abstracts out the chip specific details. If any chip specific 7 * functionality is necessary, or performance is critical the low level functions 8 * can be used directly. 9 * 10 ******************************************************************************** 11 * \copyright 12 * Copyright 2020-2021 Cypress Semiconductor Corporation (an Infineon company) or 13 * an affiliate of Cypress Semiconductor Corporation 14 * 15 * SPDX-License-Identifier: Apache-2.0 16 * 17 * Licensed under the Apache License, Version 2.0 (the "License"); 18 * you may not use this file except in compliance with the License. 19 * You may obtain a copy of the License at 20 * 21 * http://www.apache.org/licenses/LICENSE-2.0 22 * 23 * Unless required by applicable law or agreed to in writing, software 24 * distributed under the License is distributed on an "AS IS" BASIS, 25 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 26 * See the License for the specific language governing permissions and 27 * limitations under the License. 28 *******************************************************************************/ 29 30 /** 31 * \addtogroup group_hal_keyscan Keyscan 32 * \ingroup group_hal 33 * \{ 34 * High level interface for interacting with the KeyScan 35 * 36 * The KeyScan driver monitors a key matrix for actions and provides keycodes 37 * to the application for processing. 38 * 39 * \section section_keyscan_features Features 40 * * Configurable number of rows and columns 41 * * Detection of press, double press, triple press, and release actions 42 * * Buffering of multiple key actions without application intervention 43 * * Configurable callback for event-driven response to key actions 44 * 45 * See the implementation-specific documentation for information about device-specific 46 * limits on row count, column count, and buffer depth. 47 * 48 * \section section_keyscan_quickstart Quick Start 49 * Initialize a KeyScan instance using @ref cyhal_keyscan_init, providing the pins that should 50 * be used for the rows and columns of the key matrix. Use @ref cyhal_keyscan_read to read 51 * key actions. 52 * 53 * See @ref subsection_keyscan_snippet_1 for an example initialization. 54 * \note The clock parameter (const \ref cyhal_clock_t *clk) is optional and can be set to 55 * NULL to automatically configure and use an available clock resource with a default frequency. 56 * 57 * \section section_keyscan_snippets Code Snippets 58 * \note Error handling is omitted for clarity 59 * \subsection subsection_keyscan_snippet_1 Snippet 1: KeyScan initialization 60 * This snippet initializes a KeyScan resource to scan a matrix of pins. 61 * 62 * \snippet hal_keyscan.c snippet_cyhal_keyscan_init 63 * 64 * \subsection subsection_keyscan_snippet_2 Snippet 2: Polling 65 * This snippet illustrates periodic polling for key actions 66 * 67 * \snippet hal_keyscan.c snippet_cyhal_keyscan_poll 68 * 69 * \subsection subsection_keyscan_snippet_3 Snippet 3: Event Handling 70 * This snippet shows how to register a callback which is invoked when a key action occurs. 71 * 72 * \snippet hal_keyscan.c snippet_cyhal_keyscan_event 73 */ 74 75 #pragma once 76 77 #include "cyhal_hw_types.h" 78 #include "cyhal_gpio.h" 79 #include "cy_result.h" 80 #include "cyhal_clock.h" 81 82 #if defined(__cplusplus) 83 extern "C" { 84 #endif 85 86 /** An invalid pin location was specified */ 87 #define CYHAL_KEYSCAN_RSLT_ERR_INVALID_PIN \ 88 (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_KEYSCAN, 0)) 89 90 /** An invalid argument was provided */ 91 #define CYHAL_KEYSCAN_RSLT_ERR_INVALID_ARG \ 92 (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_KEYSCAN, 1)) 93 94 /** Initialization of the KeyScan hardware failed */ 95 #define CYHAL_KEYSCAN_RSLT_ERR_INIT_FAILED \ 96 (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_KEYSCAN, 2)) 97 98 /** KeyScan events */ 99 typedef enum { 100 CYHAL_KEYSCAN_EVENT_NONE = 0, //!< No interrupt 101 CYHAL_KEYSCAN_EVENT_ACTION_DETECTED = 1 << 0, //!< Key action detected 102 CYHAL_KEYSCAN_EVENT_BUFFER_FULL = 1 << 1, //!< Keycode buffer is full 103 } cyhal_keyscan_event_t; 104 105 /** Key action types */ 106 typedef enum { 107 CYHAL_KEYSCAN_ACTION_PRESS, //<! The key was pressed 108 CYHAL_KEYSCAN_ACTION_RELEASE, //<! The key was released 109 } cyhal_keyscan_action_type_t; 110 111 /** Key action description */ 112 typedef struct { 113 /** Code indicating which key the action applies to. Keycodes are assigned sequentially in column 114 * order. For example, in a key matrix with five rows and two columns, column 0 would be represented 115 * by keycode 0 - 4, and column 1 by keycode 5-9. 116 */ 117 uint8_t keycode; 118 /** The type of key action that was performd */ 119 cyhal_keyscan_action_type_t action; 120 } cyhal_keyscan_action_t; 121 122 /** Handler for KeyScan event callbacks */ 123 typedef void (*cyhal_keyscan_event_callback_t)(void *callback_arg, cyhal_keyscan_event_t event); 124 125 /** Initialize the KeyScan peripheral. 126 * 127 * @param[out] obj Pointer to a KeyScan object. The caller must allocate the memory 128 * for this object but the init function will initialize its contents. 129 * @param[in] num_rows The number of rows in the key matrix 130 * @param[in] rows Array of pins corresponding to the key matrix rows 131 * @param[in] num_columns The number of columns in the key matrix 132 * @param[in] columns Array of pins corresponding to the key matrix columns 133 * @param[in] clock Clock source to use for this instance. If NULL, a dedicated clock 134 * will be automatically allocated for this instance. 135 * @return The status of the init request 136 */ 137 cy_rslt_t cyhal_keyscan_init(cyhal_keyscan_t *obj, uint8_t num_rows, const cyhal_gpio_t *rows, 138 uint8_t num_columns, const cyhal_gpio_t *columns, const cyhal_clock_t *clock); 139 140 /** Deinitialize the KeyScan object and release the associated hardware resources. 141 * 142 * @param[in] obj The KeyScan object 143 */ 144 void cyhal_keyscan_free(cyhal_keyscan_t *obj); 145 146 /** Reads up to the specified number of key actions. 147 * 148 * \note If an error code is returned, this function will contain partial information up to the number of keys read. 149 * 150 * @param[in] obj The KeyScan object 151 * @param[in,out] count The number of key action to read. Updated with the number of keys actually read. 152 * @param[out] keys The array into which key action descriptions should be written, starting from the 153 * least recent key action at index 0. 154 * @return The status of the read request 155 */ 156 cy_rslt_t cyhal_keyscan_read(cyhal_keyscan_t *obj, uint8_t* count, cyhal_keyscan_action_t* keys); 157 158 /** Register a keyscan callback handler. 159 * 160 * This function will be called when one of the events enabled by @ref cyhal_keyscan_enable_event occurs. 161 * 162 * @param[in] obj The KeyScan object 163 * @param[in] callback The callback handler which will be invoked when the event occurs 164 * @param[in] callback_arg Generic argument that will be provided to the callback when called 165 */ 166 void cyhal_keyscan_register_callback(cyhal_keyscan_t *obj, cyhal_keyscan_event_callback_t callback, void *callback_arg); 167 168 /** Configure KeyScan events. 169 * 170 * When an enabled event occurs, the function specified by \ref cyhal_keyscan_register_callback will be called. 171 * 172 * @param[in] obj The KeyScan object 173 * @param[in] event The KeyScan event type 174 * @param[in] intr_priority The priority for NVIC interrupt events 175 * @param[in] enable True to turn on the specified event, False to turn off 176 */ 177 void cyhal_keyscan_enable_event(cyhal_keyscan_t *obj, cyhal_keyscan_event_t event, uint8_t intr_priority, bool enable); 178 179 /** Initialize the KeyScan peripheral using a configurator generated configuration struct. 180 * 181 * @param[in] obj Pointer to a KeyScan object. The caller must allocate the memory 182 * for this object but the init function will initialize its contents. 183 * @param[in] cfg Configuration structure generated by a configurator. 184 * @return The status of the operation 185 */ 186 cy_rslt_t cyhal_keyscan_init_cfg(cyhal_keyscan_t *obj, const cyhal_keyscan_configurator_t *cfg); 187 188 #if defined(__cplusplus) 189 } 190 #endif 191 192 #ifdef CYHAL_KEYSCAN_IMPL_HEADER 193 #include CYHAL_KEYSCAN_IMPL_HEADER 194 #endif /* CYHAL_KEYSCAN_IMPL_HEADER */ 195 196 /** \} group_hal_keyscan */ 197 198