]> granicus.if.org Git - esp-idf/commitdiff
driver/gpio: support wakeup function for RTC IOs
authorIvan Grokhotkov <ivan@espressif.com>
Mon, 13 Aug 2018 22:57:32 +0000 (01:57 +0300)
committerIvan Grokhotkov <ivan@espressif.com>
Thu, 6 Sep 2018 07:40:46 +0000 (15:40 +0800)
components/driver/gpio.c
components/driver/include/driver/gpio.h
components/driver/include/driver/rtc_io.h
components/driver/rtc_module.c

index d81d2c25c316e0c8933c40ed67d707b112e500ae..2e485866fbf3dafd69c7e4f930fa47e5557aa437 100644 (file)
@@ -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;
index bc8436491dcd0e1b32eee2beb1c223c868d6a597..2e878dc1ec6ed2418826bdd6b3184ba5730e95f4 100644 (file)
@@ -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);
 
 /**
index f1c321b18983bd90ae64b99a1543aeded9511576..4e84ea1da270546b5ca710fbcbc29c6c869a494a 100644 (file)
@@ -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
index f7f63100af31c7eebbf887fdf71b28ae6b6f07b3..43794a0ceaa478b6a5e6a2a5b293e8221a3690eb 100644 (file)
@@ -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