MXKEYSCAN is a DEEPSLEEP peripheral IP that performs autonomous key-matrix scan and system notification.
Key processing detects both press and un-press actions, includes micro and macro de-bouncing filters and ghost key detection.
Configurable key-matrix size supports up to 20x8 keys. Up to 20 columns are driven as the output and up to 8 rows are processed as the input. Key actions are stored in the FIFO with interrupt notification available based on the FIFO threshold.
The Scan matrix support up to 8X20 matrix, maximum of 160 keys. Any key press will be translated into an index corresponding column and corresponding row. Before any key is pressed, the Key Matrix Scan Logic is disabled. Once a key press is detected by the Key Detection Logic, it will enable the gate for clock to drive the key Matrix Scan Logic for GPIO scanning. GPIO scanning is done one column at a time by driving each column "low" and reading from the row GPIO pins to find out which input is low. After the Key Scan Logic had scanned through the matrix for a specific number for debounce times configured by firmware though the configuration register, keycode representing the pressed key is pushed into the key FIFO for firmware to read and an interrupt to CPU will be generated. There are two types of debounce mechanisms build into this scan matrix block. The micro-debounce logic will provide a small debounce period to debounce the break type of mechanical vibration. The macro debounce logic will scan through the matrix for a number of times for qualify a key as being pressed.
Features:
- Ability to turn off it's clock if no keys pressed.
- Sequential scanning of up to 160 keys in a 8X20 matrix
- Programmable number of columns from 1 to 20.
- Programmable number of rows from 1 to 8.
- 20-byte key-code buffer.
- 128-kHz clock allow scanning of full 160 key matrix in about 1.2ms.
- Keys are buffered until host microcontroller has a chance to read it, or until overflow occurs.
- Hardware debouncing and noise/glitch filtering.
This driver provides the user an easy method for accessing KeyScan registers and provides some simple functionality for reading key index from keyscan FIFO.
The IP supports only Sequential PIN configuration. For Example if the user is configuring the IP for 4 pins (2 ROWS and 2 COLUMNs) the user is suggested to use ROWS 0,1 and COLUMNS 0,1. Interleaved ROWS and COLUMNS are not supported by the IP i.e. User should not configure ROW0 and ROW3 and COLUMN1 and COLUMN4 etc.
With every Key event, User receives the following information
- Key Code : The keyCode for the key press event detected. Keycode is calculated as ((no of rows * column num) + row num)
- UP/DOWN flag : Whether the key event is for the key press or for the key release event.
- Scan Cycle flag : It is toggled for every scan cycle in which a new event is queued. Use of this flag is optional. If used, it allows the consumer to determine whether an event is detected in the same scan cycle as the previous event or a different one. Note that this flag does not indicate any separation in time.
Keyscan Matrix
Initialization:
The KeyScan driver initialization is according to the Options setup in the passed Config Struct. Several validations are done before the initialization and an error is returned if invalid Modes are requested.
KeyScan Configuration
- Enable/Disable ghost detection
- Enable/Disable wakeup host MCU when key is detected.
- Set the number of rows of key matrix
- Set the no of columns of the key matrix.
- Set the clock to stay on or gated of when no activity is detected.
- Set macro down debounce count.
- Set macro up debounce count.
- Set micro debounce count.
Application then registers for the callback. Driver notifies the user for any events in this callback function.
{
.macroUpDebCnt = 3u,
.microDebCnt = 3u,
.noofRows = 8u,
.noofColumns = 20u,
.ghostEnable = true,
.cpuWakeupEnable = true,
.clkStayOn = true
};
{
}
Interrupt Handling
Keyscan has a dedicated interrupt keyscan_interrupt_IRQn
There are 2 type of interrupts that the software has to check when there is an interrupt
- MXKEYSCAN_INTR_KEY_EDGE_DONE : Used for waking up the system from deepsleep. This should be disabled when the MF clock is active.
- MXKEYSCAN_INTR_FIFO_THRESH_DONE : For all key events
- MXKEYSCAN_INTR_KEY_EDGE_DONE interrupt is mainly used for waking up the system from deepsleep. Applications register for this interrupt before going to deepsleep, then with key event MCU will be woken up.
- MXKEYSCAN_INTR_FIFO_THRESH_DONE interrupt is triggered when there are key press/release events. In the active mode application should be registering only for this interrupt.
Applications have to call Cy_Keyscan_Interrupt_Handler function from keyscan interrupt handler. Applications will be notified of any key events through the registered callback. Applications have to read the events in the callback function by calling Cy_Keyscan_GetNextEvent function in a loop till the return value is CY_KEYSCAN_EVENT_NONE. With every Key event, User receives the following information
- Key Code : The keyCode for the key press event detected. Keycode is calculated as ((no of rows * column num) + row num)
- UP/DOWN flag : Whether the key event is for the key press or for the key release.
- Scan Cycle flag : It is toggled for every scan cycle in which a new event is queued. Use of this flag is optional. If used, it allows the consumer to determine whether an event is detected in the same scan cycle as the previous event or a different one. Note that this flag does not indicate any separation in time.
void keyscan_intHandler(void)
{
uint32_t int_status;
{
{
}
}
else
{
}
}
static void key_detected_callback(void)
{
uint8_t keyCode, scanCycle, upDownFlag;
bool events_pending;
while (events_pending)
{
{
}
{
}
{
continue;
}
(void)keyCode;
(void)scanCycle;
(void)upDownFlag;
}
}
Handling DeepSleep
Following are the points users of keyscan have to handle in their code.
- Normal DeepSleep configuration is MFO clock disabled, LF Clock enabled and edge interrupt enabled.
- When edge interrupt occurs, configure MFO to remain enabled in Deepsleep, disable edge interrupt, and go back to Deepsleep.
- Whenever MFO clock is enabled in the Deepsleep and edge interrupt is disabled, user should start a timer. Every time a key event is detected, user should restart the timer. When timer expires (and/or all keys are considered up), user should go back to Deepsleep with MFO disabled and edge interrupt enabled.
Changelog
| Version | Changes | Reason for Change |
| 1.0 | Initial version | |