RTC-GPIO (Real-Time Clock General Purpose Input/Output)
Es un soporte separado del sistema General Purpose I/O (GPIO) del chip ESP32, diseñado para funcionar cuando los pines GPIO se enrutan al subsistema analógico y de **baja potencia** "RTC".
Funcionalidad y Uso del RTC GPIO

¿Se puede usar una "estructura" como con GPIO normal?
No. A diferencia de la API GPIO estándar, la API RTC GPIO no utiliza una estructura de configuración. En su lugar, cada función se llama individualmente para configurar aspectos específicos del pin RTC GPIO.
El chip ESP32 cuenta con 34 pines GPIO físicos
(GPIO0 ~ GPIO19, GPIO21 ~ GPIO23, GPIO25 ~ GPIO27, y GPIO32 ~ GPIO39).
Una selección de estos pines GPIO también está mapeada a funciones RTC GPIO.
Por ejemplo, GPIO36 es RTC_GPIO0, GPIO32 es RTC_GPIO9, y GPIO4 es RTC_GPIO10.
Las funciones RTC GPIO son esenciales porque pueden utilizarse en situaciones donde el sistema está operando en modos de bajo consumo o usando funciones analógicas:
En modo *Deep-sleep
- Cuando el coprocesador Ultra Low Power FSM está ejecutándose
- Cuando se utilizan funciones analógicas** como ADC, DAC, etc..
Referencia API para RTC GPIO
La API específica para el control de RTC GPIO se encuentra principalmente en el archivo de cabecera `driver/rtc_io.h`
#include "driver/rtc_io.h" // Incluir el driver RTC IO
1. Inicialización y Mapeo
- Inicialización/Desinicializació
- `rtc_gpio_init` inicializa un IO para que sea un RTC GPIO, enrutándolo al RTC IO MUX
- `rtc_gpio_deinit`desinicializa un IO como RTC GPIO, devolviendo el enrutamiento al IO MUX
- Verificación de Validez: La función `rtc_gpio_is_valid_gpio` permite determinar si un IO especificado es un RTC GPIO válido.
- Mapeo de GPIO a RTC GPIO: La función `rtc_gpio_num_to_io_num` convierte un número GPIO estándar al número correspondiente de RTC GPIO.
- Obtención del Índice: `rtc_io_number_get` devuelve el índice del RTC IO correspondiente a un número GPIO dado.
rtc_gpio_init(GPIO_NUM_4); // Inicializar el pin
rtc_gpio_is_valid_gpio(GPIO_NUM_4); // Verificar si es RTC GPIO
rtc_gpio_num_to_io_num(GPIO_NUM_4); // Convertir a RTC GPIO
rtc_io_number_get(GPIO_NUM_4); // Obtener índice RTC IO
Control de Nivel y Dirección
- Nivel de Entrada/Salida: Se puede obtener el nivel de entrada con `rtc_gpio_get_level` y establecer el nivel de salida con `rtc_gpio_set_level`.
- Configuración de Dirección:`rtc_gpio_set_direction` configura la dirección del RTC GPIO (salida, entrada, o ambas). Los tipos de modo para RTC IO (`rtc_gpio_mode_t`) incluyen `RTC_GPIO_MODE_INPUT_ONLY`, `RTC_GPIO_MODE_OUTPUT_ONLY`, y modos con open-drain.
- `rtc_gpio_get_direction_in_sleep` permite configurar la dirección del RTC GPIO específicamente para el modo deep sleep (o estado de sueño deshabilitado por defecto), útil cuando el IO necesita tener otros estados durante el sueño profundo.
rtc_gpio_set_direction(GPIO_NUM_4, RTC_GPIO_MODE_INPUT_ONLY); // Modo entrada solo
rtc_gpio_get_direction_in_sleep(GPIO_NUM_4); // Dirección en deep sleep
Resistencias Pull-Up/Pull-Down y Capacidad de Drive
El control de las resistencias internas pull-up y pull-down también está disponible para los RTC IOs mediante funciones específicas (e.g., `rtc_gpio_pullup_en`/`rtc_gpio_pulldown_en`). Estas funciones solo afectan a los RTC IOs, aunque las funciones genéricas de GPIO (`gpio_pullup_en`, etc.) generalmente también funcionan para los RTC IOs.
La capacidad de *drive* de la almohadilla (pad) del RTC GPIO se puede establecer o consultar utilizando `rtc_gpio_set_drive_capability` y `rtc_gpio_get_drive_capability`, respectivamente.
rtc_gpio_pulldown_dis(GPIO_NUM_4); // Desactivar pull-down
rtc-gpio-pulldown_en(GPIO_NUM_4); // Activar pull-down
rtc_gpio_pullup_en(GPIO_NUM_4); // Desactivar pull-up
rtc_gpio_pullup_en(GPIO_NUM_4); // Activar pull-up
rtc_gpio_set_drive_capability(GPIO_NUM_4, RTC_GPIO_DRIVE_CAP_3); // Establecer capacidad de drive
rtc_gpio_get_drive_capability(GPIO_NUM_4); // Obtener capacidad de drive
Funciones de Retención (Hold) y Aislamiento
Las funciones de retención son vitales para mantener el estado de los pines durante el sueño:
- Retención de Pin Individual: `rtc_gpio_hold_en` habilita la función de retención en un pad RTC IO. Esto hace que el pad enganche los valores actuales de la configuración (incluyendo habilitación de entrada/salida, valor de salida, función y fuerza de drive), impidiendo que la configuración cambie al entrar en modo light o deep sleep. 'rtc_gpio_hold_dis' deshabilita esta función.
- Retención Forzada Global: `rtc_gpio_force_hold_en_all` activa la señal de retención forzada para todos los RTC IOs. Esta señal se habilita antes de entrar en deep sleep para los pines utilizados para el despertar EXT1.
- Aislamiento: `rtc_gpio_isolate` es una función auxiliar que desconecta los circuitos internos de un RTC IO (deshabilita entrada, salida, pullup, pulldown y habilita *hold*). Esta función debe usarse si un RTC IO necesita ser desconectado de los circuitos internos durante el *deep sleep* para minimizar la corriente de fuga. Es especialmente importante para el módulo ESP32-WROVER, donde se recomienda llamar a `rtc_gpio_isolate(GPIO_NUM_12)` antes de entrar en *deep sleep*.
rtc_gpio_hold_en(GPIO_NUM_4); // Habilitar retención
rtc_gpio_hold_dis(GPIO_NUM_4); // Deshabilitar retención
rtc_gpio_force_hold_en_all(); // Habilitar retención forzada global
rtc_gpio_isolate(GPIO_NUM_12); // Aislar GPIO12
Despertar (Wake-up)
Los RTC GPIOs pueden habilitar la función de despertar desde el modo sleep utilizando `rtc_gpio_wakeup_enable`. El tipo de interrupción de despertar está limitado a un nivel alto (`GPIO_INTR_HIGH_LEVEL`) o un nivel bajo (`GPIO_INTR_LOW_LEVEL`). La función `rtc_gpio_wakeup_disable` deshabilita esta capacidad.
rtc_gpio_wakeup_enable(GPIO_NUM_4, GPIO_INTR_HIGH_LEVEL); // Habilitar wake-up en nivel alto
rtc_gpio_wakeup_enable(GPIO_NUM_4, GPIO_INTR_low_LEVEL); // Habilitar wake-up en nivel alto
rtc_gpio_wakeup_disable(GPIO_NUM_4); // Deshabilitar wake-up
Codigo completo operativo 2
El siguiente ejemplo demuestra el uso de RTC GPIO para controlar un LED y un botón, incluyendo la funcionalidad de despertar desde el modo deep sleep.
En este código se puede ver como el LED_GPIO se configura llamada a llamada no con una estructura
El código completo quedaría así:
1 #include "stdio.h"
2 #include "freertos/FreeRTOS.h"
3 #include "freertos/task.h"
4 #include "driver/gpio.h"
5 #include "driver/rtc_io.h"
6 #include "esp_sleep.h"
7 #include "esp_log.h"
8
9 #define LED_GPIO GPIO_NUM_2
10 #define BUTTON_GPIO GPIO_NUM_4
11
12 RTC_DATA_ATTR static int boot_count = 0;
13
14 extern "C" void app_main(void)
15 {
16 boot_count++;
17 ESP_LOGI("RTC-GPIO", "=== Arranque #%d ===", boot_count);
18
19 // Verificar que el botón es un RTC GPIO válido
20 if (!rtc_gpio_is_valid_gpio(BUTTON_GPIO)) {
21 ESP_LOGE("RTC-GPIO", "BUTTON_GPIO no es un RTC GPIO válido");
22 return;
23 }
24
25 // Parpadear LED al inicio
26 gpio_set_direction(LED_GPIO, GPIO_MODE_OUTPUT);
27 for (int i = 0; i < 2; i++) {
28 gpio_set_level(LED_GPIO, 0); // Encender (activo bajo)
29 vTaskDelay(pdMS_TO_TICKS(100));
30 gpio_set_level(LED_GPIO, 1); // Apagar
31 vTaskDelay(pdMS_TO_TICKS(100));
32 }
33
34 // Configurar LED con HOLD para mantener estado en deep sleep
35 rtc_gpio_init(LED_GPIO);
36 rtc_gpio_set_direction(LED_GPIO, RTC_GPIO_MODE_OUTPUT_ONLY);
37 rtc_gpio_set_level(LED_GPIO, 1); // Mantener encendido
38 rtc_gpio_hold_en(LED_GPIO);
39
40 // Configurar botón en dominio RTC
41 rtc_gpio_init(BUTTON_GPIO);
42 rtc_gpio_set_direction(BUTTON_GPIO, RTC_GPIO_MODE_INPUT_ONLY);
43 rtc_gpio_pullup_en(BUTTON_GPIO);
44 rtc_gpio_pulldown_dis(BUTTON_GPIO);
45
46 // ✅ CORRECTO: Usar ext0 para wake-up por un solo pin
47 esp_sleep_enable_ext0_wakeup(BUTTON_GPIO, 0); // 0 = LOW, 1 = HIGH
48
49 ESP_LOGI("RTC-GPIO", "Entrando en deep sleep. ¡Presiona el botón en GPIO4 para despertar!");
50 vTaskDelay(pdMS_TO_TICKS(100));
51
52 esp_deep_sleep_start();
53 }
~
Aunque rtc_gpio_wakeup_enable()
configura el pin en el dominio RTC, el sistema de energía del ESP32 no despertará a menos que se active explícitamente una fuente de wake-up.
La función esp_sleep_enable_ext0_wakeup(BUTTON_GPIO, 0)
habilita el mecanismo EXT0 del controlador RTC para que el chip se despierte cuando el pin pase a nivel bajo.
Por eso es obligatorio incluir #include "esp_sleep.h"
y llamar a esta función: es la interfaz oficial de ESP-IDF para activar el wake-up por GPIO en deep sleep, y está directamente ligada al hardware RTC.
El atributo: RTC_DATA_ATTR
para especificar datostambien dependen de esta API