NRF_Desktop keyboard example with 4x4 keypad

Good day Everyone

Im trying to incorporate a 4x4 keypad matrix with the nrf_desktop Keyboard.conf example in Zephyr. I would like to send membrane keystrokes via USB and BLE as per original example. I have made the following changes to incorporate the keypad.

 activate CAF

CONFIG_CAF_BUTTONS_EVENT_LIMIT=16

developer.nordicsemi.com/.../buttons.html

In the Buttons_def.h I added my rows and coulombs

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <caf/gpio_pins.h>
/* This configuration file is included only once from button module and holds
* information about pins forming keyboard matrix.
*/
/* This structure enforces the header file is included only once in the build.
* Violating this requirement triggers a multiple definition error at link time.
*/
const struct {} buttons_def_include_once;
static const struct gpio_pin col[] = {
//4x4 keypad col GPIO (1,4 | 1,3 | 1,2 | 1,1) as per overlay file
{ .port = 1, .pin = DT_GPIO_PIN(DT_NODELABEL(col1), gpios) },
{ .port = 1, .pin = DT_GPIO_PIN(DT_NODELABEL(col2), gpios) },
{ .port = 1, .pin = DT_GPIO_PIN(DT_NODELABEL(col3), gpios) },
{ .port = 1, .pin = DT_GPIO_PIN(DT_NODELABEL(col4), gpios) },
};
static const struct gpio_pin row[] = {
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

In the buttons_sim_def.h I have added my keystroke array.

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
* Copyright (c) 2020 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/
#include <caf/key_id.h>
#include "usb_hid_codes.h"
/* This configuration file is included only once from buttons_sim module
* and holds information about generated button presses sequence.
*/
/* This structure enforces the header file is included only once in the build.
* Violating this requirement triggers a multiple definition error at link time.
*/
const struct {} buttons_sim_def_include_once;
const static uint16_t simulated_key_sequence[] = {
KEY_ID(0x00, 0x11), /* N */
KEY_ID(0x00, 0x12), /* O */
KEY_ID(0x00, 0x15), /* R */
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

In the App.overlay I have added the rows and column pin configuration

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{
chosen {
nordic,pm-ext-flash = &mx25r64;
};
};
/ {
chosen {
/*
* In some default configurations within the nRF Connect SDK,
* e.g. on nRF52840 and nRF9160, the chosen zephyr,entropy node
* is &cryptocell. This devicetree overlay ensures that default
* is overridden wherever it is set, as this application uses
* the RNG node for entropy exclusively.
*/
zephyr,entropy = &rng;
};
rows {
compatible = "gpio-leds";
row1: row_1 {
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
 

Im a bit stuck now as I need to now scan the matrix return the value from the array and send as per example to BLE and USB.

I was thinking of using a timer to scan the keypad every 150ms return. 

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
char keypad[ROWS][COLS] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
char read_keypad(){
for (int row_no = 0; row_no < 4; row_no++) {
gpio_pin_set_dt(&row1, row_no == 0 ? 0 : 1);
gpio_pin_set_dt(&row2, row_no == 1 ? 0 : 1);
gpio_pin_set_dt(&row3, row_no == 2 ? 0 : 1);
gpio_pin_set_dt(&row4, row_no == 3 ? 0 : 1);
if (gpio_pin_get_dt(&col1)) return keypad[row_no][0];
if (gpio_pin_get_dt(&col2)) return keypad[row_no][1];
if (gpio_pin_get_dt(&col3)) return keypad[row_no][2];
if (gpio_pin_get_dt(&col4)) return keypad[row_no][3];
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

from the timer

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
static void mytimer_cb(struct k_timer *dummy){
char key = read_keypad();
static uint8_t * p_key = keypadkey;
if (key != '\0' ){
printk (" %c\n ", key);
switch (key){
case '8': **send this somhow**(membrane_key_stroke_to_send);
break;
case '2' : **send this somhow**(membrane_key_stroke_to_send+1);
break;
case '4' : **send this somhow**(membrane_key_stroke_to_send+2);
break;
case '6' : **send this somhow**( membrane_key_stroke_to_send+3);
break;
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

If I look at https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/nrf/libraries/caf/caf_overview.html#c.button_event.key_id

It would seem the 4x4 keypad module could work out the box without me adding anything.  It may also be worth mentioning, that the 1st column on the keypad when pressed does result in the keys 'a', 'b' , 'c', d' being transmitted. Not sure where that comes from. the other columns do not respond. 

Thanks in advance as always