/********************************* (C) РОТЕК *********************************** * @module buttons * @file buttons.c * @version 1.0.0 * @date XX.XX.XXXX * $brief buttons ******************************************************************************* * @history Version Author Comment * XX.XX.XXXX 1.0.0 Telenkov D.A. First release. ******************************************************************************* */ #include "stm32f4xx.h" #include "buttons.h" #include "led.h" #include "settings_api.h" #include "web_params_api.h" #include "log.h" #include "snmp_api.h" #include "trap_api.h" #include "syslog.h" #include "hal.h" #include "FreeRTOS.h" #include "task.h" BUTTON_NO_FIX_t defButton; /** * @brief * @retval */ void BUTTON_Init(void) { defButton.id_pin = KEY_DEF; defButton.timeDelay = 5; defButton.pressHandler = BUTTON_VoidHandler; defButton.unpressHandler = BUTTON_DEF_DownHandler; defButton.counterActivation = 0; defButton.timeActivation = 40; defButton.fActivation = false; defButton.stateOld = BUTTON_GetState(&defButton); } /** * @brief Возвращает сотояние ключа */ BUTTON_STATE_t BUTTON_GetState(BUTTON_NO_FIX_t *button) { return (BUTTON_STATE_t)gpio_get(button->id_pin); } /** * @brief Обработчик кнопки без фиксации. В обработчике реализована защита * от дребезга с помощью задержки. Защита срабатывает при нажатии * и при отпускании. * @param *button: указатель на структуру типа BUTTON_NO_FIX * @retval нет */ void BUTTON_NoFixHandler(BUTTON_NO_FIX_t *button) { uint8_t temp; if (button->stateNew != BUT_NO_DEFINE) { temp = gpio_get(button->id_pin); if (temp == 0) // определяем текущее (новое) состояние кнопки button->stateNew = BUT_ON; else button->stateNew = BUT_OFF; if (button->stateNew != button->stateOld) // зафиксирован факт нажатия/отжатия button->stateNew = BUT_NO_DEFINE; // переводим кнопку в неопределенное состояние } else { button->counterDelay++; // запускаем счетчик на задержку if (button->counterDelay > button->timeDelay) // задержка закончилась { button->counterDelay = 0; temp = gpio_get(button->id_pin); button->counterActivation = 0; if (temp == 0) // определяем текущее (новое) состояние кнопки { button->stateNew = BUT_ON; button->unpressHandler(); } else { button->stateNew = BUT_OFF; button->pressHandler(); } } } button->stateOld = button->stateNew; } /** * @brief Обработчик кнопки без фиксации. Кнопка срабатывает через определеное время нажатия. * @param *button: указатель на структуру типа BUTTON_NO_FIX * @retval нет */ void BUTTON_DellayHandler(BUTTON_NO_FIX_t *button) { /* Кнопка нажата. Ведем отсчет времени удержания */ if (gpio_get(button->id_pin) == 0) // определяем текущее (новое) состояние кнопки { button->counterActivation++; button->fActivation = false; /* Кнопка нажата более необходимого времени - начинаем чаще мигать диодом */ if (button->counterActivation > button->timeActivation) LED_SetStatusLedFreq(100); } /* Кнопку отжата. Если до этого она была нажата нужное время - вызываем хендлер */ else { if ((button->counterActivation > button->timeActivation) && button->fActivation == false) { button->fActivation = true; LED_SetStatusLedFreq(1000); button->unpressHandler(); } else button->counterActivation = 0; } } /** * @brief Опрос кнопок */ void vTaskButtons(void *pvParameters) { for (;;) { BUTTON_DellayHandler(&defButton); vTaskDelay(100); //20 } } /** * @brief Заглушка */ void BUTTON_VoidHandler(void) { } /** * @brief Хендлер кнопки DEFAULT. Сброс всех настроек, сохранение и перезагрузка */ void BUTTON_DEF_DownHandler(void) { //taskENTER_CRITICAL(); SNMP_SendUserTrap(DEVICE_RESTORED); syslog_str(SYSLOG_INFORMATIONAL, "Сброс настроек (Администратор)"); log_event_data(LOG_SYSTEM_DEFCONFIG, "Администратор"); vTaskDelay(500); SETTINGS_SetDefaultDebug(); SETTINGS_Save(); vTaskDelay(1010); Reboot(OTHER_ACT); //taskEXIT_CRITICAL(); } /** * @brief Хендлер кнопки SET. Переход в bootloader */ void BUTTON_SET_DownHandler(void) { HTTP_StartResetTask(true); } /********************************* (C) РОТЕК **********************************/