[feat][keyscan] add keyscan demo and hal driver

This commit is contained in:
jzlv 2021-07-12 17:03:54 +08:00
parent bb026b1d99
commit e5f1ef82c8
8 changed files with 401 additions and 0 deletions

View file

@ -0,0 +1,89 @@
/**
* @file hal_keyscan.h
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#ifndef __HAL_KEYSCAN__H__
#define __HAL_KEYSCAN__H__
#include "drv_device.h"
#include "bl702_config.h"
#define DEVICE_CTRL_KEYSCAN_GET_KEYCODE 0x10
enum keyscan_index_type {
#ifdef BSP_USING_KEYSCAN
KEYSCAN_INDEX,
#endif
KEYSCAN_MAX_INDEX
};
enum col_num_type {
COL_NUM_1 = 1,
COL_NUM_2,
COL_NUM_3,
COL_NUM_4,
COL_NUM_5,
COL_NUM_6,
COL_NUM_7,
COL_NUM_8,
COL_NUM_9,
COL_NUM_10,
COL_NUM_11,
COL_NUM_12,
COL_NUM_13,
COL_NUM_14,
COL_NUM_15,
COL_NUM_16,
COL_NUM_17,
COL_NUM_18,
COL_NUM_19,
COL_NUM_20
};
enum row_num_type {
ROW_NUM_1 = 1,
ROW_NUM_2,
ROW_NUM_3,
ROW_NUM_4,
ROW_NUM_5,
ROW_NUM_6,
ROW_NUM_7,
ROW_NUM_8,
};
enum keyscan_event_type {
KEYSCAN_EVENT_TRIG,
KEYSCAN_EVENT_UNKNOWN
};
typedef struct keyscan_device {
struct device parent;
enum col_num_type col_num;
enum row_num_type row_num;
uint8_t deglitch_count;
} keyscan_device_t;
#define KEYSCAN_DEV(dev) ((keyscan_device_t *)dev)
int keyscan_register(enum keyscan_index_type index, const char *name);
#endif

View file

@ -0,0 +1,154 @@
/**
* @file hal_keyscan.c
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#include "hal_keyscan.h"
#include "kys_reg.h"
#include "bl702_glb.h"
static keyscan_device_t keyscan_device[KEYSCAN_MAX_INDEX] = {
#ifdef BSP_USING_KEYSCAN
KEYSCAN_CONFIG
#endif
};
static void KeyScan_IRQ(void);
/**
* @brief
*
* @param dev
* @param oflag
* @return int
*/
int keyscan_open(struct device *dev, uint16_t oflag)
{
uint32_t tmpVal;
keyscan_device_t *keyscan_device = (keyscan_device_t *)dev;
tmpVal = BL_RD_REG(KYS_BASE, KYS_KS_CTRL);
/* Set col and row */
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, KYS_COL_NUM, keyscan_device->col_num - 1);
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, KYS_ROW_NUM, keyscan_device->row_num - 1);
/* Set idle duration between column scans */
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, KYS_RC_EXT, 0);
/* ghost key event detection not support*/
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, KYS_GHOST_EN, 0);
if (keyscan_device->deglitch_count) {
/* Enable or disable deglitch function */
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, KYS_DEG_EN, 1);
/* Set deglitch count */
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, KYS_DEG_CNT, keyscan_device->deglitch_count);
} else {
/* Enable or disable deglitch function */
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, KYS_DEG_EN, 0);
/* Set deglitch count */
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, KYS_DEG_CNT, 0);
}
/* Write back */
BL_WR_REG(KYS_BASE, KYS_KS_CTRL, tmpVal);
return 0;
}
int keyscan_control(struct device *dev, int cmd, void *args)
{
switch (cmd) {
case DEVICE_CTRL_SET_INT /* constant-expression */:
Interrupt_Handler_Register(KYS_IRQn, KeyScan_IRQ);
BL_WR_REG(KYS_BASE, KYS_KS_INT_EN, 1);
NVIC_EnableIRQ(KYS_IRQn);
break;
case DEVICE_CTRL_CLR_INT /* constant-expression */:
Interrupt_Handler_Register(KYS_IRQn, NULL);
BL_WR_REG(KYS_BASE, KYS_KS_INT_EN, 0);
NVIC_DisableIRQ(KYS_IRQn);
break;
case DEVICE_CTRL_GET_INT:
return (BL_RD_REG(KYS_BASE, KYS_KS_INT_STS) & 0xf);
case DEVICE_CTRL_RESUME: {
uint32_t tmpVal;
tmpVal = BL_RD_REG(KYS_BASE, KYS_KS_CTRL);
BL_WR_REG(KYS_BASE, KYS_KS_CTRL, BL_SET_REG_BIT(tmpVal, KYS_KS_EN));
} break;
case DEVICE_CTRL_SUSPEND: {
uint32_t tmpVal;
tmpVal = BL_RD_REG(KYS_BASE, KYS_KS_CTRL);
BL_WR_REG(KYS_BASE, KYS_KS_CTRL, BL_CLR_REG_BIT(tmpVal, KYS_KS_EN));
} break;
case DEVICE_CTRL_KEYSCAN_GET_KEYCODE: {
uint32_t *key_code = (uint32_t *)args;
*key_code = BL_RD_REG(KYS_BASE, KYS_KEYCODE_VALUE);
BL_WR_REG(KYS_BASE, KYS_KEYCODE_CLR, 0xf);
} break;
default:
break;
}
return 0;
}
/**
* @brief
*
* @param index
* @param name
* @param flag
* @return int
*/
int keyscan_register(enum keyscan_index_type index, const char *name)
{
struct device *dev;
if (KEYSCAN_MAX_INDEX == 0) {
return -DEVICE_EINVAL;
}
dev = &(keyscan_device[index].parent);
dev->open = keyscan_open;
dev->close = NULL;
dev->control = keyscan_control;
dev->write = NULL;
dev->read = NULL;
dev->status = DEVICE_UNREGISTER;
dev->type = DEVICE_CLASS_KEYSCAN;
dev->handle = NULL;
return device_register(dev, name, 0);
}
static void KeyScan_IRQ(void)
{
if (keyscan_device[0].parent.callback) {
keyscan_device[0].parent.callback(&keyscan_device[0].parent, (void *)(BL_RD_REG(KYS_BASE, KYS_KEYCODE_VALUE)), 0, KEYSCAN_EVENT_TRIG);
}
BL_WR_REG(KYS_BASE, KYS_KEYCODE_CLR, 0xf);
}

