fix(ulp-riscv): Wrapped all RTC I2C and UART operations in critical sections

This commit adds a workaround for a bug where the RTC I2C operations
result in a Bus Error when interrupts are enabled. The commit also adds
a critical section protection for UART print operations.
This commit is contained in:
Sudeep Mohanty 2024-02-01 10:10:48 +01:00
parent d352ec615a
commit 993c8d4f0e
2 changed files with 23 additions and 0 deletions

View File

@ -141,6 +141,9 @@ void ulp_riscv_i2c_master_read_from_device(uint8_t *data_rd, size_t size)
return; 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 */ /* By default, RTC I2C controller is hard wired to use CMD2 register onwards for read operations */
cmd_idx = 2; 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 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_FORCE);
CLEAR_PERI_REG_MASK(SENS_SAR_I2C_CTRL_REG, SENS_SAR_I2C_START); 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; 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 */ /* By default, RTC I2C controller is hard wired to use CMD0 and CMD1 registers for write operations */
cmd_idx = 0; 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 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_FORCE);
CLEAR_PERI_REG_MASK(SENS_SAR_I2C_CTRL_REG, SENS_SAR_I2C_START); CLEAR_PERI_REG_MASK(SENS_SAR_I2C_CTRL_REG, SENS_SAR_I2C_START);
// Workaround for IDF-9145
ULP_RISCV_EXIT_CRITICAL();
} }

View File

@ -4,6 +4,7 @@
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
#include "ulp_riscv_print.h" #include "ulp_riscv_print.h"
#include "ulp_riscv_utils.h"
typedef struct { typedef struct {
putc_fn_t putc; // Putc function of the underlying driver, e.g. UART 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; return;
} }
/* Perform the bit-banged UART operation in a critical section */
ULP_RISCV_ENTER_CRITICAL();
for (int i = 0; str[i] != 0; i++) { for (int i = 0; str[i] != 0; i++) {
s_print_ctx.putc(s_print_ctx.putc_ctx, str[i]); s_print_ctx.putc(s_print_ctx.putc_ctx, str[i]);
} }
ULP_RISCV_EXIT_CRITICAL();
} }
void ulp_riscv_print_hex(int h) void ulp_riscv_print_hex(int h)
@ -38,6 +44,9 @@ void ulp_riscv_print_hex(int h)
return; 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) // Does not print '0x', only the digits (8 digits to print)
for (x = 0; x < 8; x++) { for (x = 0; x < 8; x++) {
c = (h >> 28) & 0xf; // extract the leftmost byte 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 h <<= 4; // move the 2nd leftmost byte to the left, to be extracted next
} }
ULP_RISCV_EXIT_CRITICAL();
} }