外设

[English]

外设时钟门控

与更新之前相同,外设的时钟仍由驱动处理,用户无需对外设模块的时钟门控进行设置。

但是,如果用户想基于组件 halsoc 开发自己的驱动,请注意时钟门控的头文件引用路径已由 driver/periph_ctrl.h 更新为 esp_private/periph_ctrl.h

RTC 子系统控制

RTC 控制 API 已经从 driver/rtc_cntl.h 移动到了 esp_private/rtc_ctrl.h

ADC

ADC 单次模式及连续模式驱动

ADC 单次模式的驱动已更新。

  • 新的驱动位于组件 esp_adc 中,头文件引用路径为 esp_adc/adc_oneshot.h

  • 旧版驱动仍然可用,其头文件引用路径为 driver/adc.h

对于 ADC 连续模式驱动,其位置已由组件 driver 更新为 esp_adc

  • 头文件引用路径由 driver/adc.h 更新为 esp_adc/adc_continuous.h

但是,引用两种模式的旧版路径 driver/adc.h 会默认触发如下编译警告,可通过配置 Kconfig 选项 CONFIG_ADC_SUPPRESS_DEPRECATE_WARN 关闭该警告。

legacy adc driver is deprecated, please migrate to use esp_adc/adc_oneshot.h and esp_adc/adc_continuous.h for oneshot mode and continuous mode drivers respectively

ADC 校准驱动

ADC 校准驱动已更新。

  • 新的驱动位于组件 esp_adc 中,头文件引用路径为 esp_adc/adc_cali.hesp_adc/adc_cali_scheme.h

旧版驱动仍然可用,其头文件引用路径为 esp_adc_cal.h。如果用户要使用旧版路径,需要将组件 esp_adc 添加到文件 CMakeLists.txt 的组件需求表中。

默认情况下,引用路径 esp_adc_cal.h 会默认触发如下编译警告,可通过配置 Kconfig 选项 CONFIG_ADC_CALI_SUPPRESS_DEPRECATE_WARN 关闭该警告。

legacy adc calibration driver is deprecated, please migrate to use esp_adc/adc_cali.h and esp_adc/adc_cali_scheme.h

API 更新

  • ADC 电源管理 API adc_power_acquireadc_power_release 已被移至 esp_private/adc_share_hw_ctrl.h,用于内部功能。

    • 更新前,由于硬件勘误表的工作原理,这两个 API 可以被用户调用。

    • 更新后,ADC 电源管理完全由驱动在内部实现。

    • 如果用户仍需调用这个 API,可以通过引用路径 esp_private/adc_share_hw_ctrl.h 来调用它。

  • 更新后, driver/adc2_wifi_private.h 已被移至 esp_private/adc_share_hw_ctrl.h

  • adc_unit_t 中的枚举 ADC_UNIT_BOTHADC_UNIT_ALTERADC_UNIT_MAX 已被删除。

  • 由于只有部分芯片支持下列枚举的某些取值,因此将下列枚举删除。如果用户使用了不支持的取值,会造成驱动运行错误。

    • 枚举 ADC_CHANNEL_MAX

    • 枚举 ADC_ATTEN_MAX

    • 枚举 ADC_CONV_UNIT_MAX

  • ESP32 中的 API hall_sensor_read 已被删除,因此 ESP32 不再支持霍尔传感器。

  • API adc_set_i2s_data_sourceadc_i2s_mode_init 已被弃用,相关的枚举 adc_i2s_source_t 也已被弃用,请使用 esp_adc/adc_continuous.h 进行迁移。

  • API adc_digi_filter_resetadc_digi_filter_set_configadc_digi_filter_get_configadc_digi_filter_enable 已被移除. 这些接口的行为不被保证。 枚举 adc_digi_filter_idx_tadc_digi_filter_mode_t 和结构体 adc_digi_iir_filter_t 已被移除。

  • API esp_adc_cal_characterize 已被弃用, 请迁移到 adc_cali_create_scheme_curve_fittingadc_cali_create_scheme_line_fitting.

  • API esp_adc_cal_raw_to_voltage 已被弃用, 请迁移到 adc_cali_raw_to_voltage.

  • API esp_adc_cal_get_voltage 已被弃用, 请迁移到 adc_oneshot_get_calibrated_result.

