ulp: Added ULP RISC-V support for esp32s3

This commit adds support for ULP RISC-V for esp32s3.

Signed-off-by: Sudeep Mohanty <sudeep.mohanty@espressif.com>
This commit is contained in:
Sudeep Mohanty 2021-12-23 11:42:47 +05:30 committed by Marius Vikhammer
parent 6c5fb29c2c
commit b72f987c5c
25 changed files with 400 additions and 180 deletions

View File

@ -320,6 +320,13 @@ menu "ESP32S3-Specific"
Data is reserved at the beginning of RTC slow memory.
config ESP32S3_ULP_COPROC_RISCV
bool "Enable RISC-V as ULP coprocessor"
depends on ESP32S3_ULP_COPROC_ENABLED
default n
help
Set this to y to use the RISC-V coprocessor instead of the FSM-ULP.
config ESP32S3_DEBUG_OCDAWARE
bool "Make exception and panic handlers JTAG/OCD aware"
default y

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -833,7 +833,7 @@ esp_err_t esp_sleep_disable_wakeup_source(esp_sleep_source_t source)
} else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_UART, (RTC_UART0_TRIG_EN | RTC_UART1_TRIG_EN))) {
s_config.wakeup_triggers &= ~(RTC_UART0_TRIG_EN | RTC_UART1_TRIG_EN);
}
#if defined(CONFIG_ESP32_ULP_COPROC_ENABLED) || defined(CONFIG_ESP32S2_ULP_COPROC_ENABLED)
#if defined(CONFIG_ESP32_ULP_COPROC_ENABLED) || defined(CONFIG_ESP32S2_ULP_COPROC_ENABLED) || defined(CONFIG_ESP32S3_ULP_COPROC_ENABLED)
else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_ULP, RTC_ULP_TRIG_EN)) {
s_config.wakeup_triggers &= ~RTC_ULP_TRIG_EN;
}
@ -1203,7 +1203,7 @@ esp_sleep_wakeup_cause_t esp_sleep_get_wakeup_cause(void)
} else if (wakeup_cause & RTC_BT_TRIG_EN) {
return ESP_SLEEP_WAKEUP_BT;
#endif
#if CONFIG_IDF_TARGET_ESP32S2
#if SOC_RISCV_COPROC_SUPPORTED
} else if (wakeup_cause & RTC_COCPU_TRIG_EN) {
return ESP_SLEEP_WAKEUP_ULP;
} else if (wakeup_cause & RTC_COCPU_TRAP_TRIG_EN) {

View File

@ -121,6 +121,10 @@
#define REG_SPI_MEM_BASE(i) (DR_REG_SPI0_BASE - (i) * 0x1000)
#define REG_I2C_BASE(i) (DR_REG_I2C_EXT_BASE + (i) * 0x14000 )
//Convenient way to replace the register ops when ulp riscv projects
//consume this file
#ifndef ULP_RISCV_REGISTER_OPS
//Registers Operation {{
#define ETS_UNCACHED_ADDR(addr) (addr)
#define ETS_CACHED_ADDR(addr) (addr)
@ -227,6 +231,7 @@
#endif /* !__ASSEMBLER__ */
//}}
#endif /* !ULP_RISCV_REGISTER_OPS */
//Periheral Clock {{
#define APB_CLK_FREQ_ROM (40*1000000)

View File

@ -22,6 +22,7 @@
#define SOC_CPU_CORES_NUM 2
#define SOC_CACHE_SUPPORT_WRAP 1
#define SOC_ULP_SUPPORTED 1
#define SOC_RISCV_COPROC_SUPPORTED 1
#define SOC_BT_SUPPORTED 1
#define SOC_USB_OTG_SUPPORTED 1
#define SOC_USB_SERIAL_JTAG_SUPPORTED 1

View File

@ -4,7 +4,7 @@ if(NOT (IDF_TARGET STREQUAL "esp32c3") AND NOT (IDF_TARGET STREQUAL "esp32h2"))
set(srcs "ulp.c"
"ulp_macro.c")
if(CONFIG_ESP32S2_ULP_COPROC_RISCV)
if(CONFIG_ESP32S2_ULP_COPROC_RISCV OR CONFIG_ESP32S3_ULP_COPROC_RISCV)
list(APPEND srcs "ulp_riscv.c")
endif()

View File

@ -17,10 +17,10 @@ string(REGEX MATCH "\\(GNU Binutils\\) (${version_pattern})" as_version ${as_out
set(as_version ${CMAKE_MATCH_1})
message(STATUS "Building ULP app ${ULP_APP_NAME}")
message(STATUS "Building ULP app ${ULP_APP_NAME} for ${IDF_TARGET}")
if(ULP_COCPU_IS_RISCV)
set(ULP_LD_TEMPLATE ${IDF_PATH}/components/ulp/ld/esp32s2.ulp.riscv.ld)
set(ULP_LD_TEMPLATE ${IDF_PATH}/components/ulp/ld/${IDF_TARGET}.ulp.riscv.ld)
else()
message(STATUS "ULP assembler version: ${as_version}")
@ -38,7 +38,7 @@ else()
the toolchain, or proceed at your own risk.")
endif()
set(ULP_LD_TEMPLATE ${IDF_PATH}/components/ulp/ld/esp32.ulp.ld)
set(ULP_LD_TEMPLATE ${IDF_PATH}/components/ulp/ld/ulp_fsm.ld)
endif()

View File

@ -0,0 +1,43 @@
/*
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include <stddef.h>
#include <stdlib.h>
#include "esp_err.h"
#include "ulp_common.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Run the program loaded into RTC memory
* @return ESP_OK on success
*/
esp_err_t ulp_riscv_run(void);
/**
* @brief Load ULP-RISC-V program binary into RTC memory
*
* Different than ULP FSM, the binary program has no special format, it is the ELF
* file generated by RISC-V toolchain converted to binary format using objcopy.
*
* Linker script in components/ulp/ld/esp32s3.ulp.riscv.ld produces ELF files which
* correspond to this format. This linker script produces binaries with load_addr == 0.
*
* @param program_binary pointer to program binary
* @param program_size_bytes size of the program binary
* @return
* - ESP_OK on success
* - ESP_ERR_INVALID_SIZE if program_size_bytes is more than 8KiB
*/
esp_err_t ulp_riscv_load_binary(const uint8_t* program_binary, size_t program_size_bytes);
#ifdef __cplusplus
}
#endif

View File

@ -1,20 +1,12 @@
// Copyright 2016-2018 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.
/*
* SPDX-FileCopyrightText: 2016-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
/* This file contains definitions that are common between esp32/ulp.h
and esp32s2/ulp.h
/* This file contains definitions that are common between esp32/ulp.h,
esp32s2/ulp.h and esp32s3/ulp.h
*/
#ifdef __cplusplus

View File

@ -0,0 +1,48 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "sdkconfig.h"
ENTRY(reset_vector)
MEMORY
{
ram(RW) : ORIGIN = 0, LENGTH = CONFIG_ESP32S3_ULP_COPROC_RESERVE_MEM
}
SECTIONS
{
. = ORIGIN(ram);
.text :
{
*start.S.obj(.text.vectors) /* Default reset vector must link to offset 0x0 */
*(.text)
*(.text*)
} >ram
.rodata ALIGN(4):
{
*(.rodata)
*(.rodata*)
} > ram
.data ALIGN(4):
{
*(.data)
*(.data*)
*(.sdata)
*(.sdata*)
} > ram
.bss ALIGN(4) :
{
*(.bss)
*(.bss*)
*(.sbss)
*(.sbss*)
} >ram
__stack_top = ORIGIN(ram) + LENGTH(ram);
}

View File

@ -1,7 +1,14 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "sdkconfig.h"
#if CONFIG_ESP32S2_ULP_COPROC_RESERVE_MEM
#define LOCAL_ULP_COPROC_RESERVE_MEM CONFIG_ESP32S2_ULP_COPROC_RESERVE_MEM
#elif CONFIG_ESP32S3_ULP_COPROC_RESERVE_MEM
#define LOCAL_ULP_COPROC_RESERVE_MEM CONFIG_ESP32S3_ULP_COPROC_RESERVE_MEM
#else
#define LOCAL_ULP_COPROC_RESERVE_MEM CONFIG_ESP32_ULP_COPROC_RESERVE_MEM
#endif

View File

@ -31,20 +31,19 @@ function(ulp_embed_binary app_name s_sources exp_dep_srcs)
idf_build_get_property(sdkconfig_header SDKCONFIG_HEADER)
idf_build_get_property(idf_path IDF_PATH)
idf_build_get_property(idf_target IDF_TARGET)
idf_build_get_property(python PYTHON)
idf_build_get_property(extra_cmake_args EXTRA_CMAKE_ARGS)
if(IDF_TARGET STREQUAL "esp32")
set(TOOLCHAIN_FLAG ${idf_path}/components/ulp/cmake/toolchain-esp32-ulp.cmake)
set(TOOLCHAIN_FLAG ${idf_path}/components/ulp/cmake/toolchain-${idf_target}-ulp.cmake)
set(ULP_IS_RISCV OFF)
endif()
if(IDF_TARGET STREQUAL "esp32s2")
if(CONFIG_ESP32S2_ULP_COPROC_RISCV STREQUAL "y")
set(TOOLCHAIN_FLAG ${idf_path}/components/ulp/cmake/toolchain-esp32s2-ulp-riscv.cmake)
elseif(IDF_TARGET STREQUAL "esp32s2" OR IDF_TARGET STREQUAL "esp32s3")
if(CONFIG_ESP32S2_ULP_COPROC_RISCV STREQUAL "y" OR CONFIG_ESP32S3_ULP_COPROC_RISCV STREQUAL "y")
set(TOOLCHAIN_FLAG ${idf_path}/components/ulp/cmake/toolchain-ulp-riscv.cmake)
set(ULP_IS_RISCV ON)
else()
set(TOOLCHAIN_FLAG ${idf_path}/components/ulp/cmake/toolchain-esp32s2-ulp.cmake)
set(TOOLCHAIN_FLAG ${idf_path}/components/ulp/cmake/toolchain-${idf_target}-ulp.cmake)
set(ULP_IS_RISCV OFF)
endif()
endif()
@ -60,6 +59,7 @@ function(ulp_embed_binary app_name s_sources exp_dep_srcs)
-DCOMPONENT_DIR=${COMPONENT_DIR}
-DCOMPONENT_INCLUDES=$<TARGET_PROPERTY:${COMPONENT_TARGET},INTERFACE_INCLUDE_DIRECTORIES>
-DIDF_PATH=${idf_path}
-DIDF_TARGET=${idf_target}
-DSDKCONFIG_HEADER=${SDKCONFIG_HEADER}
-DPYTHON=${python}
-DULP_COCPU_IS_RISCV=${ULP_IS_RISCV}

View File

@ -1,16 +1,18 @@
if(IDF_TARGET STREQUAL "esp32s3")
return()
if(IDF_TARGET STREQUAL "esp32")
set(src_dirs ${IDF_TARGET})
set(ulp_sources "ulp/test_jumps_esp32.S")
elseif(IDF_TARGET STREQUAL "esp32s2" OR IDF_TARGET STREQUAL "esp32s3")
if(CONFIG_ESP32S2_ULP_COPROC_RISCV STREQUAL "y" OR CONFIG_ESP32S3_ULP_COPROC_RISCV STREQUAL "y")
set(src_dirs "ulp_riscv")
set(ulp_sources "ulp_riscv/ulp/test_main.c")
endif()
#TODO: Add ULP-FSM Test case for esp32s2 and esp32s3
endif()
idf_component_register(SRC_DIRS ${IDF_TARGET}
idf_component_register(SRC_DIRS ${src_dirs}
PRIV_INCLUDE_DIRS .
PRIV_REQUIRES cmock ulp soc esp_common driver)
if(IDF_TARGET STREQUAL "esp32")
set(ulp_sources "ulp/test_jumps_esp32.S")
elseif(IDF_TARGET STREQUAL "esp32s2")
set(ulp_sources "ulp_riscv/test_main.c")
endif()
set(ulp_app_name ulp_test_app)
set(ulp_exp_dep_srcs ${IDF_TARGET})
set(ulp_exp_dep_srcs ${src_dirs})
ulp_embed_binary(${ulp_app_name} "${ulp_sources}" "${ulp_exp_dep_srcs}")

View File

@ -1,70 +0,0 @@
// Copyright 2010-2020 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.
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include "ulp_riscv/ulp_riscv.h"
#include "ulp_riscv/ulp_riscv_utils.h"
typedef enum{
RISCV_READ_WRITE_TEST = 1,
RISCV_DEEP_SLEEP_WAKEUP_TEST,
RISCV_LIGHT_SLEEP_WAKEUP_TEST,
RISCV_NO_COMMAND,
} riscv_test_commands_t;
typedef enum {
RISCV_COMMAND_OK = 1,
RISCV_COMMAND_NOK,
RISCV_COMMAND_INVALID,
} riscv_test_command_reply_t;
#define XOR_MASK 0xDEADBEEF
volatile riscv_test_commands_t main_cpu_command = RISCV_NO_COMMAND;
volatile riscv_test_command_reply_t main_cpu_reply = RISCV_COMMAND_INVALID;
volatile uint32_t riscv_test_data_in = 0;
volatile uint32_t riscv_test_data_out = 0;
void handle_commands(riscv_test_commands_t cmd)
{
switch (cmd) {
case RISCV_READ_WRITE_TEST:
riscv_test_data_out =riscv_test_data_in ^ XOR_MASK;
main_cpu_reply = RISCV_COMMAND_OK;
break;
case RISCV_DEEP_SLEEP_WAKEUP_TEST:
case RISCV_LIGHT_SLEEP_WAKEUP_TEST:
main_cpu_reply = RISCV_COMMAND_OK;
break;
default:
main_cpu_reply = RISCV_COMMAND_NOK;
break;
}
ulp_riscv_wakeup_main_processor();
}
int main (void)
{
while (1) {
handle_commands(main_cpu_command);
break;
}
/* ulp_riscv_shutdown() is called automatically when main exits */
return 0;
}

View File

@ -1,16 +1,8 @@
// Copyright 2010-2020 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.
/*
* SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include <string.h>
@ -18,10 +10,16 @@
#include "soc/rtc_cntl_reg.h"
#include "soc/sens_reg.h"
#include "soc/rtc_periph.h"
#if CONFIG_IDF_TARGET_ESP32S2
#include "esp32s2/ulp.h"
#include "esp32s2/ulp_riscv.h"
#elif CONFIG_IDF_TARGET_ESP32S3
#include "esp32s3/ulp.h"
#include "esp32s3/ulp_riscv.h"
#endif
#include "ulp_test_app.h"
#include "unity.h"
#include <sys/time.h>
typedef enum{
RISCV_READ_WRITE_TEST = 1,
@ -33,9 +31,11 @@ typedef enum{
typedef enum {
RISCV_COMMAND_OK = 1,
RISCV_COMMAND_NOK,
RISCV_COMMAND_INVALID,
} riscv_test_command_reply_t;
#define XOR_MASK 0xDEADBEEF
#define ULP_WAKEUP_PERIOD 1000000 // 1 second
extern const uint8_t ulp_main_bin_start[] asm("_binary_ulp_test_app_bin_start");
extern const uint8_t ulp_main_bin_end[] asm("_binary_ulp_test_app_bin_end");
@ -47,7 +47,7 @@ static void load_and_start_ulp_firmware(void)
TEST_ASSERT(ulp_riscv_load_binary(ulp_main_bin_start,
(ulp_main_bin_end - ulp_main_bin_start)) == ESP_OK);
TEST_ASSERT(ulp_set_wakeup_period(0, 1000000) == ESP_OK);
TEST_ASSERT(ulp_set_wakeup_period(0, ULP_WAKEUP_PERIOD) == ESP_OK);
TEST_ASSERT(ulp_riscv_run() == ESP_OK);
firmware_loaded = true;
@ -57,37 +57,87 @@ static void load_and_start_ulp_firmware(void)
TEST_CASE("ULP-RISC-V and main CPU are able to exchange data", "[ulp][ignore]")
{
const uint32_t test_data = 0x12345678;
struct timeval start, end;
/* Load ULP RISC-V firmware and start the ULP RISC-V Coprocessor */
load_and_start_ulp_firmware();
/* Setup wakeup triggers */
TEST_ASSERT(esp_sleep_enable_ulp_wakeup() == ESP_OK);
/* Setup test data */
ulp_riscv_test_data_in = test_data ^ XOR_MASK;
ulp_main_cpu_command = RISCV_READ_WRITE_TEST;
/* Enter Light Sleep */
TEST_ASSERT(esp_light_sleep_start() == ESP_OK);
TEST_ASSERT(esp_sleep_get_wakeup_cause() == ESP_SLEEP_WAKEUP_ULP);
TEST_ASSERT(ulp_main_cpu_reply == RISCV_COMMAND_OK);
/* Wait for wakeup from ULP RISC-V Coprocessor */
TEST_ASSERT(esp_sleep_get_wakeup_cause() == ESP_SLEEP_WAKEUP_ULP);
/* Wait till we receive the correct command response */
gettimeofday(&start, NULL);
while (ulp_command_resp != RISCV_READ_WRITE_TEST)
;
gettimeofday(&end, NULL);
printf("Response time %ld ms\n", (end.tv_sec - start.tv_sec) * 1000 + (end.tv_usec - start.tv_usec) / 1000);
/* Verify test data */
TEST_ASSERT(ulp_command_resp == RISCV_READ_WRITE_TEST);
TEST_ASSERT(ulp_main_cpu_reply == RISCV_COMMAND_OK);
printf("data out: 0x%X, expected: 0x%X \n", ulp_riscv_test_data_out, test_data);
TEST_ASSERT(test_data == ulp_riscv_test_data_out);
/* Clear test data */
ulp_main_cpu_command = RISCV_NO_COMMAND;
}
TEST_CASE("ULP-RISC-V is able to wakeup main CPU from light sleep", "[ulp][ignore]")
{
struct timeval start, end;
/* Load ULP RISC-V firmware and start the ULP RISC-V Coprocessor */
load_and_start_ulp_firmware();
/* Setup wakeup triggers */
TEST_ASSERT(esp_sleep_enable_ulp_wakeup() == ESP_OK);
/* Setup test data */
ulp_main_cpu_command = RISCV_LIGHT_SLEEP_WAKEUP_TEST;
/* Enter Light Sleep */
TEST_ASSERT(esp_light_sleep_start() == ESP_OK);
/* Wait for wakeup from ULP RISC-V Coprocessor */
TEST_ASSERT(esp_sleep_get_wakeup_cause() == ESP_SLEEP_WAKEUP_ULP);
/* Wait till we receive the correct command response */
gettimeofday(&start, NULL);
while (ulp_command_resp != RISCV_LIGHT_SLEEP_WAKEUP_TEST)
;
gettimeofday(&end, NULL);
printf("Response time %ld ms\n", (end.tv_sec - start.tv_sec) * 1000 + (end.tv_usec - start.tv_usec) / 1000);
/* Verify test data */
TEST_ASSERT(ulp_command_resp == RISCV_LIGHT_SLEEP_WAKEUP_TEST);
TEST_ASSERT(ulp_main_cpu_reply == RISCV_COMMAND_OK);
/* Clear test data */
ulp_main_cpu_command = RISCV_NO_COMMAND;
}
TEST_CASE("ULP-RISC-V is able to wakeup main CPU from deep sleep", "[ulp][reset=SW_CPU_RESET][ignore]")
{
/* Load ULP RISC-V firmware and start the ULP RISC-V Coprocessor */
load_and_start_ulp_firmware();
/* Setup wakeup triggers */
TEST_ASSERT(esp_sleep_enable_ulp_wakeup() == ESP_OK);
/* Setup test data */
ulp_main_cpu_command = RISCV_DEEP_SLEEP_WAKEUP_TEST;
/* Enter Deep Sleep */
esp_deep_sleep_start();
UNITY_TEST_FAIL(__LINE__, "Should not get here!");
}

View File

@ -0,0 +1,92 @@
/*
* SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include "ulp_riscv/ulp_riscv.h"
#include "ulp_riscv/ulp_riscv_utils.h"
typedef enum{
RISCV_READ_WRITE_TEST = 1,
RISCV_DEEP_SLEEP_WAKEUP_TEST,
RISCV_LIGHT_SLEEP_WAKEUP_TEST,
RISCV_NO_COMMAND,
} riscv_test_commands_t;
typedef enum {
RISCV_COMMAND_OK = 1,
RISCV_COMMAND_NOK,
RISCV_COMMAND_INVALID,
} riscv_test_command_reply_t;
#define XOR_MASK 0xDEADBEEF
volatile riscv_test_commands_t main_cpu_command = RISCV_NO_COMMAND;
volatile riscv_test_command_reply_t main_cpu_reply = RISCV_COMMAND_INVALID;
volatile riscv_test_commands_t command_resp = RISCV_NO_COMMAND;
volatile uint32_t riscv_test_data_in = 0;
volatile uint32_t riscv_test_data_out = 0;
void handle_commands(riscv_test_commands_t cmd)
{
switch (cmd) {
case RISCV_READ_WRITE_TEST:
/* Echo the command ID back to the main CPU */
command_resp = RISCV_READ_WRITE_TEST;
/* Process test data */
riscv_test_data_out = riscv_test_data_in ^ XOR_MASK;
/* Set the command reply status */
main_cpu_reply = RISCV_COMMAND_OK;
/* Wakeup the main CPU */
ulp_riscv_wakeup_main_processor();
break;
case RISCV_DEEP_SLEEP_WAKEUP_TEST:
/* Echo the command ID back to the main CPU */
command_resp = RISCV_DEEP_SLEEP_WAKEUP_TEST;
/* Set the command reply status */
main_cpu_reply = RISCV_COMMAND_OK;
/* Wakeup the main CPU */
ulp_riscv_wakeup_main_processor();
break;
case RISCV_LIGHT_SLEEP_WAKEUP_TEST:
/* Echo the command ID back to the main CPU */
command_resp = RISCV_LIGHT_SLEEP_WAKEUP_TEST;
/* Set the command reply status */
main_cpu_reply = RISCV_COMMAND_OK;
/* Wakeup the main CPU */
ulp_riscv_wakeup_main_processor();
break;
case RISCV_NO_COMMAND:
main_cpu_reply = RISCV_COMMAND_OK;
break;
default:
main_cpu_reply = RISCV_COMMAND_NOK;
break;
}
}
int main (void)
{
while (1) {
handle_commands(main_cpu_command);
break;
}
/* ulp_riscv_shutdown() is called automatically when main exits */
return 0;
}

