-
Notifications
You must be signed in to change notification settings - Fork 7.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ESP32S3 Error reading multiple bytes with ulp-riscv i2c driver (IDFGH-9822) #11154
Comments
Hello @bitfixer, Apologies for getting to this issue very late. The commit 88e4c06 added a default ULP RISC-V I2C transaction timeout of 500 msec which should have been enough for a 9-byte transaction. However, I'm not sure what is the case with the particular sensor you are using. Could you confirm if the complete 9-byte transaction is not taking more than 500 msec? Maybe you could hook up a protocol analyzer to check? Nevertheless, I shall update the driver to make timeout behaviour configurable and in a way add capability to restore the behavior of the driver before the commit so that you use case is not affected. |
I can confirm the bug with the ESP32S3_R8V even when reading a single byte. Code to reproduce:
Still the error shows:
|
I can confirm that the the RISCV is able to communicate with I2C.
the LX7 will no longer able to communicate, either way RTC or BUS. |
@aircable |
The commit 88e4c06 introduced a loop timeout for all ULP RISC-V I2C transactions to avoid getting stuck in a forever loop. The loop timeout was set to 500 msec by default. This commit improves on the concept by making the loop timeout configurable via a Kconfig option in terms of CPU ticks. If the timeout is set to -1 value then the transaction loops will never timeout, therefore restoring the driver behavior before the timeout was introduced. The commit also updates the I2C Fast mode timings for esp32s2 which need to be adjusted due to bus timing constraints. Closes #11154
The commit 88e4c06 introduced a loop timeout for all ULP RISC-V I2C transactions to avoid getting stuck in a forever loop. The loop timeout was set to 500 msec by default. This commit improves on the concept by making the loop timeout configurable via a Kconfig option in terms of CPU ticks. If the timeout is set to -1 value then the transaction loops will never timeout, therefore restoring the driver behavior before the timeout was introduced. The commit also updates the I2C Fast mode timings for esp32s2 which need to be adjusted due to bus timing constraints. Closes espressif#11154
Answers checklist.
IDF version.
42261df
Operating System used.
Linux
How did you build your project?
Command line with idf.py
If you are using Windows, please specify command line type.
None
Development Kit.
esp32s3 custom board with MMC5603 magnetometer
Power Supply used.
USB
What is the expected behavior?
Hello, I would like to report an issue with the ulp-riscv i2c driver, specifically ulp_riscv_i2c_master_read_from_device.
I have a board with an esp32s3 connected to an MMC5603 magnetometer via i2c.
On this board, SDA is GPIO 1 and SCL is GPIO 0. I am doing readings from the magnetometer, which involves first writing a control byte, waiting for a status bit, and then reading 9 bytes back from addresses 0x00-0x08 using the ulp i2c driver. I was attempting to use ulp_riscv_i2c_master_read_from_device to read multiple bytes at a time, i.e.
ulp_riscv_i2c_master_read_from_device(buffer, 9);
However, this results in i2c errors like:
Initializing RTC I2C ...
doing magnetometer reading.
attempt 0
E (12163) ulp_riscv_i2c: Read Failed!
E (12163) ulp_riscv_i2c: RTC I2C Interrupt Raw Reg 0x10c
E (12163) ulp_riscv_i2c: RTC I2C Status Reg 0x65f00000
x 240 z 126
doing magnetometer reading.
attempt 0
E (18203) ulp_riscv_i2c: Read Failed!
E (18203) ulp_riscv_i2c: RTC I2C Interrupt Raw Reg 0x10c
E (18203) ulp_riscv_i2c: RTC I2C Status Reg 0x65d00000
x 208 z 126
doing magnetometer reading.
attempt 0
E (24243) ulp_riscv_i2c: Read Failed!
E (24243) ulp_riscv_i2c: RTC I2C Interrupt Raw Reg 0x10c
E (24243) ulp_riscv_i2c: RTC I2C Status Reg 0x65f00000
x 240 z 126
If these bytes are read individually, i.e.
for (int i = 0; i < size; i++) {
ulp_riscv_i2c_master_read_from_device(buffer, 1);
buffer++;
}
the read works properly.
The multiple byte read had worked properly until commit 88e4c06, but only when read from the riscv processor.
Expected behavior would be for the multiple byte read to work without error.
What is the actual behavior?
using ulp_riscv_i2c_master_read_from_device to read multiple bytes at once yields errors like:
Initializing RTC I2C ...
doing magnetometer reading.
attempt 0
E (12163) ulp_riscv_i2c: Read Failed!
E (12163) ulp_riscv_i2c: RTC I2C Interrupt Raw Reg 0x10c
E (12163) ulp_riscv_i2c: RTC I2C Status Reg 0x65f00000
x 240 z 126
doing magnetometer reading.
attempt 0
E (18203) ulp_riscv_i2c: Read Failed!
E (18203) ulp_riscv_i2c: RTC I2C Interrupt Raw Reg 0x10c
E (18203) ulp_riscv_i2c: RTC I2C Status Reg 0x65d00000
x 208 z 126
doing magnetometer reading.
attempt 0
E (24243) ulp_riscv_i2c: Read Failed!
E (24243) ulp_riscv_i2c: RTC I2C Interrupt Raw Reg 0x10c
E (24243) ulp_riscv_i2c: RTC I2C Status Reg 0x65f00000
x 240 z 126
Steps to reproduce.
Sample code:
`#include <stdio.h>
#include <inttypes.h>
#include <ulp_riscv.h>
#include <ulp_riscv_i2c.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "ulp_main.h"
#define MAG_ADDRESS 0x30
#define MAG_CONTROL_0_REG 0x1B
#define MAG_DEVICE_ID_REG 0x39
#define MAG_DEVICE_STATUS_REG_1 0x18
#define MAG_STATUS_MEAS_DONE_BIT 0x40
#define MAG_X_OUT_0 0
#define MAG_Z_OUT_0 4
// select method of i2c reading
#define I2C_READ_MULTIPLE 1
static void init_i2c(void);
void delayms(int ms) {
vTaskDelay(ms / portTICK_PERIOD_MS);
}
void readBytesMultiple(uint8_t* buffer, int size) {
ulp_riscv_i2c_master_read_from_device(buffer, size);
}
void readBytesSingle(uint8_t* buffer, int size) {
for (int i = 0; i < size; i++) {
ulp_riscv_i2c_master_read_from_device(buffer, 1);
buffer++;
}
}
// read values from MMC5603 magnetometer
void magReading() {
ulp_riscv_i2c_master_set_slave_addr(MAG_ADDRESS);
#if I2C_READ_MULTIPLE
readBytesMultiple(magReadingBytes, 9);
#else
readBytesSingle(magReadingBytes, 9);
#endif
}
static void init_i2c(void)
{
/* Configure RTC I2C */
printf("Initializing RTC I2C ...\n");
ulp_riscv_i2c_cfg_t i2c_cfg = ULP_RISCV_I2C_DEFAULT_CONFIG();
i2c_cfg.i2c_pin_cfg.sda_io_num = GPIO_NUM_1;
i2c_cfg.i2c_pin_cfg.scl_io_num = GPIO_NUM_0;
esp_err_t ret = ulp_riscv_i2c_master_init(&i2c_cfg);
if (ret!= ESP_OK) {
printf("ERROR: Failed to initialize RTC I2C. Aborting...\n");
abort();
}
}
void app_main(void)
{
printf("Hello world!\n");
delayms(1000);
init_i2c();
while (1) {
printf("doing magnetometer reading.\n");
magReading();
delayms(1000);
}
}`
Debug Logs.
More Information.
Before commit 88e4c06, the multiple byte read worked properly when used from the ulp riscv processor but not from the CPU - on CPU it would hang.
The text was updated successfully, but these errors were encountered: