欢迎加入交流群:ESP8266 AliOS Things 群 号: 107723112
所有教程请看 AliOS Things 入门教程系列
此教程在SimonLiu的CSDN博客同步更新。
对aos入门的人来说,配网是一件很头疼的事情,但是基本上aos对现有支持的芯片做好了适配。我们以ESP8266为例来分析一下key.c源码如何实现按键配网和清除配网信息的。
源文件: platform/mcu/esp8266/bsp/key.c
。
- 宏定义。
GPIO_Pin_14
作为配网按键。
#define KEY_GPIO_PIN GPIO_Pin_14
#define KEY_GPIO_MODE GPIO_Mode_Input
#define KEY_GPIO_PULLUP GPIO_PullUp_DIS
#define KEY_GPIO_INTRTYPE GPIO_PIN_INTR_NEGEDGE
- 按键初始化并且启用下降沿中断,注册中断回调。
void key_gpio_init(void)
{
GPIO_ConfigTypeDef key_gpio_cnf;
gpio_intr_handler_register(key_gpio_isr, NULL);
key_gpio_cnf.GPIO_Pin = KEY_GPIO_PIN;
key_gpio_cnf.GPIO_Mode = KEY_GPIO_MODE;
key_gpio_cnf.GPIO_Pullup = KEY_GPIO_PULLUP;
key_gpio_cnf.GPIO_IntrType = KEY_GPIO_INTRTYPE;
gpio_config(&key_gpio_cnf);
key_gpio_enable_isr();
}
- 按键中断回调中判断是否GPIO14按下,如果是调用
handle_elink_key()
static void key_gpio_isr(void *arg)
{
uint32_t gpio_status = GPIO_REG_READ(GPIO_STATUS_ADDRESS);
GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, gpio_status);
if (gpio_status & (1 << 14))
handle_elink_key();
}
- 中断回调
handle_elink_key()
内判断是不是一次新按键事件(gpio_value == 0 && elink_time == 0
),如果是,先记录按键发生时间,并且通过aos_schedule_call()来执行key_poll_func()
。
static void handle_elink_key()
{
uint32_t level = GPIO_INPUT_GET(14);
if ((level == 0) && (elink_time == 0)) {
elink_time = aos_now_ms();
aos_schedule_call(key_poll_func, NULL);
// aos_loop_schedule_work(0, key_proc_work, NULL, NULL, NULL);
}
}
-
key_poll_func(void *arg)
判断按键(短按、长按、长长按),分别向系统发出不同的按键事件aos_post_event()
。
static void key_poll_func(void *arg)
{
uint32_t level = GPIO_INPUT_GET(14);
uint64_t diff;
if (level == 0) {
aos_post_delayed_action(10, key_poll_func, NULL);
} else {
diff = aos_now_ms() - elink_time;
if (diff > 6000) { /*long long press */
elink_time = 0;
aos_post_event(EV_KEY, CODE_BOOT, VALUE_KEY_LLTCLICK);
} else if (diff > 2000) { /* long press */
elink_time = 0;
aos_post_event(EV_KEY, CODE_BOOT, VALUE_KEY_LTCLICK);
} else if (diff > 40) { /* short press */
elink_time = 0;
aos_post_event(EV_KEY, CODE_BOOT, VALUE_KEY_CLICK);
if (click_callback) click_callback();
} else {
aos_post_delayed_action(10, key_poll_func, NULL);
}
}
}
在linkkit_example项目中,app_entry.c注册了按键事件回调。
aos_register_event_filter(EV_KEY, linkkit_key_process, NULL);
按键事件回调
linkkit_key_process
中判断如果是短按VALUE_KEY_CLICK
就do_awss_active();
进入配网模式。如果是长按VALUE_KEY_LTCLICK
就清除配网信息。
void linkkit_key_process(input_event_t *eventinfo, void *priv_data)
{
if (eventinfo->type != EV_KEY) {
return;
}
LOG("awss config press %d\n", eventinfo->value);
if (eventinfo->code == CODE_BOOT) {
if (eventinfo->value == VALUE_KEY_CLICK) {
do_awss_active();
} else if (eventinfo->value == VALUE_KEY_LTCLICK) {
do_awss_reset();
}
}
}