GPIO

  • 之前的 Kconfig 选项 RTCIO_SUPPORT_RTC_GPIO_DESC 已被删除,因此数组 rtc_gpio_desc 已不可用,请使用替代数组 rtc_io_desc

  • 更新后,用户回调函数无法再通过读取 GPIO 中断的状态寄存器来获取用于触发中断的 GPIO 管脚的编号。但是,用户可以通过使用回调函数变量来确定该管脚编号。

    • 更新前,GPIO 中断发生时,GPIO 中断状态寄存器调用用户回调函数之后,会被清空。因此,用户可以在回调函数中读取 GPIO 中断状态寄存器,以便确定触发中断的 GPIO 管脚。

    • 但是,在调用回调函数后清空中断状态寄存器可能会导致边沿触发的中断丢失。例如,在调用用户回调函数时,如果某个边沿触发的中断 (re) 被触发,该中断会被清除,并且其注册的用户回调函数还未被处理。

    • 更新后,GPIO 的中断状态寄存器在调用用户回调函数 之前 被清空。因此,用户无法读取 GPIO 中断状态寄存器来确定哪个管脚触发了中断。但是,用户可以通过回调函数变量来传递被触发的管脚编号。

定时器组驱动

为统一和简化通用定时器的使用,定时器组驱动已更新为 GPTimer

尽管我们推荐使用新的驱动 API, 旧版驱动仍然可用,其头文件引用路径为 driver/timer.h。但是,引用 driver/timer.h 会默认触发如下编译警告,可通过配置 Kconfig 选项 CONFIG_GPTIMER_SUPPRESS_DEPRECATE_WARN 关闭该警告。

legacy timer group driver is deprecated, please migrate to driver/gptimer.h

概念和使用方法上的主要更新如下所示:

主要概念更新

  • 用于识别定时器的 timer_group_ttimer_idx_t 已被删除。在新驱动中,定时器用参数 gptimer_handle_t 表示。

  • 更新后,定时器的时钟源由 gptimer_clock_source_t 定义,之前的时钟源参数 timer_src_clk_t 不再使用。

  • 更新后,定时器计数方向由 gptimer_count_direction_t 定义,之前的计数方向参数 timer_count_dir_t 不再使用。

  • 更新后,仅支持电平触发的中断, timer_intr_ttimer_intr_mode_t 不再使用。

  • 更新后,通过设置标志位 gptimer_alarm_config_t::auto_reload_on_alarm, 可以使能自动加载。 timer_autoreload_t 不再使用。

主要使用方法更新

  • 更新后,通过从 gptimer_new_timer() 创建定时器示例可以初始化定时器。用户可以在 gptimer_config_t 进行一些基本设置,如时钟源,分辨率和计数方向。请注意,无需在驱动安装阶段进行报警事件的特殊设置。

  • 更新后,报警事件在 gptimer_set_alarm_action() 中进行设置,参数在 gptimer_alarm_config_t 中进行设置。

  • 更新后,通过 gptimer_get_raw_count() 设置计数数值,通过 gptimer_set_raw_count() 获取计数数值。驱动不会自动将原始数据同步到 UTC 时间戳。由于定时器的分辨率已知,用户可以自行转换数据。

  • 更新后,如果 gptimer_event_callbacks_t::on_alarm 被设置为有效的回调函数,驱动程序也会安装中断服务。在回调函数中,用户无需配置底层寄存器,如用于“清除中断状态”,“重新使能事件”的寄存器等。因此, timer_group_get_intr_status_in_isrtimer_group_get_auto_reload_in_isr 这些函数不再使用。

  • 更新后,当报警事件发生时,为更新报警配置,用户可以在中断回调中调用 gptimer_set_alarm_action(),这样报警事件会被重新使能。

  • 更新后,如果用户将 gptimer_alarm_config_t::auto_reload_on_alarm 设置为 true,报警事件将会一直被驱动程序使能。

