1 Star 4 Fork 2

HarmonyHub/DTButton

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
dt_btn_util.c 6.51 KB
一键复制 编辑 原始数据 按行查看 历史
鉴客 提交于 2020-11-12 16:27 . init
/*
=======================================================================================
File:
dt_btn_util.c
Description:
The implementation for phisical button utility functions.
Author:
Delphi Tang (唐佐林)
http://www.dt4sw.com/
Revision History:
V0.0.1 (Initial Version)
V0.0.2 (
1. Do refactory for the interface to encapsulate the vendor SDK details
2. Move event handler call to a special thread to avoid heavy process in ISR
3. Trigger long-pressed-event after pressed-event for about 2.5 seconds
)
=======================================================================================
*/
#include <unistd.h>
#include <string.h>
#include "cmsis_os2.h"
#include "hi_systick.h"
#include "wifiiot_gpio.h"
#include "wifiiot_gpio_ex.h"
#include "dt_btn_util.h"
#define BUTTON_STACK_SIZE 2048
#define PRESS_INTERVAL 20000
#define LOOP_INTERVAL 40000
#define LONG_PRESS_INTERVAL 64
#define LONG_PRESS_END 0xFFFF
#define INDEX_ERR -1
typedef struct
{
const char* name;
unsigned int gpio;
unsigned int event;
PBtnCallback callback;
} ButtonInfo;
typedef struct
{
int pressClicked;
int longPressClicked;
int longPressInterval;
int releaseClicked;
} ButtonClicked;
static volatile hi_u64 gHisTick = 0;
static volatile int gToClick = 0;
static volatile int gIsInit = 0;
static const char* gBtnName[] = {
"GPIO_0", "GPIO_1", "GPIO_2", "GPIO_3", "GPIO_4",
"GPIO_5", "GPIO_6", "GPIO_7", "GPIO_8", "GPIO_9",
"GPIO_10", "GPIO_11", "GPIO_12", "GPIO_13", "GPIO_14",
NULL
};
static volatile ButtonInfo gBtnInfo[WIFI_IOT_IO_NAME_MAX] = {0};
static volatile ButtonClicked gBtnClicked[WIFI_IOT_IO_NAME_MAX] = {0};
static void OnButtonPressed(char* arg);
static void OnButtonReleased(char* arg);
static int GetGpioIndex(const char* name)
{
int ret = INDEX_ERR;
int i = 0;
while( gBtnName[i] && name )
{
if( strcmp(gBtnName[i], name) == 0 )
{
ret = i;
break;
}
i++;
}
return ret;
}
static void OnButtonPressed(char* arg)
{
WifiIotIoName gpio = (WifiIotIoName)arg;
hi_u64 tick = hi_systick_get_cur_tick();
gToClick = (tick - gHisTick) > PRESS_INTERVAL;
if( gToClick )
{
gHisTick = tick;
gBtnClicked[gpio].pressClicked = 1;
GpioRegisterIsrFunc(gpio,
WIFI_IOT_INT_TYPE_EDGE,
WIFI_IOT_GPIO_EDGE_RISE_LEVEL_HIGH,
OnButtonReleased, arg);
}
}
static void OnButtonReleased(char* arg)
{
WifiIotIoName gpio = (WifiIotIoName)arg;
if( gToClick )
{
gBtnClicked[gpio].releaseClicked = 1;
GpioRegisterIsrFunc(gpio,
WIFI_IOT_INT_TYPE_EDGE,
WIFI_IOT_GPIO_EDGE_FALL_LEVEL_LOW,
OnButtonPressed, arg);
}
}
static void CommonEventHandler(void)
{
int i = 0;
for(i=0; i<WIFI_IOT_IO_NAME_MAX; i++)
{
const char* name = gBtnInfo[i].name;
if( (gBtnInfo[i].event & Pressed) && gBtnClicked[i].pressClicked )
{
gBtnInfo[i].callback(name, Pressed);
gBtnClicked[i].pressClicked = 0;
gBtnClicked[i].longPressInterval = 0;
}
if( gBtnClicked[i].longPressInterval < LONG_PRESS_END )
{
gBtnClicked[i].longPressInterval++;
}
if( gBtnClicked[i].longPressInterval == LONG_PRESS_INTERVAL )
{
gBtnClicked[i].longPressClicked = 1;
}
if( (gBtnInfo[i].event & LongPressed) && gBtnClicked[i].longPressClicked )
{
gBtnInfo[i].callback(name, LongPressed);
gBtnClicked[i].longPressClicked = 0;
gBtnClicked[i].longPressInterval = LONG_PRESS_END;
}
if( (gBtnInfo[i].event & Released) && gBtnClicked[i].releaseClicked )
{
gBtnInfo[i].callback(name, Released);
gBtnClicked[i].releaseClicked = 0;
gBtnClicked[i].longPressInterval= LONG_PRESS_END;
}
}
}
static void* DTButton_Task(const char* arg)
{
(void)arg;
while( gIsInit )
{
CommonEventHandler();
usleep(LOOP_INTERVAL);
}
return NULL;
}
int DTButton_Init(void)
{
int ret = (int)GpioInit();
if( ret == (int)HI_ERR_GPIO_REPEAT_INIT )
{
ret = 0;
}
if( !ret && !gIsInit )
{
int i = 0;
osThreadAttr_t attr = {0};
for(i=0; i<WIFI_IOT_IO_NAME_MAX; i++)
{
gBtnClicked[i].longPressInterval = LONG_PRESS_END;
}
attr.name = "DTButton_Task";
attr.attr_bits = 0U;
attr.cb_mem = NULL;
attr.cb_size = 0U;
attr.stack_mem = NULL;
attr.stack_size = BUTTON_STACK_SIZE;
attr.priority = osPriorityNormal;
ret += (osThreadNew((osThreadFunc_t)DTButton_Task, NULL, &attr) == NULL);
gIsInit = (ret == 0);
}
return ret;
}
void DTButton_Deinit(void)
{
gIsInit = 0;
}
int DTButton_Enable(const char* name, PBtnCallback callback, unsigned int event)
{
int ret = -1;
int gpio = name ? GetGpioIndex(name) : INDEX_ERR;
if( (WIFI_IOT_IO_NAME_GPIO_0 <= gpio) && (gpio < WIFI_IOT_IO_NAME_MAX) && callback && event)
{
ret = IoSetFunc((WifiIotIoName)gpio, 0);
ret += GpioSetDir((WifiIotIoName)gpio, WIFI_IOT_GPIO_DIR_IN);
ret += IoSetPull((WifiIotIoName)gpio, WIFI_IOT_IO_PULL_UP);
ret += GpioRegisterIsrFunc((WifiIotIoName)gpio,
WIFI_IOT_INT_TYPE_EDGE,
WIFI_IOT_GPIO_EDGE_FALL_LEVEL_LOW,
OnButtonPressed, (char*)gpio);
}
if( ret == 0 )
{
gBtnInfo[gpio].name = name;
gBtnInfo[gpio].gpio = gpio;
gBtnInfo[gpio].event = event;
gBtnInfo[gpio].callback = callback;
}
return ret;
}
void DTButton_Disable(const char* name)
{
int gpio = name ? GetGpioIndex(name) : INDEX_ERR;
if( gpio != INDEX_ERR )
{
gBtnInfo[gpio].name = 0;
gBtnInfo[gpio].gpio = 0;
gBtnInfo[gpio].event = 0;
gBtnInfo[gpio].callback = 0;
}
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C
1
https://gitee.com/harmonyhub/dtbutton.git
git@gitee.com:harmonyhub/dtbutton.git
harmonyhub
dtbutton
DTButton
master

搜索帮助

Cb406eda 1850385 E526c682 1850385