Merge branch 'fix/lp_periph_use_int_raw_v5.5' into 'release/v5.5'

change(lp-core): Update LP I2C and LP UART drivers to use raw interrupt status (v5.5)

See merge request espressif/esp-idf!39248
This commit is contained in:
Jiang Jiang Jian
2025-05-20 11:54:58 +08:00
7 changed files with 75 additions and 29 deletions

View File

@ -291,6 +291,19 @@ static inline void i2c_ll_get_intr_mask(i2c_dev_t *hw, uint32_t *intr_status)
*intr_status = hw->int_status.val;
}
/**
* @brief Get I2C raw interrupt status
*
* @param hw Beginning address of the peripheral registers
*
* @return I2C raw interrupt status
*/
__attribute__((always_inline))
static inline void i2c_ll_get_intr_raw_mask(i2c_dev_t *hw, uint32_t *intr_status)
{
*intr_status = hw->int_raw.val;
}
/**
* @brief Configure I2C memory access mode, FIFO mode or non-FIFO mode
*

View File

@ -295,6 +295,19 @@ static inline void i2c_ll_get_intr_mask(i2c_dev_t *hw, uint32_t *intr_status)
*intr_status = hw->int_status.val;
}
/**
* @brief Get I2C raw interrupt status
*
* @param hw Beginning address of the peripheral registers
*
* @return I2C raw interrupt status
*/
__attribute__((always_inline))
static inline void i2c_ll_get_intr_raw_mask(i2c_dev_t *hw, uint32_t *intr_status)
{
*intr_status = hw->int_raw.val;
}
/**
* @brief Configure I2C memory access mode, FIFO mode or non-FIFO mode
*

View File

@ -310,6 +310,19 @@ static inline void i2c_ll_get_intr_mask(i2c_dev_t *hw, uint32_t *intr_status)
*intr_status = hw->int_status.val;
}
/**
* @brief Get I2C raw interrupt status
*
* @param hw Beginning address of the peripheral registers
*
* @return I2C raw interrupt status
*/
__attribute__((always_inline))
static inline void i2c_ll_get_intr_raw_mask(i2c_dev_t *hw, uint32_t *intr_status)
{
*intr_status = hw->int_raw.val;
}
/**
* @brief Configure I2C memory access mode, FIFO mode or non-FIFO mode
*

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -72,7 +72,7 @@ static inline esp_err_t lp_core_i2c_wait_for_interrupt(uint32_t intr_mask, int32
uint32_t to = 0;
while (1) {
i2c_ll_get_intr_mask(dev, &intr_status);
i2c_ll_get_intr_raw_mask(dev, &intr_status);
if (intr_status & intr_mask) {
if (intr_status & LP_I2C_NACK_INT_ST) {
/* The ACK/NACK received during a WRITE operation does not match the expected ACK/NACK level
@ -82,9 +82,8 @@ static inline esp_err_t lp_core_i2c_wait_for_interrupt(uint32_t intr_mask, int32
return ESP_ERR_INVALID_RESPONSE;
} else if (intr_status & LP_I2C_TRANS_COMPLETE_INT_ST_M) {
/* Transaction complete.
* Disable and clear interrupt bits and break
* Clear interrupt bits and break
*/
i2c_ll_disable_intr_mask(dev, intr_mask);
i2c_ll_clear_intr_mask(dev, intr_mask);
break;
} else {
@ -105,8 +104,7 @@ static inline esp_err_t lp_core_i2c_wait_for_interrupt(uint32_t intr_mask, int32
ulp_lp_core_delay_cycles(1);
to++;
if (to >= ticks_to_wait) {
/* Disable and clear interrupt bits */
i2c_ll_disable_intr_mask(dev, intr_mask);
/* Timeout. Clear interrupt bits and return an error */
i2c_ll_clear_intr_mask(dev, intr_mask);
return ESP_ERR_TIMEOUT;
}
@ -169,7 +167,7 @@ esp_err_t lp_core_i2c_master_read_from_device(i2c_port_t lp_i2c_num, uint16_t de
/* Enable trans complete interrupt and end detect interrupt for read/write operation */
uint32_t intr_mask = (1 << LP_I2C_TRANS_COMPLETE_INT_ST_S) | (1 << LP_I2C_END_DETECT_INT_ST_S);
i2c_ll_enable_intr_mask(dev, intr_mask);
i2c_ll_clear_intr_mask(dev, intr_mask);
/* Read data */
uint32_t fifo_size = 0;
@ -273,7 +271,7 @@ esp_err_t lp_core_i2c_master_write_to_device(i2c_port_t lp_i2c_num, uint16_t dev
/* Enable LP_I2C_NACK_INT to check for ACK errors */
intr_mask |= (1 << LP_I2C_NACK_INT_ST_S);
}
i2c_ll_enable_intr_mask(dev, intr_mask);
i2c_ll_clear_intr_mask(dev, intr_mask);
/* Write data */
uint32_t fifo_available = LP_I2C_FIFO_LEN - addr_len; // Initially, 1 or 2 fifo slots are taken by the device address
@ -358,7 +356,7 @@ esp_err_t lp_core_i2c_master_write_read_device(i2c_port_t lp_i2c_num, uint16_t d
/* Enable LP_I2C_NACK_INT to check for ACK errors */
intr_mask |= (1 << LP_I2C_NACK_INT_ST_S);
}
i2c_ll_enable_intr_mask(dev, intr_mask);
i2c_ll_clear_intr_mask(dev, intr_mask);
/* Execute RSTART command to send the START bit */
lp_core_i2c_format_cmd(cmd_idx++, I2C_LL_CMD_RESTART, 0, 0, 0, 0);

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -99,7 +99,6 @@ esp_err_t lp_core_uart_write_bytes(uart_port_t lp_uart_num, const void *src, siz
/* Enable the Tx done interrupt */
uint32_t intr_mask = LP_UART_TX_INT_FLAG | LP_UART_ERR_INT_FLAG;
uart_hal_clr_intsts_mask(&hal, intr_mask);
uart_hal_ena_intr_mask(&hal, intr_mask);
/* Transmit data */
uint32_t tx_len;
@ -118,22 +117,23 @@ esp_err_t lp_core_uart_write_bytes(uart_port_t lp_uart_num, const void *src, siz
/* We have managed to write some data to the Tx FIFO. Check Tx interrupt status */
while (1) {
/* Fetch the interrupt status */
intr_status = uart_hal_get_intsts_mask(&hal);
intr_status = uart_hal_get_intraw_mask(&hal);
if (intr_status & LP_UART_TX_INT_FLAG) {
/* Clear interrupt status and break */
uart_hal_clr_intsts_mask(&hal, intr_mask);
break;
} else if ((intr_status & LP_UART_ERR_INT_FLAG)) {
/* Transaction error. Abort */
uart_hal_clr_intsts_mask(&hal, intr_mask);
return ESP_FAIL;
}
/* Check for transaction timeout */
ret = lp_core_uart_check_timeout(intr_mask, timeout, &to);
if (ret == ESP_ERR_TIMEOUT) {
/* Timeout */
uart_hal_disable_intr_mask(&hal, intr_mask);
return ret;
/* Timeout. Clear interrupt status and break */
uart_hal_clr_intsts_mask(&hal, intr_mask);
break;
}
}
@ -144,16 +144,13 @@ esp_err_t lp_core_uart_write_bytes(uart_port_t lp_uart_num, const void *src, siz
/* Tx FIFO does not have empty slots. Check for transaction timeout */
ret = lp_core_uart_check_timeout(intr_mask, timeout, &to);
if (ret == ESP_ERR_TIMEOUT) {
/* Timeout */
uart_hal_disable_intr_mask(&hal, intr_mask);
return ret;
/* Timeout. Clear interrupt status and break */
uart_hal_clr_intsts_mask(&hal, intr_mask);
break;
}
}
}
/* Disable the Tx done interrupt */
uart_hal_disable_intr_mask(&hal, intr_mask);
return ret;
}
@ -179,8 +176,6 @@ int lp_core_uart_read_bytes(uart_port_t lp_uart_num, void *buf, size_t size, int
/* Enable the Rx interrupts */
uint32_t intr_mask = LP_UART_RX_INT_FLAG | LP_UART_ERR_INT_FLAG;
uart_hal_clr_intsts_mask(&hal, intr_mask);
uart_hal_ena_intr_mask(&hal, intr_mask);
/* Receive data */
int rx_len = 0;
uint32_t bytes_rcvd = 0;
@ -198,7 +193,7 @@ int lp_core_uart_read_bytes(uart_port_t lp_uart_num, void *buf, size_t size, int
if (rx_len) {
/* We have some data to read from the Rx FIFO. Check Rx interrupt status */
intr_status = uart_hal_get_intsts_mask(&hal);
intr_status = uart_hal_get_intraw_mask(&hal);
if ((intr_status & UART_INTR_RXFIFO_FULL) ||
(intr_status & UART_INTR_RXFIFO_TOUT)) {
/* This is expected. Clear interrupt status and break */
@ -212,7 +207,6 @@ int lp_core_uart_read_bytes(uart_port_t lp_uart_num, void *buf, size_t size, int
} else if ((intr_status & LP_UART_ERR_INT_FLAG)) {
/* Transaction error. Abort */
uart_hal_clr_intsts_mask(&hal, intr_mask);
uart_hal_disable_intr_mask(&hal, intr_mask);
return -1;
}
@ -223,14 +217,13 @@ int lp_core_uart_read_bytes(uart_port_t lp_uart_num, void *buf, size_t size, int
/* We have no data to read from the Rx FIFO. Check for transaction timeout */
ret = lp_core_uart_check_timeout(intr_mask, timeout, &to);
if (ret == ESP_ERR_TIMEOUT) {
/* Timeout. Clear interrupt status and break */
uart_hal_clr_intsts_mask(&hal, intr_mask);
break;
}
}
}
/* Disable the Rx interrupts */
uart_hal_disable_intr_mask(&hal, intr_mask);
/* Return the number of bytes received */
return bytes_rcvd;
}

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -8,6 +8,7 @@
#include "test_shared.h"
#include "ulp_lp_core_utils.h"
#include "ulp_lp_core_i2c.h"
#include "ulp_lp_core_interrupts.h"
#define LP_I2C_TRANS_WAIT_FOREVER -1
@ -19,6 +20,13 @@ uint8_t data_wr[DATA_LENGTH] = {};
int main(void)
{
/* Enable interrupts.
* This does not affect how the LP I2C functions
* but it will add extra test coverage to make sure
* the interrupt handler does not cause any issues.
*/
ulp_lp_core_intr_enable();
lp_core_i2c_master_read_from_device(LP_I2C_NUM_0, I2C_SLAVE_ADDRESS, data_rd, RW_TEST_LENGTH, LP_I2C_TRANS_WAIT_FOREVER);
read_test_reply = LP_CORE_COMMAND_OK;

View File

@ -11,6 +11,7 @@
#include "ulp_lp_core_uart.h"
#include "ulp_lp_core_print.h"
#include "soc/soc_caps.h"
#include "ulp_lp_core_interrupts.h"
#define LP_UART_PORT_NUM LP_UART_NUM_0
#define LP_UART_BUFFER_LEN UART_BUF_SIZE
@ -37,6 +38,13 @@ volatile char test_character;
int main(void)
{
/* Enable interrupts.
* This does not affect how the LP UART functions
* but it will add extra test coverage to make sure
* the interrupt handler does not cause any issues.
*/
ulp_lp_core_intr_enable();
while (1) {
/* Wait for the HP core to start the test */
while (test_cmd == LP_CORE_NO_COMMAND) {