UART

删除/弃用项目

替代

备注

uart_isr_register()

更新后,UART 中断由驱动处理。

uart_isr_free()

更新后,UART 中断由驱动处理。

uart_config_t 中的 use_ref_tick

uart_config_t::source_clk

选择时钟源。

uart_enable_pattern_det_intr()

uart_enable_pattern_det_baud_intr()

使能模式检测中断。

I2C

删除/弃用项目

替代

备注

i2c_isr_register()

更新后,I2C 中断由驱动处理。

i2c_isr_register()

更新后,I2C 中断由驱动处理。

i2c_opmode_t

更新后,该项不再在 esp-idf 中使用。

SPI

删除/弃用项目

替代

备注

spi_cal_clock()

spi_get_actual_clock()

获取 SPI 真实的工作频率。

  • 内部头文件 spi_common_internal.h 已被移至 esp_private/spi_common_internal.h

LEDC

删除/弃用项目

替代

备注

ledc_timer_config_t 中的 bit_num

ledc_timer_config_t::duty_resolution

设置占空比分辨率。

LCD

  • LCD 面板的初始化流程也有一些更新。更新后,esp_lcd_panel_init() 不再会自动打开显示器。用户需要调用 esp_lcd_panel_disp_on_off() 来手动打开显示器。请注意,打开显示器与打开背光是不同的。更新后,打开屏幕前,用户可以烧录一个预定义的图案,这可以避免开机复位后屏幕上的随机噪音。

  • 更新后, esp_lcd_panel_disp_off() 已被弃用,请使用 esp_lcd_panel_disp_on_off() 作为替代。

  • 更新后, dc_as_cmd_phase 已被删除,SPI LCD 驱动不再支持 9-bit 的 SPI LCD。请使用专用的 GPIO 管脚来控制 LCD D/C 线。

  • 更新后,用于注册 RGB 面板的事件回调函数已从 esp_lcd_rgb_panel_config_t 更新为单独的 API esp_lcd_rgb_panel_register_event_callbacks()。但是,事件回调签名仍保持不变。

  • 更新后, esp_lcd_rgb_panel_config_t 中的标志位 relax_on_idle 被重命名为 esp_lcd_rgb_panel_config_t::refresh_on_demand,后者虽表达了同样的含义,但是其命名更有意义。

  • 更新后,如果创建 RGB LCD 时,标志位 refresh_on_demand 使能,驱动不会在 esp_lcd_panel_draw_bitmap() 中进行刷新,用户需要调用 esp_lcd_rgb_panel_refresh() 来刷新屏幕。

  • 更新后,esp_lcd_color_space_t 已被弃用,请使用 lcd_color_space_t 来描述色彩空间,使用 lcd_rgb_element_order_t 来描述 RGB 颜色的排列顺序。

用于访问寄存器的宏

更新前,所有用于访问寄存器的宏都可以作为表达式来使用,所以以下命令是允许的:

uint32_t val = REG_SET_BITS(reg, bits, mask);

在 ESP-IDF v5.0 中,用于写入或读取-修改-写入寄存器的宏不能再作为表达式使用,而只能作为语句使用,这适用于以下宏: REG_WRITEREG_SET_BITREG_CLR_BITREG_SET_BITSREG_SET_FIELDWRITE_PERI_REGCLEAR_PERI_REG_MASKSET_PERI_REG_MASKSET_PERI_REG_BITS

为存储要写入寄存器的值,请按以下步骤完成操作:

uint32_t new_val = REG_READ(reg) | mask;
REG_WRITE(reg, new_val);

要获得修改后的寄存器的值(该值可能与写入的值不同),要增加一个显示的读取命令:

REG_SET_BITS(reg, bits, mask);
uint32_t new_val = REG_READ(reg);