diff --git a/components/driver/gpio.c b/components/driver/gpio.c index d81d2c25c3..2e485866fb 100644 --- a/components/driver/gpio.c +++ b/components/driver/gpio.c @@ -423,16 +423,19 @@ esp_err_t gpio_isr_register(void (*fn)(void*), void * arg, int intr_alloc_flags, return esp_intr_alloc(ETS_GPIO_INTR_SOURCE, intr_alloc_flags, fn, arg, handle); } -/*only level interrupt can be used for wake-up function*/ esp_err_t gpio_wakeup_enable(gpio_num_t gpio_num, gpio_int_type_t intr_type) { GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG); esp_err_t ret = ESP_OK; if (( intr_type == GPIO_INTR_LOW_LEVEL ) || ( intr_type == GPIO_INTR_HIGH_LEVEL )) { - GPIO.pin[gpio_num].int_type = intr_type; - GPIO.pin[gpio_num].wakeup_enable = 0x1; + if (RTC_GPIO_IS_VALID_GPIO(gpio_num)) { + ret = rtc_gpio_wakeup_enable(gpio_num, intr_type); + } else { + GPIO.pin[gpio_num].int_type = intr_type; + GPIO.pin[gpio_num].wakeup_enable = 0x1; + } } else { - ESP_LOGE(GPIO_TAG, "GPIO wakeup only support Level mode,but edge mode set. gpio_num:%u", gpio_num); + ESP_LOGE(GPIO_TAG, "GPIO wakeup only supports level mode, but edge mode set. gpio_num:%u", gpio_num); ret = ESP_ERR_INVALID_ARG; } return ret; diff --git a/components/driver/include/driver/gpio.h b/components/driver/include/driver/gpio.h index bc8436491d..2e878dc1ec 100644 --- a/components/driver/include/driver/gpio.h +++ b/components/driver/include/driver/gpio.h @@ -359,27 +359,27 @@ esp_err_t gpio_set_direction(gpio_num_t gpio_num, gpio_mode_t mode); esp_err_t gpio_set_pull_mode(gpio_num_t gpio_num, gpio_pull_mode_t pull); /** - * @brief Enable GPIO wake-up function. - * - * @param gpio_num GPIO number. - * - * @param intr_type GPIO wake-up type. Only GPIO_INTR_LOW_LEVEL or GPIO_INTR_HIGH_LEVEL can be used. - * - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Parameter error - */ + * @brief Enable GPIO wake-up function. + * + * @param gpio_num GPIO number. + * + * @param intr_type GPIO wake-up type. Only GPIO_INTR_LOW_LEVEL or GPIO_INTR_HIGH_LEVEL can be used. + * + * @return + * - ESP_OK Success + * - ESP_ERR_INVALID_ARG Parameter error + */ esp_err_t gpio_wakeup_enable(gpio_num_t gpio_num, gpio_int_type_t intr_type); /** - * @brief Disable GPIO wake-up function. - * - * @param gpio_num GPIO number - * - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Parameter error - */ + * @brief Disable GPIO wake-up function. + * + * @param gpio_num GPIO number + * + * @return + * - ESP_OK Success + * - ESP_ERR_INVALID_ARG Parameter error + */ esp_err_t gpio_wakeup_disable(gpio_num_t gpio_num); /** diff --git a/components/driver/include/driver/rtc_io.h b/components/driver/include/driver/rtc_io.h index f1c321b189..4e84ea1da2 100644 --- a/components/driver/include/driver/rtc_io.h +++ b/components/driver/include/driver/rtc_io.h @@ -223,29 +223,52 @@ esp_err_t rtc_gpio_isolate(gpio_num_t gpio_num); void rtc_gpio_force_hold_dis_all(); /** - * @brief Set RTC GPIO pad drive capability - * - * @param gpio_num GPIO number, only support output GPIOs - * @param strength Drive capability of the pad - * - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Parameter error - */ + * @brief Set RTC GPIO pad drive capability + * + * @param gpio_num GPIO number, only support output GPIOs + * @param strength Drive capability of the pad + * + * @return + * - ESP_OK Success + * - ESP_ERR_INVALID_ARG Parameter error + */ esp_err_t rtc_gpio_set_drive_capability(gpio_num_t gpio_num, gpio_drive_cap_t strength); /** - * @brief Get RTC GPIO pad drive capability - * - * @param gpio_num GPIO number, only support output GPIOs - * @param strength Pointer to accept drive capability of the pad - * - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Parameter error - */ + * @brief Get RTC GPIO pad drive capability + * + * @param gpio_num GPIO number, only support output GPIOs + * @param strength Pointer to accept drive capability of the pad + * + * @return + * - ESP_OK Success + * - ESP_ERR_INVALID_ARG Parameter error + */ esp_err_t rtc_gpio_get_drive_capability(gpio_num_t gpio_num, gpio_drive_cap_t* strength); +/** + * @brief Enable wakeup from sleep mode using specific GPIO + * @param gpio_num GPIO number + * @param intr_type Wakeup on high level (GPIO_INTR_HIGH_LEVEL) or low level + * (GPIO_INTR_LOW_LEVEL) + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_ARG if gpio_num is not an RTC IO, or intr_type is not + * one of GPIO_INTR_HIGH_LEVEL, GPIO_INTR_LOW_LEVEL. + */ +esp_err_t rtc_gpio_wakeup_enable(gpio_num_t gpio_num, gpio_int_type_t intr_type); + +/** + * @brief Disable wakeup from sleep mode using specific GPIO + * @param gpio_num GPIO number + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_ARG if gpio_num is not an RTC IO + */ +esp_err_t rtc_gpio_wakeup_disable(gpio_num_t gpio_num); + + + #ifdef __cplusplus } #endif diff --git a/components/driver/rtc_module.c b/components/driver/rtc_module.c index f7f63100af..43794a0cea 100644 --- a/components/driver/rtc_module.c +++ b/components/driver/rtc_module.c @@ -383,6 +383,37 @@ void rtc_gpio_force_hold_dis_all() } } +esp_err_t rtc_gpio_wakeup_enable(gpio_num_t gpio_num, gpio_int_type_t intr_type) +{ + int rtc_num = rtc_gpio_desc[gpio_num].rtc_num; + if (rtc_num < 0) { + return ESP_ERR_INVALID_ARG; + } + if (( intr_type != GPIO_INTR_LOW_LEVEL ) && ( intr_type != GPIO_INTR_HIGH_LEVEL )) { + return ESP_ERR_INVALID_ARG; + } + + uint32_t reg = RTC_GPIO_PIN0_REG + rtc_num * sizeof(uint32_t); + /* each pin has its own register, spinlock not needed */ + REG_SET_BIT(reg, RTC_GPIO_PIN0_WAKEUP_ENABLE); + REG_SET_FIELD(reg, RTC_GPIO_PIN0_INT_TYPE, intr_type); + return ESP_OK; +} + +esp_err_t rtc_gpio_wakeup_disable(gpio_num_t gpio_num) +{ + int rtc_num = rtc_gpio_desc[gpio_num].rtc_num; + if (rtc_num < 0) { + return ESP_ERR_INVALID_ARG; + } + + uint32_t reg = RTC_GPIO_PIN0_REG + rtc_num * sizeof(uint32_t); + /* each pin has its own register, spinlock not needed */ + REG_CLR_BIT(reg, RTC_GPIO_PIN0_WAKEUP_ENABLE); + REG_SET_FIELD(reg, RTC_GPIO_PIN0_INT_TYPE, 0); + return ESP_OK; +} + /*--------------------------------------------------------------- Touch Pad