mirror of
https://github.com/espressif/esp-idf
synced 2025-03-10 01:29:21 -04:00
Merge branch 'bugfix/ulp_rtc_i2c_doesnt_work_with_interrupts' into 'master'
RTC I2C does not work when interrupts are enabled on ULP RISC-V See merge request espressif/esp-idf!28844
This commit is contained in:
commit
f65a55952c
@ -43,6 +43,13 @@ menu "Ultra Low Power (ULP) Co-processor"
|
||||
menu "ULP RISC-V Settings"
|
||||
depends on ULP_COPROC_TYPE_RISCV
|
||||
|
||||
config ULP_RISCV_INTERRUPT_ENABLE
|
||||
bool
|
||||
prompt "Enable ULP RISC-V interrupts"
|
||||
default "n"
|
||||
help
|
||||
Turn on this setting to enabled interrupts on the ULP RISC-V core.
|
||||
|
||||
config ULP_RISCV_UART_BAUDRATE
|
||||
int
|
||||
prompt "Baudrate used by the bitbanged ULP RISC-V UART driver"
|
||||
|
@ -3,6 +3,10 @@ cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
list(PREPEND SDKCONFIG_DEFAULTS "$ENV{IDF_PATH}/tools/test_apps/configs/sdkconfig.debug_helpers" "sdkconfig.defaults")
|
||||
|
||||
set(EXTRA_COMPONENT_DIRS
|
||||
"$ENV{IDF_PATH}/tools/unit-test-app/components"
|
||||
)
|
||||
|
||||
# "Trim" the build. Include the minimal set of components, main, and anything it depends on.
|
||||
set(COMPONENTS main)
|
||||
|
||||
|
@ -1,17 +1,20 @@
|
||||
set(app_sources "test_app_main.c" "test_ulp_riscv.c")
|
||||
set(app_sources "test_app_main.c" "test_ulp_riscv.c" "test_ulp_riscv_i2c.c")
|
||||
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")
|
||||
set(ulp_sources4 "ulp/test_main_i2c.c")
|
||||
|
||||
idf_component_register(SRCS ${app_sources}
|
||||
INCLUDE_DIRS "ulp"
|
||||
REQUIRES ulp unity
|
||||
REQUIRES ulp unity test_utils
|
||||
WHOLE_ARCHIVE)
|
||||
|
||||
set(ulp_app_name ulp_test_app)
|
||||
set(ulp_app_name2 ulp_test_app2)
|
||||
set(ulp_app_name3 ulp_test_app3)
|
||||
set(ulp_app_name4 ulp_test_app_i2c)
|
||||
set(ulp_exp_dep_srcs ${app_sources})
|
||||
ulp_embed_binary(${ulp_app_name} "${ulp_sources}" "${ulp_exp_dep_srcs}")
|
||||
ulp_embed_binary(${ulp_app_name2} "${ulp_sources2}" "${ulp_exp_dep_srcs}")
|
||||
ulp_embed_binary(${ulp_app_name3} "${ulp_sources3}" "${ulp_exp_dep_srcs}")
|
||||
ulp_embed_binary(${ulp_app_name4} "${ulp_sources4}" "${ulp_exp_dep_srcs}")
|
||||
|
166
components/ulp/test_apps/ulp_riscv/main/test_ulp_riscv_i2c.c
Normal file
166
components/ulp/test_apps/ulp_riscv/main/test_ulp_riscv_i2c.c
Normal file
@ -0,0 +1,166 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "ulp_riscv.h"
|
||||
#include "ulp_riscv_i2c.h"
|
||||
#include "ulp_test_app_i2c.h"
|
||||
#include "ulp_test_shared.h"
|
||||
#include "unity.h"
|
||||
#include "test_utils.h"
|
||||
#include "esp_log.h"
|
||||
#include "driver/i2c.h"
|
||||
|
||||
#define ULP_WAKEUP_PERIOD 1000000 // 1 second
|
||||
static const char* TAG = "ulp_riscv_i2c_test";
|
||||
|
||||
// ULP RISC-V RTC I2C firmware
|
||||
extern const uint8_t ulp_test_app_i2c_bin_start[] asm("_binary_ulp_test_app_i2c_bin_start");
|
||||
extern const size_t ulp_test_app_i2c_bin_length asm("ulp_test_app_i2c_bin_length");
|
||||
|
||||
static void load_and_start_ulp_riscv_firmware(const uint8_t* ulp_bin, size_t ulp_bin_len)
|
||||
{
|
||||
TEST_ASSERT(ulp_riscv_load_binary(ulp_bin, ulp_bin_len) == ESP_OK);
|
||||
TEST_ASSERT(ulp_set_wakeup_period(0, ULP_WAKEUP_PERIOD) == ESP_OK);
|
||||
TEST_ASSERT(ulp_riscv_run() == ESP_OK);
|
||||
}
|
||||
|
||||
#define I2C_SLAVE_SCL_IO 7 /*!<I2C gpio number for SCL */
|
||||
#define I2C_SLAVE_SDA_IO 6 /*!<I2C gpio number for SDA */
|
||||
#define I2C_SLAVE_NUM I2C_NUM_0 /*!<I2C port number for slave dev */
|
||||
#define I2C_SLAVE_TX_BUF_LEN (2*DATA_LENGTH) /*!<I2C slave tx buffer size */
|
||||
#define I2C_SLAVE_RX_BUF_LEN (2*DATA_LENGTH) /*!<I2C slave rx buffer size */
|
||||
|
||||
static uint8_t expected_master_write_data[DATA_LENGTH];
|
||||
static uint8_t expected_master_read_data[DATA_LENGTH];
|
||||
|
||||
static void init_test_data(size_t len)
|
||||
{
|
||||
/* Set up test data with some predictable patterns */
|
||||
for (int i = 0; i < len; i++) {
|
||||
expected_master_write_data[i] = i % 3;
|
||||
}
|
||||
|
||||
for (int i = 0; i < len; i++) {
|
||||
expected_master_read_data[i] = i / 2;
|
||||
}
|
||||
}
|
||||
|
||||
static esp_err_t init_i2c(void)
|
||||
{
|
||||
/* Configure RTC I2C */
|
||||
printf("Initializing RTC I2C ...\n");
|
||||
ulp_riscv_i2c_cfg_t i2c_cfg = ULP_RISCV_I2C_DEFAULT_CONFIG();
|
||||
esp_err_t ret = ulp_riscv_i2c_master_init(&i2c_cfg);
|
||||
if (ret != ESP_OK) {
|
||||
printf("ERROR: Failed to initialize RTC I2C. Aborting...\n");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* This runs on the DUT */
|
||||
static void i2c_master_write_read_test(void)
|
||||
{
|
||||
/* Initialize the test data */
|
||||
init_test_data(DATA_LENGTH);
|
||||
|
||||
/* Initialize RTC I2C */
|
||||
TEST_ASSERT(init_i2c() == ESP_OK);
|
||||
|
||||
/* Wait for the I2C slave device to be ready */
|
||||
unity_wait_for_signal("i2c slave init finish");
|
||||
|
||||
/* Load and Run the ULP RISC-V firmware */
|
||||
load_and_start_ulp_riscv_firmware(ulp_test_app_i2c_bin_start, ulp_test_app_i2c_bin_length);
|
||||
|
||||
/* Wait for ULP RISC-V to finish reading */
|
||||
while (ulp_read_test_reply == RISCV_COMMAND_INVALID) {
|
||||
}
|
||||
|
||||
/* Verify the test data read by the DUT */
|
||||
uint8_t *read_data = (uint8_t*)&ulp_data_rd;
|
||||
ESP_LOGI(TAG, "Master read data:");
|
||||
ESP_LOG_BUFFER_HEX(TAG, read_data, RW_TEST_LENGTH);
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_master_read_data, read_data, RW_TEST_LENGTH);
|
||||
|
||||
/* Prepare the test data to be written to the I2C slave device */
|
||||
uint8_t *wr_data = (uint8_t*)&ulp_data_wr;
|
||||
for (int i = 0; i < RW_TEST_LENGTH; i++) {
|
||||
wr_data[i] = expected_master_write_data[i];
|
||||
}
|
||||
|
||||
/* Wait for the I2C slave device to be ready */
|
||||
unity_wait_for_signal("master write");
|
||||
|
||||
/* Signal the ULR RISC-V to perform the write to the I2C slave device */
|
||||
volatile riscv_test_command_reply_t* write_test_cmd = (riscv_test_command_reply_t*)&ulp_write_test_cmd;
|
||||
*write_test_cmd = RISCV_COMMAND_OK;
|
||||
|
||||
/* Wait for ULP to finish writing */
|
||||
while (*write_test_cmd != RISCV_COMMAND_NOK) {
|
||||
}
|
||||
|
||||
/* Signal the I2C slave device to read the data */
|
||||
unity_send_signal("slave read");
|
||||
}
|
||||
|
||||
static i2c_config_t i2c_slave_init(void)
|
||||
{
|
||||
i2c_config_t conf_slave = {
|
||||
.mode = I2C_MODE_SLAVE,
|
||||
.sda_io_num = I2C_SLAVE_SDA_IO,
|
||||
.scl_io_num = I2C_SLAVE_SCL_IO,
|
||||
.sda_pullup_en = GPIO_PULLUP_ENABLE,
|
||||
.scl_pullup_en = GPIO_PULLUP_ENABLE,
|
||||
.slave.addr_10bit_en = 0,
|
||||
.slave.slave_addr = I2C_SLAVE_ADDRESS,
|
||||
};
|
||||
return conf_slave;
|
||||
}
|
||||
|
||||
/* This runs on the I2C slave device */
|
||||
static void i2c_slave_read_write_test(void)
|
||||
{
|
||||
/* Initialize test data */
|
||||
init_test_data(DATA_LENGTH);
|
||||
|
||||
uint8_t *data_rd = (uint8_t *) malloc(DATA_LENGTH);
|
||||
memset(data_rd, 0, DATA_LENGTH);
|
||||
int size_rd;
|
||||
|
||||
/* Initialize I2C slave device */
|
||||
i2c_config_t conf_slave = i2c_slave_init();
|
||||
TEST_ESP_OK(i2c_param_config(I2C_SLAVE_NUM, &conf_slave));
|
||||
TEST_ESP_OK(i2c_driver_install(I2C_SLAVE_NUM, I2C_MODE_SLAVE,
|
||||
I2C_SLAVE_RX_BUF_LEN,
|
||||
I2C_SLAVE_TX_BUF_LEN, 0));
|
||||
|
||||
/* Signal the DUT that the I2C slave device is ready */
|
||||
unity_send_signal("i2c slave init finish");
|
||||
|
||||
/* Prepare the test data to be read by the DUT */
|
||||
size_rd = i2c_slave_write_buffer(I2C_SLAVE_NUM, expected_master_read_data, RW_TEST_LENGTH, 2000 / portTICK_PERIOD_MS);
|
||||
ESP_LOG_BUFFER_HEX(TAG, expected_master_read_data, size_rd);
|
||||
|
||||
/* Signal the DUT to write test data */
|
||||
unity_send_signal("master write");
|
||||
|
||||
/* Wait for DUT to write test data before reading it */
|
||||
unity_wait_for_signal("slave read");
|
||||
|
||||
/* Verify the test data written by the DUT */
|
||||
size_rd = i2c_slave_read_buffer(I2C_SLAVE_NUM, data_rd, RW_TEST_LENGTH, 10000 / portTICK_PERIOD_MS);
|
||||
ESP_LOGI(TAG, "Slave read data:");
|
||||
ESP_LOG_BUFFER_HEX(TAG, data_rd, size_rd);
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_master_write_data, data_rd, RW_TEST_LENGTH);
|
||||
|
||||
/* Clean up */
|
||||
free(data_rd);
|
||||
i2c_driver_delete(I2C_SLAVE_NUM);
|
||||
}
|
||||
|
||||
TEST_CASE_MULTIPLE_DEVICES("ULP RISC-V RTC I2C read and write test", "[ulp][test_env=generic_multi_device][timeout=150]", i2c_master_write_read_test, i2c_slave_read_write_test);
|
42
components/ulp/test_apps/ulp_riscv/main/ulp/test_main_i2c.c
Normal file
42
components/ulp/test_apps/ulp_riscv/main/ulp/test_main_i2c.c
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "ulp_test_shared.h"
|
||||
// #include "ulp_riscv.h"
|
||||
#include "ulp_riscv_utils.h"
|
||||
#include "ulp_riscv_i2c_ulp_core.h"
|
||||
|
||||
volatile riscv_test_command_reply_t read_test_reply = RISCV_COMMAND_INVALID;
|
||||
volatile riscv_test_command_reply_t write_test_cmd = RISCV_COMMAND_INVALID;
|
||||
|
||||
uint8_t data_rd[DATA_LENGTH] = {};
|
||||
uint8_t data_wr[DATA_LENGTH] = {};
|
||||
|
||||
int main(void)
|
||||
{
|
||||
/* Set I2C slave device address */
|
||||
ulp_riscv_i2c_master_set_slave_addr(I2C_SLAVE_ADDRESS);
|
||||
|
||||
/* Read from the I2C slave device */
|
||||
ulp_riscv_i2c_master_read_from_device(data_rd, RW_TEST_LENGTH);
|
||||
|
||||
/* Signal the main CPU once read is done */
|
||||
read_test_reply = RISCV_COMMAND_OK;
|
||||
|
||||
/* Wait for write command from main CPU */
|
||||
while (write_test_cmd != RISCV_COMMAND_OK) {
|
||||
}
|
||||
|
||||
/* Write to the I2C slave device */
|
||||
ulp_riscv_i2c_master_write_to_device(data_wr, RW_TEST_LENGTH);
|
||||
|
||||
/* Signal the main CPU once write is done */
|
||||
write_test_cmd = RISCV_COMMAND_NOK;
|
||||
|
||||
while (1) {
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
@ -8,6 +8,12 @@
|
||||
#define MUTEX_TEST_ITERATIONS 100000
|
||||
#define XOR_MASK 0xDEADBEEF
|
||||
|
||||
/* I2C test params */
|
||||
#define I2C_SLAVE_ADDRESS 0x28
|
||||
#define DATA_LENGTH 200
|
||||
// TODO: Updated the test to perform multi-byte read/write (IDFGH-11056)
|
||||
#define RW_TEST_LENGTH 1 /*!<Data length for r/w test, any value from 0-DATA_LENGTH*/
|
||||
|
||||
typedef enum {
|
||||
RISCV_READ_WRITE_TEST = 1,
|
||||
RISCV_DEEP_SLEEP_WAKEUP_SHORT_DELAY_TEST,
|
||||
|
@ -1,11 +1,23 @@
|
||||
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
import pytest
|
||||
from pytest_embedded import Dut
|
||||
|
||||
|
||||
@pytest.mark.esp32s2
|
||||
@pytest.mark.esp32s3
|
||||
@pytest.mark.generic
|
||||
def test_ulp_riscv(case_tester) -> None: # type: ignore
|
||||
case_tester.run_all_cases()
|
||||
def test_ulp_riscv(dut: Dut) -> None: # type: ignore
|
||||
dut.run_all_single_board_cases()
|
||||
|
||||
|
||||
@pytest.mark.esp32s2
|
||||
@pytest.mark.esp32s3
|
||||
@pytest.mark.generic_multi_device
|
||||
@pytest.mark.parametrize(
|
||||
'count', [2], indirect=True
|
||||
)
|
||||
def test_ulp_riscv_multi_device(case_tester) -> None: # type: ignore
|
||||
for case in case_tester.test_menu:
|
||||
if case.attributes.get('test_env', 'generic_multi_device') == 'generic_multi_device':
|
||||
case_tester.run_multi_dev_case(case=case, reset=True)
|
||||
|
@ -10,6 +10,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#include "soc/rtc_io_reg.h"
|
||||
#include "soc/sens_reg.h"
|
||||
#include "ulp_riscv_register_ops.h"
|
||||
@ -131,6 +132,8 @@ static inline void ulp_riscv_gpio_pulldown_disable(gpio_num_t gpio_num)
|
||||
CLEAR_PERI_REG_MASK(RTC_IO_TOUCH_PAD0_REG + gpio_num * 4, RTC_IO_TOUCH_PAD0_RDE);
|
||||
}
|
||||
|
||||
#if CONFIG_ULP_RISCV_INTERRUPT_ENABLE
|
||||
|
||||
/**
|
||||
* @brief Set RTC IO interrupt type and handler
|
||||
*
|
||||
@ -152,6 +155,8 @@ esp_err_t ulp_riscv_gpio_isr_register(gpio_num_t gpio_num, ulp_riscv_gpio_int_ty
|
||||
*/
|
||||
esp_err_t ulp_riscv_gpio_isr_deregister(gpio_num_t gpio_num);
|
||||
|
||||
#endif /* CONFIG_ULP_RISCV_INTERRUPT_ENABLE */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -14,6 +14,8 @@ extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#if CONFIG_ULP_RISCV_INTERRUPT_ENABLE
|
||||
|
||||
/* ULP RISC-V Interrupt sources */
|
||||
typedef enum {
|
||||
ULP_RISCV_SW_INTR_SOURCE = 0, /**< Interrupt triggered by SW */
|
||||
@ -62,6 +64,8 @@ esp_err_t ulp_riscv_intr_alloc(ulp_riscv_interrupt_source_t source, intr_handler
|
||||
*/
|
||||
esp_err_t ulp_riscv_intr_free(ulp_riscv_interrupt_source_t source);
|
||||
|
||||
#endif /* CONFIG_ULP_RISCV_INTERRUPT_ENABLE */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -111,6 +111,7 @@ void static inline ulp_riscv_delay_cycles(uint32_t cycles)
|
||||
*/
|
||||
void ulp_riscv_gpio_wakeup_clear(void);
|
||||
|
||||
#if CONFIG_ULP_RISCV_INTERRUPT_ENABLE
|
||||
/**
|
||||
* @brief Enable ULP RISC-V SW Interrupt
|
||||
*
|
||||
@ -131,6 +132,34 @@ void ulp_riscv_disable_sw_intr(void);
|
||||
*/
|
||||
void ulp_riscv_trigger_sw_intr(void);
|
||||
|
||||
/**
|
||||
* @brief Enter a critical section by disabling all interrupts
|
||||
* This inline assembly construct uses the t0 register and is equivalent to:
|
||||
*
|
||||
* li t0, 0x80000007
|
||||
* maskirq_insn(zero, t0) // Mask all interrupt bits
|
||||
*/
|
||||
#define ULP_RISCV_ENTER_CRITICAL() \
|
||||
asm volatile ( \
|
||||
"li t0, 0x80000007\n" \
|
||||
".word 0x0602e00b" \
|
||||
); \
|
||||
|
||||
/**
|
||||
* @brief Exit a critical section by enabling all interrupts
|
||||
* This inline assembly construct is equivalent to:
|
||||
*
|
||||
* maskirq_insn(zero, zero) // Unmask all interrupt bits
|
||||
*/
|
||||
#define ULP_RISCV_EXIT_CRITICAL() asm volatile (".word 0x0600600b");
|
||||
|
||||
#else /* CONFIG_ULP_RISCV_INTERRUPT_ENABLE */
|
||||
|
||||
#define ULP_RISCV_ENTER_CRITICAL()
|
||||
#define ULP_RISCV_EXIT_CRITICAL()
|
||||
|
||||
#endif /* CONFIG_ULP_RISCV_INTERRUPT_ENABLE */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -1,9 +1,10 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#include "ulp_riscv_interrupt_ops.h"
|
||||
|
||||
.section .text
|
||||
@ -14,8 +15,10 @@ __start:
|
||||
/* setup the stack pointer */
|
||||
la sp, __stack_top
|
||||
|
||||
#if CONFIG_ULP_RISCV_INTERRUPT_ENABLE
|
||||
/* Enable interrupts globally */
|
||||
maskirq_insn(zero, zero)
|
||||
#endif /* CONFIG_ULP_RISCV_INTERRUPT_ENABLE */
|
||||
|
||||
/* Start ULP user code */
|
||||
call ulp_riscv_rescue_from_monitor
|
||||
|
@ -3,9 +3,11 @@
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "sdkconfig.h"
|
||||
#include "ulp_riscv_gpio.h"
|
||||
#include "include/ulp_riscv_gpio.h"
|
||||
|
||||
#if CONFIG_ULP_RISCV_INTERRUPT_ENABLE
|
||||
esp_err_t ulp_riscv_gpio_isr_register(gpio_num_t gpio_num, ulp_riscv_gpio_int_type_t intr_type, intr_handler_t handler, void *arg)
|
||||
{
|
||||
if (gpio_num < 0 || gpio_num >= GPIO_NUM_MAX) {
|
||||
@ -31,3 +33,4 @@ esp_err_t ulp_riscv_gpio_isr_deregister(gpio_num_t gpio_num)
|
||||
{
|
||||
return ulp_riscv_intr_free(ULP_RISCV_RTCIO0_INTR_SOURCE + gpio_num);
|
||||
}
|
||||
#endif /* CONFIG_ULP_RISCV_INTERRUPT_ENABLE */
|
||||
|
@ -141,6 +141,9 @@ void ulp_riscv_i2c_master_read_from_device(uint8_t *data_rd, size_t size)
|
||||
return;
|
||||
}
|
||||
|
||||
// Workaround for IDF-9145
|
||||
ULP_RISCV_ENTER_CRITICAL();
|
||||
|
||||
/* By default, RTC I2C controller is hard wired to use CMD2 register onwards for read operations */
|
||||
cmd_idx = 2;
|
||||
|
||||
@ -201,6 +204,9 @@ void ulp_riscv_i2c_master_read_from_device(uint8_t *data_rd, size_t size)
|
||||
/* Clear the RTC I2C transmission bits */
|
||||
CLEAR_PERI_REG_MASK(SENS_SAR_I2C_CTRL_REG, SENS_SAR_I2C_START_FORCE);
|
||||
CLEAR_PERI_REG_MASK(SENS_SAR_I2C_CTRL_REG, SENS_SAR_I2C_START);
|
||||
|
||||
// Workaround for IDF-9145
|
||||
ULP_RISCV_EXIT_CRITICAL();
|
||||
}
|
||||
|
||||
/*
|
||||
@ -230,6 +236,9 @@ void ulp_riscv_i2c_master_write_to_device(uint8_t *data_wr, size_t size)
|
||||
return;
|
||||
}
|
||||
|
||||
// Workaround for IDF-9145
|
||||
ULP_RISCV_ENTER_CRITICAL();
|
||||
|
||||
/* By default, RTC I2C controller is hard wired to use CMD0 and CMD1 registers for write operations */
|
||||
cmd_idx = 0;
|
||||
|
||||
@ -269,4 +278,7 @@ void ulp_riscv_i2c_master_write_to_device(uint8_t *data_wr, size_t size)
|
||||
/* Clear the RTC I2C transmission bits */
|
||||
CLEAR_PERI_REG_MASK(SENS_SAR_I2C_CTRL_REG, SENS_SAR_I2C_START_FORCE);
|
||||
CLEAR_PERI_REG_MASK(SENS_SAR_I2C_CTRL_REG, SENS_SAR_I2C_START);
|
||||
|
||||
// Workaround for IDF-9145
|
||||
ULP_RISCV_EXIT_CRITICAL();
|
||||
}
|
||||
|
@ -1,15 +1,18 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include "sdkconfig.h"
|
||||
#include "include/ulp_riscv_interrupt.h"
|
||||
#include "ulp_riscv_register_ops.h"
|
||||
#include "ulp_riscv_interrupt.h"
|
||||
#include "ulp_riscv_gpio.h"
|
||||
#include "soc/sens_reg.h"
|
||||
|
||||
#if CONFIG_ULP_RISCV_INTERRUPT_ENABLE
|
||||
|
||||
#define ULP_RISCV_TIMER_INT (1 << 0U) /* Internal Timer Interrupt */
|
||||
#define ULP_RISCV_EBREAK_ECALL_ILLEGAL_INSN_INT (1 << 1U) /* EBREAK, ECALL or Illegal instruction */
|
||||
#define ULP_RISCV_BUS_ERROR_INT (1 << 2U) /* Bus Error (Unaligned Memory Access) */
|
||||
@ -130,3 +133,5 @@ void __attribute__((weak)) _ulp_riscv_interrupt_handler(uint32_t q1)
|
||||
/* TODO: RTC I2C interrupt */
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CONFIG_ULP_RISCV_INTERRUPT_ENABLE */
|
||||
|
@ -4,6 +4,7 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "ulp_riscv_print.h"
|
||||
#include "ulp_riscv_utils.h"
|
||||
|
||||
typedef struct {
|
||||
putc_fn_t putc; // Putc function of the underlying driver, e.g. UART
|
||||
@ -24,9 +25,14 @@ void ulp_riscv_print_str(const char *str)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Perform the bit-banged UART operation in a critical section */
|
||||
ULP_RISCV_ENTER_CRITICAL();
|
||||
|
||||
for (int i = 0; str[i] != 0; i++) {
|
||||
s_print_ctx.putc(s_print_ctx.putc_ctx, str[i]);
|
||||
}
|
||||
|
||||
ULP_RISCV_EXIT_CRITICAL();
|
||||
}
|
||||
|
||||
void ulp_riscv_print_hex(int h)
|
||||
@ -38,6 +44,9 @@ void ulp_riscv_print_hex(int h)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Perform the bit-banged UART operation in a critical section */
|
||||
ULP_RISCV_ENTER_CRITICAL();
|
||||
|
||||
// Does not print '0x', only the digits (8 digits to print)
|
||||
for (x = 0; x < 8; x++) {
|
||||
c = (h >> 28) & 0xf; // extract the leftmost byte
|
||||
@ -48,4 +57,6 @@ void ulp_riscv_print_hex(int h)
|
||||
}
|
||||
h <<= 4; // move the 2nd leftmost byte to the left, to be extracted next
|
||||
}
|
||||
|
||||
ULP_RISCV_EXIT_CRITICAL();
|
||||
}
|
||||
|
@ -1,9 +1,10 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#include "ulp_riscv_utils.h"
|
||||
#include "ulp_riscv_register_ops.h"
|
||||
#include "soc/soc.h"
|
||||
@ -48,6 +49,8 @@ void ulp_riscv_gpio_wakeup_clear(void)
|
||||
SET_PERI_REG_MASK(RTC_CNTL_ULP_CP_TIMER_REG, RTC_CNTL_ULP_CP_GPIO_WAKEUP_CLR);
|
||||
}
|
||||
|
||||
#if CONFIG_ULP_RISCV_INTERRUPT_ENABLE
|
||||
|
||||
void ulp_riscv_enable_sw_intr(intr_handler_t handler, void *arg)
|
||||
{
|
||||
/* Enable ULP RISC-V SW interrupt */
|
||||
@ -72,3 +75,5 @@ void ulp_riscv_trigger_sw_intr(void)
|
||||
{
|
||||
SET_PERI_REG_MASK(RTC_CNTL_COCPU_CTRL_REG, RTC_CNTL_COCPU_SW_INT_TRIGGER);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_ULP_RISCV_INTERRUPT_ENABLE */
|
||||
|
@ -1,9 +1,10 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#include "ulp_riscv_interrupt_ops.h"
|
||||
#include "riscv/rvruntime-frames.h"
|
||||
.equ SAVE_REGS, 17
|
||||
@ -69,6 +70,7 @@
|
||||
reset_vector:
|
||||
j __start
|
||||
|
||||
#if CONFIG_ULP_RISCV_INTERRUPT_ENABLE
|
||||
/* Interrupt handler */
|
||||
.balign 0x10
|
||||
irq_vector:
|
||||
@ -89,3 +91,5 @@ irq_vector:
|
||||
|
||||
/* Exit interrupt handler by executing the custom retirq instruction which will retore pc and re-enable interrupts */
|
||||
retirq_insn()
|
||||
|
||||
#endif /* CONFIG_ULP_RISCV_INTERRUPT_ENABLE */
|
||||
|
@ -2,6 +2,7 @@
|
||||
CONFIG_ULP_COPROC_ENABLED=y
|
||||
CONFIG_ULP_COPROC_TYPE_RISCV=y
|
||||
CONFIG_ULP_COPROC_RESERVE_MEM=4096
|
||||
CONFIG_ULP_RISCV_INTERRUPT_ENABLE=y
|
||||
# Set log level to Warning to produce clean output
|
||||
CONFIG_BOOTLOADER_LOG_LEVEL_WARN=y
|
||||
CONFIG_BOOTLOADER_LOG_LEVEL=2
|
||||
|
Loading…
x
Reference in New Issue
Block a user