ESP32-S2-WROVER I2C transaction failure after receiving NACK during write

kalpanavengala
Posts: 3
Joined: Sat Jun 12, 2021 2:04 pm

ESP32-S2-WROVER I2C transaction failure after receiving NACK during write

Postby kalpanavengala » Mon Jul 19, 2021 11:35 pm

I am using ESP32 as Master and AVR32 using as a slave device.

AVR32 image sends
Sends ACK (if lock on block data is successful) during the first read transaction
Sends a NACK during the start of the second read transaction at the end of receiving the second register address byte.
Send ACKs (if lock on block data is successful) during subsequent read transactions.

ESP32 image :
I2C data packet <START>0x40(write)<ACK>0xFE<ACK>0x00<ACK><RPT_START>0x41(read)<ACK>data[0]<ACK>data[1]<ACK>...<STOP>
Performs a read transaction in a while(1) loop

1st read transaction: the scope output from a write transaction is: start+(slave_addr | write_bit)+ACK+reg_addr_high+ACK+reg_addr_Low+ACK. The read continues and successfully reads all data.
2nd read transaction: the scope output from a write transaction is: start+(slave_addr | write_bit)+ACK+reg_addr_high+ACK+reg_addr_Low+NACK
After this transaction, SCL and SDA are going to high.
3rd read transaction: the scope output from a write transaction is: start+(slave_addr | read_bit) after that the SCL is pulling down to 0 and SDA is pulled down to zero

only the first i2c read operation getting data and second read operation NACK after that getting timeout error repeatedly

Questions:
1.Please help me how to overcome the ESP_ERR_TIMEOUT error and how to release the I2C SDA and SCL buses come back to normal operation.
How to handle in master side (to stop the I2C transaction)if the NACK comes from slave after reading the 16bit register value properly without I2C bus hangings.

Attaching the code and screenlog file.
esp_err_t i2c_master_read_operation(device_addr_t dev_addr, uint8_t *read_buff, size_t size) {

esp_err_t ret_val;
// int time_out;
uint8_t counter = 0;
// while(1) {

i2c_cmd_handle_t cmd_handle = i2c_cmd_link_create();
i2c_master_start(cmd_handle);
i2c_master_write_byte(cmd_handle, ( dev_addr.device_id<< 1) | WRITE_BIT, ACK_CHECK_EN);
i2c_master_write_byte(cmd_handle,dev_addr.device_block_id, ACK_CHECK_EN);
i2c_master_write_byte(cmd_handle, dev_addr.device_block_id, ACK_CHECK_EN);
i2c_master_write_byte(cmd_handle, dev_addr.reg_offset_id, ACK_CHECK_EN);
// i2c_master_stop(cmd_handle);
// i2c_set_timeout(I2C_NUM_0,40000);// set time out 100 ms
ret_val = i2c_master_cmd_begin(I2C_NUM_0, cmd_handle,1000 / portTICK_PERIOD_MS );
i2c_cmd_link_delete(cmd_handle);

if(ret_val==ESP_FAIL){
ESP_LOGE(TAG,"I2C command write failed %s \n",esp_err_to_name(ret_val));

cmd_handle = i2c_cmd_link_create();
i2c_master_stop(cmd_handle);
i2c_master_cmd_begin(I2C_NUM_0, cmd_handle, 1000 / portTICK_PERIOD_MS);
i2c_cmd_link_delete(cmd_handle);
return ESP_FAIL;
} else if(ret_val==ESP_OK)
{
cmd_handle = i2c_cmd_link_create();
/*I2C master to generate a restart signal*/
i2c_master_start(cmd_handle);
i2c_master_write_byte(cmd_handle, ( dev_addr.device_id<< 1)| READ_BIT, ACK_CHECK_EN);
for (size_t i = 0; i<size-1; i++) {
i2c_master_read_byte(cmd_handle, read_buff + i, ACK_VAL);
}

i2c_master_read_byte(cmd_handle, read_buff + size-1, NACK_VAL );
i2c_master_stop(cmd_handle);
ret_val = i2c_master_cmd_begin(I2C_NUM_0, cmd_handle, 1000 / portTICK_PERIOD_MS);
i2c_cmd_link_delete(cmd_handle);
printf("ret_val of data read operation R:%d, %u (%d, %d)\n", ret_val, counter++, ESP_ERR_TIMEOUT, ESP_FAIL);
return ret_val;
} else
{
ESP_LOGI(TAG,"i2c command write failure %s\n",esp_err_to_name(ret_val));
return ret_val;
}

}