View File

@ -1,16 +1,8 @@
// Copyright 2010-2016 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.
/*
* SPDX-FileCopyrightText: 2010-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include <string.h>
@ -69,7 +61,7 @@ esp_err_t ulp_run(uint32_t entry_point)
SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BIAS_SLEEP_FOLW_8M);
// enable ULP timer
SET_PERI_REG_MASK(RTC_CNTL_STATE0_REG, RTC_CNTL_ULP_CP_SLP_TIMER_EN);
#elif defined CONFIG_IDF_TARGET_ESP32S2
#elif defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3)
// disable ULP timer
CLEAR_PERI_REG_MASK(RTC_CNTL_ULP_CP_TIMER_REG, RTC_CNTL_ULP_CP_SLP_TIMER_EN);
// wait for at least 1 RTC_SLOW_CLK cycle
@ -154,7 +146,7 @@ esp_err_t ulp_set_wakeup_period(size_t period_index, uint32_t period_us)
}
REG_SET_FIELD(SENS_ULP_CP_SLEEP_CYC0_REG + period_index * sizeof(uint32_t),
SENS_SLEEP_CYCLES_S0, (uint32_t) period_cycles);
#elif defined CONFIG_IDF_TARGET_ESP32S2
#elif defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3)
if (period_index > 4) {
return ESP_ERR_INVALID_ARG;
}

View File

@ -1,16 +1,8 @@
// Copyright 2020 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.
/*
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include <string.h>
@ -19,9 +11,15 @@
#include "esp_attr.h"
#include "esp_err.h"
#include "esp_log.h"
#if CONFIG_IDF_TARGET_ESP32S2
#include "esp32s2/clk.h"
#include "esp32s2/ulp.h"
#include "esp32s2/ulp_riscv.h"
#elif CONFIG_IDF_TARGET_ESP32S3
#include "esp32s3/clk.h"
#include "esp32s3/ulp.h"
#include "esp32s3/ulp_riscv.h"
#endif
#include "soc/soc.h"
#include "soc/rtc.h"
#include "soc/rtc_cntl_reg.h"
@ -31,6 +29,7 @@
esp_err_t ulp_riscv_run(void)
{
#if CONFIG_IDF_TARGET_ESP32S2
/* Reset COCPU when power on. */
SET_PERI_REG_MASK(RTC_CNTL_COCPU_CTRL_REG, RTC_CNTL_COCPU_SHUT_RESET_EN);
esp_rom_delay_us(20);
@ -55,6 +54,48 @@ esp_err_t ulp_riscv_run(void)
SET_PERI_REG_MASK(RTC_CNTL_ULP_CP_TIMER_REG, RTC_CNTL_ULP_CP_SLP_TIMER_EN);
return ESP_OK;
#elif CONFIG_IDF_TARGET_ESP32S3
/* Reset COCPU when power on. */
SET_PERI_REG_MASK(RTC_CNTL_COCPU_CTRL_REG, RTC_CNTL_COCPU_CLK_FO);
SET_PERI_REG_MASK(RTC_CNTL_COCPU_CTRL_REG, RTC_CNTL_COCPU_SHUT_RESET_EN);
esp_rom_delay_us(20);
CLEAR_PERI_REG_MASK(RTC_CNTL_COCPU_CTRL_REG, RTC_CNTL_COCPU_CLK_FO);
CLEAR_PERI_REG_MASK(RTC_CNTL_COCPU_CTRL_REG, RTC_CNTL_COCPU_SHUT_RESET_EN);
/* Disable ULP timer */
CLEAR_PERI_REG_MASK(RTC_CNTL_ULP_CP_TIMER_REG, RTC_CNTL_ULP_CP_SLP_TIMER_EN);
/* wait for at least 1 RTC_SLOW_CLK cycle */
esp_rom_delay_us(20);
/* We do not select RISC-V as the Coprocessor here as this could lead to a hang
* in the main CPU. Instead, we reset RTC_CNTL_COCPU_SEL after we have enabled the ULP timer.
*
* IDF-4510
*/
//CLEAR_PERI_REG_MASK(RTC_CNTL_COCPU_CTRL_REG, RTC_CNTL_COCPU_SEL);
/* Select ULP-RISC-V to send the DONE signal */
SET_PERI_REG_MASK(RTC_CNTL_COCPU_CTRL_REG, RTC_CNTL_COCPU_DONE_FORCE);
/* Set the CLKGATE_EN signal */
SET_PERI_REG_MASK(RTC_CNTL_COCPU_CTRL_REG, RTC_CNTL_COCPU_CLKGATE_EN);
/* start ULP_TIMER */
CLEAR_PERI_REG_MASK(RTC_CNTL_ULP_CP_CTRL_REG, RTC_CNTL_ULP_CP_FORCE_START_TOP);
SET_PERI_REG_MASK(RTC_CNTL_ULP_CP_TIMER_REG, RTC_CNTL_ULP_CP_SLP_TIMER_EN);
/* Select RISC-V as the ULP_TIMER trigger target
* Selecting the RISC-V as the Coprocessor at the end is a workaround
* for the hang issue recorded in IDF-4510.
*/
CLEAR_PERI_REG_MASK(RTC_CNTL_COCPU_CTRL_REG, RTC_CNTL_COCPU_SEL);
/* Clear any spurious wakeup trigger interrupts upon ULP startup */
esp_rom_delay_us(20);
REG_WRITE(RTC_CNTL_INT_CLR_REG, RTC_CNTL_COCPU_INT_CLR | RTC_CNTL_COCPU_TRAP_INT_CLR | RTC_CNTL_ULP_CP_INT_CLR);
return ESP_OK;
#endif
}
esp_err_t ulp_riscv_load_binary(const uint8_t* program_binary, size_t program_size_bytes)

