1 // Copyright 2015-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 #pragma once 16 17 #include "esp_err.h" 18 #include "esp_intr_alloc.h" 19 #include "soc/soc.h" 20 #include "hal/ledc_types.h" 21 #include "driver/gpio.h" 22 #include "driver/periph_ctrl.h" 23 24 #ifdef __cplusplus 25 extern "C" { 26 #endif 27 28 #define LEDC_APB_CLK_HZ (APB_CLK_FREQ) 29 #define LEDC_REF_CLK_HZ (REF_CLK_FREQ) 30 #define LEDC_ERR_DUTY (0xFFFFFFFF) 31 #define LEDC_ERR_VAL (-1) 32 33 typedef intr_handle_t ledc_isr_handle_t; 34 35 /** 36 * @brief LEDC channel configuration 37 * Configure LEDC channel with the given channel/output gpio_num/interrupt/source timer/frequency(Hz)/LEDC duty resolution 38 * 39 * @param ledc_conf Pointer of LEDC channel configure struct 40 * 41 * @return 42 * - ESP_OK Success 43 * - ESP_ERR_INVALID_ARG Parameter error 44 */ 45 esp_err_t ledc_channel_config(const ledc_channel_config_t* ledc_conf); 46 47 /** 48 * @brief LEDC timer configuration 49 * Configure LEDC timer with the given source timer/frequency(Hz)/duty_resolution 50 * 51 * @param timer_conf Pointer of LEDC timer configure struct 52 * 53 * @return 54 * - ESP_OK Success 55 * - ESP_ERR_INVALID_ARG Parameter error 56 * - ESP_FAIL Can not find a proper pre-divider number base on the given frequency and the current duty_resolution. 57 */ 58 esp_err_t ledc_timer_config(const ledc_timer_config_t* timer_conf); 59 60 /** 61 * @brief LEDC update channel parameters 62 * @note Call this function to activate the LEDC updated parameters. 63 * After ledc_set_duty, we need to call this function to update the settings. 64 * @note ledc_set_duty, ledc_set_duty_with_hpoint and ledc_update_duty are not thread-safe, do not call these functions to 65 * control one LEDC channel in different tasks at the same time. 66 * A thread-safe version of API is ledc_set_duty_and_update 67 * @param speed_mode Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode. 68 * @param channel LEDC channel (0-7), select from ledc_channel_t 69 * 70 * @return 71 * - ESP_OK Success 72 * - ESP_ERR_INVALID_ARG Parameter error 73 * 74 */ 75 esp_err_t ledc_update_duty(ledc_mode_t speed_mode, ledc_channel_t channel); 76 77 /** 78 * @brief Set LEDC output gpio. 79 * 80 * @param gpio_num The LEDC output gpio 81 * @param speed_mode Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode. 82 * @param ledc_channel LEDC channel (0-7), select from ledc_channel_t 83 * 84 * @return 85 * - ESP_OK Success 86 * - ESP_ERR_INVALID_ARG Parameter error 87 */ 88 esp_err_t ledc_set_pin(int gpio_num, ledc_mode_t speed_mode, ledc_channel_t ledc_channel); 89 90 /** 91 * @brief LEDC stop. 92 * Disable LEDC output, and set idle level 93 * 94 * @param speed_mode Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode. 95 * @param channel LEDC channel (0-7), select from ledc_channel_t 96 * @param idle_level Set output idle level after LEDC stops. 97 * 98 * @return 99 * - ESP_OK Success 100 * - ESP_ERR_INVALID_ARG Parameter error 101 */ 102 esp_err_t ledc_stop(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t idle_level); 103 104 /** 105 * @brief LEDC set channel frequency (Hz) 106 * 107 * @param speed_mode Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode. 108 * @param timer_num LEDC timer index (0-3), select from ledc_timer_t 109 * @param freq_hz Set the LEDC frequency 110 * 111 * @return 112 * - ESP_OK Success 113 * - ESP_ERR_INVALID_ARG Parameter error 114 * - ESP_FAIL Can not find a proper pre-divider number base on the given frequency and the current duty_resolution. 115 */ 116 esp_err_t ledc_set_freq(ledc_mode_t speed_mode, ledc_timer_t timer_num, uint32_t freq_hz); 117 118 /** 119 * @brief LEDC get channel frequency (Hz) 120 * 121 * @param speed_mode Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode. 122 * @param timer_num LEDC timer index (0-3), select from ledc_timer_t 123 * 124 * @return 125 * - 0 error 126 * - Others Current LEDC frequency 127 */ 128 uint32_t ledc_get_freq(ledc_mode_t speed_mode, ledc_timer_t timer_num); 129 130 /** 131 * @brief LEDC set duty and hpoint value 132 * Only after calling ledc_update_duty will the duty update. 133 * @note ledc_set_duty, ledc_set_duty_with_hpoint and ledc_update_duty are not thread-safe, do not call these functions to 134 * control one LEDC channel in different tasks at the same time. 135 * A thread-safe version of API is ledc_set_duty_and_update 136 * @note If a fade operation is running in progress on that channel, the driver would not allow it to be stopped. 137 * Other duty operations will have to wait until the fade operation has finished. 138 * @param speed_mode Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode. 139 * @param channel LEDC channel (0-7), select from ledc_channel_t 140 * @param duty Set the LEDC duty, the range of duty setting is [0, (2**duty_resolution)] 141 * @param hpoint Set the LEDC hpoint value(max: 0xfffff) 142 * 143 * @return 144 * - ESP_OK Success 145 * - ESP_ERR_INVALID_ARG Parameter error 146 */ 147 esp_err_t ledc_set_duty_with_hpoint(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t duty, uint32_t hpoint); 148 149 /** 150 * @brief LEDC get hpoint value, the counter value when the output is set high level. 151 * 152 * @param speed_mode Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode. 153 * @param channel LEDC channel (0-7), select from ledc_channel_t 154 * @return 155 * - LEDC_ERR_VAL if parameter error 156 * - Others Current hpoint value of LEDC channel 157 */ 158 int ledc_get_hpoint(ledc_mode_t speed_mode, ledc_channel_t channel); 159 160 /** 161 * @brief LEDC set duty 162 * This function do not change the hpoint value of this channel. if needed, please call ledc_set_duty_with_hpoint. 163 * only after calling ledc_update_duty will the duty update. 164 * @note ledc_set_duty, ledc_set_duty_with_hpoint and ledc_update_duty are not thread-safe, do not call these functions to 165 * control one LEDC channel in different tasks at the same time. 166 * A thread-safe version of API is ledc_set_duty_and_update. 167 * @note If a fade operation is running in progress on that channel, the driver would not allow it to be stopped. 168 * Other duty operations will have to wait until the fade operation has finished. 169 * @param speed_mode Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode. 170 * @param channel LEDC channel (0-7), select from ledc_channel_t 171 * @param duty Set the LEDC duty, the range of duty setting is [0, (2**duty_resolution)] 172 * 173 * @return 174 * - ESP_OK Success 175 * - ESP_ERR_INVALID_ARG Parameter error 176 */ 177 esp_err_t ledc_set_duty(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t duty); 178 179 /** 180 * @brief LEDC get duty 181 * 182 * @param speed_mode Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode. 183 * @param channel LEDC channel (0-7), select from ledc_channel_t 184 * 185 * @return 186 * - LEDC_ERR_DUTY if parameter error 187 * - Others Current LEDC duty 188 */ 189 uint32_t ledc_get_duty(ledc_mode_t speed_mode, ledc_channel_t channel); 190 191 /** 192 * @brief LEDC set gradient 193 * Set LEDC gradient, After the function calls the ledc_update_duty function, the function can take effect. 194 * @note If a fade operation is running in progress on that channel, the driver would not allow it to be stopped. 195 * Other duty operations will have to wait until the fade operation has finished. 196 * @param speed_mode Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode. 197 * @param channel LEDC channel (0-7), select from ledc_channel_t 198 * @param duty Set the start of the gradient duty, the range of duty setting is [0, (2**duty_resolution)] 199 * @param fade_direction Set the direction of the gradient 200 * @param step_num Set the number of the gradient 201 * @param duty_cycle_num Set how many LEDC tick each time the gradient lasts 202 * @param duty_scale Set gradient change amplitude 203 * 204 * @return 205 * - ESP_OK Success 206 * - ESP_ERR_INVALID_ARG Parameter error 207 */ 208 esp_err_t ledc_set_fade(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t duty, ledc_duty_direction_t fade_direction, 209 uint32_t step_num, uint32_t duty_cycle_num, uint32_t duty_scale); 210 211 /** 212 * @brief Register LEDC interrupt handler, the handler is an ISR. 213 * The handler will be attached to the same CPU core that this function is running on. 214 * 215 * @param fn Interrupt handler function. 216 * @param arg User-supplied argument passed to the handler function. 217 * @param intr_alloc_flags Flags used to allocate the interrupt. One or multiple (ORred) 218 * ESP_INTR_FLAG_* values. See esp_intr_alloc.h for more info. 219 * @param handle Pointer to return handle. If non-NULL, a handle for the interrupt will 220 * be returned here. 221 * 222 * @return 223 * - ESP_OK Success 224 * - ESP_ERR_INVALID_ARG Function pointer error. 225 */ 226 esp_err_t ledc_isr_register(void (*fn)(void*), void * arg, int intr_alloc_flags, ledc_isr_handle_t *handle); 227 228 /** 229 * @brief Configure LEDC settings 230 * 231 * @param speed_mode Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode. 232 * @param timer_sel Timer index (0-3), there are 4 timers in LEDC module 233 * @param clock_divider Timer clock divide value, the timer clock is divided from the selected clock source 234 * @param duty_resolution Resolution of duty setting in number of bits. The range of duty values is [0, (2**duty_resolution)] 235 * @param clk_src Select LEDC source clock. 236 * 237 * @return 238 * - (-1) Parameter error 239 * - Other Current LEDC duty 240 */ 241 esp_err_t ledc_timer_set(ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_t clock_divider, uint32_t duty_resolution, ledc_clk_src_t clk_src); 242 243 /** 244 * @brief Reset LEDC timer 245 * 246 * @param speed_mode Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode. 247 * @param timer_sel LEDC timer index (0-3), select from ledc_timer_t 248 * 249 * @return 250 * - ESP_ERR_INVALID_ARG Parameter error 251 * - ESP_OK Success 252 */ 253 esp_err_t ledc_timer_rst(ledc_mode_t speed_mode, ledc_timer_t timer_sel); 254 255 /** 256 * @brief Pause LEDC timer counter 257 * 258 * @param speed_mode Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode. 259 * @param timer_sel LEDC timer index (0-3), select from ledc_timer_t 260 * 261 * @return 262 * - ESP_ERR_INVALID_ARG Parameter error 263 * - ESP_OK Success 264 * 265 */ 266 esp_err_t ledc_timer_pause(ledc_mode_t speed_mode, ledc_timer_t timer_sel); 267 268 /** 269 * @brief Resume LEDC timer 270 * 271 * @param speed_mode Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode. 272 * @param timer_sel LEDC timer index (0-3), select from ledc_timer_t 273 * 274 * @return 275 * - ESP_ERR_INVALID_ARG Parameter error 276 * - ESP_OK Success 277 */ 278 esp_err_t ledc_timer_resume(ledc_mode_t speed_mode, ledc_timer_t timer_sel); 279 280 /** 281 * @brief Bind LEDC channel with the selected timer 282 * 283 * @param speed_mode Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode. 284 * @param channel LEDC channel index (0-7), select from ledc_channel_t 285 * @param timer_sel LEDC timer index (0-3), select from ledc_timer_t 286 * 287 * @return 288 * - ESP_ERR_INVALID_ARG Parameter error 289 * - ESP_OK Success 290 */ 291 esp_err_t ledc_bind_channel_timer(ledc_mode_t speed_mode, ledc_channel_t channel, ledc_timer_t timer_sel); 292 293 /** 294 * @brief Set LEDC fade function. 295 * @note Call ledc_fade_func_install() once before calling this function. 296 * Call ledc_fade_start() after this to start fading. 297 * @note ledc_set_fade_with_step, ledc_set_fade_with_time and ledc_fade_start are not thread-safe, do not call these functions to 298 * control one LEDC channel in different tasks at the same time. 299 * A thread-safe version of API is ledc_set_fade_step_and_start 300 * @note If a fade operation is running in progress on that channel, the driver would not allow it to be stopped. 301 * Other duty operations will have to wait until the fade operation has finished. 302 * @param speed_mode Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode. , 303 * @param channel LEDC channel index (0-7), select from ledc_channel_t 304 * @param target_duty Target duty of fading [0, (2**duty_resolution) - 1] 305 * @param scale Controls the increase or decrease step scale. 306 * @param cycle_num increase or decrease the duty every cycle_num cycles 307 * 308 * @return 309 * - ESP_ERR_INVALID_ARG Parameter error 310 * - ESP_OK Success 311 * - ESP_ERR_INVALID_STATE Fade function not installed. 312 * - ESP_FAIL Fade function init error 313 */ 314 esp_err_t ledc_set_fade_with_step(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t target_duty, uint32_t scale, uint32_t cycle_num); 315 316 /** 317 * @brief Set LEDC fade function, with a limited time. 318 * @note Call ledc_fade_func_install() once before calling this function. 319 * Call ledc_fade_start() after this to start fading. 320 * @note ledc_set_fade_with_step, ledc_set_fade_with_time and ledc_fade_start are not thread-safe, do not call these functions to 321 * control one LEDC channel in different tasks at the same time. 322 * A thread-safe version of API is ledc_set_fade_step_and_start 323 * @note If a fade operation is running in progress on that channel, the driver would not allow it to be stopped. 324 * Other duty operations will have to wait until the fade operation has finished. 325 * @param speed_mode Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode. , 326 * @param channel LEDC channel index (0-7), select from ledc_channel_t 327 * @param target_duty Target duty of fading.( 0 - (2 ** duty_resolution - 1))) 328 * @param max_fade_time_ms The maximum time of the fading ( ms ). 329 * 330 * @return 331 * - ESP_ERR_INVALID_ARG Parameter error 332 * - ESP_OK Success 333 * - ESP_ERR_INVALID_STATE Fade function not installed. 334 * - ESP_FAIL Fade function init error 335 */ 336 esp_err_t ledc_set_fade_with_time(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t target_duty, int max_fade_time_ms); 337 338 /** 339 * @brief Install LEDC fade function. This function will occupy interrupt of LEDC module. 340 * @param intr_alloc_flags Flags used to allocate the interrupt. One or multiple (ORred) 341 * ESP_INTR_FLAG_* values. See esp_intr_alloc.h for more info. 342 * 343 * @return 344 * - ESP_OK Success 345 * - ESP_ERR_INVALID_STATE Fade function already installed. 346 */ 347 esp_err_t ledc_fade_func_install(int intr_alloc_flags); 348 349 /** 350 * @brief Uninstall LEDC fade function. 351 * 352 */ 353 void ledc_fade_func_uninstall(void); 354 355 /** 356 * @brief Start LEDC fading. 357 * @note Call ledc_fade_func_install() once before calling this function. 358 * Call this API right after ledc_set_fade_with_time or ledc_set_fade_with_step before to start fading. 359 * @note If a fade operation is running in progress on that channel, the driver would not allow it to be stopped. 360 * Other duty operations will have to wait until the fade operation has finished. 361 * @param speed_mode Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode. 362 * @param channel LEDC channel number 363 * @param fade_mode Whether to block until fading done. 364 * 365 * @return 366 * - ESP_OK Success 367 * - ESP_ERR_INVALID_STATE Fade function not installed. 368 * - ESP_ERR_INVALID_ARG Parameter error. 369 */ 370 esp_err_t ledc_fade_start(ledc_mode_t speed_mode, ledc_channel_t channel, ledc_fade_mode_t fade_mode); 371 372 /** 373 * @brief A thread-safe API to set duty for LEDC channel and return when duty updated. 374 * @note If a fade operation is running in progress on that channel, the driver would not allow it to be stopped. 375 * Other duty operations will have to wait until the fade operation has finished. 376 * 377 * @param speed_mode Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode. 378 * @param channel LEDC channel (0-7), select from ledc_channel_t 379 * @param duty Set the LEDC duty, the range of duty setting is [0, (2**duty_resolution)] 380 * @param hpoint Set the LEDC hpoint value(max: 0xfffff) 381 * 382 */ 383 esp_err_t ledc_set_duty_and_update(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t duty, uint32_t hpoint); 384 385 /** 386 * @brief A thread-safe API to set and start LEDC fade function, with a limited time. 387 * @note Call ledc_fade_func_install() once, before calling this function. 388 * @note If a fade operation is running in progress on that channel, the driver would not allow it to be stopped. 389 * Other duty operations will have to wait until the fade operation has finished. 390 * @param speed_mode Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode. 391 * @param channel LEDC channel index (0-7), select from ledc_channel_t 392 * @param target_duty Target duty of fading.( 0 - (2 ** duty_resolution - 1))) 393 * @param max_fade_time_ms The maximum time of the fading ( ms ). 394 * @param fade_mode choose blocking or non-blocking mode 395 * @return 396 * - ESP_ERR_INVALID_ARG Parameter error 397 * - ESP_OK Success 398 * - ESP_ERR_INVALID_STATE Fade function not installed. 399 * - ESP_FAIL Fade function init error 400 */ 401 esp_err_t ledc_set_fade_time_and_start(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t target_duty, uint32_t max_fade_time_ms, ledc_fade_mode_t fade_mode); 402 403 /** 404 * @brief A thread-safe API to set and start LEDC fade function. 405 * @note Call ledc_fade_func_install() once before calling this function. 406 * @note If a fade operation is running in progress on that channel, the driver would not allow it to be stopped. 407 * Other duty operations will have to wait until the fade operation has finished. 408 * @param speed_mode Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode. 409 * @param channel LEDC channel index (0-7), select from ledc_channel_t 410 * @param target_duty Target duty of fading [0, (2**duty_resolution) - 1] 411 * @param scale Controls the increase or decrease step scale. 412 * @param cycle_num increase or decrease the duty every cycle_num cycles 413 * @param fade_mode choose blocking or non-blocking mode 414 * @return 415 * - ESP_ERR_INVALID_ARG Parameter error 416 * - ESP_OK Success 417 * - ESP_ERR_INVALID_STATE Fade function not installed. 418 * - ESP_FAIL Fade function init error 419 */ 420 esp_err_t ledc_set_fade_step_and_start(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t target_duty, uint32_t scale, uint32_t cycle_num, ledc_fade_mode_t fade_mode); 421 #ifdef __cplusplus 422 } 423 #endif 424