rtc_io.c
1 // Copyright 2019 Espressif Systems (Shanghai) PTE LTD 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #include <string.h> 16 #include "esp_log.h" 17 #include "esp_err.h" 18 #include "freertos/FreeRTOS.h" 19 #include "freertos/semphr.h" 20 #include "freertos/timers.h" 21 #include "driver/rtc_io.h" 22 #include "hal/rtc_io_hal.h" 23 24 static const char *RTCIO_TAG = "RTCIO"; 25 26 #define RTCIO_CHECK(a, str, ret_val) ({ \ 27 if (!(a)) { \ 28 ESP_LOGE(RTCIO_TAG,"%s(%d): %s", __FUNCTION__, __LINE__, str); \ 29 return (ret_val); \ 30 } \ 31 }) 32 33 extern portMUX_TYPE rtc_spinlock; //TODO: Will be placed in the appropriate position after the rtc module is finished. 34 #define RTCIO_ENTER_CRITICAL() portENTER_CRITICAL(&rtc_spinlock) 35 #define RTCIO_EXIT_CRITICAL() portEXIT_CRITICAL(&rtc_spinlock) 36 37 /*--------------------------------------------------------------- 38 RTC IO 39 ---------------------------------------------------------------*/ 40 esp_err_t rtc_gpio_init(gpio_num_t gpio_num) 41 { 42 RTCIO_CHECK(rtc_gpio_is_valid_gpio(gpio_num), "RTCIO number error", ESP_ERR_INVALID_ARG); 43 RTCIO_ENTER_CRITICAL(); 44 rtcio_hal_function_select(rtc_io_number_get(gpio_num), RTCIO_FUNC_RTC); 45 RTCIO_EXIT_CRITICAL(); 46 47 return ESP_OK; 48 } 49 50 esp_err_t rtc_gpio_deinit(gpio_num_t gpio_num) 51 { 52 RTCIO_CHECK(rtc_gpio_is_valid_gpio(gpio_num), "RTCIO number error", ESP_ERR_INVALID_ARG); 53 RTCIO_ENTER_CRITICAL(); 54 // Select Gpio as Digital Gpio 55 rtcio_hal_function_select(rtc_io_number_get(gpio_num), RTCIO_FUNC_DIGITAL); 56 RTCIO_EXIT_CRITICAL(); 57 58 return ESP_OK; 59 } 60 61 esp_err_t rtc_gpio_set_level(gpio_num_t gpio_num, uint32_t level) 62 { 63 RTCIO_CHECK(rtc_gpio_is_valid_gpio(gpio_num), "RTCIO number error", ESP_ERR_INVALID_ARG); 64 RTCIO_ENTER_CRITICAL(); 65 rtcio_hal_set_level(rtc_io_number_get(gpio_num), level); 66 RTCIO_EXIT_CRITICAL(); 67 68 return ESP_OK; 69 } 70 71 uint32_t rtc_gpio_get_level(gpio_num_t gpio_num) 72 { 73 RTCIO_CHECK(rtc_gpio_is_valid_gpio(gpio_num), "RTCIO number error", ESP_ERR_INVALID_ARG); 74 return rtcio_hal_get_level(rtc_io_number_get(gpio_num)); 75 } 76 77 esp_err_t rtc_gpio_set_drive_capability(gpio_num_t gpio_num, gpio_drive_cap_t strength) 78 { 79 RTCIO_CHECK(rtc_gpio_is_valid_gpio(gpio_num), "RTCIO number error", ESP_ERR_INVALID_ARG); 80 RTCIO_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(gpio_num), "Output pad only", ESP_ERR_INVALID_ARG); 81 RTCIO_CHECK(strength < GPIO_DRIVE_CAP_MAX, "RTCIO drive capability error", ESP_ERR_INVALID_ARG); 82 RTCIO_ENTER_CRITICAL(); 83 rtcio_hal_set_drive_capability(rtc_io_number_get(gpio_num), strength); 84 RTCIO_EXIT_CRITICAL(); 85 86 return ESP_OK; 87 } 88 89 esp_err_t rtc_gpio_get_drive_capability(gpio_num_t gpio_num, gpio_drive_cap_t *strength) 90 { 91 RTCIO_CHECK(rtc_gpio_is_valid_gpio(gpio_num), "RTCIO number error", ESP_ERR_INVALID_ARG); 92 RTCIO_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(gpio_num), "Output pad only", ESP_ERR_INVALID_ARG); 93 RTCIO_CHECK(strength != NULL, "GPIO drive pointer error", ESP_ERR_INVALID_ARG); 94 *strength = (gpio_drive_cap_t)rtcio_hal_get_drive_capability(rtc_io_number_get(gpio_num)); 95 96 return ESP_OK; 97 } 98 99 esp_err_t rtc_gpio_set_direction(gpio_num_t gpio_num, rtc_gpio_mode_t mode) 100 { 101 RTCIO_CHECK(rtc_gpio_is_valid_gpio(gpio_num), "RTCIO number error", ESP_ERR_INVALID_ARG); 102 RTCIO_ENTER_CRITICAL(); 103 rtcio_hal_set_direction(rtc_io_number_get(gpio_num), mode); 104 RTCIO_EXIT_CRITICAL(); 105 106 return ESP_OK; 107 } 108 109 esp_err_t rtc_gpio_set_direction_in_sleep(gpio_num_t gpio_num, rtc_gpio_mode_t mode) 110 { 111 RTCIO_CHECK(rtc_gpio_is_valid_gpio(gpio_num), "RTCIO number error", ESP_ERR_INVALID_ARG); 112 RTCIO_ENTER_CRITICAL(); 113 rtcio_hal_set_direction_in_sleep(rtc_io_number_get(gpio_num), mode); 114 RTCIO_EXIT_CRITICAL(); 115 116 return ESP_OK; 117 } 118 119 esp_err_t rtc_gpio_pullup_en(gpio_num_t gpio_num) 120 { 121 RTCIO_CHECK(rtc_gpio_is_valid_gpio(gpio_num), "RTCIO number error", ESP_ERR_INVALID_ARG); 122 RTCIO_ENTER_CRITICAL(); 123 rtcio_hal_pullup_enable(rtc_io_number_get(gpio_num)); 124 RTCIO_EXIT_CRITICAL(); 125 126 return ESP_OK; 127 } 128 129 esp_err_t rtc_gpio_pullup_dis(gpio_num_t gpio_num) 130 { 131 RTCIO_CHECK(rtc_gpio_is_valid_gpio(gpio_num), "RTCIO number error", ESP_ERR_INVALID_ARG); 132 RTCIO_ENTER_CRITICAL(); 133 rtcio_hal_pullup_disable(rtc_io_number_get(gpio_num)); 134 RTCIO_EXIT_CRITICAL(); 135 136 return ESP_OK; 137 } 138 139 esp_err_t rtc_gpio_pulldown_en(gpio_num_t gpio_num) 140 { 141 RTCIO_CHECK(rtc_gpio_is_valid_gpio(gpio_num), "RTCIO number error", ESP_ERR_INVALID_ARG); 142 RTCIO_ENTER_CRITICAL(); 143 rtcio_hal_pulldown_enable(rtc_io_number_get(gpio_num)); 144 RTCIO_EXIT_CRITICAL(); 145 146 return ESP_OK; 147 } 148 149 esp_err_t rtc_gpio_pulldown_dis(gpio_num_t gpio_num) 150 { 151 RTCIO_CHECK(rtc_gpio_is_valid_gpio(gpio_num), "RTCIO number error", ESP_ERR_INVALID_ARG); 152 RTCIO_ENTER_CRITICAL(); 153 rtcio_hal_pulldown_disable(rtc_io_number_get(gpio_num)); 154 RTCIO_EXIT_CRITICAL(); 155 156 return ESP_OK; 157 } 158 159 esp_err_t rtc_gpio_hold_en(gpio_num_t gpio_num) 160 { 161 RTCIO_CHECK(rtc_gpio_is_valid_gpio(gpio_num), "RTCIO number error", ESP_ERR_INVALID_ARG); 162 RTCIO_ENTER_CRITICAL(); 163 rtcio_hal_hold_enable(rtc_io_number_get(gpio_num)); 164 RTCIO_EXIT_CRITICAL(); 165 166 return ESP_OK; 167 } 168 169 esp_err_t rtc_gpio_hold_dis(gpio_num_t gpio_num) 170 { 171 RTCIO_CHECK(rtc_gpio_is_valid_gpio(gpio_num), "RTCIO number error", ESP_ERR_INVALID_ARG); 172 RTCIO_ENTER_CRITICAL(); 173 rtcio_hal_hold_disable(rtc_io_number_get(gpio_num)); 174 RTCIO_EXIT_CRITICAL(); 175 176 return ESP_OK; 177 } 178 179 esp_err_t rtc_gpio_isolate(gpio_num_t gpio_num) 180 { 181 RTCIO_CHECK(rtc_gpio_is_valid_gpio(gpio_num), "RTCIO number error", ESP_ERR_INVALID_ARG); 182 RTCIO_ENTER_CRITICAL(); 183 rtcio_hal_isolate(rtc_io_number_get(gpio_num)); 184 RTCIO_EXIT_CRITICAL(); 185 186 return ESP_OK; 187 } 188 189 esp_err_t rtc_gpio_force_hold_en_all(void) 190 { 191 RTCIO_ENTER_CRITICAL(); 192 rtcio_hal_hold_all(); 193 RTCIO_EXIT_CRITICAL(); 194 195 return ESP_OK; 196 } 197 198 esp_err_t rtc_gpio_force_hold_dis_all(void) 199 { 200 RTCIO_ENTER_CRITICAL(); 201 rtcio_hal_unhold_all(); 202 RTCIO_EXIT_CRITICAL(); 203 204 return ESP_OK; 205 } 206 207 esp_err_t rtc_gpio_wakeup_enable(gpio_num_t gpio_num, gpio_int_type_t intr_type) 208 { 209 RTCIO_CHECK(rtc_gpio_is_valid_gpio(gpio_num), "RTCIO number error", ESP_ERR_INVALID_ARG); 210 if (intr_type == GPIO_INTR_POSEDGE || intr_type == GPIO_INTR_NEGEDGE || intr_type == GPIO_INTR_ANYEDGE) { 211 return ESP_ERR_INVALID_ARG; // Dont support this mode. 212 } 213 RTCIO_ENTER_CRITICAL(); 214 rtcio_hal_wakeup_enable(rtc_io_number_get(gpio_num), intr_type); 215 RTCIO_EXIT_CRITICAL(); 216 217 return ESP_OK; 218 } 219 220 esp_err_t rtc_gpio_wakeup_disable(gpio_num_t gpio_num) 221 { 222 RTCIO_CHECK(rtc_gpio_is_valid_gpio(gpio_num), "RTCIO number error", ESP_ERR_INVALID_ARG); 223 RTCIO_ENTER_CRITICAL(); 224 rtcio_hal_wakeup_disable(rtc_io_number_get(gpio_num)); 225 RTCIO_EXIT_CRITICAL(); 226 227 return ESP_OK; 228 }