mirror of
https://github.com/Fishwaldo/bl_mcu_sdk.git
synced 2025-07-09 14:28:37 +00:00
[feat][keyscan] add keyscan demo and hal driver
This commit is contained in:
parent
bb026b1d99
commit
e5f1ef82c8
8 changed files with 401 additions and 0 deletions
89
drivers/bl702_driver/hal_drv/inc/hal_keyscan.h
Normal file
89
drivers/bl702_driver/hal_drv/inc/hal_keyscan.h
Normal 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
|
154
drivers/bl702_driver/hal_drv/src/hal_keyscan.c
Normal file
154
drivers/bl702_driver/hal_drv/src/hal_keyscan.c
Normal 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);
|
||||
}
|
5
examples/keyscan/keyscan_it/CMakeLists.txt
Normal file
5
examples/keyscan/keyscan_it/CMakeLists.txt
Normal file
|
@ -0,0 +1,5 @@
|
|||
set(mains main.c)
|
||||
generate_bin()
|
||||
|
||||
|
||||
|
56
examples/keyscan/keyscan_it/main.c
Normal file
56
examples/keyscan/keyscan_it/main.c
Normal 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);
|
||||
}
|
||||
}
|
19
examples/keyscan/keyscan_it/readme.md
Normal file
19
examples/keyscan/keyscan_it/readme.md
Normal 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
|
||||
|
||||
```
|
5
examples/keyscan/keyscan_poll/CMakeLists.txt
Normal file
5
examples/keyscan/keyscan_poll/CMakeLists.txt
Normal file
|
@ -0,0 +1,5 @@
|
|||
set(mains main.c)
|
||||
generate_bin()
|
||||
|
||||
|
||||
|
54
examples/keyscan/keyscan_poll/main.c
Normal file
54
examples/keyscan/keyscan_poll/main.c
Normal 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);
|
||||
}
|
||||
}
|
19
examples/keyscan/keyscan_poll/readme.md
Normal file
19
examples/keyscan/keyscan_poll/readme.md
Normal 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
|
||||
|
||||
```
|
Loading…
Add table
Add a link
Reference in a new issue