diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index c350649201..1b3b2e277f 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -1058,19 +1058,23 @@ static esp_err_t SLEEP_FN_ATTR esp_sleep_start(uint32_t sleep_flags, uint32_t cl // Enable ULP wakeup #if CONFIG_ULP_COPROC_TYPE_FSM if (s_config.wakeup_triggers & RTC_ULP_TRIG_EN) { -#elif CONFIG_ULP_COPROC_TYPE_RISCV - if (s_config.wakeup_triggers & (RTC_COCPU_TRIG_EN | RTC_COCPU_TRAP_TRIG_EN)) { -#elif CONFIG_ULP_COPROC_TYPE_LP_CORE - if (s_config.wakeup_triggers & (RTC_LP_CORE_TRIG_EN | RTC_LP_CORE_TRAP_TRIG_EN)) { -#endif #ifdef CONFIG_IDF_TARGET_ESP32 rtc_hal_ulp_wakeup_enable(); -#elif CONFIG_ULP_COPROC_TYPE_LP_CORE - pmu_ll_hp_clear_sw_intr_status(&PMU); #else rtc_hal_ulp_int_clear(); #endif } +#endif +#if CONFIG_ULP_COPROC_TYPE_RISCV + if (s_config.wakeup_triggers & (RTC_COCPU_TRIG_EN | RTC_COCPU_TRAP_TRIG_EN)) { + rtc_hal_ulp_int_clear(); + } +#endif +#if CONFIG_ULP_COPROC_TYPE_LP_CORE + if (s_config.wakeup_triggers & (RTC_LP_CORE_TRIG_EN | RTC_LP_CORE_TRAP_TRIG_EN)) { + pmu_ll_hp_clear_sw_intr_status(&PMU); + } +#endif #endif // CONFIG_ULP_COPROC_ENABLED misc_modules_sleep_prepare(sleep_flags, deep_sleep); @@ -1800,7 +1804,10 @@ esp_err_t esp_sleep_enable_ulp_wakeup(void) } #endif //CONFIG_IDF_TARGET_ESP32 -#if CONFIG_ULP_COPROC_TYPE_FSM +#if CONFIG_ULP_COPROC_TYPE_FSM && CONFIG_ULP_COPROC_TYPE_RISCV + s_config.wakeup_triggers |= (RTC_ULP_TRIG_EN | RTC_COCPU_TRIG_EN | RTC_COCPU_TRAP_TRIG_EN); + return ESP_OK; +#elif CONFIG_ULP_COPROC_TYPE_FSM s_config.wakeup_triggers |= RTC_ULP_TRIG_EN; return ESP_OK; #elif CONFIG_ULP_COPROC_TYPE_RISCV diff --git a/components/ulp/CMakeLists.txt b/components/ulp/CMakeLists.txt index 405ddcc362..c0ca9be67c 100644 --- a/components/ulp/CMakeLists.txt +++ b/components/ulp/CMakeLists.txt @@ -40,8 +40,9 @@ if(CONFIG_ULP_COPROC_TYPE_FSM OR CONFIG_ULP_COPROC_TYPE_RISCV) list(APPEND srcs "ulp_fsm/ulp.c" "ulp_fsm/ulp_macro.c") + endif() - elseif(CONFIG_ULP_COPROC_TYPE_RISCV) + if(CONFIG_ULP_COPROC_TYPE_RISCV) list(APPEND srcs "ulp_riscv/ulp_riscv.c" "ulp_riscv/ulp_riscv_lock.c" diff --git a/components/ulp/Kconfig b/components/ulp/Kconfig index 2fbb436130..6eca1766e6 100644 --- a/components/ulp/Kconfig +++ b/components/ulp/Kconfig @@ -8,23 +8,24 @@ menu "Ultra Low Power (ULP) Co-processor" Enable this feature if you plan to use the ULP Co-processor. Once this option is enabled, further ULP co-processor configuration will appear in the menu. - choice ULP_COPROC_TYPE - prompt "ULP Co-processor type" + menu "ULP Coprocessor types" depends on ULP_COPROC_ENABLED - default ULP_COPROC_TYPE_RISCV if (IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3) - help - Choose the ULP Coprocessor type: ULP FSM (Finite State Machine) or ULP RISC-V. config ULP_COPROC_TYPE_FSM bool "ULP FSM (Finite State Machine)" depends on SOC_ULP_FSM_SUPPORTED + default y if IDF_TARGET_ESP32 + config ULP_COPROC_TYPE_RISCV bool "ULP RISC-V" depends on SOC_RISCV_COPROC_SUPPORTED + default y if (IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3) && !ULP_COPROC_TYPE_FSM + config ULP_COPROC_TYPE_LP_CORE bool "LP core RISC-V" depends on SOC_LP_CORE_SUPPORTED - endchoice + default y if (!IDF_TARGET_ESP32 && !IDF_TARGET_ESP32S2 && !IDF_TARGET_ESP32S3) + endmenu config ULP_COPROC_RESERVE_MEM int diff --git a/components/ulp/cmake/IDFULPProject.cmake b/components/ulp/cmake/IDFULPProject.cmake index ec5d85e9db..aa0ccb4f07 100644 --- a/components/ulp/cmake/IDFULPProject.cmake +++ b/components/ulp/cmake/IDFULPProject.cmake @@ -2,24 +2,46 @@ include(${SDKCONFIG_CMAKE}) enable_language(C ASM) set(CMAKE_EXECUTABLE_SUFFIX ".elf") +# Logic to determine ULP type and set reusable flags +set(BUILD_RISCV OFF) +set(BUILD_FSM OFF) +set(BUILD_LP_CORE OFF) + +# If ULP_TYPE is explicitly set, use it; otherwise fall back to CONFIG checks +if(ULP_TYPE) + string(TOLOWER "${ULP_TYPE}" ulp_type_lower) + if(ulp_type_lower STREQUAL "riscv") + set(BUILD_RISCV ON) + elseif(ulp_type_lower STREQUAL "fsm") + set(BUILD_FSM ON) + elseif(ulp_type_lower STREQUAL "lp_core") + set(BUILD_LP_CORE ON) + endif() +elseif(CONFIG_ULP_COPROC_TYPE_RISCV) + set(BUILD_RISCV ON) +elseif(CONFIG_ULP_COPROC_TYPE_LP_CORE) + set(BUILD_LP_CORE ON) +elseif(CONFIG_ULP_COPROC_TYPE_FSM) + set(BUILD_FSM ON) +endif() + # Check the supported assembler version -if(CONFIG_ULP_COPROC_TYPE_FSM) +if(BUILD_FSM) check_expected_tool_version("esp32ulp-elf" ${CMAKE_ASM_COMPILER}) endif() function(ulp_apply_default_options ulp_app_name) - if(CONFIG_ULP_COPROC_TYPE_RISCV) + if(BUILD_RISCV) target_link_options(${ulp_app_name} PRIVATE "-nostartfiles") target_link_options(${ulp_app_name} PRIVATE -Wl,--gc-sections) target_link_options(${ulp_app_name} PRIVATE "-Wl,--no-warn-rwx-segments") target_link_options(${ulp_app_name} PRIVATE -Wl,-Map=${CMAKE_CURRENT_BINARY_DIR}/${ulp_app_name}.map) - - elseif(CONFIG_ULP_COPROC_TYPE_LP_CORE) + elseif(BUILD_LP_CORE) target_link_options(${ulp_app_name} PRIVATE "-nostartfiles") target_link_options(${ulp_app_name} PRIVATE "-Wl,--no-warn-rwx-segments") target_link_options(${ulp_app_name} PRIVATE -Wl,--gc-sections) target_link_options(${ulp_app_name} PRIVATE -Wl,-Map=${CMAKE_CURRENT_BINARY_DIR}/${ulp_app_name}.map) - else() + elseif(BUILD_FSM) target_link_options(${ulp_app_name} PRIVATE -Map=${CMAKE_CURRENT_BINARY_DIR}/${ulp_app_name}.map) endif() endfunction() @@ -52,12 +74,14 @@ function(ulp_apply_default_sources ulp_app_name) target_include_directories(${ulp_app_name} PRIVATE ${COMPONENT_INCLUDES} ${sdkconfig_dir}) # Pre-process the linker script - if(CONFIG_ULP_COPROC_TYPE_RISCV) + if(BUILD_RISCV) set(ULP_LD_TEMPLATE ${IDF_PATH}/components/ulp/ld/ulp_riscv.ld) - elseif(CONFIG_ULP_COPROC_TYPE_LP_CORE) + elseif(BUILD_LP_CORE) set(ULP_LD_TEMPLATE ${IDF_PATH}/components/ulp/ld/lp_core_riscv.ld) - else() + elseif(BUILD_FSM) set(ULP_LD_TEMPLATE ${IDF_PATH}/components/ulp/ld/ulp_fsm.ld) + else() + message(FATAL_ERROR "Unable to determine ULP type. ") endif() get_filename_component(ULP_LD_SCRIPT ${ULP_LD_TEMPLATE} NAME) @@ -81,8 +105,15 @@ function(ulp_apply_default_sources ulp_app_name) # To avoid warning "Manually-specified variables were not used by the project" set(bypassWarning "${IDF_TARGET}") set(bypassWarning "${ULP_VAR_PREFIX}") + set(bypassWarning "${ULP_TYPE}") - if(CONFIG_ULP_COPROC_TYPE_RISCV) + # Save user sources before adding core sources + set(ULP_USER_SOURCES ${ULP_S_SOURCES}) + + # Clear ULP_S_SOURCES and rebuild it with only the sources we need + set(ULP_S_SOURCES ${ULP_USER_SOURCES}) + + if(BUILD_RISCV) #risc-v ulp uses extra files for building: list(APPEND ULP_S_SOURCES "${IDF_PATH}/components/ulp/ulp_riscv/ulp_core/ulp_riscv_vectors.S" @@ -97,7 +128,6 @@ function(ulp_apply_default_sources ulp_app_name) "${IDF_PATH}/components/ulp/ulp_riscv/ulp_core/ulp_riscv_gpio.c" "${IDF_PATH}/components/ulp/ulp_riscv/ulp_core/ulp_riscv_interrupt.c") - target_sources(${ulp_app_name} PRIVATE ${ULP_S_SOURCES}) #Makes the csr utillies for riscv visible: target_include_directories(${ulp_app_name} PRIVATE "${IDF_PATH}/components/ulp/ulp_riscv/ulp_core/include" @@ -107,7 +137,32 @@ function(ulp_apply_default_sources ulp_app_name) target_compile_definitions(${ulp_app_name} PRIVATE IS_ULP_COCPU) target_compile_definitions(${ulp_app_name} PRIVATE ULP_RISCV_REGISTER_OPS) - elseif(CONFIG_ULP_COPROC_TYPE_LP_CORE) + elseif(BUILD_FSM) + foreach(ulp_s_source ${ULP_S_SOURCES}) + get_filename_component(ulp_ps_source ${ulp_s_source} NAME_WE) + set(ulp_ps_output ${CMAKE_CURRENT_BINARY_DIR}/${ulp_ps_source}.ulp.S) + # Put all arguments to the list + set(preprocessor_args -D__ASSEMBLER__ -E -P -xc -o ${ulp_ps_output} ${ULP_PREPRO_ARGS} ${ulp_s_source}) + + set(compiler_arguments_file ${CMAKE_CURRENT_BINARY_DIR}/${ulp_ps_source}_args.txt) + create_arg_file("${preprocessor_args}" "${compiler_arguments_file}") + + # Generate preprocessed assembly files. + add_custom_command(OUTPUT ${ulp_ps_output} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_C_COMPILER} @${compiler_arguments_file} + DEPENDS ${ulp_s_source} + VERBATIM) + # During assembly file compilation, output listing files as well. + set_source_files_properties(${ulp_ps_output} + PROPERTIES COMPILE_FLAGS + "-al=${CMAKE_CURRENT_BINARY_DIR}/${ulp_ps_source}.lst") + list(APPEND ULP_PS_SOURCES ${ulp_ps_output}) + endforeach() + + target_sources(${ulp_app_name} PRIVATE ${ULP_PS_SOURCES}) + + elseif(BUILD_LP_CORE) list(APPEND ULP_S_SOURCES "${IDF_PATH}/components/ulp/lp_core/lp_core/start.S" "${IDF_PATH}/components/ulp/lp_core/lp_core/vector.S" @@ -167,31 +222,6 @@ function(ulp_apply_default_sources ulp_app_name) "${IDF_PATH}/components/ulp/lp_core/shared/include") target_compile_definitions(${ulp_app_name} PRIVATE IS_ULP_COCPU) - else() - foreach(ulp_s_source ${ULP_S_SOURCES}) - get_filename_component(ulp_ps_source ${ulp_s_source} NAME_WE) - set(ulp_ps_output ${CMAKE_CURRENT_BINARY_DIR}/${ulp_ps_source}.ulp.S) - # Put all arguments to the list - set(preprocessor_args -D__ASSEMBLER__ -E -P -xc -o ${ulp_ps_output} ${ULP_PREPRO_ARGS} ${ulp_s_source}) - - set(compiler_arguments_file ${CMAKE_CURRENT_BINARY_DIR}/${ulp_ps_source}_args.txt) - create_arg_file("${preprocessor_args}" "${compiler_arguments_file}") - - # Generate preprocessed assembly files. - add_custom_command(OUTPUT ${ulp_ps_output} - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${CMAKE_C_COMPILER} @${compiler_arguments_file} - DEPENDS ${ulp_s_source} - VERBATIM) - # During assembly file compilation, output listing files as well. - set_source_files_properties(${ulp_ps_output} - PROPERTIES COMPILE_FLAGS - "-al=${CMAKE_CURRENT_BINARY_DIR}/${ulp_ps_source}.lst") - list(APPEND ULP_PS_SOURCES ${ulp_ps_output}) - endforeach() - - target_sources(${ulp_app_name} PRIVATE ${ULP_PS_SOURCES}) - endif() endfunction() @@ -206,7 +236,7 @@ function(ulp_add_build_binary_targets ulp_app_name) target_compile_options(${ulp_app_name} PRIVATE $<$:-specs=picolibcpp.specs>) endif() - if(CONFIG_ULP_COPROC_TYPE_LP_CORE) + if(BUILD_LP_CORE) set(ULP_BASE_ADDR "0x0") else() set(ULP_BASE_ADDR "0x50000000") diff --git a/components/ulp/project_include.cmake b/components/ulp/project_include.cmake index 05550d9f42..891bbaecc4 100644 --- a/components/ulp/project_include.cmake +++ b/components/ulp/project_include.cmake @@ -2,7 +2,7 @@ # # Create ULP binary and embed into the application. -function(__setup_ulp_project app_name project_path prefix s_sources exp_dep_srcs) +function(__setup_ulp_project app_name project_path prefix type s_sources exp_dep_srcs) if(NOT CMAKE_BUILD_EARLY_EXPANSION) spaces2list(s_sources) @@ -39,13 +39,36 @@ function(__setup_ulp_project app_name project_path prefix s_sources exp_dep_srcs idf_build_get_property(extra_cmake_args EXTRA_CMAKE_ARGS) if(IDF_TARGET STREQUAL "esp32") + # esp32 only supports FSM + if(type) + string(TOLOWER "${type}" type_lower) + if(type_lower STREQUAL "riscv") + message(FATAL_ERROR "TYPE=riscv is not supported on ${IDF_TARGET}. " + "Only FSM type is available for ULP on this target.") + endif() + endif() set(TOOLCHAIN_FLAG ${idf_path}/components/ulp/cmake/toolchain-${idf_target}-ulp.cmake) set(ULP_IS_RISCV OFF) elseif(IDF_TARGET STREQUAL "esp32s2" OR IDF_TARGET STREQUAL "esp32s3") - if(CONFIG_ULP_COPROC_TYPE_RISCV STREQUAL "y") - set(TOOLCHAIN_FLAG ${idf_path}/components/ulp/cmake/toolchain-ulp-riscv.cmake) + # If both FSM and RISC-V are enabled in sdkconfig and a TYPE was + # provided by the caller, use TYPE to disambiguate which toolchain + # to select for this ULP external project. + if((CONFIG_ULP_COPROC_TYPE_RISCV STREQUAL "y") AND (CONFIG_ULP_COPROC_TYPE_FSM STREQUAL "y")) + message(STATUS "Both RISCV and FSM are enabled, using '${type}' toolchain for ${app_name} ULP project.") + string(TOLOWER "${type}" type_lower) + if(type_lower STREQUAL "riscv") + set(TOOLCHAIN_FLAG ${idf_path}/components/ulp/cmake/toolchain-ulp-riscv.cmake) + elseif(type_lower STREQUAL "fsm") + set(TOOLCHAIN_FLAG ${idf_path}/components/ulp/cmake/toolchain-${idf_target}-ulp.cmake) + else() + message(FATAL_ERROR "Invalid ULP_TYPE '${type}'; expected 'fsm' or 'riscv'.") + endif() else() - set(TOOLCHAIN_FLAG ${idf_path}/components/ulp/cmake/toolchain-${idf_target}-ulp.cmake) + if(CONFIG_ULP_COPROC_TYPE_RISCV STREQUAL "y") + set(TOOLCHAIN_FLAG ${idf_path}/components/ulp/cmake/toolchain-ulp-riscv.cmake) + else() + set(TOOLCHAIN_FLAG ${idf_path}/components/ulp/cmake/toolchain-${idf_target}-ulp.cmake) + endif() endif() elseif(CONFIG_ULP_COPROC_TYPE_LP_CORE) set(TOOLCHAIN_FLAG ${idf_path}/components/ulp/cmake/toolchain-lp-core-riscv.cmake) @@ -62,6 +85,7 @@ function(__setup_ulp_project app_name project_path prefix s_sources exp_dep_srcs -DULP_APP_NAME=${app_name} -DADD_PICOLIBC_SPECS=${CONFIG_LIBC_PICOLIBC} -DULP_VAR_PREFIX=${prefix} + -DULP_TYPE=${type} -DCOMPONENT_DIR=${COMPONENT_DIR} -DCOMPONENT_INCLUDES=$ -DIDF_TARGET=${idf_target} @@ -93,15 +117,46 @@ function(__setup_ulp_project app_name project_path prefix s_sources exp_dep_srcs endif() endfunction() +function(validate_ulp_type ULP_TYPE) + if(CONFIG_ULP_COPROC_ENABLED) + if(NOT CONFIG_ULP_COPROC_TYPE_FSM AND NOT CONFIG_ULP_COPROC_TYPE_RISCV AND NOT CONFIG_ULP_COPROC_TYPE_LP_CORE) + message(FATAL_ERROR "ULP co-processor is enabled (CONFIG_ULP_COPROC_ENABLED=y), but no ULP type " + "is selected. Please enable at least one of: CONFIG_ULP_COPROC_TYPE_FSM, " + "CONFIG_ULP_COPROC_TYPE_RISCV, or CONFIG_ULP_COPROC_TYPE_LP_CORE in menuconfig.") + endif() + endif() + + if(NOT ULP_TYPE) + # If the user didn't pass TYPE here and both ULP types are enabled in sdkconfig, + # require an explicit TYPE to decide which toolchain to use. + if((CONFIG_ULP_COPROC_TYPE_RISCV STREQUAL "y") AND (CONFIG_ULP_COPROC_TYPE_FSM STREQUAL "y")) + message(FATAL_ERROR "Both CONFIG_ULP_COPROC_TYPE_FSM and CONFIG_ULP_COPROC_TYPE_RISCV are enabled " + "in menuconfig, but calling ulp_embed_binary without TYPE, so the toolchain to use " + "is ambiguous. Call ulp_embed_binary(... TYPE fsm) or ulp_embed_binary(... TYPE riscv)" + " to select the desired ULP type in your CMakeLists.txt file.") + endif() + endif() +endfunction() + function(ulp_embed_binary app_name s_sources exp_dep_srcs) - cmake_parse_arguments(ULP "" "PREFIX" "" ${ARGN}) + cmake_parse_arguments(ULP "" "PREFIX;TYPE" "" ${ARGN}) if(NOT ULP_PREFIX) set(ULP_PREFIX "ulp_") endif() + + validate_ulp_type("${ULP_TYPE}") + __setup_ulp_project("${app_name}" "${idf_path}/components/ulp/cmake" - "${ULP_PREFIX}" "${s_sources}" "${exp_dep_srcs}") + "${ULP_PREFIX}" "${ULP_TYPE}" "${s_sources}" "${exp_dep_srcs}") endfunction() function(ulp_add_project app_name project_path) - __setup_ulp_project("${app_name}" "${project_path}" "ulp_" "" "") + cmake_parse_arguments(ULP "" "PREFIX;TYPE" "" ${ARGN}) + if(NOT ULP_PREFIX) + set(ULP_PREFIX "ulp_") + endif() + + validate_ulp_type("${ULP_TYPE}") + + __setup_ulp_project("${app_name}" "${project_path}" "${ULP_PREFIX}" "${ULP_TYPE}" "" "") endfunction() diff --git a/examples/system/ulp/ulp_fsm/ulp_adc/main/CMakeLists.txt b/examples/system/ulp/ulp_fsm/ulp_adc/main/CMakeLists.txt index c53cee29d4..1b8bd324b3 100644 --- a/examples/system/ulp/ulp_fsm/ulp_adc/main/CMakeLists.txt +++ b/examples/system/ulp/ulp_fsm/ulp_adc/main/CMakeLists.txt @@ -18,4 +18,4 @@ set(ulp_exp_dep_srcs "ulp_adc_example_main.c") # # 4. Call function to build ULP binary and embed in project using the argument # values above. -ulp_embed_binary(${ulp_app_name} "${ulp_s_sources}" "${ulp_exp_dep_srcs}") +ulp_embed_binary(${ulp_app_name} "${ulp_s_sources}" "${ulp_exp_dep_srcs}" TYPE fsm)