View file

@ -0,0 +1,5 @@
set(mains main.c)
generate_bin()

View file

@ -0,0 +1,56 @@
/**
* @file main.c
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#include "hal_uart.h"
#include "hal_keyscan.h"
static void keyscan_irq_callback(struct device *dev, void *args, uint32_t size, uint32_t state)
{
uint32_t key_code = (uint32_t)args;
MSG("Keycode0 value: %d\r\n", key_code & 0xff);
MSG("Keycode1 value: %d\r\n", (key_code & 0xff00) >> 8);
MSG("Keycode2 value: %d\n", (key_code & 0xff0000) >> 16);
MSG("Keycode3 value: %d\r\n", (key_code & 0xff000000) >> 24);
}
int main(void)
{
bflb_platform_init(0);
keyscan_register(KEYSCAN_INDEX, "4x4_keyscan");
struct device *keyscan = device_find("4x4_keyscan");
if (keyscan) {
KEYSCAN_DEV(keyscan)->col_num = COL_NUM_4;
KEYSCAN_DEV(keyscan)->row_num = ROW_NUM_4;
device_open(keyscan, 0); //current scan latency is 32M/1/8 = 4Khz
device_set_callback(keyscan, keyscan_irq_callback);
device_control(keyscan, DEVICE_CTRL_SET_INT, NULL);
device_control(keyscan, DEVICE_CTRL_RESUME, NULL);
MSG("keyscan found\n");
}
BL_CASE_SUCCESS;
while (1) {
bflb_platform_delay_ms(100);
}
}

View file

@ -0,0 +1,19 @@
**board/bl706_iot/pinmux_config.h** 中, 以下宏设置成 **GPIO_FUN_KEY_SCAN_ROW**
- **CONFIG_GPIO16_FUNC**
- **CONFIG_GPIO17_FUNC**
- **CONFIG_GPIO18_FUNC**
- **CONFIG_GPIO19_FUNC**
**board/bl706_iot/pinmux_config.h** 中, 以下宏设置成 **GPIO_FUN_KEY_SCAN_COL**
- **CONFIG_GPIO0_FUNC**
- **CONFIG_GPIO1_FUNC**
- **CONFIG_GPIO2_FUNC**
- **CONFIG_GPIO3_FUNC**
```bash
$ make APP=keyscan_it BOARD=bl706_iot
```

View file

@ -0,0 +1,5 @@
set(mains main.c)
generate_bin()

View file

@ -0,0 +1,54 @@
/**
* @file main.c
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#include "hal_uart.h"
#include "hal_keyscan.h"
int main(void)
{
bflb_platform_init(0);
keyscan_register(KEYSCAN_INDEX, "4x4_keyscan");
struct device *keyscan = device_find("4x4_keyscan");
if (keyscan) {
KEYSCAN_DEV(keyscan)->col_num = COL_NUM_4;
KEYSCAN_DEV(keyscan)->row_num = ROW_NUM_4;
device_open(keyscan, 0); //current scan latency is 32M/1/8 = 4Khz
device_control(keyscan, DEVICE_CTRL_RESUME, NULL);
MSG("keyscan found\n");
}
BL_CASE_SUCCESS;
uint32_t key_code;
while (1) {
/*get it status*/
while (device_control(keyscan, DEVICE_CTRL_GET_INT, NULL) == 0) {
}
device_control(keyscan, DEVICE_CTRL_KEYSCAN_GET_KEYCODE, &key_code);
MSG("Keycode0 value: %d\r\n", key_code & 0xff);
MSG("Keycode1 value: %d\r\n", (key_code & 0xff00) >> 8);
MSG("Keycode2 value: %d\n", (key_code & 0xff0000) >> 16);
MSG("Keycode3 value: %d\r\n", (key_code & 0xff000000) >> 24);
bflb_platform_delay_ms(100);
}
}

View file

@ -0,0 +1,19 @@
**board/bl706_iot/pinmux_config.h** 中, 以下宏设置成 **GPIO_FUN_KEY_SCAN_ROW**
- **CONFIG_GPIO16_FUNC**
- **CONFIG_GPIO17_FUNC**
- **CONFIG_GPIO18_FUNC**
- **CONFIG_GPIO19_FUNC**
**board/bl706_iot/pinmux_config.h** 中, 以下宏设置成 **GPIO_FUN_KEY_SCAN_COL**
- **CONFIG_GPIO0_FUNC**
- **CONFIG_GPIO1_FUNC**
- **CONFIG_GPIO2_FUNC**
- **CONFIG_GPIO3_FUNC**
```bash
$ make APP=keyscan_poll BOARD=bl706_iot
```