mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'feature/ulp_stop' into 'master'
ULP: add functions for stopping/restarting the ulp-riscv Closes IDFGH-6588 See merge request espressif/esp-idf!16853
This commit is contained in:
commit
cbe23087fc
@ -33,3 +33,29 @@ esp_err_t ulp_riscv_run(void);
|
||||
* - 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);
|
||||
|
||||
/**
|
||||
* @brief Stop the ULP timer
|
||||
*
|
||||
* @note This will stop the ULP from waking up if halted, but will not abort any program
|
||||
* currently executing on the ULP.
|
||||
*/
|
||||
void ulp_riscv_timer_stop(void);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Resumes the ULP timer
|
||||
*
|
||||
* @note This will resume an already configured timer, but does no other configuration
|
||||
*
|
||||
*/
|
||||
void ulp_riscv_timer_resume(void);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Halts the program currently running on the ULP-RISC-V
|
||||
*
|
||||
* @note Program will restart at the next ULP timer trigger if timer is still running.
|
||||
* If you want to stop the ULP from waking up then call ulp_riscv_timer_stop() first.
|
||||
*/
|
||||
void ulp_riscv_halt(void);
|
||||
|
@ -38,6 +38,32 @@ esp_err_t ulp_riscv_run(void);
|
||||
*/
|
||||
esp_err_t ulp_riscv_load_binary(const uint8_t* program_binary, size_t program_size_bytes);
|
||||
|
||||
/**
|
||||
* @brief Stop the ULP timer
|
||||
*
|
||||
* @note This will stop the ULP from waking up if halted, but will not abort any program
|
||||
* currently executing on the ULP.
|
||||
*/
|
||||
void ulp_riscv_timer_stop(void);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Resumes the ULP timer
|
||||
*
|
||||
* @note This will resume an already configured timer, but does no other configuration
|
||||
*
|
||||
*/
|
||||
void ulp_riscv_timer_resume(void);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Halts the program currently running on the ULP-RISC-V
|
||||
*
|
||||
* @note Program will restart at the next ULP timer trigger if timer is still running.
|
||||
* If you want to stop the ULP from waking up then call ulp_riscv_timer_stop() first.
|
||||
*/
|
||||
void ulp_riscv_halt(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -20,11 +20,14 @@
|
||||
#include "ulp_test_app.h"
|
||||
#include "unity.h"
|
||||
#include <sys/time.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
typedef enum{
|
||||
RISCV_READ_WRITE_TEST = 1,
|
||||
RISCV_DEEP_SLEEP_WAKEUP_TEST,
|
||||
RISCV_LIGHT_SLEEP_WAKEUP_TEST,
|
||||
RISCV_STOP_TEST,
|
||||
RISCV_NO_COMMAND,
|
||||
} riscv_test_commands_t;
|
||||
|
||||
@ -54,7 +57,7 @@ static void load_and_start_ulp_firmware(void)
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("ULP-RISC-V and main CPU are able to exchange data", "[ulp][ignore]")
|
||||
TEST_CASE("ULP-RISC-V and main CPU are able to exchange data", "[ulp]")
|
||||
{
|
||||
const uint32_t test_data = 0x12345678;
|
||||
struct timeval start, end;
|
||||
@ -92,7 +95,7 @@ TEST_CASE("ULP-RISC-V and main CPU are able to exchange data", "[ulp][ignore]")
|
||||
ulp_main_cpu_command = RISCV_NO_COMMAND;
|
||||
}
|
||||
|
||||
TEST_CASE("ULP-RISC-V is able to wakeup main CPU from light sleep", "[ulp][ignore]")
|
||||
TEST_CASE("ULP-RISC-V is able to wakeup main CPU from light sleep", "[ulp]")
|
||||
{
|
||||
struct timeval start, end;
|
||||
|
||||
@ -141,3 +144,64 @@ TEST_CASE("ULP-RISC-V is able to wakeup main CPU from deep sleep", "[ulp][reset=
|
||||
esp_deep_sleep_start();
|
||||
UNITY_TEST_FAIL(__LINE__, "Should not get here!");
|
||||
}
|
||||
|
||||
static bool ulp_riscv_is_running(void)
|
||||
{
|
||||
uint32_t start_cnt = ulp_riscv_counter;
|
||||
|
||||
/* Wait a few ULP wakeup cycles to ensure ULP has run */
|
||||
vTaskDelay((5 * ULP_WAKEUP_PERIOD / 1000) / portTICK_PERIOD_MS);
|
||||
|
||||
uint32_t end_cnt = ulp_riscv_counter;
|
||||
printf("start run count: %d, end run count %d\n", start_cnt, end_cnt);
|
||||
|
||||
/* If the ulp is running the counter should have been incremented */
|
||||
return (start_cnt != end_cnt);
|
||||
}
|
||||
|
||||
TEST_CASE("ULP-RISC-V can be stopped and resumed from main CPU", "[ulp]")
|
||||
{
|
||||
/* Load ULP RISC-V firmware and start the ULP RISC-V Coprocessor */
|
||||
load_and_start_ulp_firmware();
|
||||
|
||||
TEST_ASSERT(ulp_riscv_is_running());
|
||||
|
||||
printf("Stopping the ULP\n");
|
||||
ulp_riscv_timer_stop();
|
||||
ulp_riscv_halt();
|
||||
|
||||
TEST_ASSERT(!ulp_riscv_is_running());
|
||||
|
||||
printf("Resuming the ULP\n");
|
||||
ulp_riscv_timer_resume();
|
||||
|
||||
TEST_ASSERT(ulp_riscv_is_running());
|
||||
}
|
||||
|
||||
TEST_CASE("ULP-RISC-V can stop itself and be resumed from the main CPU", "[ulp]")
|
||||
{
|
||||
volatile riscv_test_commands_t *command_resp = &ulp_command_resp;
|
||||
|
||||
/* Load ULP RISC-V firmware and start the ULP RISC-V Coprocessor */
|
||||
load_and_start_ulp_firmware();
|
||||
|
||||
TEST_ASSERT(ulp_riscv_is_running());
|
||||
|
||||
printf("Stopping the ULP\n");
|
||||
/* Setup test data */
|
||||
ulp_main_cpu_command = RISCV_STOP_TEST;
|
||||
|
||||
while (*command_resp != RISCV_STOP_TEST) {
|
||||
}
|
||||
|
||||
/* Wait a bit to ensure ULP finished shutting down */
|
||||
vTaskDelay(100 / portTICK_PERIOD_MS);
|
||||
|
||||
TEST_ASSERT(!ulp_riscv_is_running());
|
||||
|
||||
printf("Resuming the ULP\n");
|
||||
ulp_main_cpu_command = RISCV_NO_COMMAND;
|
||||
ulp_riscv_timer_resume();
|
||||
|
||||
TEST_ASSERT(ulp_riscv_is_running());
|
||||
}
|
||||
|
@ -9,11 +9,13 @@
|
||||
#include <stdbool.h>
|
||||
#include "ulp_riscv/ulp_riscv.h"
|
||||
#include "ulp_riscv/ulp_riscv_utils.h"
|
||||
#include "ulp_riscv/ulp_riscv_gpio.h"
|
||||
|
||||
typedef enum{
|
||||
RISCV_READ_WRITE_TEST = 1,
|
||||
RISCV_DEEP_SLEEP_WAKEUP_TEST,
|
||||
RISCV_LIGHT_SLEEP_WAKEUP_TEST,
|
||||
RISCV_STOP_TEST,
|
||||
RISCV_NO_COMMAND,
|
||||
} riscv_test_commands_t;
|
||||
|
||||
@ -30,9 +32,12 @@ 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;
|
||||
volatile uint32_t riscv_counter = 0;
|
||||
|
||||
void handle_commands(riscv_test_commands_t cmd)
|
||||
{
|
||||
riscv_counter++;
|
||||
|
||||
switch (cmd) {
|
||||
case RISCV_READ_WRITE_TEST:
|
||||
/* Echo the command ID back to the main CPU */
|
||||
@ -70,6 +75,19 @@ void handle_commands(riscv_test_commands_t cmd)
|
||||
ulp_riscv_wakeup_main_processor();
|
||||
break;
|
||||
|
||||
case RISCV_STOP_TEST:
|
||||
/* Echo the command ID back to the main CPU */
|
||||
command_resp = RISCV_STOP_TEST;
|
||||
|
||||
/* Set the command reply status */
|
||||
main_cpu_reply = RISCV_COMMAND_OK;
|
||||
|
||||
/* Will never return from here */
|
||||
ulp_riscv_timer_stop();
|
||||
ulp_riscv_halt();
|
||||
|
||||
break;
|
||||
|
||||
case RISCV_NO_COMMAND:
|
||||
main_cpu_reply = RISCV_COMMAND_OK;
|
||||
break;
|
||||
@ -87,6 +105,6 @@ int main (void)
|
||||
break;
|
||||
}
|
||||
|
||||
/* ulp_riscv_shutdown() is called automatically when main exits */
|
||||
/* ulp_riscv_halt() is called automatically when main exits */
|
||||
return 0;
|
||||
}
|
||||
|
@ -97,6 +97,27 @@ esp_err_t ulp_riscv_run(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
void ulp_riscv_timer_stop(void)
|
||||
{
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_ULP_CP_TIMER_REG, RTC_CNTL_ULP_CP_SLP_TIMER_EN);
|
||||
}
|
||||
|
||||
void ulp_riscv_timer_resume(void)
|
||||
{
|
||||
SET_PERI_REG_MASK(RTC_CNTL_ULP_CP_TIMER_REG, RTC_CNTL_ULP_CP_SLP_TIMER_EN);
|
||||
}
|
||||
|
||||
void ulp_riscv_halt(void)
|
||||
{
|
||||
ulp_riscv_timer_stop();
|
||||
|
||||
/* suspends the ulp operation*/
|
||||
SET_PERI_REG_MASK(RTC_CNTL_COCPU_CTRL_REG, RTC_CNTL_COCPU_DONE);
|
||||
|
||||
/* Resets the processor */
|
||||
SET_PERI_REG_MASK(RTC_CNTL_COCPU_CTRL_REG, RTC_CNTL_COCPU_SHUT_RESET_EN);
|
||||
}
|
||||
|
||||
esp_err_t ulp_riscv_load_binary(const uint8_t* program_binary, size_t program_size_bytes)
|
||||
{
|
||||
if (program_binary == NULL) {
|
||||
|
@ -43,12 +43,34 @@ void ulp_riscv_rescue_from_monitor(void);
|
||||
* @note Returning from main() in the ULP program results on
|
||||
* calling this function.
|
||||
*
|
||||
* @note To stop the ULP from waking up, call ulp_riscv_timer_stop()
|
||||
* before halting.
|
||||
*
|
||||
* This function should be called after the ULP program Finishes
|
||||
* its processing, it will trigger the timer for the next wakeup,
|
||||
* put the ULP in monitor mode and triggers a reset.
|
||||
*
|
||||
*/
|
||||
void __attribute__((noreturn)) ulp_riscv_shutdown(void);
|
||||
void __attribute__((noreturn)) ulp_riscv_halt(void);
|
||||
|
||||
#define ulp_riscv_shutdown ulp_riscv_halt
|
||||
|
||||
/**
|
||||
* @brief Stop the ULP timer
|
||||
*
|
||||
* @note This will stop the ULP from waking up if halted, but will not abort any program
|
||||
* currently executing on the ULP.
|
||||
*/
|
||||
void ulp_riscv_timer_stop(void);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Resumes the ULP timer
|
||||
*
|
||||
* @note This will resume an already configured timer, but does no other configuration
|
||||
*
|
||||
*/
|
||||
void ulp_riscv_timer_resume(void);
|
||||
|
||||
#define ULP_RISCV_GET_CCOUNT() ({ int __ccount; \
|
||||
asm volatile("rdcycle %0;" : "=r"(__ccount)); \
|
||||
|
@ -18,6 +18,6 @@ __start:
|
||||
la sp, __stack_top
|
||||
call ulp_riscv_rescue_from_monitor
|
||||
call main
|
||||
call ulp_riscv_shutdown
|
||||
call ulp_riscv_halt
|
||||
loop:
|
||||
j loop
|
||||
|
@ -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
|
||||
*/
|
||||
|
||||
#include "ulp_riscv/ulp_riscv.h"
|
||||
#include "ulp_riscv/ulp_riscv_utils.h"
|
||||
@ -26,7 +18,7 @@ void ulp_riscv_wakeup_main_processor(void)
|
||||
SET_PERI_REG_MASK(RTC_CNTL_STATE0_REG, RTC_CNTL_SW_CPU_INT);
|
||||
}
|
||||
|
||||
void ulp_riscv_shutdown(void)
|
||||
void ulp_riscv_halt(void)
|
||||
{
|
||||
/* Setting the delay time after RISCV recv `DONE` signal, Ensure that action `RESET` can be executed in time. */
|
||||
REG_SET_FIELD(RTC_CNTL_COCPU_CTRL_REG, RTC_CNTL_COCPU_SHUT_2_CLK_DIS, 0x3F);
|
||||
@ -48,3 +40,13 @@ void ulp_riscv_delay_cycles(uint32_t cycles)
|
||||
/* Wait */
|
||||
}
|
||||
}
|
||||
|
||||
void ulp_riscv_timer_stop(void)
|
||||
{
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_ULP_CP_TIMER_REG, RTC_CNTL_ULP_CP_SLP_TIMER_EN);
|
||||
}
|
||||
|
||||
void ulp_riscv_timer_resume(void)
|
||||
{
|
||||
SET_PERI_REG_MASK(RTC_CNTL_ULP_CP_TIMER_REG, RTC_CNTL_ULP_CP_SLP_TIMER_EN);
|
||||
}
|
||||
|
@ -148,7 +148,7 @@ int main (void)
|
||||
break;
|
||||
}
|
||||
|
||||
/* ulp_riscv_shutdown() is called automatically when main exits,
|
||||
/* ulp_riscv_halt() is called automatically when main exits,
|
||||
main will be executed again at the next timeout period,
|
||||
according to ulp_set_wakeup_period()
|
||||
*/
|
||||
|
@ -36,6 +36,6 @@ int main (void)
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* ulp_riscv_shutdown() is called automatically when main exits */
|
||||
/* ulp_riscv_halt() is called automatically when main exits */
|
||||
return 0;
|
||||
}
|
||||
|
@ -2069,7 +2069,6 @@ components/ulp/ulp_macro.c
|
||||
components/ulp/ulp_private.h
|
||||
components/ulp/ulp_riscv/include/ulp_riscv/ulp_riscv.h
|
||||
components/ulp/ulp_riscv/include/ulp_riscv/ulp_riscv_register_ops.h
|
||||
components/ulp/ulp_riscv/ulp_riscv_utils.c
|
||||
components/unity/include/priv/setjmp.h
|
||||
components/unity/include/unity_config.h
|
||||
components/unity/include/unity_fixture_extras.h
|
||||
|
Loading…
x
Reference in New Issue
Block a user