Supported ICs
Introduction
As a keyboard scanning device, Key-Scan provides freely configurable row and column numbers, supporting up to an 8 x 8 key matrix.
Key-Scan supports the following features:
Configurable number of rows and columns to accommodate various keypad sizes.
Multi-key detection, allowing up to 6 keys to be pressed simultaneously
Two working modes: event-driven mode and regular scanning mode
Stuck key detection
Low power mode and wakeup functionality
Block Diagram
The block diagram of Key-Scan is illustrated in the following figure.
Key-Scan contains 6 key Components:
Interrupt Control: control and manage interrupts
Registers and FIFO: configure Key-Scan parameters and FIFO
Clock: 131KHz clock for key-stuck detection and low-power wake-up
Keypad Control: scanning logic, wakeup control, and input/output control
Keypad: 16 GPIOs for 8x8 array implementation
Keypad
The rows and columns of Key-Scan are configurable, with both the maximum number of columns and rows supported up to 8.
8x8 Key Matrix Configuration
After a key is pressed, the complete scanning process is as follows:
In the initial state, all columns output a low level, and all rows are configured as inputs with internal pull-ups.
When one or more keys are pressed (creating a short circuit between a row and a column), the input level of the corresponding row changes from high to low. This triggers the internal state machine to start the keypad scanning process, in order to determine the row and column of the pressed key(s).
The state machine sets the first column to output low while all other columns are set to high impedance (Hi-Z), then scans all rows to detect which keys are pressed. Next, it sets the second column to output low, with all other columns in Hi-Z, and repeats this process until all columns have been scanned.
After two complete scans of the entire key matrix, the pressed keys are finally confirmed.
When all keys are released, Key-Scan still performs two full scans of the matrix. Once it confirms that no key is pressed, the scanning ends and the state machine stops.
The following figure illustrates the scan timing sequence after a key is pressed on a 2 x 2 keypad.
Keypad Scan Timing
There are three configurable timers used in the keypad scanning process:
Debounce Timer: Two consecutive full keypad scans constitute one complete full scan; a debounce timer runs between these two full scans. Additionally, there is an extra debounce timing before the first full keypad scan.
Scan Interval Timer: There is a waiting period defined by the scan interval timer between two consecutive full scans.
All Keys Released Timer: When all keys are released, Key-Scan will still perform a full scan (two rounds of full keypad scans). Once scanning confirms that no keys are pressed, the release timer starts. After this timer expires, the state machine will stop.
Work Mode
Key-Scan contains two work modes: Event Trigger Mode and Regular Scan Mode.
Work mode |
Description |
---|---|
Event Trigger |
key press/release event is stored in the FIFO only once during each key press/release operation |
Regular Scan |
At each full scan, any key press event is stored in the FIFO until it is released |
The following figure shows the difference of FIFO items between Event Trigger Mode and Regular Scan Mode during a key press and release.
In most cases, the event-driven mode is more commonly used. In this mode, continuous scanning is not required; the key matrix is only scanned when a key state change is detected.
FIFO Mechanism
The FIFO of Key-Scan has a depth of 16 and an entry width of 12 bits. The FIFO structure of Key-Scan is illustrated below.
Bit |
Indication |
Description |
---|---|---|
[8] |
Event |
|
[7:4] |
Row index |
|
[3:0] |
Column index |
|
Key Stuck Detection
In actual use, key sticking may occur. If a key is not released in time, the Key-Scan state machine will continue to scan and cannot enter the IDLE state.
To address this issue, Key-Scan supports automatic detection of stuck keys.
Stuck Key Detection: When this feature is enabled, if the duration of a key press exceeds the configured threshold, the key will be considered a stuck key and a stuck key interrupt will be triggered. Users can mask the row of the stuck key in the stuck key interrupt handler.
Stuck Key Masking: The status of stuck keys can be obtained by reading the stuck key status register. By setting the default state of the row containing the stuck key, when Key-Scan scans this row, it will consider that no keys are pressed in that row, allowing the system to smoothly enter the IDLE state.
Stuck Key UnMask: There are two methods:
Once the stuck key is released, a stuck key interrupt will be triggered. Users can unmask the row of the stuck key in this interrupt handler.
The key in the row of non-stuck keys is pressed, the scan state machine is triggered and a scan interrupt is generated. Users can unmask the row of the stuck key in the interrupt handler.
Note
After a stuck key is masked:
Pressing other keys in the same row as the stuck key will not trigger the Key-Scan scan state machine.
Only keys in the row of non-stuck keys can trigger the Key-Scan scan state machine. After the scan state machine is awakened, if the mask state on the stuck key’s row has not been cleared, other keys in that row still cannot be recognized, while keys in non-stuck rows are recognized normally.
Usage
Normal Operation
To use Key-Scan in either Event Trigger Mode or Regular Scan Mode, perform the following steps:
Configure the pin multiplexing for Key-Scan keypads.
Set the column pins to no pull and configure the column pin multiplexing function.
PAD_PullCtrl(pad_colx, GPIO_PuPd_NOPULL); Pinmux_Config(pad_colx, PINMUX_FUNCTION_KEY_COLx);
Set the row pins to pull-up and configure the row pin multiplexing function.
PAD_PullCtrl(pad_rowx, GPIO_PuPd_UP); Pinmux_Config(pad_rowx, PINMUX_FUNCTION_KEY_ROWx);
Initialize Key-Scan parameters.
Select the number of key rows and columns (one bit corresponds to one row or column) according to keypads, and set work mode to Event Trigger Mode or Regular Scan Mode, etc.
KeyScan_StructInit(&KeyScan_InitStruct); KeyScan_InitStruct.KS_ColSel = 0xFF; //8 columns KeyScan_InitStruct.KS_RowSel = 0xFF; //8 rows KeyScan_InitStruct.KS_WorkMode = KS_EVENT_TRIGGER_MODE; KeyScan_Init(KeyScan, &KeyScan_InitStruct);
KeyScan_StructInit(&KeyScan_InitStruct); KeyScan_InitStruct.KS_ColSel = 0xFF; //8 columns KeyScan_InitStruct.KS_RowSel = 0xFF; //8 rows KeyScan_InitStruct.KS_WorkMode = KS_REGULAR_SCAN_MODE; KeyScan_Init(KeyScan, &KeyScan_InitStruct);
Enable Key-Scan interrupt and register Key-Scan interrupt handler.
Enable Key-Scan.
KeyScan_Cmd(KeyScan, ENABLE);
Wait for the Key-Scan interrupt and handle items.
Key Stuck Handling
When a stuck key occurs, perform the following steps:
Configure the pin multiplexing for Key-Scan keypads.
Set the column pins to no pull and configure the column pin multiplexing function.
PAD_PullCtrl(pad_colx, GPIO_PuPd_NOPULL); Pinmux_Config(pad_colx, PINMUX_FUNCTION_KEY_COLx);
Set the row pins to pull-up and configure the row pin multiplexing function.
PAD_PullCtrl(pad_rowx, GPIO_PuPd_UP); Pinmux_Config(pad_rowx, PINMUX_FUNCTION_KEY_ROWx);
Initialize Key-Scan parameters.
Select the number of key rows and columns (one bit corresponds to one row or column) according to keypads, and set work mode to Regular Scan Mode, etc.
KeyScan_StructInit(&KeyScan_InitStruct); KeyScan_InitStruct.KS_ColSel = 0xFF; //8 columns KeyScan_InitStruct.KS_RowSel = 0xFF; //8 rows KeyScan_Init(KeyScan, &KeyScan_InitStruct);
Enable the Key-Scan stuck key auto-detection function.
KeyScan_StuckAutoCmd(KeyScan, ENABLE);
Set the stuck time threshold and configure the stuck row detection time and interval.
KeyScan_SetStuckThreshold(KeyScan, 10); //stuck time threshold: 10ms KeyScan_StuckPeriodicalPull(KeyScan,2000,4000);//pull time:2000us, no pull time:4000us
5. Enable the Key-Scan stuck key and all default interrupts, and register the Key-Scan interrupt handler. 7. Enable Key-Scan.
KeyScan_Cmd(KeyScan, ENABLE);
Wait for the Key-Scan interrupt and handle it.
In stuck key event interrupt, get the row status, set the default row status to indicate stuck row, and mask all the keys of the stuck row.
row_status = KeyScan_GetStuckRow(KeyScan); KeyScan_SetStuckRow(KeyScan, row_status);
In all default interrupts, reset row default status to initial value, disable all default interrupt, enable scan event interrupt and all release the interrupt, then other keys except the stuck key can work normally.
KeyScan_INTConfig(KeyScan, KS_BIT_ALL_DEFAULT_INT_MASK, DISABLE); KeyScan_SetStuckRow(KeyScan, 0); KeyScan_INTConfig(KeyScan, KS_BIT_ALL_RELEASE_INT_MASK | KS_BIT_SCAN_EVENT_INT_MASK, ENABLE);
Key or keys except the stuck key press or release will generate the corresponding interrupts normally.