蓝牙BLE芯片PHY6222之GPIO按键操作
按键唤醒
IO初始化
void key_init(void)
{
uint8 i;
key_state.key[0].pin = GPIO_P14;
key_state.key[0].idle_level = HAL_HIGH_IDLE;
hal_gpio_pin_init(P14, IE);
hal_gpio_pull_set(P14, GPIO_PULL_UP_S);
key_state.key_callbank = key_press_evt;//按键按下触发的回调
hal_gpioin_register(P14, pin_event_handler, pin_event_handler);//可配置成GPIO的引脚都可产生中断唤醒
hal_pwrmgr_register(MOD_USR1, NULL, NULL);
}
static void key_press_evt(uint8_t i, key_evt_t key_evt)
{
LOG("\nkey index:%d gpio:%d ", i, key_state.key[i].pin);
switch(key_evt)
{
case HAL_KEY_EVT_PRESS:
LOG("key(press down)\n");
break;
case HAL_KEY_EVT_RELEASE:
LOG("key(press release)\n");
break;
#ifdef HAL_KEY_SUPPORT_LONG_PRESS
case HAL_KEY_EVT_LONG_RELEASE:
hal_pwrmgr_unlock(MOD_USR1);
LOG("key(long press release)\n");
break;
#endif
default:
LOG("unexpect\n");
break;
}
}
按键中断唤醒回调
static void pin_event_handler(gpio_pin_e pin,IO_Wakeup_Pol_e type)
{
uint8 i;
for(i = 0; i < HAL_KEY_NUM; i++)
{
if(pin == key_state.key[i].pin)
break;
}
if(i < HAL_KEY_NUM)
{
switch(key_state.key[i].state)
{
case HAL_STATE_KEY_IDLE:
key_idle_handler(i,type);
break;
case HAL_STATE_KEY_PRESS_DEBOUNCE:
key_press_debonce_handler(i,type);
break;
case HAL_STATE_KEY_PRESS:
key_press_handler(i,type);
break;
case HAL_STATE_KEY_RELEASE_DEBOUNCE:
key_release_debonce_handler(i,type);
break;
default:
break;
}
}
}
static void key_idle_handler(uint8 i,IO_Wakeup_Pol_e type)
{
if(((type == NEGEDGE) && (key_state.key[i].idle_level == HAL_HIGH_IDLE)) ||
((type == POSEDGE) && (key_state.key[i].idle_level == HAL_LOW_IDLE)))
{
hal_pwrmgr_lock(MOD_USR1);//lock住mod_usr1---禁止睡眠
key_state.key[i].state = HAL_STATE_KEY_PRESS_DEBOUNCE;//改变状态
key_state.temp[i].in_enable = TRUE;
key_timer_start(HAL_KEY_DEBOUNCD);//20ms消抖
}
}
static void key_press_debonce_timer_handler(uint8 i)
{
//读取IO的状态
if(((hal_gpio_read(key_state.key[i].pin) == FALSE) && (key_state.key[i].idle_level == HAL_HIGH_IDLE)) ||
((hal_gpio_read(key_state.key[i].pin) == TRUE) && (key_state.key[i].idle_level == HAL_LOW_IDLE)))
{
#ifdef HAL_KEY_SUPPORT_LONG_PRESS
//3s后读取状态,触发按键长按的事件
osal_start_timerEx(key_state.task_id,KEY_DEMO_LONG_PRESS_EVT,HAL_KEY_LONG_PRESS_TIME);
#endif
hal_pwrmgr_unlock(MOD_USR1);
key_state.key[i].state = HAL_STATE_KEY_PRESS;
key_state.temp[i].timer_tick = getMcuPrecisionCount();
if(key_state.key_callbank != NULL)
{
key_state.key_callbank(i,HAL_KEY_EVT_PRESS);//执行初始化时key_press_evt的回调
}
}
else
{
key_state.key[i].state = HAL_STATE_KEY_IDLE;
key_state.temp[i].in_enable = FALSE;
}
}
短按&长按触发的事件
if( events & HAL_KEY_EVENT) //do not modify,key will use it
{
for (uint8 i = 0; i < HAL_KEY_NUM; ++i)
{
if ((key_state.temp[i].in_enable == TRUE) ||
(key_state.key[i].state == HAL_STATE_KEY_RELEASE_DEBOUNCE))
{
gpio_key_timer_handler(i);
}
}
return (events ^ HAL_KEY_EVENT);
}
#ifdef HAL_KEY_SUPPORT_LONG_PRESS
if( events & KEY_DEMO_LONG_PRESS_EVT)
{
for (int i = 0; i < HAL_KEY_NUM; ++i)
{
if(key_state.key[i].state == HAL_KEY_EVT_PRESS)
{
LOG("key:%d gpio:%d ", i, key_state.key[i].pin);
LOG("key(long press down)");
//user app code long press down process这里实现长按的应用操作
}
}
return (events ^ KEY_DEMO_LONG_PRESS_EVT);
}
#endif
注意:在PHY622的J版本(新版本)的芯片上要把P16,P17配置成GPIO的话可参考以下设置,J版本以前的芯片不支持配置成GPIO