void app_main()
{
//i2c code part
esp_err_t ret;
ret = i2c_master_initialize();

if (ret != ESP_OK) {
printf("Master init failed");
}

ESP_LOGW("LOG","Master intialized successfully %d",ret);
device_addr_t dev_addr3 = {.device_id = ESP_SLAVE_ADDR, .device_block_id = 0xFE, .reg_offset_id = 0x00};
for (int i = 0; i < DATA_LENGTH; i++) {
data_rd = 0;
}
while(1)
{
memset(data_rd,0,d_size);
ret = i2c_master_read_operation(dev_addr3, data_rd, d_size);
if(ret==ESP_OK) {
ESP_LOGI("main:","Read operation completed successfully\n");
disp_buf(data_rd, d_size);
// vTaskDelay(100 / portTICK_PERIOD_MS);
} else if (ret == ESP_ERR_TIMEOUT) {
ESP_LOGE("main:", "I2C Timeout");
} else {
ESP_LOGW("main:", " I2C %s...\n",esp_err_to_name(ret));
}

}
}

screenlog.o :
---------------------
Boot
[0;33mW (30322) LOG: Master intialized successfully 0[0m
ret_val of data read operation R:0, 0 (263, -1)
[0;32mI (30342) main:: Read operation completed successfully
[0m
04 03 02 01 08 07 06 05 0c 0b 0a 09 10 0f 0e 0d
14 13 12 11 15 19 18 17 16 1d 1c 1b 1a 1e 22 21
20 1f 26 25 24 23 27 2b 2a 29 28 2f 2e 2d 2c 30
34 33 32 31 38 37 36 35 39 3d 3c 3b 3a 41 40 3f
3e 45 44 43 42 49 48 47 46 4d 4c 4b 4a 51 50 4f
4e 52 53 57 56 55 54 5b 5a 59 58 5f 5e 5d 5c 63
62 61 60 6b 6a 69 68 67 66 65 64 6c 6e 6d 6f 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00
ret_val of data read operation R:263, 0 (263, -1)
[0;31mE (30392) main:: I2C Timeout[0m
[0;32mI (31392) i2c: i2c command write failure ESP_ERR_TIMEOUT
[0m
[0;31mE (31392) main:: I2C Timeout[0m
[0;32mI (32392) i2c: i2c command write failure ESP_ERR_TIMEOUT
[0m
[0;31mE (32392) main:: I2C Timeout[0m
[0;32mI (33392) i2c: i2c command write failure ESP_ERR_TIMEOUT
[0m
[0;31mE (33392) main:: I2C Timeout[0m
[0;32mI (34392) i2c: i2c command write failure ESP_ERR_TIMEOUT
[0m
[0;31mE (34392) main:: I2C Timeout[0m
[0;32mI (35392) i2c: i2c command write failure ESP_ERR_TIMEOUT
[0m
[0;31mE (35392) main:: I2C Timeout[0m
[0;32mI (36392) i2c: i2c command write failure ESP_ERR_TIMEOUT
[0m
[0;31mE (36392) main:: I2C Timeout[0m
[0;32mI (37392) i2c: i2c command write failure ESP_ERR_TIMEOUT
[0m
[0;31mE (37392) main:: I2C Timeout[0m
[0;32mI (38392) i2c: i2c command write failure ESP_ERR_TIMEOUT
[0m

Who is online

Users browsing this forum: Google [Bot] and 144 guests