diff --git a/components/ulp/lp_core/include/lp_core_i2c.h b/components/ulp/lp_core/include/lp_core_i2c.h index 90c34d4d8d4..9f910b46ba0 100644 --- a/components/ulp/lp_core/include/lp_core_i2c.h +++ b/components/ulp/lp_core/include/lp_core_i2c.h @@ -43,6 +43,41 @@ typedef struct { } lp_core_i2c_cfg_t; /* Default LP I2C GPIO settings */ +#ifdef __cplusplus +#define LP_I2C_DEFAULT_GPIO_CONFIG() (__extension__({ \ + lp_core_i2c_pin_cfg_t __lp_i2c_pin_cfg; \ + __lp_i2c_pin_cfg.sda_io_num = LP_I2C_SDA_IO; \ + __lp_i2c_pin_cfg.scl_io_num = LP_I2C_SCL_IO; \ + __lp_i2c_pin_cfg.sda_pullup_en = true; \ + __lp_i2c_pin_cfg.scl_pullup_en = true; \ + __lp_i2c_pin_cfg; \ +})) + +/* LP I2C fast mode config. Max SCL freq of 400 KHz. */ +#define LP_I2C_FAST_MODE_CONFIG() (__extension__({ \ + lp_core_i2c_timing_cfg_t __lp_i2c_timing_cfg; \ + __lp_i2c_timing_cfg.clk_speed_hz = 400000; \ + __lp_i2c_timing_cfg; \ +})) + +/* LP I2C standard mode config. Max SCL freq of 100 KHz. */ +#define LP_I2C_STANDARD_MODE_CONFIG() (__extension__({ \ + lp_core_i2c_timing_cfg_t __lp_i2c_timing_cfg; \ + __lp_i2c_timing_cfg.clk_speed_hz = 100000; \ + __lp_i2c_timing_cfg; \ +})) + +#define LP_I2C_DEFAULT_SRC_CLK() LP_I2C_SCLK_LP_FAST + +/* Default LP I2C GPIO settings and timing parameters */ +#define LP_CORE_I2C_DEFAULT_CONFIG() (__extension__({ \ + lp_core_i2c_cfg_t __lp_i2c_cfg; \ + __lp_i2c_cfg.i2c_pin_cfg = LP_I2C_DEFAULT_GPIO_CONFIG(); \ + __lp_i2c_cfg.i2c_timing_cfg = LP_I2C_FAST_MODE_CONFIG(); \ + __lp_i2c_cfg.i2c_src_clk = LP_I2C_DEFAULT_SRC_CLK(); \ + __lp_i2c_cfg; \ +})) +#else #define LP_I2C_DEFAULT_GPIO_CONFIG() \ .i2c_pin_cfg.sda_io_num = GPIO_NUM_6, \ .i2c_pin_cfg.scl_io_num = GPIO_NUM_7, \ @@ -60,13 +95,14 @@ typedef struct { #define LP_I2C_DEFAULT_SRC_CLK() \ .i2c_src_clk = LP_I2C_SCLK_LP_FAST, \ -/* Default LP I2C GPIO settings and timing parametes */ +/* Default LP I2C GPIO settings and timing parameters */ #define LP_CORE_I2C_DEFAULT_CONFIG() \ { \ LP_I2C_DEFAULT_GPIO_CONFIG() \ LP_I2C_FAST_MODE_CONFIG() \ LP_I2C_DEFAULT_SRC_CLK() \ } +#endif /* __cplusplus */ /** * @brief Initialize and configure the LP I2C for use by the LP core @@ -77,7 +113,7 @@ typedef struct { * @return esp_err_t ESP_OK when successful * * @note The internal pull-up resistors for SDA and SCL pins, if enabled, will - * provide a weak pull-up value of about 30-50 kOhm. Users are adviced to enable + * provide a weak pull-up value of about 30-50 kOhm. Users are advised to enable * external pull-ups for better performance at higher SCL frequencies. */ esp_err_t lp_core_i2c_master_init(i2c_port_t lp_i2c_num, const lp_core_i2c_cfg_t *cfg); diff --git a/components/ulp/lp_core/include/lp_core_uart.h b/components/ulp/lp_core/include/lp_core_uart.h index bd91f5fbcfa..23569655eb3 100644 --- a/components/ulp/lp_core/include/lp_core_uart.h +++ b/components/ulp/lp_core/include/lp_core_uart.h @@ -21,8 +21,8 @@ extern "C" { #if CONFIG_IDF_TARGET_ESP32P4 #define LP_UART_DEFAULT_TX_GPIO_NUM GPIO_NUM_14 #define LP_UART_DEFAULT_RX_GPIO_NUM GPIO_NUM_15 -#define LP_UART_DEFAULT_RTS_GPIO_NUM (-1) -#define LP_UART_DEFAULT_CTS_GPIO_NUM (-1) +#define LP_UART_DEFAULT_RTS_GPIO_NUM ((gpio_num_t)(-1)) +#define LP_UART_DEFAULT_CTS_GPIO_NUM ((gpio_num_t)(-1)) #elif (CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32C5) #define LP_UART_DEFAULT_TX_GPIO_NUM GPIO_NUM_5 #define LP_UART_DEFAULT_RX_GPIO_NUM GPIO_NUM_4 @@ -64,6 +64,40 @@ typedef struct { } lp_core_uart_cfg_t; /* Default LP UART GPIO settings */ +#ifdef __cplusplus +#define LP_UART_DEFAULT_GPIO_CONFIG() (__extension__({ \ + lp_core_uart_pin_cfg_t __lp_uart_pin_cfg; \ + __lp_uart_pin_cfg.tx_io_num = LP_UART_DEFAULT_TX_GPIO_NUM; \ + __lp_uart_pin_cfg.rx_io_num = LP_UART_DEFAULT_RX_GPIO_NUM; \ + __lp_uart_pin_cfg.rts_io_num = LP_UART_DEFAULT_RTS_GPIO_NUM; \ + __lp_uart_pin_cfg.cts_io_num = LP_UART_DEFAULT_CTS_GPIO_NUM; \ + __lp_uart_pin_cfg; \ +})) + +/* Default LP UART protocol config */ +#define LP_UART_DEFAULT_PROTO_CONFIG() (__extension__({ \ + lp_core_uart_proto_cfg_t __lp_uart_proto_cfg; \ + __lp_uart_proto_cfg.baud_rate = 115200; \ + __lp_uart_proto_cfg.data_bits = UART_DATA_8_BITS; \ + __lp_uart_proto_cfg.parity = UART_PARITY_DISABLE; \ + __lp_uart_proto_cfg.stop_bits = UART_STOP_BITS_1; \ + __lp_uart_proto_cfg.flow_ctrl = UART_HW_FLOWCTRL_DISABLE; \ + __lp_uart_proto_cfg.rx_flow_ctrl_thresh = 0; \ + __lp_uart_proto_cfg; \ +})) + +/* Default LP UART source clock config */ +#define LP_UART_DEFAULT_CLOCK_CONFIG() LP_UART_SCLK_DEFAULT + +/* Default LP UART GPIO settings and protocol parameters */ +#define LP_CORE_UART_DEFAULT_CONFIG() (__extension__({ \ + lp_core_uart_cfg_t __lp_uart_cfg; \ + __lp_uart_cfg.uart_pin_cfg = LP_UART_DEFAULT_GPIO_CONFIG(); \ + __lp_uart_cfg.uart_proto_cfg = LP_UART_DEFAULT_PROTO_CONFIG(); \ + __lp_uart_cfg.lp_uart_source_clk = LP_UART_DEFAULT_CLOCK_CONFIG(); \ + __lp_uart_cfg; \ +})) +#else #define LP_UART_DEFAULT_GPIO_CONFIG() \ .uart_pin_cfg.tx_io_num = LP_UART_DEFAULT_TX_GPIO_NUM, \ .uart_pin_cfg.rx_io_num = LP_UART_DEFAULT_RX_GPIO_NUM, \ @@ -90,6 +124,7 @@ typedef struct { LP_UART_DEFAULT_PROTO_CONFIG() \ LP_UART_DEFAULT_CLOCK_CONFIG() \ } +#endif /* __cplusplus */ /** * @brief Initialize and configure the LP UART to be used from the LP core diff --git a/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/CMakeLists.txt b/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/CMakeLists.txt index 239b78cf330..b0cb7795421 100644 --- a/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/CMakeLists.txt +++ b/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/CMakeLists.txt @@ -24,6 +24,8 @@ if(CONFIG_SOC_LP_VAD_SUPPORTED) list(APPEND app_sources "test_lp_core_vad.c") endif() +list(APPEND app_sources "test_lp_periph_config_cpp.cpp") + set(lp_core_sources "lp_core/test_main.c") set(lp_core_sources_counter "lp_core/test_main_counter.c") diff --git a/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/test_lp_periph_config_cpp.cpp b/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/test_lp_periph_config_cpp.cpp new file mode 100644 index 00000000000..18e1270e282 --- /dev/null +++ b/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/test_lp_periph_config_cpp.cpp @@ -0,0 +1,43 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +// Compile LP peripheral default-config macros as C++ to catch incompatibilities. +#include "sdkconfig.h" +#include "soc/soc_caps.h" + +#if SOC_ULP_LP_UART_SUPPORTED +#include "lp_core_uart.h" + +static void test_lp_uart_default_config_cpp(void) __attribute__((unused)); +static void test_lp_uart_default_config_cpp(void) +{ + lp_core_uart_cfg_t cfg = LP_CORE_UART_DEFAULT_CONFIG(); + lp_core_uart_pin_cfg_t pin_cfg = LP_UART_DEFAULT_GPIO_CONFIG(); + lp_core_uart_proto_cfg_t proto_cfg = LP_UART_DEFAULT_PROTO_CONFIG(); + (void)cfg; + (void)pin_cfg; + (void)proto_cfg; + (void)LP_UART_DEFAULT_CLOCK_CONFIG(); +} +#endif /* SOC_ULP_LP_UART_SUPPORTED */ + +#if SOC_LP_CORE_SUPPORT_I2C +#include "lp_core_i2c.h" + +static void test_lp_i2c_default_config_cpp(void) __attribute__((unused)); +static void test_lp_i2c_default_config_cpp(void) +{ + lp_core_i2c_cfg_t cfg = LP_CORE_I2C_DEFAULT_CONFIG(); + lp_core_i2c_pin_cfg_t pin_cfg = LP_I2C_DEFAULT_GPIO_CONFIG(); + lp_core_i2c_timing_cfg_t fast_cfg = LP_I2C_FAST_MODE_CONFIG(); + lp_core_i2c_timing_cfg_t std_cfg = LP_I2C_STANDARD_MODE_CONFIG(); + (void)cfg; + (void)pin_cfg; + (void)fast_cfg; + (void)std_cfg; + (void)LP_I2C_DEFAULT_SRC_CLK(); +} +#endif /* SOC_LP_CORE_SUPPORT_I2C */ diff --git a/components/ulp/test_apps/ulp_riscv/main/CMakeLists.txt b/components/ulp/test_apps/ulp_riscv/main/CMakeLists.txt index ff7fe449411..3beb5448651 100644 --- a/components/ulp/test_apps/ulp_riscv/main/CMakeLists.txt +++ b/components/ulp/test_apps/ulp_riscv/main/CMakeLists.txt @@ -1,4 +1,4 @@ -set(app_sources "test_app_main.c" "test_ulp_riscv.c" "test_ulp_riscv_i2c.c") +set(app_sources "test_app_main.c" "test_ulp_riscv.c" "test_ulp_riscv_i2c.c" "test_ulp_riscv_i2c_config_cpp.cpp") set(ulp_sources "ulp/test_main.c") set(ulp_sources2 "ulp/test_main_second_cocpu_firmware.c") set(ulp_sources3 "ulp/test_main_cocpu_crash.c") diff --git a/components/ulp/test_apps/ulp_riscv/main/test_ulp_riscv_i2c_config_cpp.cpp b/components/ulp/test_apps/ulp_riscv/main/test_ulp_riscv_i2c_config_cpp.cpp new file mode 100644 index 00000000000..682910208c5 --- /dev/null +++ b/components/ulp/test_apps/ulp_riscv/main/test_ulp_riscv_i2c_config_cpp.cpp @@ -0,0 +1,21 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +// Compile ULP RISC-V I2C default-config macros as C++ to catch incompatibilities. +#include "ulp_riscv_i2c.h" + +static void test_ulp_riscv_i2c_default_config_cpp(void) __attribute__((unused)); +static void test_ulp_riscv_i2c_default_config_cpp(void) +{ + ulp_riscv_i2c_cfg_t cfg = ULP_RISCV_I2C_DEFAULT_CONFIG(); + ulp_riscv_i2c_pin_cfg_t pin_cfg = ULP_RISCV_I2C_DEFAULT_GPIO_CONFIG(); + ulp_riscv_i2c_timing_cfg_t fast_cfg = ULP_RISCV_I2C_FAST_MODE_CONFIG(); + ulp_riscv_i2c_timing_cfg_t std_cfg = ULP_RISCV_I2C_STANDARD_MODE_CONFIG(); + (void)cfg; + (void)pin_cfg; + (void)fast_cfg; + (void)std_cfg; +} diff --git a/components/ulp/ulp_riscv/include/ulp_riscv_i2c.h b/components/ulp/ulp_riscv/include/ulp_riscv_i2c.h index 907e62c1ec4..19cafc3b93b 100644 --- a/components/ulp/ulp_riscv/include/ulp_riscv_i2c.h +++ b/components/ulp/ulp_riscv/include/ulp_riscv_i2c.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -46,6 +46,63 @@ typedef struct { } ulp_riscv_i2c_cfg_t; /* Default RTC I2C GPIO settings */ +#ifdef __cplusplus +#define ULP_RISCV_I2C_DEFAULT_GPIO_CONFIG() (__extension__({ \ + ulp_riscv_i2c_pin_cfg_t __ulp_riscv_i2c_pin_cfg; \ + __ulp_riscv_i2c_pin_cfg.sda_io_num = GPIO_NUM_3; \ + __ulp_riscv_i2c_pin_cfg.scl_io_num = GPIO_NUM_2; \ + __ulp_riscv_i2c_pin_cfg.sda_pullup_en = true; \ + __ulp_riscv_i2c_pin_cfg.scl_pullup_en = true; \ + __ulp_riscv_i2c_pin_cfg; \ +})) + +#if CONFIG_IDF_TARGET_ESP32S3 +/* Nominal I2C bus timing parameters for I2C fast mode. Max SCL freq of 400 KHz. */ +#define ULP_RISCV_I2C_FAST_MODE_CONFIG() (__extension__({ \ + ulp_riscv_i2c_timing_cfg_t __ulp_riscv_i2c_timing_cfg; \ + __ulp_riscv_i2c_timing_cfg.scl_low_period = 1.4; \ + __ulp_riscv_i2c_timing_cfg.scl_high_period = 0.3; \ + __ulp_riscv_i2c_timing_cfg.sda_duty_period = 1; \ + __ulp_riscv_i2c_timing_cfg.scl_start_period = 2; \ + __ulp_riscv_i2c_timing_cfg.scl_stop_period = 1.3; \ + __ulp_riscv_i2c_timing_cfg.i2c_trans_timeout = 20; \ + __ulp_riscv_i2c_timing_cfg; \ +})) +#elif CONFIG_IDF_TARGET_ESP32S2 +/* Nominal I2C bus timing parameters for I2C fast mode. Max SCL freq on S2 is about 233 KHz due to timing constraints. */ +#define ULP_RISCV_I2C_FAST_MODE_CONFIG() (__extension__({ \ + ulp_riscv_i2c_timing_cfg_t __ulp_riscv_i2c_timing_cfg; \ + __ulp_riscv_i2c_timing_cfg.scl_low_period = 2; \ + __ulp_riscv_i2c_timing_cfg.scl_high_period = 0.7; \ + __ulp_riscv_i2c_timing_cfg.sda_duty_period = 1.7; \ + __ulp_riscv_i2c_timing_cfg.scl_start_period = 2.4; \ + __ulp_riscv_i2c_timing_cfg.scl_stop_period = 1.3; \ + __ulp_riscv_i2c_timing_cfg.i2c_trans_timeout = 20; \ + __ulp_riscv_i2c_timing_cfg; \ +})) +#endif + +/* Nominal I2C bus timing parameters for I2C standard mode. Max SCL freq of 100 KHz. */ +#define ULP_RISCV_I2C_STANDARD_MODE_CONFIG() (__extension__({ \ + ulp_riscv_i2c_timing_cfg_t __ulp_riscv_i2c_timing_cfg; \ + __ulp_riscv_i2c_timing_cfg.scl_low_period = 5; \ + __ulp_riscv_i2c_timing_cfg.scl_high_period = 5; \ + __ulp_riscv_i2c_timing_cfg.sda_duty_period = 2; \ + __ulp_riscv_i2c_timing_cfg.scl_start_period = 3; \ + __ulp_riscv_i2c_timing_cfg.scl_stop_period = 6; \ + __ulp_riscv_i2c_timing_cfg.i2c_trans_timeout = 20; \ + __ulp_riscv_i2c_timing_cfg; \ +})) + +/* Default RTC I2C configuration settings. Uses I2C fast mode. */ +//TODO: Move to smaller units of time in the future like nano seconds to avoid floating point operations. +#define ULP_RISCV_I2C_DEFAULT_CONFIG() (__extension__({ \ + ulp_riscv_i2c_cfg_t __ulp_riscv_i2c_cfg; \ + __ulp_riscv_i2c_cfg.i2c_pin_cfg = ULP_RISCV_I2C_DEFAULT_GPIO_CONFIG(); \ + __ulp_riscv_i2c_cfg.i2c_timing_cfg = ULP_RISCV_I2C_FAST_MODE_CONFIG(); \ + __ulp_riscv_i2c_cfg; \ +})) +#else #define ULP_RISCV_I2C_DEFAULT_GPIO_CONFIG() \ .i2c_pin_cfg.sda_io_num = GPIO_NUM_3, \ .i2c_pin_cfg.scl_io_num = GPIO_NUM_2, \ @@ -88,6 +145,7 @@ typedef struct { ULP_RISCV_I2C_DEFAULT_GPIO_CONFIG() \ ULP_RISCV_I2C_FAST_MODE_CONFIG() \ } +#endif /* __cplusplus */ /** * @brief Set the I2C slave device address