View File

@ -1,16 +1,8 @@
// Copyright 2010-2020 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.
/*
* SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
@ -55,7 +47,11 @@ typedef enum {
static inline void ulp_riscv_gpio_init(gpio_num_t gpio_num)
{
#if CONFIG_IDF_TARGET_ESP32S2
SET_PERI_REG_MASK(SENS_SAR_IO_MUX_CONF_REG, SENS_IOMUX_CLK_GATE_EN_M);
#elif CONFIG_IDF_TARGET_ESP32S3
SET_PERI_REG_MASK(SENS_SAR_PERI_CLK_GATE_CONF_REG, SENS_IOMUX_CLK_EN_M);
#endif
SET_PERI_REG_MASK(RTC_IO_TOUCH_PAD0_REG + gpio_num*4, RTC_IO_TOUCH_PAD0_MUX_SEL);
REG_SET_FIELD(RTC_IO_TOUCH_PAD0_REG + gpio_num*4, RTC_IO_TOUCH_PAD0_FUN_SEL, 0);
}

View File

@ -1,16 +1,8 @@
// Copyright 2015-2020 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.
/*
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
@ -63,10 +55,14 @@ void __attribute__((noreturn)) ulp_riscv_shutdown(void);
__ccount; })
#if CONFIG_IDF_TARGET_ESP32S2
/* These are only approximate default numbers, the default frequency
of the 8M oscillator is 8.5MHz +/- 5%, at the default DCAP setting
*/
#define ULP_RISCV_CYCLES_PER_US 8.5
#elif CONFIG_IDF_TARGET_ESP32S3
#define ULP_RISCV_CYCLES_PER_US 17.5
#endif
#define ULP_RISCV_CYCLES_PER_MS ULP_RISCV_CYCLES_PER_US*1000
/**

View File

@ -8,6 +8,8 @@ INPUT += \
$(PROJECT_PATH)/components/driver/include/driver/pcnt.h \
$(PROJECT_PATH)/components/soc/$(IDF_TARGET)/include/soc/touch_sensor_channel.h \
$(PROJECT_PATH)/components/driver/$(IDF_TARGET)/include/driver/touch_sensor.h \
$(PROJECT_PATH)/components/ulp/include/esp32s3/ulp_riscv.h \
$(PROJECT_PATH)/components/ulp/include/$(IDF_TARGET)/ulp.h \
$(PROJECT_PATH)/components/usb/include/usb/usb_helpers.h \
$(PROJECT_PATH)/components/usb/include/usb/usb_host.h \
$(PROJECT_PATH)/components/usb/include/usb/usb_types_ch9.h \

View File

@ -39,7 +39,7 @@ API 指南
工具 <tools/index>
:SOC_ULP_SUPPORTED: ULP 协处理器 <ulp>
:esp32: ULP (传统 GNU Make) <ulp-legacy>
:esp32s2: ULP-RISC-V 协处理器 <ulp-risc-v>
:SOC_RISCV_COPROC_SUPPORTED: ULP-RISC-V 协处理器 <ulp-risc-v>
单元测试 (Target) <unit-tests>
单元测试 (Linux Host) <linux-host-testing>
:esp32: 单元测试 (传统 GNU Make) <unit-tests-legacy>

View File

@ -2,5 +2,11 @@
# in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)
if(NOT IDF_TARGET STREQUAL "esp32s2")
#IDF-4514
message(FATAL_ERROR "DO NOT BUILD THIS APP FOR ANY TARGET OTHER THAN ESP32-S2 OTHERWISE YOU MAY BRICK YOUR DEVICE")
return()
endif()
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(ulp_riscv_ds18b20_example)

View File

@ -2,5 +2,11 @@
# in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)
if(NOT IDF_TARGET STREQUAL "esp32s2")
#IDF-4514
message(FATAL_ERROR "DO NOT BUILD THIS APP FOR ANY TARGET OTHER THAN ESP32-S2 OTHERWISE YOU MAY BRICK YOUR DEVICE")
return()
endif()
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(ulp_riscv_example)

View File

@ -1 +1,5 @@
CONFIG_ESP32S3_DEFAULT_CPU_FREQ_240=y
CONFIG_ESP32S3_ULP_COPROC_ENABLED=y
CONFIG_ESP32S3_ULP_COPROC_RISCV=y
CONFIG_ESP32S3_ULP_COPROC_RESERVE_MEM=4096