feat(ledc): refactor ledc driver
1. add hal and low-level layer for ledc driver 2. support esp32s2beta ledc
This commit is contained in:
parent
9f9da9ec96
commit
857dec108d
12 changed files with 1821 additions and 332 deletions
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
@ -12,131 +12,23 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef _DRIVER_LEDC_H_
|
||||
#define _DRIVER_LEDC_H_
|
||||
#pragma once
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "soc/soc.h"
|
||||
#include "hal/ledc_types.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/periph_ctrl.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define LEDC_APB_CLK_HZ (APB_CLK_FREQ)
|
||||
#define LEDC_REF_CLK_HZ (1*1000000)
|
||||
#define LEDC_ERR_DUTY (0xFFFFFFFF)
|
||||
#define LEDC_ERR_VAL (-1)
|
||||
|
||||
typedef enum {
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
LEDC_HIGH_SPEED_MODE = 0, /*!< LEDC high speed speed_mode */
|
||||
#endif
|
||||
LEDC_LOW_SPEED_MODE, /*!< LEDC low speed speed_mode */
|
||||
LEDC_SPEED_MODE_MAX, /*!< LEDC speed limit */
|
||||
} ledc_mode_t;
|
||||
|
||||
typedef enum {
|
||||
LEDC_INTR_DISABLE = 0, /*!< Disable LEDC interrupt */
|
||||
LEDC_INTR_FADE_END, /*!< Enable LEDC interrupt */
|
||||
} ledc_intr_type_t;
|
||||
|
||||
typedef enum {
|
||||
LEDC_DUTY_DIR_DECREASE = 0, /*!< LEDC duty decrease direction */
|
||||
LEDC_DUTY_DIR_INCREASE = 1, /*!< LEDC duty increase direction */
|
||||
LEDC_DUTY_DIR_MAX,
|
||||
} ledc_duty_direction_t;
|
||||
|
||||
typedef enum {
|
||||
LEDC_REF_TICK = 0, /*!< LEDC timer clock divided from reference tick (1Mhz) */
|
||||
LEDC_APB_CLK, /*!< LEDC timer clock divided from APB clock (80Mhz) */
|
||||
} ledc_clk_src_t;
|
||||
|
||||
typedef enum {
|
||||
LEDC_AUTO_CLK, /*!< The driver will automatically select the source clock(REF_TICK or APB) based on the giving resolution and duty parameter when init the timer*/
|
||||
LEDC_USE_REF_TICK, /*!< LEDC timer select REF_TICK clock as source clock*/
|
||||
LEDC_USE_APB_CLK, /*!< LEDC timer select APB clock as source clock*/
|
||||
LEDC_USE_RTC8M_CLK, /*!< LEDC timer select RTC8M_CLK as source clock. Only for low speed channels and this parameter must be the same for all low speed channels*/
|
||||
} ledc_clk_cfg_t;
|
||||
|
||||
typedef enum {
|
||||
LEDC_TIMER_0 = 0, /*!< LEDC timer 0 */
|
||||
LEDC_TIMER_1, /*!< LEDC timer 1 */
|
||||
LEDC_TIMER_2, /*!< LEDC timer 2 */
|
||||
LEDC_TIMER_3, /*!< LEDC timer 3 */
|
||||
LEDC_TIMER_MAX,
|
||||
} ledc_timer_t;
|
||||
|
||||
typedef enum {
|
||||
LEDC_CHANNEL_0 = 0, /*!< LEDC channel 0 */
|
||||
LEDC_CHANNEL_1, /*!< LEDC channel 1 */
|
||||
LEDC_CHANNEL_2, /*!< LEDC channel 2 */
|
||||
LEDC_CHANNEL_3, /*!< LEDC channel 3 */
|
||||
LEDC_CHANNEL_4, /*!< LEDC channel 4 */
|
||||
LEDC_CHANNEL_5, /*!< LEDC channel 5 */
|
||||
LEDC_CHANNEL_6, /*!< LEDC channel 6 */
|
||||
LEDC_CHANNEL_7, /*!< LEDC channel 7 */
|
||||
LEDC_CHANNEL_MAX,
|
||||
} ledc_channel_t;
|
||||
|
||||
typedef enum {
|
||||
LEDC_TIMER_1_BIT = 1, /*!< LEDC PWM duty resolution of 1 bits */
|
||||
LEDC_TIMER_2_BIT, /*!< LEDC PWM duty resolution of 2 bits */
|
||||
LEDC_TIMER_3_BIT, /*!< LEDC PWM duty resolution of 3 bits */
|
||||
LEDC_TIMER_4_BIT, /*!< LEDC PWM duty resolution of 4 bits */
|
||||
LEDC_TIMER_5_BIT, /*!< LEDC PWM duty resolution of 5 bits */
|
||||
LEDC_TIMER_6_BIT, /*!< LEDC PWM duty resolution of 6 bits */
|
||||
LEDC_TIMER_7_BIT, /*!< LEDC PWM duty resolution of 7 bits */
|
||||
LEDC_TIMER_8_BIT, /*!< LEDC PWM duty resolution of 8 bits */
|
||||
LEDC_TIMER_9_BIT, /*!< LEDC PWM duty resolution of 9 bits */
|
||||
LEDC_TIMER_10_BIT, /*!< LEDC PWM duty resolution of 10 bits */
|
||||
LEDC_TIMER_11_BIT, /*!< LEDC PWM duty resolution of 11 bits */
|
||||
LEDC_TIMER_12_BIT, /*!< LEDC PWM duty resolution of 12 bits */
|
||||
LEDC_TIMER_13_BIT, /*!< LEDC PWM duty resolution of 13 bits */
|
||||
LEDC_TIMER_14_BIT, /*!< LEDC PWM duty resolution of 14 bits */
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
LEDC_TIMER_15_BIT, /*!< LEDC PWM duty resolution of 15 bits */
|
||||
LEDC_TIMER_16_BIT, /*!< LEDC PWM duty resolution of 16 bits */
|
||||
LEDC_TIMER_17_BIT, /*!< LEDC PWM duty resolution of 17 bits */
|
||||
LEDC_TIMER_18_BIT, /*!< LEDC PWM duty resolution of 18 bits */
|
||||
LEDC_TIMER_19_BIT, /*!< LEDC PWM duty resolution of 19 bits */
|
||||
LEDC_TIMER_20_BIT, /*!< LEDC PWM duty resolution of 20 bits */
|
||||
#endif
|
||||
LEDC_TIMER_BIT_MAX,
|
||||
} ledc_timer_bit_t;
|
||||
|
||||
typedef enum {
|
||||
LEDC_FADE_NO_WAIT = 0, /*!< LEDC fade function will return immediately */
|
||||
LEDC_FADE_WAIT_DONE, /*!< LEDC fade function will block until fading to the target duty */
|
||||
LEDC_FADE_MAX,
|
||||
} ledc_fade_mode_t;
|
||||
|
||||
/**
|
||||
* @brief Configuration parameters of LEDC channel for ledc_channel_config function
|
||||
*/
|
||||
typedef struct {
|
||||
int gpio_num; /*!< the LEDC output gpio_num, if you want to use gpio16, gpio_num = 16 */
|
||||
ledc_mode_t speed_mode; /*!< LEDC speed speed_mode, high-speed mode or low-speed mode */
|
||||
ledc_channel_t channel; /*!< LEDC channel (0 - 7) */
|
||||
ledc_intr_type_t intr_type; /*!< configure interrupt, Fade interrupt enable or Fade interrupt disable */
|
||||
ledc_timer_t timer_sel; /*!< Select the timer source of channel (0 - 3) */
|
||||
uint32_t duty; /*!< LEDC channel duty, the range of duty setting is [0, (2**duty_resolution)] */
|
||||
int hpoint; /*!< LEDC channel hpoint value, the max value is 0xfffff */
|
||||
} ledc_channel_config_t;
|
||||
|
||||
/**
|
||||
* @brief Configuration parameters of LEDC Timer timer for ledc_timer_config function
|
||||
*/
|
||||
typedef struct {
|
||||
ledc_mode_t speed_mode; /*!< LEDC speed speed_mode, high-speed mode or low-speed mode */
|
||||
ledc_timer_bit_t duty_resolution; /*!< LEDC channel duty resolution */
|
||||
ledc_timer_t timer_num; /*!< The timer source of channel (0 - 3) */
|
||||
uint32_t freq_hz; /*!< LEDC timer frequency (Hz) */
|
||||
ledc_clk_cfg_t clk_cfg; /*!< Configure LEDC source clock.
|
||||
For low speed channels and high speed channels, you can specify the source clock using LEDC_USE_REF_TICK, LEDC_USE_APB_CLK or LEDC_AUTO_CLK.
|
||||
For low speed channels, you can also specify the source clock using LEDC_USE_RTC8M_CLK, in this case, all low speed channel's source clock must be RTC8M_CLK*/
|
||||
} ledc_timer_config_t;
|
||||
#define LEDC_APB_CLK_HZ (APB_CLK_FREQ)
|
||||
#define LEDC_REF_CLK_HZ (REF_CLK_FREQ)
|
||||
#define LEDC_ERR_DUTY (0xFFFFFFFF)
|
||||
#define LEDC_ERR_VAL (-1)
|
||||
|
||||
typedef intr_handle_t ledc_isr_handle_t;
|
||||
|
||||
|
@ -293,7 +185,7 @@ uint32_t ledc_get_duty(ledc_mode_t speed_mode, ledc_channel_t channel);
|
|||
* @param duty Set the start of the gradient duty, the range of duty setting is [0, (2**duty_resolution)]
|
||||
* @param fade_direction Set the direction of the gradient
|
||||
* @param step_num Set the number of the gradient
|
||||
* @param duty_cyle_num Set how many LEDC tick each time the gradient lasts
|
||||
* @param duty_cycle_num Set how many LEDC tick each time the gradient lasts
|
||||
* @param duty_scale Set gradient change amplitude
|
||||
*
|
||||
* @return
|
||||
|
@ -301,7 +193,7 @@ uint32_t ledc_get_duty(ledc_mode_t speed_mode, ledc_channel_t channel);
|
|||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*/
|
||||
esp_err_t ledc_set_fade(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t duty, ledc_duty_direction_t fade_direction,
|
||||
uint32_t step_num, uint32_t duty_cyle_num, uint32_t duty_scale);
|
||||
uint32_t step_num, uint32_t duty_cycle_num, uint32_t duty_scale);
|
||||
|
||||
/**
|
||||
* @brief Register LEDC interrupt handler, the handler is an ISR.
|
||||
|
@ -345,7 +237,7 @@ esp_err_t ledc_timer_set(ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_
|
|||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
* - ESP_OK Success
|
||||
*/
|
||||
esp_err_t ledc_timer_rst(ledc_mode_t speed_mode, uint32_t timer_sel);
|
||||
esp_err_t ledc_timer_rst(ledc_mode_t speed_mode, ledc_timer_t timer_sel);
|
||||
|
||||
/**
|
||||
* @brief Pause LEDC timer counter
|
||||
|
@ -358,7 +250,7 @@ esp_err_t ledc_timer_rst(ledc_mode_t speed_mode, uint32_t timer_sel);
|
|||
* - ESP_OK Success
|
||||
*
|
||||
*/
|
||||
esp_err_t ledc_timer_pause(ledc_mode_t speed_mode, uint32_t timer_sel);
|
||||
esp_err_t ledc_timer_pause(ledc_mode_t speed_mode, ledc_timer_t timer_sel);
|
||||
|
||||
/**
|
||||
* @brief Resume LEDC timer
|
||||
|
@ -370,20 +262,20 @@ esp_err_t ledc_timer_pause(ledc_mode_t speed_mode, uint32_t timer_sel);
|
|||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
* - ESP_OK Success
|
||||
*/
|
||||
esp_err_t ledc_timer_resume(ledc_mode_t speed_mode, uint32_t timer_sel);
|
||||
esp_err_t ledc_timer_resume(ledc_mode_t speed_mode, ledc_timer_t timer_sel);
|
||||
|
||||
/**
|
||||
* @brief Bind LEDC channel with the selected timer
|
||||
*
|
||||
* @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode
|
||||
* @param channel LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param timer_idx LEDC timer index (0-3), select from ledc_timer_t
|
||||
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_t
|
||||
*
|
||||
* @return
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
* - ESP_OK Success
|
||||
*/
|
||||
esp_err_t ledc_bind_channel_timer(ledc_mode_t speed_mode, uint32_t channel, uint32_t timer_idx);
|
||||
esp_err_t ledc_bind_channel_timer(ledc_mode_t speed_mode, ledc_channel_t channel, ledc_timer_t timer_sel);
|
||||
|
||||
/**
|
||||
* @brief Set LEDC fade function.
|
||||
|
@ -516,5 +408,3 @@ esp_err_t ledc_set_fade_step_and_start(ledc_mode_t speed_mode, ledc_channel_t ch
|
|||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _DRIVER_LEDC_H_ */
|
||||
|
|
|
@ -16,25 +16,25 @@
|
|||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "freertos/xtensa_api.h"
|
||||
#include "esp_log.h"
|
||||
#include "soc/gpio_periph.h"
|
||||
#include "driver/ledc.h"
|
||||
#include "soc/ledc_periph.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "esp_log.h"
|
||||
#include "hal/ledc_hal.h"
|
||||
#include "driver/ledc.h"
|
||||
|
||||
static const char* LEDC_TAG = "ledc";
|
||||
static portMUX_TYPE ledc_spinlock = portMUX_INITIALIZER_UNLOCKED;
|
||||
|
||||
#define LEDC_CHECK(a, str, ret_val) \
|
||||
if (!(a)) { \
|
||||
ESP_LOGE(LEDC_TAG, "%s(%d): %s", __FUNCTION__, __LINE__, str); \
|
||||
return (ret_val); \
|
||||
}
|
||||
|
||||
#define LEDC_ARG_CHECK(a, param) LEDC_CHECK(a, param " argument is invalid", ESP_ERR_INVALID_ARG)
|
||||
|
||||
typedef struct {
|
||||
uint16_t speed_mode;
|
||||
uint16_t direction;
|
||||
ledc_mode_t speed_mode;
|
||||
ledc_duty_direction_t direction;
|
||||
uint32_t target_duty;
|
||||
int cycle_num;
|
||||
int scale;
|
||||
|
@ -46,8 +46,14 @@ typedef struct {
|
|||
#endif
|
||||
} ledc_fade_t;
|
||||
|
||||
typedef struct {
|
||||
ledc_hal_context_t ledc_hal; /*!< LEDC hal context*/
|
||||
} ledc_obj_t;
|
||||
|
||||
static ledc_obj_t *p_ledc_obj[LEDC_SPEED_MODE_MAX] = {0};
|
||||
static ledc_fade_t *s_ledc_fade_rec[LEDC_SPEED_MODE_MAX][LEDC_CHANNEL_MAX];
|
||||
static ledc_isr_handle_t s_ledc_fade_isr_handle = NULL;
|
||||
static portMUX_TYPE ledc_spinlock = portMUX_INITIALIZER_UNLOCKED;
|
||||
|
||||
#define LEDC_VAL_NO_CHANGE (-1)
|
||||
#define LEDC_STEP_NUM_MAX (1023)
|
||||
|
@ -61,6 +67,8 @@ static ledc_isr_handle_t s_ledc_fade_isr_handle = NULL;
|
|||
#define SLOW_CLK_CYC_CALIBRATE (13)
|
||||
#define LEDC_FADE_TOO_SLOW_STR "LEDC FADE TOO SLOW"
|
||||
#define LEDC_FADE_TOO_FAST_STR "LEDC FADE TOO FAST"
|
||||
|
||||
static const char *LEDC_NOT_INIT = "LEDC is not initialized";
|
||||
static const char *LEDC_FADE_SERVICE_ERR_STR = "LEDC fade service not installed";
|
||||
static const char *LEDC_FADE_INIT_ERROR_STR = "LEDC fade channel init error, not enough memory or service not installed";
|
||||
|
||||
|
@ -70,14 +78,14 @@ static uint32_t s_ledc_slow_clk_8M = 0;
|
|||
static void ledc_ls_timer_update(ledc_mode_t speed_mode, ledc_timer_t timer_sel)
|
||||
{
|
||||
if (speed_mode == LEDC_LOW_SPEED_MODE) {
|
||||
LEDC.timer_group[speed_mode].timer[timer_sel].conf.low_speed_update = 1;
|
||||
ledc_hal_ls_timer_update(&(p_ledc_obj[speed_mode]->ledc_hal), timer_sel);
|
||||
}
|
||||
}
|
||||
|
||||
static IRAM_ATTR void ledc_ls_channel_update(ledc_mode_t speed_mode, ledc_channel_t channel_num)
|
||||
static IRAM_ATTR void ledc_ls_channel_update(ledc_mode_t speed_mode, ledc_channel_t channel)
|
||||
{
|
||||
if (speed_mode == LEDC_LOW_SPEED_MODE) {
|
||||
LEDC.channel_group[speed_mode].channel[channel_num].conf0.low_speed_update = 1;
|
||||
ledc_hal_ls_channel_update(&(p_ledc_obj[speed_mode]->ledc_hal), channel);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -103,25 +111,30 @@ static bool ledc_slow_clk_calibrate(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
static esp_err_t ledc_enable_intr_type(ledc_mode_t speed_mode, uint32_t channel, ledc_intr_type_t type)
|
||||
static uint32_t ledc_get_src_clk_freq(ledc_clk_cfg_t clk_cfg)
|
||||
{
|
||||
LEDC_ARG_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "speed_mode");
|
||||
uint32_t value;
|
||||
uint32_t intr_type = type;
|
||||
portENTER_CRITICAL(&ledc_spinlock);
|
||||
value = LEDC.int_ena.val;
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
uint8_t int_en_base = LEDC_DUTY_CHNG_END_HSCH0_INT_ENA_S;
|
||||
#elif defined CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
uint8_t int_en_base = LEDC_DUTY_CHNG_END_LSCH0_INT_ENA_S;
|
||||
uint32_t src_clk_freq = 0;
|
||||
if (clk_cfg == LEDC_USE_APB_CLK) {
|
||||
src_clk_freq = LEDC_APB_CLK_HZ;
|
||||
} else if (clk_cfg == LEDC_USE_REF_TICK) {
|
||||
src_clk_freq = LEDC_REF_CLK_HZ;
|
||||
} else if (clk_cfg == LEDC_USE_RTC8M_CLK) {
|
||||
src_clk_freq = s_ledc_slow_clk_8M;
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
} else if (clk_cfg == LEDC_USE_XTAL_CLK) {
|
||||
src_clk_freq = rtc_clk_xtal_freq_get() * 1000000;
|
||||
#endif
|
||||
if (speed_mode == LEDC_LOW_SPEED_MODE) {
|
||||
int_en_base = LEDC_DUTY_CHNG_END_LSCH0_INT_ENA_S;
|
||||
}
|
||||
if (intr_type == LEDC_INTR_FADE_END) {
|
||||
LEDC.int_ena.val = value | BIT(int_en_base + channel);
|
||||
return src_clk_freq;
|
||||
}
|
||||
|
||||
static esp_err_t ledc_enable_intr_type(ledc_mode_t speed_mode, ledc_channel_t channel, ledc_intr_type_t type)
|
||||
{
|
||||
portENTER_CRITICAL(&ledc_spinlock);
|
||||
if (type == LEDC_INTR_FADE_END) {
|
||||
ledc_hal_set_fade_end_intr(&(p_ledc_obj[speed_mode]->ledc_hal), channel, true);
|
||||
} else {
|
||||
LEDC.int_ena.val = (value & (~(BIT(int_en_base + channel))));
|
||||
ledc_hal_set_fade_end_intr(&(p_ledc_obj[speed_mode]->ledc_hal), channel, false);
|
||||
}
|
||||
portEXIT_CRITICAL(&ledc_spinlock);
|
||||
return ESP_OK;
|
||||
|
@ -163,117 +176,88 @@ static void _ledc_op_lock_release(ledc_mode_t mode, ledc_channel_t channel)
|
|||
static int ledc_get_max_duty(ledc_mode_t speed_mode, ledc_channel_t channel)
|
||||
{
|
||||
// The arguments are checked before internally calling this function.
|
||||
int timer_sel = LEDC.channel_group[speed_mode].channel[channel].conf0.timer_sel;
|
||||
int max_duty = (1 << (LEDC.timer_group[speed_mode].timer[timer_sel].conf.duty_resolution));
|
||||
uint32_t max_duty;
|
||||
ledc_hal_get_max_duty(&(p_ledc_obj[speed_mode]->ledc_hal), channel, &max_duty);
|
||||
return max_duty;
|
||||
}
|
||||
|
||||
static ledc_clk_cfg_t ledc_timer_get_source_clk(ledc_mode_t speed_mode, ledc_timer_t timer_sel)
|
||||
{
|
||||
ledc_clk_cfg_t clk_cfg = LEDC_USE_APB_CLK;
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
if (speed_mode == LEDC_LOW_SPEED_MODE && LEDC.conf.slow_clk_sel == 0) {
|
||||
clk_cfg = LEDC_USE_RTC8M_CLK;
|
||||
} else if( LEDC.timer_group[speed_mode].timer[timer_sel].conf.tick_sel == 0) {
|
||||
clk_cfg = LEDC_USE_REF_TICK;
|
||||
}
|
||||
#elif defined CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
if (LEDC.conf.apb_clk_sel == 2) {
|
||||
clk_cfg = LEDC_USE_RTC8M_CLK;
|
||||
} else if (LEDC.conf.apb_clk_sel == 1) {
|
||||
if (LEDC.timer_group[speed_mode].timer[timer_sel].conf.tick_sel) {
|
||||
clk_cfg = LEDC_USE_REF_TICK;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return clk_cfg;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
LEDC_ARG_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "speed_mode");
|
||||
LEDC_ARG_CHECK(timer_sel < LEDC_TIMER_MAX, "timer_select");
|
||||
LEDC_CHECK(p_ledc_obj[speed_mode] != NULL, LEDC_NOT_INIT, ESP_ERR_INVALID_STATE);
|
||||
portENTER_CRITICAL(&ledc_spinlock);
|
||||
LEDC.timer_group[speed_mode].timer[timer_sel].conf.clock_divider = clock_divider;
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
LEDC.timer_group[speed_mode].timer[timer_sel].conf.tick_sel = clk_src;
|
||||
#elif defined CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
if(clk_src == LEDC_REF_TICK) {
|
||||
//REF_TICK can only be used when APB is selected.
|
||||
LEDC.timer_group[speed_mode].timer[timer_sel].conf.tick_sel = 1;
|
||||
LEDC.conf.apb_clk_sel = 1;
|
||||
} else {
|
||||
LEDC.timer_group[speed_mode].timer[timer_sel].conf.tick_sel = 0;
|
||||
}
|
||||
#endif
|
||||
LEDC.timer_group[speed_mode].timer[timer_sel].conf.duty_resolution = duty_resolution;
|
||||
ledc_hal_set_clock_divider(&(p_ledc_obj[speed_mode]->ledc_hal), timer_sel, clock_divider);
|
||||
ledc_hal_set_clock_source(&(p_ledc_obj[speed_mode]->ledc_hal), timer_sel, clk_src);
|
||||
ledc_hal_set_duty_resolution(&(p_ledc_obj[speed_mode]->ledc_hal), timer_sel, duty_resolution);
|
||||
ledc_ls_timer_update(speed_mode, timer_sel);
|
||||
portEXIT_CRITICAL(&ledc_spinlock);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static IRAM_ATTR esp_err_t ledc_duty_config(ledc_mode_t speed_mode, ledc_channel_t channel_num, int hpoint_val, int duty_val,
|
||||
uint32_t duty_direction, uint32_t duty_num, uint32_t duty_cycle, uint32_t duty_scale)
|
||||
static IRAM_ATTR esp_err_t ledc_duty_config(ledc_mode_t speed_mode, ledc_channel_t channel, int hpoint_val, int duty_val,
|
||||
ledc_duty_direction_t duty_direction, uint32_t duty_num, uint32_t duty_cycle, uint32_t duty_scale)
|
||||
{
|
||||
portENTER_CRITICAL(&ledc_spinlock);
|
||||
if (hpoint_val >= 0) {
|
||||
LEDC.channel_group[speed_mode].channel[channel_num].hpoint.hpoint = hpoint_val;
|
||||
ledc_hal_set_hpoint(&(p_ledc_obj[speed_mode]->ledc_hal), channel, hpoint_val);
|
||||
}
|
||||
if (duty_val >= 0) {
|
||||
LEDC.channel_group[speed_mode].channel[channel_num].duty.duty = duty_val;
|
||||
ledc_hal_set_duty_int_part(&(p_ledc_obj[speed_mode]->ledc_hal), channel, duty_val);
|
||||
}
|
||||
typeof(LEDC.channel_group[0].channel[0].conf1) channel_cfg;
|
||||
channel_cfg.val = 0;
|
||||
channel_cfg.duty_inc = duty_direction;
|
||||
channel_cfg.duty_num = duty_num;
|
||||
channel_cfg.duty_cycle = duty_cycle;
|
||||
channel_cfg.duty_scale = duty_scale;
|
||||
LEDC.channel_group[speed_mode].channel[channel_num].conf1.val = channel_cfg.val;
|
||||
ledc_ls_channel_update(speed_mode, channel_num);
|
||||
portEXIT_CRITICAL(&ledc_spinlock);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t ledc_bind_channel_timer(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t timer_idx)
|
||||
{
|
||||
LEDC_ARG_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "speed_mode");
|
||||
LEDC_ARG_CHECK(timer_idx < LEDC_TIMER_MAX, "timer_select"); portENTER_CRITICAL(&ledc_spinlock);
|
||||
LEDC.channel_group[speed_mode].channel[channel].conf0.timer_sel = timer_idx;
|
||||
ledc_hal_set_duty_direction(&(p_ledc_obj[speed_mode]->ledc_hal), channel, duty_direction);
|
||||
ledc_hal_set_duty_num(&(p_ledc_obj[speed_mode]->ledc_hal), channel, duty_num);
|
||||
ledc_hal_set_duty_cycle(&(p_ledc_obj[speed_mode]->ledc_hal), channel, duty_cycle);
|
||||
ledc_hal_set_duty_scale(&(p_ledc_obj[speed_mode]->ledc_hal), channel, duty_scale);
|
||||
ledc_ls_channel_update(speed_mode, channel);
|
||||
portEXIT_CRITICAL(&ledc_spinlock);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t ledc_timer_rst(ledc_mode_t speed_mode, uint32_t timer_sel)
|
||||
esp_err_t ledc_bind_channel_timer(ledc_mode_t speed_mode, ledc_channel_t channel, ledc_timer_t timer_sel)
|
||||
{
|
||||
LEDC_ARG_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "speed_mode");
|
||||
LEDC_ARG_CHECK(timer_sel < LEDC_TIMER_MAX, "timer_select");
|
||||
LEDC_CHECK(p_ledc_obj[speed_mode] != NULL, LEDC_NOT_INIT, ESP_ERR_INVALID_STATE);
|
||||
portENTER_CRITICAL(&ledc_spinlock);
|
||||
LEDC.timer_group[speed_mode].timer[timer_sel].conf.rst = 1;
|
||||
LEDC.timer_group[speed_mode].timer[timer_sel].conf.rst = 0;
|
||||
ledc_hal_bind_channel_timer(&(p_ledc_obj[speed_mode]->ledc_hal), channel, timer_sel);
|
||||
ledc_ls_channel_update(speed_mode, channel);
|
||||
portEXIT_CRITICAL(&ledc_spinlock);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t ledc_timer_rst(ledc_mode_t speed_mode, ledc_timer_t timer_sel)
|
||||
{
|
||||
LEDC_ARG_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "speed_mode");
|
||||
LEDC_ARG_CHECK(timer_sel < LEDC_TIMER_MAX, "timer_select");
|
||||
LEDC_CHECK(p_ledc_obj[speed_mode] != NULL, LEDC_NOT_INIT, ESP_ERR_INVALID_STATE);
|
||||
portENTER_CRITICAL(&ledc_spinlock);
|
||||
ledc_hal_timer_rst(&(p_ledc_obj[speed_mode]->ledc_hal), timer_sel);
|
||||
ledc_ls_timer_update(speed_mode, timer_sel);
|
||||
portEXIT_CRITICAL(&ledc_spinlock);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t ledc_timer_pause(ledc_mode_t speed_mode, uint32_t timer_sel)
|
||||
esp_err_t ledc_timer_pause(ledc_mode_t speed_mode, ledc_timer_t timer_sel)
|
||||
{
|
||||
LEDC_ARG_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "speed_mode");
|
||||
LEDC_ARG_CHECK(timer_sel < LEDC_TIMER_MAX, "timer_select");
|
||||
LEDC_CHECK(p_ledc_obj[speed_mode] != NULL, LEDC_NOT_INIT, ESP_ERR_INVALID_STATE);
|
||||
portENTER_CRITICAL(&ledc_spinlock);
|
||||
LEDC.timer_group[speed_mode].timer[timer_sel].conf.pause = 1;
|
||||
ledc_hal_timer_pause(&(p_ledc_obj[speed_mode]->ledc_hal), timer_sel);
|
||||
ledc_ls_timer_update(speed_mode, timer_sel);
|
||||
portEXIT_CRITICAL(&ledc_spinlock);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t ledc_timer_resume(ledc_mode_t speed_mode, uint32_t timer_sel)
|
||||
esp_err_t ledc_timer_resume(ledc_mode_t speed_mode, ledc_timer_t timer_sel)
|
||||
{
|
||||
LEDC_ARG_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "speed_mode");
|
||||
LEDC_ARG_CHECK(timer_sel < LEDC_TIMER_MAX, "timer_select");
|
||||
LEDC_CHECK(p_ledc_obj[speed_mode] != NULL, LEDC_NOT_INIT, ESP_ERR_INVALID_STATE);
|
||||
portENTER_CRITICAL(&ledc_spinlock);
|
||||
LEDC.timer_group[speed_mode].timer[timer_sel].conf.pause = 0;
|
||||
ledc_hal_timer_resume(&(p_ledc_obj[speed_mode]->ledc_hal), timer_sel);
|
||||
ledc_ls_timer_update(speed_mode, timer_sel);
|
||||
portEXIT_CRITICAL(&ledc_spinlock);
|
||||
return ESP_OK;
|
||||
|
@ -295,7 +279,6 @@ static esp_err_t ledc_set_timer_div(ledc_mode_t speed_mode, ledc_timer_t timer_n
|
|||
uint32_t div_param = 0;
|
||||
uint32_t precision = ( 0x1 << duty_resolution );
|
||||
ledc_clk_src_t timer_clk_src = LEDC_APB_CLK;
|
||||
|
||||
// Calculate the divisor
|
||||
// User specified source clock(RTC8M_CLK) for low speed channel
|
||||
if ((speed_mode == LEDC_LOW_SPEED_MODE) && (clk_cfg == LEDC_USE_RTC8M_CLK)) {
|
||||
|
@ -320,29 +303,19 @@ static esp_err_t ledc_set_timer_div(ledc_mode_t speed_mode, ledc_timer_t timer_n
|
|||
}
|
||||
// User specified source clock(LEDC_APB_CLK_HZ or LEDC_REF_TICK)
|
||||
} else {
|
||||
timer_clk_src = (clk_cfg == LEDC_USE_APB_CLK) ? LEDC_APB_CLK : LEDC_REF_TICK;
|
||||
uint32_t sclk_freq = (clk_cfg == LEDC_USE_APB_CLK) ? LEDC_APB_CLK_HZ : LEDC_REF_CLK_HZ;
|
||||
div_param = ( (uint64_t) sclk_freq << 8 ) / freq_hz / precision;
|
||||
timer_clk_src = (clk_cfg == LEDC_USE_REF_TICK) ? LEDC_REF_TICK : LEDC_APB_CLK;
|
||||
uint32_t src_clk_freq = ledc_get_src_clk_freq(clk_cfg);
|
||||
div_param = ( (uint64_t) src_clk_freq << 8 ) / freq_hz / precision;
|
||||
}
|
||||
}
|
||||
if (div_param < 256 || div_param > LEDC_TIMER_DIV_NUM_MAX) {
|
||||
goto error;
|
||||
}
|
||||
portENTER_CRITICAL(&ledc_spinlock);
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
// For low speed channels, if RTC_8MCLK is used as the source clock, the `slow_clk_sel` register should be cleared, otherwise it should be set.
|
||||
if (speed_mode == LEDC_LOW_SPEED_MODE) {
|
||||
LEDC.conf.slow_clk_sel = (clk_cfg == LEDC_USE_RTC8M_CLK) ? 0 : 1;
|
||||
portENTER_CRITICAL(&ledc_spinlock);
|
||||
ledc_hal_set_slow_clk(&(p_ledc_obj[speed_mode]->ledc_hal), clk_cfg);
|
||||
portEXIT_CRITICAL(&ledc_spinlock);
|
||||
}
|
||||
#elif defined CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
if (clk_cfg == LEDC_USE_RTC8M_CLK) {
|
||||
LEDC.conf.apb_clk_sel = 2;
|
||||
} else {
|
||||
LEDC.conf.apb_clk_sel = 1;
|
||||
}
|
||||
//TODO:Support XTAL_CLK
|
||||
#endif
|
||||
portEXIT_CRITICAL(&ledc_spinlock);
|
||||
//Set the divisor
|
||||
ledc_timer_set(speed_mode, timer_num, div_param, duty_resolution, timer_clk_src);
|
||||
// reset the timer
|
||||
|
@ -372,6 +345,12 @@ esp_err_t ledc_timer_config(const ledc_timer_config_t* timer_conf)
|
|||
ESP_LOGE(LEDC_TAG, "invalid timer #%u", timer_num);
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if(p_ledc_obj[speed_mode] == NULL) {
|
||||
p_ledc_obj[speed_mode] = (ledc_obj_t *) heap_caps_calloc(1, sizeof(ledc_obj_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
|
||||
ledc_hal_init(&(p_ledc_obj[speed_mode]->ledc_hal), speed_mode);
|
||||
}
|
||||
|
||||
return ledc_set_timer_div(speed_mode, timer_num, timer_conf->clk_cfg, freq_hz, duty_resolution);
|
||||
}
|
||||
|
||||
|
@ -402,6 +381,12 @@ esp_err_t ledc_channel_config(const ledc_channel_config_t* ledc_conf)
|
|||
LEDC_ARG_CHECK(timer_select < LEDC_TIMER_MAX, "timer_select");
|
||||
periph_module_enable(PERIPH_LEDC_MODULE);
|
||||
esp_err_t ret = ESP_OK;
|
||||
|
||||
if(p_ledc_obj[speed_mode] == NULL) {
|
||||
p_ledc_obj[speed_mode] = (ledc_obj_t *) heap_caps_calloc(1, sizeof(ledc_obj_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
|
||||
ledc_hal_init(&(p_ledc_obj[speed_mode]->ledc_hal), speed_mode);
|
||||
}
|
||||
|
||||
/*set channel parameters*/
|
||||
/* channel parameters decide how the waveform looks like in one period*/
|
||||
/* set channel duty and hpoint value, duty range is (0 ~ ((2 ** duty_resolution) - 1)), max hpoint value is 0xfffff*/
|
||||
|
@ -427,9 +412,10 @@ esp_err_t ledc_update_duty(ledc_mode_t speed_mode, ledc_channel_t channel)
|
|||
{
|
||||
LEDC_ARG_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "speed_mode");
|
||||
LEDC_ARG_CHECK(channel < LEDC_CHANNEL_MAX, "channel");
|
||||
LEDC_CHECK(p_ledc_obj[speed_mode] != NULL, LEDC_NOT_INIT, ESP_ERR_INVALID_STATE);
|
||||
portENTER_CRITICAL(&ledc_spinlock);
|
||||
LEDC.channel_group[speed_mode].channel[channel].conf0.sig_out_en = 1;
|
||||
LEDC.channel_group[speed_mode].channel[channel].conf1.duty_start = 1;
|
||||
ledc_hal_set_sig_out_en(&(p_ledc_obj[speed_mode]->ledc_hal), channel, true);
|
||||
ledc_hal_set_duty_start(&(p_ledc_obj[speed_mode]->ledc_hal), channel, true);
|
||||
ledc_ls_channel_update(speed_mode, channel);
|
||||
portEXIT_CRITICAL(&ledc_spinlock);
|
||||
return ESP_OK;
|
||||
|
@ -439,10 +425,11 @@ esp_err_t ledc_stop(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t idl
|
|||
{
|
||||
LEDC_ARG_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "speed_mode");
|
||||
LEDC_ARG_CHECK(channel < LEDC_CHANNEL_MAX, "channel");
|
||||
LEDC_CHECK(p_ledc_obj[speed_mode] != NULL, LEDC_NOT_INIT, ESP_ERR_INVALID_STATE);
|
||||
portENTER_CRITICAL(&ledc_spinlock);
|
||||
LEDC.channel_group[speed_mode].channel[channel].conf0.idle_lv = idle_level & 0x1;
|
||||
LEDC.channel_group[speed_mode].channel[channel].conf0.sig_out_en = 0;
|
||||
LEDC.channel_group[speed_mode].channel[channel].conf1.duty_start = 0;
|
||||
ledc_hal_set_idle_level(&(p_ledc_obj[speed_mode]->ledc_hal), channel, idle_level);
|
||||
ledc_hal_set_sig_out_en(&(p_ledc_obj[speed_mode]->ledc_hal), channel, false);
|
||||
ledc_hal_set_duty_start(&(p_ledc_obj[speed_mode]->ledc_hal), channel, false);
|
||||
ledc_ls_channel_update(speed_mode, channel);
|
||||
portEXIT_CRITICAL(&ledc_spinlock);
|
||||
return ESP_OK;
|
||||
|
@ -457,11 +444,12 @@ esp_err_t ledc_set_fade(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t
|
|||
LEDC_ARG_CHECK(step_num <= LEDC_DUTY_NUM_MAX, "step_num");
|
||||
LEDC_ARG_CHECK(duty_cyle_num <= LEDC_DUTY_CYCLE_MAX, "duty_cycle_num");
|
||||
LEDC_ARG_CHECK(duty_scale <= LEDC_DUTY_SCALE_MAX, "duty_scale");
|
||||
LEDC_CHECK(p_ledc_obj[speed_mode] != NULL, LEDC_NOT_INIT, ESP_ERR_INVALID_STATE);
|
||||
_ledc_fade_hw_acquire(speed_mode, channel);
|
||||
ledc_duty_config(speed_mode,
|
||||
channel, //uint32_t chan_num,
|
||||
LEDC_VAL_NO_CHANGE,
|
||||
duty << 4, //uint32_t duty_val,the least 4 bits are decimal part
|
||||
duty, //uint32_t duty_val,
|
||||
fade_direction, //uint32_t increase,
|
||||
step_num, //uint32_t duty_num,
|
||||
duty_cyle_num, //uint32_t duty_cycle,
|
||||
|
@ -476,12 +464,13 @@ esp_err_t ledc_set_duty_with_hpoint(ledc_mode_t speed_mode, ledc_channel_t chann
|
|||
LEDC_ARG_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "speed_mode");
|
||||
LEDC_ARG_CHECK(channel < LEDC_CHANNEL_MAX, "channel");
|
||||
LEDC_ARG_CHECK(hpoint <= LEDC_HPOINT_VAL_MAX, "hpoint");
|
||||
LEDC_CHECK(p_ledc_obj[speed_mode] != NULL, LEDC_NOT_INIT, ESP_ERR_INVALID_STATE);
|
||||
/* The channel configuration should not be changed before the fade operation is done. */
|
||||
_ledc_fade_hw_acquire(speed_mode, channel);
|
||||
ledc_duty_config(speed_mode,
|
||||
channel, //uint32_t chan_num,
|
||||
hpoint, //uint32_t hpoint_val,
|
||||
duty << 4, //uint32_t duty_val,the least 4 bits are decimal part
|
||||
duty, //uint32_t duty_val,
|
||||
1, //uint32_t increase,
|
||||
1, //uint32_t duty_num,
|
||||
1, //uint32_t duty_cycle,
|
||||
|
@ -495,12 +484,13 @@ esp_err_t ledc_set_duty(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t
|
|||
{
|
||||
LEDC_ARG_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "speed_mode");
|
||||
LEDC_ARG_CHECK(channel < LEDC_CHANNEL_MAX, "channel");
|
||||
LEDC_CHECK(p_ledc_obj[speed_mode] != NULL, LEDC_NOT_INIT, ESP_ERR_INVALID_STATE);
|
||||
/* The channel configuration should not be changed before the fade operation is done. */
|
||||
_ledc_fade_hw_acquire(speed_mode, channel);
|
||||
ledc_duty_config(speed_mode,
|
||||
channel, //uint32_t chan_num,
|
||||
LEDC_VAL_NO_CHANGE,
|
||||
duty << 4, //uint32_t duty_val,the least 4 bits are decimal part
|
||||
duty, //uint32_t duty_val,
|
||||
1, //uint32_t increase,
|
||||
1, //uint32_t duty_num,
|
||||
1, //uint32_t duty_cycle,
|
||||
|
@ -513,7 +503,10 @@ esp_err_t ledc_set_duty(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t
|
|||
uint32_t ledc_get_duty(ledc_mode_t speed_mode, ledc_channel_t channel)
|
||||
{
|
||||
LEDC_ARG_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "speed_mode");
|
||||
uint32_t duty = (LEDC.channel_group[speed_mode].channel[channel].duty_rd.duty_read >> 4);
|
||||
LEDC_ARG_CHECK(channel < LEDC_CHANNEL_MAX, "channel");
|
||||
LEDC_CHECK(p_ledc_obj[speed_mode] != NULL, LEDC_NOT_INIT, ESP_ERR_INVALID_STATE);
|
||||
uint32_t duty = 0;
|
||||
ledc_hal_get_duty(&(p_ledc_obj[speed_mode]->ledc_hal), channel, &duty);
|
||||
return duty;
|
||||
}
|
||||
|
||||
|
@ -521,110 +514,114 @@ int ledc_get_hpoint(ledc_mode_t speed_mode, ledc_channel_t channel)
|
|||
{
|
||||
LEDC_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "speed_mode argument is invalid", LEDC_ERR_VAL);
|
||||
LEDC_CHECK(channel < LEDC_CHANNEL_MAX, "channel argument is invalid", LEDC_ERR_VAL);
|
||||
uint32_t hpoint = LEDC.channel_group[speed_mode].channel[channel].hpoint.hpoint;
|
||||
LEDC_CHECK(p_ledc_obj[speed_mode] != NULL, LEDC_NOT_INIT, ESP_ERR_INVALID_STATE);
|
||||
uint32_t hpoint = 0;
|
||||
ledc_hal_get_hpoint(&(p_ledc_obj[speed_mode]->ledc_hal), channel, &hpoint);
|
||||
return hpoint;
|
||||
}
|
||||
|
||||
esp_err_t ledc_set_freq(ledc_mode_t speed_mode, ledc_timer_t timer_num, uint32_t freq_hz)
|
||||
{
|
||||
LEDC_ARG_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "speed_mode");
|
||||
esp_err_t ret = ESP_OK;
|
||||
ledc_clk_cfg_t clk_cfg = LEDC_AUTO_CLK;
|
||||
portENTER_CRITICAL(&ledc_spinlock);
|
||||
uint32_t duty_resolution = LEDC.timer_group[speed_mode].timer[timer_num].conf.duty_resolution;
|
||||
ledc_set_timer_div(speed_mode, timer_num, clk_cfg, freq_hz, duty_resolution);
|
||||
portEXIT_CRITICAL(&ledc_spinlock);
|
||||
return ret;
|
||||
LEDC_ARG_CHECK(timer_num < LEDC_TIMER_MAX, "timer_num");
|
||||
LEDC_CHECK(p_ledc_obj[speed_mode] != NULL, LEDC_NOT_INIT, ESP_ERR_INVALID_STATE);
|
||||
ledc_clk_cfg_t clk_cfg = LEDC_USE_APB_CLK;
|
||||
uint32_t duty_resolution = 0;
|
||||
ledc_hal_get_clk_cfg(&(p_ledc_obj[speed_mode]->ledc_hal), timer_num, &clk_cfg);
|
||||
ledc_hal_get_duty_resolution(&(p_ledc_obj[speed_mode]->ledc_hal), timer_num, &duty_resolution);
|
||||
return ledc_set_timer_div(speed_mode, timer_num, clk_cfg, freq_hz, duty_resolution);
|
||||
}
|
||||
|
||||
uint32_t ledc_get_freq(ledc_mode_t speed_mode, ledc_timer_t timer_num)
|
||||
{
|
||||
LEDC_ARG_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "speed_mode");
|
||||
uint32_t freq = 0;
|
||||
LEDC_ARG_CHECK(timer_num < LEDC_TIMER_MAX, "timer_num");
|
||||
LEDC_CHECK(p_ledc_obj[speed_mode] != NULL, LEDC_NOT_INIT, ESP_ERR_INVALID_STATE);
|
||||
portENTER_CRITICAL(&ledc_spinlock);
|
||||
ledc_clk_cfg_t timer_source_clk = ledc_timer_get_source_clk(speed_mode, timer_num);
|
||||
uint32_t duty_resolution = LEDC.timer_group[speed_mode].timer[timer_num].conf.duty_resolution;
|
||||
uint32_t clock_divider = LEDC.timer_group[speed_mode].timer[timer_num].conf.clock_divider;
|
||||
uint32_t clock_divider = 0;
|
||||
uint32_t duty_resolution = 0;
|
||||
ledc_clk_cfg_t clk_cfg = LEDC_USE_APB_CLK;
|
||||
ledc_hal_get_clock_divider(&(p_ledc_obj[speed_mode]->ledc_hal), timer_num, &clock_divider);
|
||||
ledc_hal_get_duty_resolution(&(p_ledc_obj[speed_mode]->ledc_hal), timer_num, &duty_resolution);
|
||||
ledc_hal_get_clk_cfg(&(p_ledc_obj[speed_mode]->ledc_hal), timer_num, &clk_cfg);
|
||||
uint32_t precision = (0x1 << duty_resolution);
|
||||
uint32_t src_clk_freq = ledc_get_src_clk_freq(clk_cfg);
|
||||
portEXIT_CRITICAL(&ledc_spinlock);
|
||||
if (timer_source_clk == LEDC_USE_APB_CLK) {
|
||||
freq = ((uint64_t) LEDC_APB_CLK_HZ << 8) / precision / clock_divider;
|
||||
} else if(timer_source_clk == LEDC_USE_RTC8M_CLK) {
|
||||
freq = ((uint64_t) s_ledc_slow_clk_8M << 8) / precision / clock_divider;
|
||||
} else {
|
||||
freq = ((uint64_t) LEDC_REF_CLK_HZ << 8) / precision / clock_divider;
|
||||
}
|
||||
return freq;
|
||||
return ((uint64_t) src_clk_freq << 8) / precision / clock_divider;
|
||||
}
|
||||
|
||||
static inline void ledc_calc_fade_end_channel(uint32_t *fade_end_status, int *channel, int *speed_mode)
|
||||
static inline void ledc_calc_fade_end_channel(uint32_t *fade_end_status, uint32_t *channel)
|
||||
{
|
||||
int i = __builtin_ffs((*fade_end_status)) - 1;
|
||||
uint32_t i = __builtin_ffs((*fade_end_status)) - 1;
|
||||
(*fade_end_status) &= ~(1 << i);
|
||||
*speed_mode = LEDC_LOW_SPEED_MODE;
|
||||
*channel = i;
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
if (i < LEDC_CHANNEL_MAX) {
|
||||
*speed_mode = LEDC_HIGH_SPEED_MODE;
|
||||
} else {
|
||||
*channel = i - LEDC_CHANNEL_MAX;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void IRAM_ATTR ledc_fade_isr(void* arg)
|
||||
{
|
||||
portBASE_TYPE HPTaskAwoken = pdFALSE;
|
||||
uint32_t intr_status = LEDC.int_st.val; //read LEDC interrupt status.
|
||||
uint32_t fade_end_status = (intr_status >> LEDC_LSTIMER0_OVF_INT_ST_S);
|
||||
int speed_mode;
|
||||
int channel;
|
||||
while (fade_end_status) {
|
||||
ledc_calc_fade_end_channel(&fade_end_status, &channel, &speed_mode);
|
||||
if (s_ledc_fade_rec[speed_mode][channel] == NULL) {
|
||||
//fade object not initialized yet.
|
||||
continue;
|
||||
uint32_t speed_mode = 0;
|
||||
uint32_t channel = 0;
|
||||
uint32_t intr_status = 0;
|
||||
|
||||
for (speed_mode = 0; speed_mode < LEDC_SPEED_MODE_MAX; speed_mode++) {
|
||||
ledc_hal_get_fade_end_intr_status(&(p_ledc_obj[speed_mode]->ledc_hal), &intr_status);
|
||||
while(intr_status) {
|
||||
ledc_calc_fade_end_channel(&intr_status, &channel);
|
||||
|
||||
// clear interrupt
|
||||
portENTER_CRITICAL(&ledc_spinlock);
|
||||
ledc_hal_clear_fade_end_intr_status(&(p_ledc_obj[speed_mode]->ledc_hal), channel);
|
||||
portEXIT_CRITICAL(&ledc_spinlock);
|
||||
|
||||
if (s_ledc_fade_rec[speed_mode][channel] == NULL) {
|
||||
//fade object not initialized yet.
|
||||
continue;
|
||||
}
|
||||
|
||||
uint32_t duty_cur = 0;
|
||||
ledc_hal_get_duty(&(p_ledc_obj[speed_mode]->ledc_hal), channel, &duty_cur);
|
||||
if (duty_cur == s_ledc_fade_rec[speed_mode][channel]->target_duty) {
|
||||
xSemaphoreGiveFromISR(s_ledc_fade_rec[speed_mode][channel]->ledc_fade_sem, &HPTaskAwoken);
|
||||
if (HPTaskAwoken == pdTRUE) {
|
||||
portYIELD_FROM_ISR();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
uint32_t duty_tar = s_ledc_fade_rec[speed_mode][channel]->target_duty;
|
||||
int scale = s_ledc_fade_rec[speed_mode][channel]->scale;
|
||||
if (scale == 0) {
|
||||
xSemaphoreGiveFromISR(s_ledc_fade_rec[speed_mode][channel]->ledc_fade_sem, &HPTaskAwoken);
|
||||
continue;
|
||||
}
|
||||
int cycle = s_ledc_fade_rec[speed_mode][channel]->cycle_num;
|
||||
int delta = s_ledc_fade_rec[speed_mode][channel]->direction == LEDC_DUTY_DIR_DECREASE ? duty_cur - duty_tar : duty_tar - duty_cur;
|
||||
int step = delta / scale > LEDC_STEP_NUM_MAX ? LEDC_STEP_NUM_MAX : delta / scale;
|
||||
if (delta > scale) {
|
||||
ledc_duty_config(
|
||||
speed_mode,
|
||||
channel,
|
||||
LEDC_VAL_NO_CHANGE,
|
||||
duty_cur,
|
||||
s_ledc_fade_rec[speed_mode][channel]->direction,
|
||||
step,
|
||||
cycle,
|
||||
scale);
|
||||
} else {
|
||||
ledc_duty_config(
|
||||
speed_mode,
|
||||
channel,
|
||||
LEDC_VAL_NO_CHANGE,
|
||||
duty_tar,
|
||||
s_ledc_fade_rec[speed_mode][channel]->direction,
|
||||
1,
|
||||
1,
|
||||
0);
|
||||
}
|
||||
portENTER_CRITICAL(&ledc_spinlock);
|
||||
ledc_hal_set_duty_start(&(p_ledc_obj[speed_mode]->ledc_hal), channel, true);
|
||||
portEXIT_CRITICAL(&ledc_spinlock);
|
||||
}
|
||||
uint32_t duty_cur = LEDC.channel_group[speed_mode].channel[channel].duty_rd.duty_read >> LEDC_DUTY_DECIMAL_BIT_NUM;
|
||||
if (duty_cur == s_ledc_fade_rec[speed_mode][channel]->target_duty) {
|
||||
xSemaphoreGiveFromISR(s_ledc_fade_rec[speed_mode][channel]->ledc_fade_sem, &HPTaskAwoken);
|
||||
continue;
|
||||
}
|
||||
uint32_t duty_tar = s_ledc_fade_rec[speed_mode][channel]->target_duty;
|
||||
int scale = s_ledc_fade_rec[speed_mode][channel]->scale;
|
||||
if (scale == 0) {
|
||||
xSemaphoreGiveFromISR(s_ledc_fade_rec[speed_mode][channel]->ledc_fade_sem, &HPTaskAwoken);
|
||||
continue;
|
||||
}
|
||||
int cycle = s_ledc_fade_rec[speed_mode][channel]->cycle_num;
|
||||
int delta = s_ledc_fade_rec[speed_mode][channel]->direction == LEDC_DUTY_DIR_DECREASE ? duty_cur - duty_tar : duty_tar - duty_cur;
|
||||
int step = delta / scale > LEDC_STEP_NUM_MAX ? LEDC_STEP_NUM_MAX : delta / scale;
|
||||
if (delta > scale) {
|
||||
ledc_duty_config(
|
||||
speed_mode,
|
||||
channel,
|
||||
LEDC_VAL_NO_CHANGE,
|
||||
duty_cur << LEDC_DUTY_DECIMAL_BIT_NUM,
|
||||
s_ledc_fade_rec[speed_mode][channel]->direction,
|
||||
step,
|
||||
cycle,
|
||||
scale);
|
||||
} else {
|
||||
ledc_duty_config(
|
||||
speed_mode,
|
||||
channel,
|
||||
LEDC_VAL_NO_CHANGE,
|
||||
duty_tar << LEDC_DUTY_DECIMAL_BIT_NUM,
|
||||
s_ledc_fade_rec[speed_mode][channel]->direction,
|
||||
1,
|
||||
1,
|
||||
0);
|
||||
}
|
||||
LEDC.channel_group[speed_mode].channel[channel].conf1.duty_start = 1;
|
||||
}
|
||||
LEDC.int_clr.val = intr_status; //clear LEDC interrupt status.
|
||||
if (HPTaskAwoken == pdTRUE) {
|
||||
portYIELD_FROM_ISR();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -653,7 +650,7 @@ static esp_err_t ledc_fade_channel_init_check(ledc_mode_t speed_mode, ledc_chann
|
|||
}
|
||||
if (s_ledc_fade_rec[speed_mode][channel] == NULL) {
|
||||
#if CONFIG_SPIRAM_USE_MALLOC
|
||||
s_ledc_fade_rec[speed_mode][channel] = (ledc_fade_t *) heap_caps_calloc(1, sizeof(ledc_fade_t), MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
|
||||
s_ledc_fade_rec[speed_mode][channel] = (ledc_fade_t *) heap_caps_calloc(1, sizeof(ledc_fade_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
|
||||
if (!s_ledc_fade_rec[speed_mode][channel]) {
|
||||
ledc_fade_channel_deinit(speed_mode, channel);
|
||||
return ESP_FAIL;
|
||||
|
@ -681,7 +678,8 @@ static esp_err_t ledc_fade_channel_init_check(ledc_mode_t speed_mode, ledc_chann
|
|||
static esp_err_t _ledc_set_fade_with_step(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t target_duty, int scale, int cycle_num)
|
||||
{
|
||||
portENTER_CRITICAL(&ledc_spinlock);
|
||||
uint32_t duty_cur = LEDC.channel_group[speed_mode].channel[channel].duty_rd.duty_read >> LEDC_DUTY_DECIMAL_BIT_NUM;
|
||||
uint32_t duty_cur = 0;
|
||||
ledc_hal_get_duty(&(p_ledc_obj[speed_mode]->ledc_hal), channel, &duty_cur);
|
||||
// When duty == max_duty, meanwhile, if scale == 1 and fade_down == 1, counter would overflow.
|
||||
if (duty_cur == ledc_get_max_duty(speed_mode, channel)) {
|
||||
duty_cur -= 1;
|
||||
|
@ -707,11 +705,11 @@ static esp_err_t _ledc_set_fade_with_step(ledc_mode_t speed_mode, ledc_channel_t
|
|||
|
||||
portEXIT_CRITICAL(&ledc_spinlock);
|
||||
if (scale > 0 && step_num > 0) {
|
||||
ledc_duty_config(speed_mode, channel, LEDC_VAL_NO_CHANGE, duty_cur << 4, dir, step_num, cycle_num, scale);
|
||||
ledc_duty_config(speed_mode, channel, LEDC_VAL_NO_CHANGE, duty_cur, dir, step_num, cycle_num, scale);
|
||||
ESP_LOGD(LEDC_TAG, "cur duty: %d; target: %d, step: %d, cycle: %d; scale: %d; dir: %d\n",
|
||||
duty_cur, target_duty, step_num, cycle_num, scale, dir);
|
||||
} else {
|
||||
ledc_duty_config(speed_mode, channel, LEDC_VAL_NO_CHANGE, target_duty << 4, dir, 0, 1, 0);
|
||||
ledc_duty_config(speed_mode, channel, LEDC_VAL_NO_CHANGE, target_duty, dir, 0, 1, 0);
|
||||
ESP_LOGD(LEDC_TAG, "Set to target duty: %d", target_duty);
|
||||
}
|
||||
return ESP_OK;
|
||||
|
@ -719,9 +717,11 @@ static esp_err_t _ledc_set_fade_with_step(ledc_mode_t speed_mode, ledc_channel_t
|
|||
|
||||
static 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)
|
||||
{
|
||||
int timer_sel = LEDC.channel_group[speed_mode].channel[channel].conf0.timer_sel;
|
||||
ledc_timer_t timer_sel;
|
||||
uint32_t duty_cur = 0;
|
||||
ledc_hal_get_channel_timer(&(p_ledc_obj[speed_mode]->ledc_hal), channel, &timer_sel);
|
||||
ledc_hal_get_duty(&(p_ledc_obj[speed_mode]->ledc_hal), channel, &duty_cur);
|
||||
uint32_t freq = ledc_get_freq(speed_mode, timer_sel);
|
||||
uint32_t duty_cur = LEDC.channel_group[speed_mode].channel[channel].duty_rd.duty_read >> LEDC_DUTY_DECIMAL_BIT_NUM;
|
||||
uint32_t duty_delta = target_duty > duty_cur ? target_duty - duty_cur : duty_cur - target_duty;
|
||||
|
||||
if (duty_delta == 0) {
|
||||
|
@ -755,12 +755,7 @@ static void _ledc_fade_start(ledc_mode_t speed_mode, ledc_channel_t channel, led
|
|||
{
|
||||
s_ledc_fade_rec[speed_mode][channel]->mode = fade_mode;
|
||||
// Clear interrupt status of channel
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
int duty_resolution_ch0 = (speed_mode == LEDC_HIGH_SPEED_MODE) ? LEDC_DUTY_CHNG_END_HSCH0_INT_ENA_S : LEDC_DUTY_CHNG_END_LSCH0_INT_ENA_S;
|
||||
#elif defined CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
int duty_resolution_ch0 = LEDC_DUTY_CHNG_END_LSCH0_INT_ENA_S;
|
||||
#endif
|
||||
LEDC.int_clr.val |= BIT(duty_resolution_ch0 + channel);
|
||||
ledc_hal_clear_fade_end_intr_status(&(p_ledc_obj[speed_mode]->ledc_hal), channel);
|
||||
// Enable interrupt for channel
|
||||
ledc_enable_intr_type(speed_mode, channel, LEDC_INTR_FADE_END);
|
||||
ledc_update_duty(speed_mode, channel);
|
||||
|
@ -774,6 +769,7 @@ esp_err_t ledc_set_fade_with_time(ledc_mode_t speed_mode, ledc_channel_t channel
|
|||
LEDC_ARG_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "speed_mode");
|
||||
LEDC_ARG_CHECK(channel < LEDC_CHANNEL_MAX, "channel");
|
||||
LEDC_ARG_CHECK(target_duty <= ledc_get_max_duty(speed_mode, channel), "target_duty");
|
||||
LEDC_CHECK(p_ledc_obj[speed_mode] != NULL, LEDC_NOT_INIT, ESP_ERR_INVALID_STATE);
|
||||
LEDC_CHECK(ledc_fade_channel_init_check(speed_mode, channel) == ESP_OK , LEDC_FADE_INIT_ERROR_STR, ESP_FAIL);
|
||||
|
||||
_ledc_fade_hw_acquire(speed_mode, channel);
|
||||
|
@ -789,6 +785,7 @@ esp_err_t ledc_set_fade_with_step(ledc_mode_t speed_mode, ledc_channel_t channel
|
|||
LEDC_ARG_CHECK((scale > 0) && (scale <= LEDC_DUTY_SCALE_MAX), "fade scale");
|
||||
LEDC_ARG_CHECK((cycle_num > 0) && (cycle_num <= LEDC_DUTY_CYCLE_MAX), "cycle_num");
|
||||
LEDC_ARG_CHECK(target_duty <= ledc_get_max_duty(speed_mode, channel), "target_duty");
|
||||
LEDC_CHECK(p_ledc_obj[speed_mode] != NULL, LEDC_NOT_INIT, ESP_ERR_INVALID_STATE);
|
||||
LEDC_CHECK(ledc_fade_channel_init_check(speed_mode, channel) == ESP_OK , LEDC_FADE_INIT_ERROR_STR, ESP_FAIL);
|
||||
|
||||
_ledc_fade_hw_acquire(speed_mode, channel);
|
||||
|
@ -800,7 +797,9 @@ esp_err_t ledc_set_fade_with_step(ledc_mode_t speed_mode, ledc_channel_t channel
|
|||
esp_err_t ledc_fade_start(ledc_mode_t speed_mode, ledc_channel_t channel, ledc_fade_mode_t fade_mode)
|
||||
{
|
||||
LEDC_CHECK(s_ledc_fade_rec != NULL, LEDC_FADE_SERVICE_ERR_STR, ESP_ERR_INVALID_STATE);
|
||||
LEDC_ARG_CHECK(channel < LEDC_CHANNEL_MAX, "channel");
|
||||
LEDC_ARG_CHECK(fade_mode < LEDC_FADE_MAX, "fade_mode");
|
||||
LEDC_CHECK(p_ledc_obj[speed_mode] != NULL, LEDC_NOT_INIT, ESP_ERR_INVALID_STATE);
|
||||
_ledc_fade_hw_acquire(speed_mode, channel);
|
||||
_ledc_fade_start(speed_mode, channel, fade_mode);
|
||||
_ledc_fade_hw_release(speed_mode, channel);
|
||||
|
@ -840,6 +839,7 @@ esp_err_t ledc_set_duty_and_update(ledc_mode_t speed_mode, ledc_channel_t channe
|
|||
LEDC_ARG_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "speed_mode");
|
||||
LEDC_ARG_CHECK(channel < LEDC_CHANNEL_MAX, "channel");
|
||||
LEDC_ARG_CHECK(duty <= ledc_get_max_duty(speed_mode, channel), "target_duty");
|
||||
LEDC_CHECK(p_ledc_obj[speed_mode] != NULL, LEDC_NOT_INIT, ESP_ERR_INVALID_STATE);
|
||||
LEDC_CHECK(ledc_fade_channel_init_check(speed_mode, channel) == ESP_OK , LEDC_FADE_INIT_ERROR_STR, ESP_FAIL);
|
||||
_ledc_op_lock_acquire(speed_mode, channel);
|
||||
_ledc_fade_hw_acquire(speed_mode, channel);
|
||||
|
@ -855,6 +855,7 @@ esp_err_t ledc_set_fade_time_and_start(ledc_mode_t speed_mode, ledc_channel_t ch
|
|||
LEDC_ARG_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "speed_mode");
|
||||
LEDC_ARG_CHECK(channel < LEDC_CHANNEL_MAX, "channel");
|
||||
LEDC_ARG_CHECK(fade_mode < LEDC_FADE_MAX, "fade_mode");
|
||||
LEDC_CHECK(p_ledc_obj[speed_mode] != NULL, LEDC_NOT_INIT, ESP_ERR_INVALID_STATE);
|
||||
LEDC_CHECK(ledc_fade_channel_init_check(speed_mode, channel) == ESP_OK , LEDC_FADE_INIT_ERROR_STR, ESP_FAIL);
|
||||
LEDC_ARG_CHECK(target_duty <= ledc_get_max_duty(speed_mode, channel), "target_duty");
|
||||
_ledc_op_lock_acquire(speed_mode, channel);
|
||||
|
@ -873,6 +874,7 @@ esp_err_t ledc_set_fade_step_and_start(ledc_mode_t speed_mode, ledc_channel_t ch
|
|||
LEDC_ARG_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "speed_mode");
|
||||
LEDC_ARG_CHECK(channel < LEDC_CHANNEL_MAX, "channel");
|
||||
LEDC_ARG_CHECK(fade_mode < LEDC_FADE_MAX, "fade_mode");
|
||||
LEDC_CHECK(p_ledc_obj[speed_mode] != NULL, LEDC_NOT_INIT, ESP_ERR_INVALID_STATE);
|
||||
LEDC_CHECK(ledc_fade_channel_init_check(speed_mode, channel) == ESP_OK , LEDC_FADE_INIT_ERROR_STR, ESP_FAIL);
|
||||
LEDC_ARG_CHECK((scale > 0) && (scale <= LEDC_DUTY_SCALE_MAX), "fade scale");
|
||||
LEDC_ARG_CHECK((cycle_num > 0) && (cycle_num <= LEDC_DUTY_CYCLE_MAX), "cycle_num");
|
||||
|
|
|
@ -23,6 +23,8 @@ list(APPEND srcs
|
|||
"src/hal/i2s_hal.c"
|
||||
"src/hal/sigmadelta_hal.c"
|
||||
"src/hal/timer_hal.c"
|
||||
"src/hal/ledc_hal.c"
|
||||
"src/hal/ledc_hal_iram.c"
|
||||
)
|
||||
|
||||
# TODO: SPI Flash HAL for ESP32S2Beta also
|
||||
|
|
454
components/soc/esp32/include/hal/ledc_ll.h
Normal file
454
components/soc/esp32/include/hal/ledc_ll.h
Normal file
|
@ -0,0 +1,454 @@
|
|||
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// The LL layer for LEDC register operations.
|
||||
// Note that most of the register operations in this layer are non-atomic operations.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "hal/ledc_types.h"
|
||||
#include "soc/ledc_periph.h"
|
||||
|
||||
#define LEDC_LL_GET_HW() &LEDC
|
||||
|
||||
/**
|
||||
* @brief Set LEDC low speed timer clock
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param slow_clk_sel LEDC low speed timer clock source
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_set_slow_clk_sel(ledc_dev_t *hw, ledc_slow_clk_sel_t slow_clk_sel){
|
||||
hw->conf.slow_clk_sel = slow_clk_sel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get LEDC low speed timer clock
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param slow_clk_sel LEDC low speed timer clock source
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_get_slow_clk_sel(ledc_dev_t *hw, ledc_slow_clk_sel_t *slow_clk_sel){
|
||||
*slow_clk_sel = hw->conf.slow_clk_sel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Update LEDC low speed timer
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_ls_timer_update(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel){
|
||||
hw->timer_group[speed_mode].timer[timer_sel].conf.low_speed_update = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset LEDC timer
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_timer_rst(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel){
|
||||
hw->timer_group[speed_mode].timer[timer_sel].conf.rst = 1;
|
||||
hw->timer_group[speed_mode].timer[timer_sel].conf.rst = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Pause LEDC timer
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_timer_pause(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel){
|
||||
hw->timer_group[speed_mode].timer[timer_sel].conf.pause = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Resume LEDC timer
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_timer_resume(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel){
|
||||
hw->timer_group[speed_mode].timer[timer_sel].conf.pause = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set LEDC timer clock divider
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_t
|
||||
* @param clock_divider Timer clock divide value, the timer clock is divided from the selected clock source
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_set_clock_divider(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_t clock_divider){
|
||||
hw->timer_group[speed_mode].timer[timer_sel].conf.clock_divider = clock_divider;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get LEDC timer clock divider
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_t
|
||||
* @param clock_divider Timer clock divide value, the timer clock is divided from the selected clock source
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_get_clock_divider(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_t *clock_divider){
|
||||
*clock_divider = hw->timer_group[speed_mode].timer[timer_sel].conf.clock_divider;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set LEDC timer clock source
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_t
|
||||
* @param clk_src Timer clock source
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_set_clock_source(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, ledc_clk_src_t clk_src){
|
||||
hw->timer_group[speed_mode].timer[timer_sel].conf.tick_sel = clk_src;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get LEDC timer clock source
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_t
|
||||
* @param clk_src Pointer to accept the timer clock source
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_get_clock_source(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, ledc_clk_src_t *clk_src){
|
||||
*clk_src = hw->timer_group[speed_mode].timer[timer_sel].conf.tick_sel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set LEDC duty resolution
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_t
|
||||
* @param duty_resolution Resolution of duty setting in number of bits. The range of duty values is [0, (2**duty_resolution)]
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_set_duty_resolution(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_t duty_resolution){
|
||||
hw->timer_group[speed_mode].timer[timer_sel].conf.duty_resolution = duty_resolution;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get LEDC duty resolution
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_t
|
||||
* @param duty_resolution Pointer to accept the resolution of duty setting in number of bits.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_get_duty_resolution(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_t *duty_resolution){
|
||||
*duty_resolution = hw->timer_group[speed_mode].timer[timer_sel].conf.duty_resolution;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Update channel configure when select low speed mode
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_ls_channel_update(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num){
|
||||
hw->channel_group[speed_mode].channel[channel_num].conf0.low_speed_update = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get LEDC max duty
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param max_duty Pointer to accept the max duty
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_get_max_duty(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t *max_duty){
|
||||
int timer_sel = hw->channel_group[speed_mode].channel[channel_num].conf0.timer_sel;
|
||||
*max_duty = (1 << (LEDC.timer_group[speed_mode].timer[timer_sel].conf.duty_resolution));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set LEDC hpoint value
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param hpoint_val LEDC hpoint value(max: 0xfffff)
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_set_hpoint(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t hpoint_val){
|
||||
hw->channel_group[speed_mode].channel[channel_num].hpoint.hpoint = hpoint_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get LEDC hpoint value
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param hpoint_val Pointer to accept the LEDC hpoint value(max: 0xfffff)
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_get_hpoint(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t *hpoint_val){
|
||||
*hpoint_val = hw->channel_group[speed_mode].channel[channel_num].hpoint.hpoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set LEDC the integer part of duty value
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param duty_val LEDC duty value, the range of duty setting is [0, (2**duty_resolution)]
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_set_duty_int_part(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t duty_val){
|
||||
hw->channel_group[speed_mode].channel[channel_num].duty.duty = duty_val << 4;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get LEDC duty value
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param duty_val Pointer to accept the LEDC duty value
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_get_duty(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t *duty_val){
|
||||
*duty_val = (hw->channel_group[speed_mode].channel[channel_num].duty_rd.duty_read >> 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set LEDC duty change direction
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param duty_direction LEDC duty change direction, increase or decrease
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_set_duty_direction(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, ledc_duty_direction_t duty_direction){
|
||||
hw->channel_group[speed_mode].channel[channel_num].conf1.duty_inc = duty_direction;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get LEDC duty change direction
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param duty_direction Pointer to accept the LEDC duty change direction, increase or decrease
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_get_duty_direction(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, ledc_duty_direction_t *duty_direction){
|
||||
*duty_direction = hw->channel_group[speed_mode].channel[channel_num].conf1.duty_inc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the number of increased or decreased times
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param duty_num The number of increased or decreased times
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_set_duty_num(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t duty_num){
|
||||
hw->channel_group[speed_mode].channel[channel_num].conf1.duty_num = duty_num;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the duty cycles of increase or decrease
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param duty_cycle The duty cycles
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_set_duty_cycle(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t duty_cycle){
|
||||
hw->channel_group[speed_mode].channel[channel_num].conf1.duty_cycle = duty_cycle;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the step scale of increase or decrease
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param duty_scale The step scale
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_set_duty_scale(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t duty_scale){
|
||||
hw->channel_group[speed_mode].channel[channel_num].conf1.duty_scale = duty_scale;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the output enable
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param sig_out_en The output enable status
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_set_sig_out_en(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, bool sig_out_en){
|
||||
hw->channel_group[speed_mode].channel[channel_num].conf0.sig_out_en = sig_out_en;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the duty start
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param duty_start The duty start
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_set_duty_start(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, bool duty_start){
|
||||
hw->channel_group[speed_mode].channel[channel_num].conf1.duty_start = duty_start;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set output idle level
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param idle_level The output idle level
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_set_idle_level(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t idle_level){
|
||||
hw->channel_group[speed_mode].channel[channel_num].conf0.idle_lv = idle_level & 0x1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set fade end interrupt enable
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param fade_end_intr_en The fade end interrupt enable status
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_set_fade_end_intr(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, bool fade_end_intr_en){
|
||||
uint32_t value = hw->int_ena.val;
|
||||
uint32_t int_en_base = (speed_mode == LEDC_LOW_SPEED_MODE) ? LEDC_DUTY_CHNG_END_LSCH0_INT_ENA_S : LEDC_DUTY_CHNG_END_HSCH0_INT_ENA_S;
|
||||
hw->int_ena.val = fade_end_intr_en ? (value | BIT(int_en_base + channel_num)) : (value & (~(BIT(int_en_base + channel_num))));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get fade end interrupt status
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param intr_status The fade end interrupt status
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_get_fade_end_intr_status(ledc_dev_t *hw, ledc_mode_t speed_mode, uint32_t *intr_status){
|
||||
uint32_t value = hw->int_st.val;
|
||||
uint32_t int_en_base = (speed_mode == LEDC_LOW_SPEED_MODE) ? LEDC_DUTY_CHNG_END_LSCH0_INT_ENA_S : LEDC_DUTY_CHNG_END_HSCH0_INT_ENA_S;
|
||||
*intr_status = (value >> int_en_base) & 0xff;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear fade end interrupt status
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_clear_fade_end_intr_status(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num){
|
||||
uint32_t int_en_base = (speed_mode == LEDC_LOW_SPEED_MODE) ? LEDC_DUTY_CHNG_END_LSCH0_INT_ENA_S : LEDC_DUTY_CHNG_END_HSCH0_INT_ENA_S;
|
||||
hw->int_clr.val = BIT(int_en_base + channel_num);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set timer index of the specified channel
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_bind_channel_timer(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, ledc_timer_t timer_sel){
|
||||
hw->channel_group[speed_mode].channel[channel_num].conf0.timer_sel = timer_sel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get timer index of the specified channel
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param timer_sel Pointer to accept the LEDC timer index
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_get_channel_timer(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, ledc_timer_t *timer_sel){
|
||||
*timer_sel = hw->channel_group[speed_mode].channel[channel_num].conf0.timer_sel;
|
||||
}
|
479
components/soc/esp32s2beta/include/hal/ledc_ll.h
Normal file
479
components/soc/esp32s2beta/include/hal/ledc_ll.h
Normal file
|
@ -0,0 +1,479 @@
|
|||
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// The LL layer for LEDC register operations.
|
||||
// Note that most of the register operations in this layer are non-atomic operations.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "hal/ledc_types.h"
|
||||
#include "soc/ledc_periph.h"
|
||||
|
||||
#define LEDC_LL_GET_HW() &LEDC
|
||||
|
||||
/**
|
||||
* @brief Set LEDC low speed timer clock
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param slow_clk_sel LEDC low speed timer clock source
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_set_slow_clk_sel(ledc_dev_t *hw, ledc_slow_clk_sel_t slow_clk_sel){
|
||||
uint32_t clk_sel_val = 0;
|
||||
if (slow_clk_sel == LEDC_SLOW_CLK_APB) {
|
||||
clk_sel_val = 1;
|
||||
} else if (slow_clk_sel == LEDC_SLOW_CLK_RTC8M) {
|
||||
clk_sel_val = 2;
|
||||
} else if (slow_clk_sel == LEDC_SLOW_CLK_XTAL) {
|
||||
clk_sel_val = 3;
|
||||
}
|
||||
hw->conf.apb_clk_sel = clk_sel_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get LEDC low speed timer clock
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param slow_clk_sel LEDC low speed timer clock source
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_get_slow_clk_sel(ledc_dev_t *hw, ledc_slow_clk_sel_t *slow_clk_sel){
|
||||
uint32_t clk_sel_val = hw->conf.apb_clk_sel;
|
||||
if (clk_sel_val == 1) {
|
||||
*slow_clk_sel = LEDC_SLOW_CLK_APB;
|
||||
} else if (clk_sel_val == 2) {
|
||||
*slow_clk_sel = LEDC_SLOW_CLK_RTC8M;
|
||||
} else if (clk_sel_val == 3) {
|
||||
*slow_clk_sel = LEDC_SLOW_CLK_XTAL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Update LEDC low speed timer
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_ls_timer_update(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel){
|
||||
hw->timer_group[speed_mode].timer[timer_sel].conf.low_speed_update = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset LEDC timer
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_timer_rst(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel){
|
||||
hw->timer_group[speed_mode].timer[timer_sel].conf.rst = 1;
|
||||
hw->timer_group[speed_mode].timer[timer_sel].conf.rst = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Pause LEDC timer
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_timer_pause(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel){
|
||||
hw->timer_group[speed_mode].timer[timer_sel].conf.pause = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Resume LEDC timer
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_timer_resume(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel){
|
||||
hw->timer_group[speed_mode].timer[timer_sel].conf.pause = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set LEDC timer clock divider
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_t
|
||||
* @param clock_divider Timer clock divide value, the timer clock is divided from the selected clock source
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_set_clock_divider(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_t clock_divider){
|
||||
hw->timer_group[speed_mode].timer[timer_sel].conf.clock_divider = clock_divider;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get LEDC timer clock divider
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_t
|
||||
* @param clock_divider Timer clock divide value, the timer clock is divided from the selected clock source
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_get_clock_divider(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_t *clock_divider){
|
||||
*clock_divider = hw->timer_group[speed_mode].timer[timer_sel].conf.clock_divider;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set LEDC timer clock source
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_t
|
||||
* @param clk_src Timer clock source
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_set_clock_source(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, ledc_clk_src_t clk_src){
|
||||
if (clk_src == LEDC_REF_TICK) {
|
||||
//REF_TICK can only be used when APB is selected.
|
||||
hw->timer_group[speed_mode].timer[timer_sel].conf.tick_sel = 1;
|
||||
hw->conf.apb_clk_sel = 1;
|
||||
} else {
|
||||
hw->timer_group[speed_mode].timer[timer_sel].conf.tick_sel = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get LEDC timer clock source
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_t
|
||||
* @param clk_src Pointer to accept the timer clock source
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_get_clock_source(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, ledc_clk_src_t *clk_src){
|
||||
if (hw->timer_group[speed_mode].timer[timer_sel].conf.tick_sel == 1) {
|
||||
*clk_src = LEDC_REF_TICK;
|
||||
} else {
|
||||
*clk_src = LEDC_APB_CLK;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set LEDC duty resolution
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_t
|
||||
* @param duty_resolution Resolution of duty setting in number of bits. The range of duty values is [0, (2**duty_resolution)]
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_set_duty_resolution(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_t duty_resolution){
|
||||
hw->timer_group[speed_mode].timer[timer_sel].conf.duty_resolution = duty_resolution;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get LEDC duty resolution
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_t
|
||||
* @param duty_resolution Pointer to accept the resolution of duty setting in number of bits.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_get_duty_resolution(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_t *duty_resolution){
|
||||
*duty_resolution = hw->timer_group[speed_mode].timer[timer_sel].conf.duty_resolution;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Update channel configure when select low speed mode
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_ls_channel_update(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num){
|
||||
hw->channel_group[speed_mode].channel[channel_num].conf0.low_speed_update = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get LEDC max duty
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param max_duty Pointer to accept the max duty
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_get_max_duty(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t *max_duty){
|
||||
uint32_t timer_sel = hw->channel_group[speed_mode].channel[channel_num].conf0.timer_sel;
|
||||
*max_duty = (1 << (LEDC.timer_group[speed_mode].timer[timer_sel].conf.duty_resolution));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set LEDC hpoint value
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param hpoint_val LEDC hpoint value(max: 0xfffff)
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_set_hpoint(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t hpoint_val){
|
||||
hw->channel_group[speed_mode].channel[channel_num].hpoint.hpoint = hpoint_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get LEDC hpoint value
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param hpoint_val Pointer to accept the LEDC hpoint value(max: 0xfffff)
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_get_hpoint(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t *hpoint_val){
|
||||
*hpoint_val = hw->channel_group[speed_mode].channel[channel_num].hpoint.hpoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set LEDC the integer part of duty value
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param duty_val LEDC duty value, the range of duty setting is [0, (2**duty_resolution)]
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_set_duty_int_part(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t duty_val){
|
||||
hw->channel_group[speed_mode].channel[channel_num].duty.duty = duty_val << 4;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get LEDC duty value
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param duty_val Pointer to accept the LEDC duty value
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_get_duty(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t *duty_val){
|
||||
*duty_val = (hw->channel_group[speed_mode].channel[channel_num].duty_rd.duty_read >> 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set LEDC duty change direction
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param duty_direction LEDC duty change direction, increase or decrease
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_set_duty_direction(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, ledc_duty_direction_t duty_direction){
|
||||
hw->channel_group[speed_mode].channel[channel_num].conf1.duty_inc = duty_direction;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get LEDC duty change direction
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param duty_direction Pointer to accept the LEDC duty change direction, increase or decrease
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_get_duty_direction(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, ledc_duty_direction_t *duty_direction){
|
||||
*duty_direction = hw->channel_group[speed_mode].channel[channel_num].conf1.duty_inc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the number of increased or decreased times
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param duty_num The number of increased or decreased times
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_set_duty_num(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t duty_num){
|
||||
hw->channel_group[speed_mode].channel[channel_num].conf1.duty_num = duty_num;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the duty cycles of increase or decrease
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param duty_cycle The duty cycles
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_set_duty_cycle(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t duty_cycle){
|
||||
hw->channel_group[speed_mode].channel[channel_num].conf1.duty_cycle = duty_cycle;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the step scale of increase or decrease
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param duty_scale The step scale
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_set_duty_scale(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t duty_scale){
|
||||
hw->channel_group[speed_mode].channel[channel_num].conf1.duty_scale = duty_scale;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the output enable
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param sig_out_en The output enable status
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_set_sig_out_en(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, bool sig_out_en){
|
||||
hw->channel_group[speed_mode].channel[channel_num].conf0.sig_out_en = sig_out_en;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the duty start
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param duty_start The duty start
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_set_duty_start(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, bool duty_start){
|
||||
hw->channel_group[speed_mode].channel[channel_num].conf1.duty_start = duty_start;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set output idle level
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param idle_level The output idle level
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_set_idle_level(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t idle_level){
|
||||
hw->channel_group[speed_mode].channel[channel_num].conf0.idle_lv = idle_level & 0x1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set fade end interrupt enable
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param fade_end_intr_en The fade end interrupt enable status
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_set_fade_end_intr(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, bool fade_end_intr_en){
|
||||
uint32_t value = hw->int_ena.val;
|
||||
uint32_t int_en_base = LEDC_DUTY_CHNG_END_LSCH0_INT_ENA_S;
|
||||
hw->int_ena.val = fade_end_intr_en ? (value | BIT(int_en_base + channel_num)) : (value & (~(BIT(int_en_base + channel_num))));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get fade end interrupt status
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param intr_status The fade end interrupt status
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_get_fade_end_intr_status(ledc_dev_t *hw, ledc_mode_t speed_mode, uint32_t *intr_status){
|
||||
uint32_t value = hw->int_st.val;
|
||||
uint32_t int_en_base = LEDC_DUTY_CHNG_END_LSCH0_INT_ENA_S;
|
||||
*intr_status = (value >> int_en_base) & 0xff;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear fade end interrupt status
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_clear_fade_end_intr_status(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num){
|
||||
uint32_t int_en_base = LEDC_DUTY_CHNG_END_LSCH0_INT_ENA_S;
|
||||
hw->int_clr.val = BIT(int_en_base + channel_num);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set timer index of the specified channel
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_bind_channel_timer(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, ledc_timer_t timer_sel){
|
||||
hw->channel_group[speed_mode].channel[channel_num].conf0.timer_sel = timer_sel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get timer index of the specified channel
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param timer_sel Pointer to accept the LEDC timer index
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void ledc_ll_get_channel_timer(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, ledc_timer_t *timer_sel){
|
||||
*timer_sel = hw->channel_group[speed_mode].channel[channel_num].conf0.timer_sel;
|
||||
}
|
|
@ -198,7 +198,7 @@ typedef volatile struct {
|
|||
} int_clr;
|
||||
union {
|
||||
struct {
|
||||
uint32_t apb_clk_sel: 2;
|
||||
uint32_t apb_clk_sel: 2; // 0:invalid; 1:80MHz APB clock; 2:8MHz RTC clock; 3:XTAL clock
|
||||
uint32_t reserved2: 30;
|
||||
};
|
||||
uint32_t val;
|
||||
|
|
388
components/soc/include/hal/ledc_hal.h
Normal file
388
components/soc/include/hal/ledc_hal.h
Normal file
|
@ -0,0 +1,388 @@
|
|||
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/*******************************************************************************
|
||||
* NOTICE
|
||||
* The hal is not public api, don't use in application code.
|
||||
* See readme.md in soc/include/hal/readme.md
|
||||
******************************************************************************/
|
||||
|
||||
// The HAL layer for LEDC.
|
||||
// There is no parameter check in the hal layer, so the caller must ensure the correctness of the parameters.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "hal/ledc_ll.h"
|
||||
#include "hal/ledc_types.h"
|
||||
|
||||
/**
|
||||
* Context that should be maintained by both the driver and the HAL
|
||||
*/
|
||||
typedef struct {
|
||||
ledc_dev_t *dev;
|
||||
ledc_mode_t speed_mode;
|
||||
} ledc_hal_context_t;
|
||||
|
||||
/**
|
||||
* @brief Set LEDC low speed timer clock
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param slow_clk_sel LEDC low speed timer clock source
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
#define ledc_hal_set_slow_clk_sel(hal, slow_clk_sel) ledc_ll_set_slow_clk_sel((hal)->dev, slow_clk_sel)
|
||||
|
||||
/**
|
||||
* @brief Get LEDC low speed timer clock
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param slow_clk_sel LEDC low speed timer clock source
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
#define ledc_hal_get_slow_clk_sel(hal, slow_clk_sel) ledc_ll_get_slow_clk_sel((hal)->dev, slow_clk_sel)
|
||||
|
||||
/**
|
||||
* @brief Update LEDC low speed timer
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
#define ledc_hal_ls_timer_update(hal, timer_sel) ledc_ll_ls_timer_update((hal)->dev, (hal)->speed_mode, timer_sel)
|
||||
|
||||
/**
|
||||
* @brief Reset LEDC timer
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
#define ledc_hal_timer_rst(hal, timer_sel) ledc_ll_timer_rst((hal)->dev, (hal)->speed_mode, timer_sel)
|
||||
|
||||
/**
|
||||
* @brief Pause LEDC timer
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
#define ledc_hal_timer_pause(hal, timer_sel) ledc_ll_timer_pause((hal)->dev, (hal)->speed_mode, timer_sel)
|
||||
|
||||
/**
|
||||
* @brief Resume LEDC timer
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
#define ledc_hal_timer_resume(hal, timer_sel) ledc_ll_timer_resume((hal)->dev, (hal)->speed_mode, timer_sel)
|
||||
|
||||
/**
|
||||
* @brief Set LEDC timer clock divider
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_t
|
||||
* @param clock_divider Timer clock divide value, the timer clock is divided from the selected clock source
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
#define ledc_hal_set_clock_divider(hal, timer_sel, clock_divider) ledc_ll_set_clock_divider((hal)->dev, (hal)->speed_mode, timer_sel, clock_divider)
|
||||
|
||||
/**
|
||||
* @brief Get LEDC timer clock divider
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_t
|
||||
* @param clock_divider Timer clock divide value, the timer clock is divided from the selected clock source
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
#define ledc_hal_get_clock_divider(hal, timer_sel, clock_divider) ledc_ll_get_clock_divider((hal)->dev, (hal)->speed_mode, timer_sel, clock_divider)
|
||||
|
||||
/**
|
||||
* @brief Set LEDC timer clock source
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_t
|
||||
* @param clk_src Timer clock source
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
#define ledc_hal_set_clock_source(hal, timer_sel, clk_src) ledc_ll_set_clock_source((hal)->dev, (hal)->speed_mode, timer_sel, clk_src)
|
||||
|
||||
/**
|
||||
* @brief Get LEDC timer clock source
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_t
|
||||
* @param clk_src Pointer to accept the timer clock source
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
#define ledc_hal_get_clock_source(hal, timer_sel, clk_src) ledc_ll_get_clock_source((hal)->dev, (hal)->speed_mode, timer_sel, clk_src)
|
||||
|
||||
/**
|
||||
* @brief Set LEDC duty resolution
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_t
|
||||
* @param duty_resolution Resolution of duty setting in number of bits. The range of duty values is [0, (2**duty_resolution)]
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
#define ledc_hal_set_duty_resolution(hal, timer_sel, duty_resolution) ledc_ll_set_duty_resolution((hal)->dev, (hal)->speed_mode, timer_sel, duty_resolution)
|
||||
|
||||
/**
|
||||
* @brief Get LEDC duty resolution
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_t
|
||||
* @param duty_resolution Pointer to accept the resolution of duty setting in number of bits.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
#define ledc_hal_get_duty_resolution(hal, timer_sel, duty_resolution) ledc_ll_get_duty_resolution((hal)->dev, (hal)->speed_mode, timer_sel, duty_resolution)
|
||||
|
||||
/**
|
||||
* @brief Get LEDC max duty
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param max_duty Pointer to accept the max duty
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
#define ledc_hal_get_max_duty(hal, channel_num, max_duty) ledc_ll_get_max_duty((hal)->dev, (hal)->speed_mode, channel_num, max_duty)
|
||||
|
||||
/**
|
||||
* @brief Get LEDC hpoint value
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param hpoint_val Pointer to accept the LEDC hpoint value(max: 0xfffff)
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
#define ledc_hal_get_hpoint(hal, channel_num, hpoint_val) ledc_ll_get_hpoint((hal)->dev, (hal)->speed_mode, channel_num, hpoint_val)
|
||||
|
||||
/**
|
||||
* @brief Set LEDC the integer part of duty value
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param duty_val LEDC duty value, the range of duty setting is [0, (2**duty_resolution)]
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
#define ledc_hal_set_duty_int_part(hal, channel_num, duty_val) ledc_ll_set_duty_int_part((hal)->dev, (hal)->speed_mode, channel_num, duty_val)
|
||||
|
||||
/**
|
||||
* @brief Set the output enable
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param sig_out_en The output enable status
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
#define ledc_hal_set_sig_out_en(hal, channel_num, sig_out_en) ledc_ll_set_sig_out_en((hal)->dev, (hal)->speed_mode, channel_num, sig_out_en)
|
||||
|
||||
/**
|
||||
* @brief Set the duty start
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param duty_start The duty start
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
#define ledc_hal_set_duty_start(hal, channel_num, duty_start) ledc_ll_set_duty_start((hal)->dev, (hal)->speed_mode, channel_num, duty_start)
|
||||
|
||||
/**
|
||||
* @brief Set output idle level
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param idle_level The output idle level
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
#define ledc_hal_set_idle_level(hal, channel_num, idle_level) ledc_ll_set_idle_level((hal)->dev, (hal)->speed_mode, channel_num, idle_level)
|
||||
|
||||
/**
|
||||
* @brief Set fade end interrupt enable
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param fade_end_intr_en The fade end interrupt enable status
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
#define ledc_hal_set_fade_end_intr(hal, channel_num, fade_end_intr_en) ledc_ll_set_fade_end_intr((hal)->dev, (hal)->speed_mode, channel_num, fade_end_intr_en)
|
||||
|
||||
/**
|
||||
* @brief Set timer index of the specified channel
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
#define ledc_hal_bind_channel_timer(hal, channel_num, timer_sel) ledc_ll_bind_channel_timer((hal)->dev, (hal)->speed_mode, channel_num, timer_sel)
|
||||
|
||||
/**
|
||||
* @brief Get timer index of the specified channel
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param timer_sel Pointer to accept the LEDC timer index
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
#define ledc_hal_get_channel_timer(hal, channel_num, timer_sel) ledc_ll_get_channel_timer((hal)->dev, (hal)->speed_mode, channel_num, timer_sel)
|
||||
|
||||
/**
|
||||
* @brief Init the LEDC hal. This function should be called first before other hal layer function is called
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param speed_mode speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mod
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void ledc_hal_init(ledc_hal_context_t *hal, ledc_mode_t speed_mode);
|
||||
|
||||
/**
|
||||
* @brief Update channel configure when select low speed mode
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void ledc_hal_ls_channel_update(ledc_hal_context_t *hal, ledc_channel_t channel_num);
|
||||
|
||||
/**
|
||||
* @brief Set LEDC hpoint value
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param hpoint_val LEDC hpoint value(max: 0xfffff)
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void ledc_hal_set_hpoint(ledc_hal_context_t *hal, ledc_channel_t channel_num, uint32_t hpoint_val);
|
||||
|
||||
/**
|
||||
* @brief Get LEDC duty value
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param duty_val Pointer to accept the LEDC duty value
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void ledc_hal_get_duty(ledc_hal_context_t *hal, ledc_channel_t channel_num, uint32_t *duty_val);
|
||||
|
||||
/**
|
||||
* @brief Set LEDC duty change direction
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param duty_direction LEDC duty change direction, increase or decrease
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void ledc_hal_set_duty_direction(ledc_hal_context_t *hal, ledc_channel_t channel_num, ledc_duty_direction_t duty_direction);
|
||||
|
||||
/**
|
||||
* @brief Set the number of increased or decreased times
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param duty_num The number of increased or decreased times
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void ledc_hal_set_duty_num(ledc_hal_context_t *hal, ledc_channel_t channel_num, uint32_t duty_num);
|
||||
|
||||
/**
|
||||
* @brief Set the duty cycles of increase or decrease
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param duty_cycle The duty cycles
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void ledc_hal_set_duty_cycle(ledc_hal_context_t *hal, ledc_channel_t channel_num, uint32_t duty_cycle);
|
||||
|
||||
/**
|
||||
* @brief Set the step scale of increase or decrease
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param duty_scale The step scale
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void ledc_hal_set_duty_scale(ledc_hal_context_t *hal, ledc_channel_t channel_num, uint32_t duty_scale);
|
||||
|
||||
/**
|
||||
* @brief Get interrupt status of the specified channel
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
* @param intr_status Pointer to accept the interrupt status
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void ledc_hal_get_fade_end_intr_status(ledc_hal_context_t *hal, uint32_t *intr_status);
|
||||
|
||||
/**
|
||||
* @brief Clear interrupt status of the specified channel
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void ledc_hal_clear_fade_end_intr_status(ledc_hal_context_t *hal, ledc_channel_t channel_num);
|
||||
|
||||
/**
|
||||
* @brief Get clock config of LEDC timer
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_t
|
||||
* @param clk_cfg Pointer to accept clock config
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void ledc_hal_get_clk_cfg(ledc_hal_context_t *hal, ledc_timer_t timer_sel, ledc_clk_cfg_t *clk_cfg);
|
||||
|
||||
/**
|
||||
* @brief Config low speed timer clock source with clock config
|
||||
*s
|
||||
* @param hal Context of the HAL layer
|
||||
* @param clk_cfg clock config
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void ledc_hal_set_slow_clk(ledc_hal_context_t *hal, ledc_clk_cfg_t clk_cfg);
|
148
components/soc/include/hal/ledc_types.h
Normal file
148
components/soc/include/hal/ledc_types.h
Normal file
|
@ -0,0 +1,148 @@
|
|||
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef enum {
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
LEDC_HIGH_SPEED_MODE = 0, /*!< LEDC high speed speed_mode */
|
||||
#endif
|
||||
LEDC_LOW_SPEED_MODE, /*!< LEDC low speed speed_mode */
|
||||
LEDC_SPEED_MODE_MAX, /*!< LEDC speed limit */
|
||||
} ledc_mode_t;
|
||||
|
||||
typedef enum {
|
||||
LEDC_INTR_DISABLE = 0, /*!< Disable LEDC interrupt */
|
||||
LEDC_INTR_FADE_END, /*!< Enable LEDC interrupt */
|
||||
LEDC_INTR_MAX,
|
||||
} ledc_intr_type_t;
|
||||
|
||||
typedef enum {
|
||||
LEDC_DUTY_DIR_DECREASE = 0, /*!< LEDC duty decrease direction */
|
||||
LEDC_DUTY_DIR_INCREASE = 1, /*!< LEDC duty increase direction */
|
||||
LEDC_DUTY_DIR_MAX,
|
||||
} ledc_duty_direction_t;
|
||||
|
||||
typedef enum {
|
||||
LEDC_REF_TICK = 0, /*!< LEDC timer clock divided from reference tick (1Mhz) */
|
||||
LEDC_APB_CLK, /*!< LEDC timer clock divided from APB clock (80Mhz) */
|
||||
} ledc_clk_src_t;
|
||||
|
||||
typedef enum {
|
||||
LEDC_SLOW_CLK_RTC8M = 0, /*!< LEDC low speed timer clock source is 8MHz RTC clock*/
|
||||
LEDC_SLOW_CLK_APB, /*!< LEDC low speed timer clock source is 80MHz APB clock*/
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
LEDC_SLOW_CLK_XTAL, /*!< LEDC low speed timer clock source XTAL clock*/
|
||||
#endif
|
||||
} ledc_slow_clk_sel_t;
|
||||
|
||||
typedef enum {
|
||||
LEDC_AUTO_CLK = 0, /*!< The driver will automatically select the source clock(REF_TICK or APB) based on the giving resolution and duty parameter when init the timer*/
|
||||
LEDC_USE_REF_TICK, /*!< LEDC timer select REF_TICK clock as source clock*/
|
||||
LEDC_USE_APB_CLK, /*!< LEDC timer select APB clock as source clock*/
|
||||
LEDC_USE_RTC8M_CLK, /*!< LEDC timer select RTC8M_CLK as source clock. Only for low speed channels and this parameter must be the same for all low speed channels*/
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
LEDC_USE_XTAL_CLK, /*!< LEDC timer select XTAL clock as source clock*/
|
||||
#endif
|
||||
} ledc_clk_cfg_t;
|
||||
|
||||
typedef enum {
|
||||
LEDC_TIMER_0 = 0, /*!< LEDC timer 0 */
|
||||
LEDC_TIMER_1, /*!< LEDC timer 1 */
|
||||
LEDC_TIMER_2, /*!< LEDC timer 2 */
|
||||
LEDC_TIMER_3, /*!< LEDC timer 3 */
|
||||
LEDC_TIMER_MAX,
|
||||
} ledc_timer_t;
|
||||
|
||||
typedef enum {
|
||||
LEDC_CHANNEL_0 = 0, /*!< LEDC channel 0 */
|
||||
LEDC_CHANNEL_1, /*!< LEDC channel 1 */
|
||||
LEDC_CHANNEL_2, /*!< LEDC channel 2 */
|
||||
LEDC_CHANNEL_3, /*!< LEDC channel 3 */
|
||||
LEDC_CHANNEL_4, /*!< LEDC channel 4 */
|
||||
LEDC_CHANNEL_5, /*!< LEDC channel 5 */
|
||||
LEDC_CHANNEL_6, /*!< LEDC channel 6 */
|
||||
LEDC_CHANNEL_7, /*!< LEDC channel 7 */
|
||||
LEDC_CHANNEL_MAX,
|
||||
} ledc_channel_t;
|
||||
|
||||
typedef enum {
|
||||
LEDC_TIMER_1_BIT = 1, /*!< LEDC PWM duty resolution of 1 bits */
|
||||
LEDC_TIMER_2_BIT, /*!< LEDC PWM duty resolution of 2 bits */
|
||||
LEDC_TIMER_3_BIT, /*!< LEDC PWM duty resolution of 3 bits */
|
||||
LEDC_TIMER_4_BIT, /*!< LEDC PWM duty resolution of 4 bits */
|
||||
LEDC_TIMER_5_BIT, /*!< LEDC PWM duty resolution of 5 bits */
|
||||
LEDC_TIMER_6_BIT, /*!< LEDC PWM duty resolution of 6 bits */
|
||||
LEDC_TIMER_7_BIT, /*!< LEDC PWM duty resolution of 7 bits */
|
||||
LEDC_TIMER_8_BIT, /*!< LEDC PWM duty resolution of 8 bits */
|
||||
LEDC_TIMER_9_BIT, /*!< LEDC PWM duty resolution of 9 bits */
|
||||
LEDC_TIMER_10_BIT, /*!< LEDC PWM duty resolution of 10 bits */
|
||||
LEDC_TIMER_11_BIT, /*!< LEDC PWM duty resolution of 11 bits */
|
||||
LEDC_TIMER_12_BIT, /*!< LEDC PWM duty resolution of 12 bits */
|
||||
LEDC_TIMER_13_BIT, /*!< LEDC PWM duty resolution of 13 bits */
|
||||
LEDC_TIMER_14_BIT, /*!< LEDC PWM duty resolution of 14 bits */
|
||||
LEDC_TIMER_15_BIT, /*!< LEDC PWM duty resolution of 15 bits */
|
||||
LEDC_TIMER_16_BIT, /*!< LEDC PWM duty resolution of 16 bits */
|
||||
LEDC_TIMER_17_BIT, /*!< LEDC PWM duty resolution of 17 bits */
|
||||
LEDC_TIMER_18_BIT, /*!< LEDC PWM duty resolution of 18 bits */
|
||||
LEDC_TIMER_19_BIT, /*!< LEDC PWM duty resolution of 19 bits */
|
||||
LEDC_TIMER_20_BIT, /*!< LEDC PWM duty resolution of 20 bits */
|
||||
LEDC_TIMER_BIT_MAX,
|
||||
} ledc_timer_bit_t;
|
||||
|
||||
typedef enum {
|
||||
LEDC_FADE_NO_WAIT = 0, /*!< LEDC fade function will return immediately */
|
||||
LEDC_FADE_WAIT_DONE, /*!< LEDC fade function will block until fading to the target duty */
|
||||
LEDC_FADE_MAX,
|
||||
} ledc_fade_mode_t;
|
||||
|
||||
/**
|
||||
* @brief Configuration parameters of LEDC channel for ledc_channel_config function
|
||||
*/
|
||||
typedef struct {
|
||||
int gpio_num; /*!< the LEDC output gpio_num, if you want to use gpio16, gpio_num = 16 */
|
||||
ledc_mode_t speed_mode; /*!< LEDC speed speed_mode, high-speed mode or low-speed mode */
|
||||
ledc_channel_t channel; /*!< LEDC channel (0 - 7) */
|
||||
ledc_intr_type_t intr_type; /*!< configure interrupt, Fade interrupt enable or Fade interrupt disable */
|
||||
ledc_timer_t timer_sel; /*!< Select the timer source of channel (0 - 3) */
|
||||
uint32_t duty; /*!< LEDC channel duty, the range of duty setting is [0, (2**duty_resolution)] */
|
||||
int hpoint; /*!< LEDC channel hpoint value, the max value is 0xfffff */
|
||||
} ledc_channel_config_t;
|
||||
|
||||
/**
|
||||
* @brief Configuration parameters of LEDC Timer timer for ledc_timer_config function
|
||||
*/
|
||||
typedef struct {
|
||||
ledc_mode_t speed_mode; /*!< LEDC speed speed_mode, high-speed mode or low-speed mode */
|
||||
union {
|
||||
ledc_timer_bit_t duty_resolution; /*!< LEDC channel duty resolution */
|
||||
ledc_timer_bit_t bit_num __attribute__((deprecated)); /*!< Deprecated in ESP-IDF 3.0. This is an alias to 'duty_resolution' for backward compatibility with ESP-IDF 2.1 */
|
||||
};
|
||||
ledc_timer_t timer_num; /*!< The timer source of channel (0 - 3) */
|
||||
uint32_t freq_hz; /*!< LEDC timer frequency (Hz) */
|
||||
ledc_clk_cfg_t clk_cfg; /*!< Configure LEDC source clock.
|
||||
For low speed channels and high speed channels, you can specify the source clock using LEDC_USE_REF_TICK, LEDC_USE_APB_CLK or LEDC_AUTO_CLK.
|
||||
For low speed channels, you can also specify the source clock using LEDC_USE_RTC8M_CLK, in this case, all low speed channel's source clock must be RTC8M_CLK*/
|
||||
} ledc_timer_config_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -13,4 +13,5 @@ entries:
|
|||
spi_hal_iram (noflash_text)
|
||||
spi_slave_hal_iram (noflash_text)
|
||||
spi_flash_hal_iram (noflash)
|
||||
ledc_hal_iram (noflash_text)
|
||||
lldesc (noflash_text)
|
||||
|
|
60
components/soc/src/hal/ledc_hal.c
Normal file
60
components/soc/src/hal/ledc_hal.c
Normal file
|
@ -0,0 +1,60 @@
|
|||
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// The HAL layer for LEDC (common part)
|
||||
|
||||
#include "esp_attr.h"
|
||||
#include "hal/ledc_hal.h"
|
||||
|
||||
void ledc_hal_init(ledc_hal_context_t *hal, ledc_mode_t speed_mode)
|
||||
{
|
||||
//Get hardware instance.
|
||||
hal->dev = LEDC_LL_GET_HW();
|
||||
hal->speed_mode = speed_mode;
|
||||
}
|
||||
|
||||
void ledc_hal_get_clk_cfg(ledc_hal_context_t *hal, ledc_timer_t timer_sel, ledc_clk_cfg_t *clk_cfg)
|
||||
{
|
||||
ledc_clk_src_t clk_src = LEDC_APB_CLK;
|
||||
ledc_hal_get_clock_source(hal, timer_sel, &clk_src);
|
||||
if (clk_src == LEDC_REF_TICK) {
|
||||
*clk_cfg = LEDC_USE_REF_TICK;
|
||||
} else {
|
||||
*clk_cfg = LEDC_USE_APB_CLK;
|
||||
if (hal->speed_mode == LEDC_LOW_SPEED_MODE) {
|
||||
ledc_slow_clk_sel_t slow_clk = LEDC_SLOW_CLK_APB;
|
||||
ledc_hal_get_slow_clk_sel(hal, &slow_clk);
|
||||
if (slow_clk == LEDC_SLOW_CLK_RTC8M) {
|
||||
*clk_cfg = LEDC_USE_RTC8M_CLK;
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
} else if (slow_clk == LEDC_SLOW_CLK_XTAL) {
|
||||
*clk_cfg = LEDC_USE_XTAL_CLK;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ledc_hal_set_slow_clk(ledc_hal_context_t *hal, ledc_clk_cfg_t clk_cfg)
|
||||
{
|
||||
// For low speed channels, if RTC_8MCLK is used as the source clock, the `slow_clk_sel` register should be cleared, otherwise it should be set.
|
||||
ledc_slow_clk_sel_t slow_clk_sel = LEDC_SLOW_CLK_APB;
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
slow_clk_sel = (clk_cfg == LEDC_USE_RTC8M_CLK) ? LEDC_SLOW_CLK_RTC8M : LEDC_SLOW_CLK_APB;
|
||||
#elif defined CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
slow_clk_sel = (clk_cfg == LEDC_USE_RTC8M_CLK) ? LEDC_SLOW_CLK_RTC8M :
|
||||
((clk_cfg == LEDC_USE_XTAL_CLK) ? LEDC_SLOW_CLK_XTAL : LEDC_SLOW_CLK_APB);
|
||||
#endif
|
||||
ledc_hal_set_slow_clk_sel(hal, slow_clk_sel);
|
||||
}
|
64
components/soc/src/hal/ledc_hal_iram.c
Normal file
64
components/soc/src/hal/ledc_hal_iram.c
Normal file
|
@ -0,0 +1,64 @@
|
|||
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// The HAL layer for LEDC (common part, in iram)
|
||||
// make these functions in a seperate file to make sure all LL functions are in the IRAM.
|
||||
|
||||
#include "esp_attr.h"
|
||||
#include "hal/ledc_hal.h"
|
||||
|
||||
void ledc_hal_ls_channel_update(ledc_hal_context_t *hal, ledc_channel_t channel_num)
|
||||
{
|
||||
ledc_ll_ls_channel_update(hal->dev, hal->speed_mode, channel_num);
|
||||
}
|
||||
|
||||
void ledc_hal_set_hpoint(ledc_hal_context_t *hal, ledc_channel_t channel_num, uint32_t hpoint_val)
|
||||
{
|
||||
ledc_ll_set_hpoint(hal->dev, hal->speed_mode, channel_num, hpoint_val);
|
||||
}
|
||||
|
||||
void ledc_hal_get_duty(ledc_hal_context_t *hal, ledc_channel_t channel_num, uint32_t *duty_val)
|
||||
{
|
||||
ledc_ll_get_duty(hal->dev, hal->speed_mode, channel_num, duty_val);
|
||||
}
|
||||
|
||||
void ledc_hal_set_duty_direction(ledc_hal_context_t *hal, ledc_channel_t channel_num, ledc_duty_direction_t duty_direction)
|
||||
{
|
||||
ledc_ll_set_duty_direction(hal->dev, hal->speed_mode, channel_num, duty_direction);
|
||||
}
|
||||
|
||||
void ledc_hal_set_duty_num(ledc_hal_context_t *hal, ledc_channel_t channel_num, uint32_t duty_num)
|
||||
{
|
||||
ledc_ll_set_duty_num(hal->dev, hal->speed_mode, channel_num, duty_num);
|
||||
}
|
||||
|
||||
void ledc_hal_set_duty_cycle(ledc_hal_context_t *hal, ledc_channel_t channel_num, uint32_t duty_cycle)
|
||||
{
|
||||
ledc_ll_set_duty_cycle(hal->dev, hal->speed_mode, channel_num, duty_cycle);
|
||||
}
|
||||
|
||||
void ledc_hal_set_duty_scale(ledc_hal_context_t *hal, ledc_channel_t channel_num, uint32_t duty_scale)
|
||||
{
|
||||
ledc_ll_set_duty_scale(hal->dev, hal->speed_mode, channel_num, duty_scale);
|
||||
}
|
||||
|
||||
void ledc_hal_get_fade_end_intr_status(ledc_hal_context_t *hal, uint32_t *intr_status)
|
||||
{
|
||||
ledc_ll_get_fade_end_intr_status(hal->dev, hal->speed_mode, intr_status);
|
||||
}
|
||||
|
||||
void ledc_hal_clear_fade_end_intr_status(ledc_hal_context_t *hal, ledc_channel_t channel_num)
|
||||
{
|
||||
ledc_ll_clear_fade_end_intr_status(hal->dev, hal->speed_mode, channel_num);
|
||||
}
|
|
@ -110,6 +110,7 @@ INPUT = \
|
|||
../../components/soc/include/hal/rtc_io_types.h \
|
||||
../../components/soc/include/hal/sigmadelta_types.h \
|
||||
../../components/soc/include/hal/timer_types.h \
|
||||
../../components/soc/include/hal/ledc_types.h \
|
||||
../../components/soc/esp32/include/soc/adc_channel.h \
|
||||
../../components/soc/esp32/include/soc/dac_channel.h \
|
||||
../../components/soc/esp32/include/soc/touch_channel.h \
|
||||
|
|
Loading…
Reference in a new issue