I2C assert failed,and not work somtimes!

WayneJia
Posts: 17
Joined: Thu Aug 03, 2017 7:28 am

I2C assert failed,and not work somtimes!

Postby WayneJia » Thu Aug 03, 2017 8:20 am

I have two problems with I2C.
I read data from BMX055(9 axis sensor) through I2C per 20ms

1.I2C will have assert failed when the device run for a while.
This is log:

Code: Select all

C:/esp32-idf/esp-idf/components/freertos/ringbuf.c:600 (xRingbufferReceiveUpToFromISR)- assert failed!
abort() was called at PC 0x400879d5 on core 0
Guru Meditation Error: Core  0 panic'ed (abort)

Backtrace: 0x400d1408:0x3ffc0590 0x4008542c:0x3ffc05b0 0x40118908:0x3ffc05d0 0x40081f41:0x3ffc0600

Rebooting...
ets Jun  8 2016 00:22:57

rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
2.Another problem is that i2c not work totally.(I2C work normally at most of the time)
Sometimes,device reboot whith i2c not work totally.This situation most commonly happened when I turn on device after make erase_flash flash or mak flash.I2C will not respond,all read or write operations failed,so the code of I2C part will run very slowly and the device will not work.In this situation ,I must unplug battery to make I2C work again.Even I make erase_flash flash again,the device not working, either!

This is part of my code:
1.I init I2C at main_app().
2.I read data from sensor per 20ms in other task.

Code: Select all

#define I2C_MASTER_FREQ_HZ         400000     /*!< I2C master clock frequency */
#define I2C_PIN_SCL 13
#define I2C_PIN_SDA 14

void i2c_master_App_init(void)
{
	esp_err_t err;
	
    int i2c_master_port = I2C_NUM_0;
    i2c_config_t conf;
    conf.mode = I2C_MODE_MASTER;
    conf.sda_io_num = I2C_PIN_SDA;
    conf.sda_pullup_en = GPIO_PULLUP_ENABLE;
    conf.scl_io_num = I2C_PIN_SCL;
    conf.scl_pullup_en = GPIO_PULLUP_ENABLE;
    conf.master.clk_speed = I2C_MASTER_FREQ_HZ;
    err = i2c_param_config(i2c_master_port, &conf);
    err = i2c_driver_install(i2c_master_port, conf.mode,
                       I2C_MASTER_RX_BUF_DISABLE,
                       I2C_MASTER_TX_BUF_DISABLE, 0);
}

esp_err_t i2c_master_read_slave(uint8_t slaveAddr,uint8_t* data_rd, size_t size)
{
    esp_err_t err;
	
    if (size == 0) {
        return ESP_OK;
    }
    i2c_cmd_handle_t cmd = i2c_cmd_link_create();
    err = i2c_master_start(cmd);
    err = i2c_master_write_byte(cmd, ( slaveAddr << 1 ) | READ_BIT, ACK_CHECK_EN);
    if (size > 1) {
        err = i2c_master_read(cmd, data_rd, size - 1, ACK_VAL);
    }
    err = i2c_master_read_byte(cmd, data_rd + size - 1, NACK_VAL);
    err = i2c_master_stop(cmd);
    esp_err_t ret = i2c_master_cmd_begin(I2C_NUM_0, cmd, 1000 / portTICK_RATE_MS);
    i2c_cmd_link_delete(cmd);
    return ret;
}

esp_err_t i2c_master_write_slave(uint8_t slaveAddr,uint8_t* data_wr, size_t size)
{
   esp_err_t err;
	
    i2c_cmd_handle_t cmd = i2c_cmd_link_create();
    err = i2c_master_start(cmd);
    err = i2c_master_write_byte(cmd, ( slaveAddr << 1 ) | WRITE_BIT, ACK_CHECK_EN);
    err = i2c_master_write(cmd, data_wr, size, ACK_CHECK_EN);
    err = i2c_master_stop(cmd);
    esp_err_t ret = i2c_master_cmd_begin(I2C_NUM_0, cmd, 1000 / portTICK_RATE_MS);
    i2c_cmd_link_delete(cmd);
    return ret;
}

esp_err_t BMX055_IIC_Write_Bytes(uint8_t Sensor_Slave_Addr,uint8_t addr,uint8_t* data_wr, size_t size)
{

        uint8_t data[16];
	data[0]=addr;
	MEMCPY(data+1,data_wr,size);
	esp_err_t err = i2c_master_write_slave(Sensor_Slave_Addr,data,size+1);//write addr+data
	return err;
}

esp_err_t BMX055_IIC_Read_Bytes(uint8_t Sensor_Slave_Addr,uint8_t addr,uint8_t* data_re, size_t size)
{
        uint8_t data[1];
	data[0]=addr;
	esp_err_t err = i2c_master_write_slave(Sensor_Slave_Addr,data,1);//write addr
	if(err!=ESP_OK)return err;
	err = i2c_master_read_slave(Sensor_Slave_Addr,data_re,size);//read data
	return err;
}

abcdcadb
Posts: 36
Joined: Mon Aug 07, 2017 1:28 am

Re: I2C assert failed,and not work somtimes!

Postby abcdcadb » Tue Aug 22, 2017 9:52 am

Hi,

Did you overcome your problem? I got the same but worse.

My I2C code stops at : i2c_master_cmd_begin(I2C_NUM_0, cmd, 1000/portTICK_PERIOD_MS)
the console showed: ESP_ERROR_CHECK failed: esp_err_t 0x107 at 0x4011231e
expression: i2c_master_cmd_begin(I2C_NUM_0, cmd, 1000/portTICK_PERIOD_MS)
Guru Meditation Error: Core 0 panic'ed (abort)

Backtrace: 0x40114ef9:0x3ffbb500 0x40085420:0x3ffbb520 0x401129a6:0x3ffbb570 0x0

Rebooting...

and reboot
if you have any idea, I will be grateful

jp1992
Posts: 1
Joined: Tue Nov 07, 2017 10:35 am

Re: I2C assert failed,and not work somtimes!

Postby jp1992 » Tue Nov 07, 2017 12:24 pm

Hi,

Unfortunately I am experiencing similar problems while working with the I2C peripheral.
The I2C peripheral stops working after a random amount of time.

The first I2C device I use in a lot of projects is the PCF8574 I2C IO expander. The code is supposed to toggle P7 high/low. The other tasks that are running don't use the I2C peripheral.

Code: Select all


static void pcf_task(void *pVParameter)
{
	/* Init I2C */
	//PCF8574 pcf1 = PCF8574(PCF8574_ADDR);
	
	int i2c_master_port = I2C_EXAMPLE_MASTER_NUM; // 0
	i2c_config_t conf;
	conf.mode = I2C_MODE_MASTER;
	conf.sda_io_num = (gpio_num_t)I2C_EXAMPLE_MASTER_SDA_IO; // IO12
	conf.sda_pullup_en = GPIO_PULLUP_ENABLE;
	conf.scl_io_num = (gpio_num_t)I2C_EXAMPLE_MASTER_SCL_IO; // IO14
	conf.scl_pullup_en = GPIO_PULLUP_ENABLE;
	conf.master.clk_speed = I2C_EXAMPLE_MASTER_FREQ_HZ; // 100KHz
	i2c_param_config((i2c_port_t)i2c_master_port, &conf);
	i2c_driver_install((i2c_port_t)i2c_master_port,
		conf.mode,
		I2C_EXAMPLE_MASTER_RX_BUF_DISABLE,
		I2C_EXAMPLE_MASTER_TX_BUF_DISABLE,
		0);
	
	for (;;)
	{
//		pcf1._write(0x01);
//		vTaskDelay(500 / portTICK_PERIOD_MS);
//		pcf1._write(0x00);	
//		vTaskDelay(500 / portTICK_PERIOD_MS);
		i2c_cmd_handle_t cmd = i2c_cmd_link_create();
		i2c_master_start(cmd);
		i2c_master_write_byte(cmd, 0x20 << 1 | WRITE_BIT, ACK_CHECK_EN);// ADDR pins are low, 0x20 is the base address
		i2c_master_write_byte(cmd, 0x80, ACK_CHECK_EN);						// 0x80 sets P7 to HIGH
		i2c_master_stop(cmd);
		int ret = i2c_master_cmd_begin(I2C_NUM_0, cmd, 1000 / portTICK_RATE_MS);
		i2c_cmd_link_delete(cmd);
		if (ret == ESP_FAIL) {
			printf("Failed 1!");
		}
		vTaskDelay(100 / portTICK_RATE_MS);
		//printf("Go low\n");		
		cmd = i2c_cmd_link_create();
		i2c_master_start(cmd);
		i2c_master_write_byte(cmd, 0x20 << 1 | WRITE_BIT, ACK_CHECK_EN);// ADDR pins are low, 0x20 is the base address
		i2c_master_write_byte(cmd, 0x00, ACK_CHECK_EN); 					// 0x00 sets P7 to LOW
		i2c_master_stop(cmd);
		ret = i2c_master_cmd_begin(I2C_NUM_0, cmd, 1000 / portTICK_RATE_MS);
		i2c_cmd_link_delete(cmd);
		if (ret == ESP_FAIL) {
			printf("Failed 2!");
		}
		vTaskDelay(100 / portTICK_RATE_MS);
		//printf("Go high\n");			
	}
}

...
...

void app_main()
{	
	//test();
	nvs_flash_init();	
	//initialise_wifi();
	//xTaskCreate(&http_get_task, "http_get_task", 1024 * 5, NULL, 3, NULL);
	//xTaskCreate(&hello_task, "hello_task", 2048, NULL, 5, NULL);
	//xTaskCreate(&status_led_task, "status_led_task", 1024, NULL, 5, NULL);
	//xTaskCreate(&adc_task, "adc1task", 1024 * 3, NULL, 10, NULL);
	xTaskCreate(&temperature_task, "temperature_task", 1024 * 2, NULL, 6, NULL);
	xTaskCreate(&fan_task, "fan_task", 1024 * 3, NULL, 10, NULL);	
	xTaskCreate(&pwm_reader, "pwm_reader_task", 1024 * 8, NULL, 6, NULL);
	//xTaskCreate(&uart_task, "uart_task", 1024 * 3, NULL, 6, NULL);
	xTaskCreate(&pcf_task, "pcf_task", 1024 * 8, NULL, 2, NULL);
}

This code works for an x ammount of time, but always leads to an error ( esp_code 0x107). The error is caused by the following part of i2c_master_cmd_begin() located in the file i2c.c:

Code: Select all

 res = xSemaphoreTake(p_i2c->cmd_sem, ticks_to_wait);
    if (res == pdFALSE) {
	    ESP_LOGE(I2C_TAG, "Timeout 2!");
        ret = ESP_ERR_TIMEOUT;
I dont think there is any hardware related problem in my setup. The last output generated by the esp looks good to me. After this sequence nothing happens on the lines anymore ( program is still running but outputs the 107 error):
esp32-pcf.png
esp32-pcf.png (23.2 KiB) Viewed 12572 times
So I think the semaphore is not released somewhere (within the specified block time). I am new to the freertos, and I can't figure out why the semaphore could be in use by anything else.
Anyone ever experienced the exact same issue and was able to solve it?

JuergenD
Posts: 6
Joined: Sat Jan 28, 2017 1:09 pm

Re: I2C assert failed,and not work somtimes!

Postby JuergenD » Tue Nov 21, 2017 7:15 pm

Hello,

seems I have exactly the same problem.

I saw also the Problem with this semaphore. When I was digging a little more deeper I saw that the I2C Interrupt stopped working and the i2C Interrupt monitoring timed out.

What I found out was: it never occured if I have no Network traffic through WLAN. (using REST requests). And when I am hammering the System with a high frequency of web requests the I2C fails much more often and the I2C timeout stopps.
I assume that there is a Problem with the Interrupt priorities between I2C and somewhat of WLAN.

Juergen

User avatar
Jakobsen
Posts: 89
Joined: Mon Jan 16, 2017 8:12 am

Re: I2C assert failed,and not work somtimes!

Postby Jakobsen » Wed Nov 22, 2017 10:33 am

Hi
Same pattern here - I have audio running through wlan on Buddy Casinos Web radio and a web socket to monitor/control my amplifier using a I2C interface. I2C interface random crashed and only power cycle can get system back on track.
Love to get this bug nailed.
/Jørgen
Analog Digital IC designer / DevOps @ Merus Audio, Copenhagen, Denmark.
We do novel and best in class Audio amplifiers for consumer products.
Programmed assembler for C-64 back in 1980's, learned some electronics - hacking since then

WiFive
Posts: 3529
Joined: Tue Dec 01, 2015 7:35 am

Re: I2C assert failed,and not work somtimes!

Postby WiFive » Wed Nov 22, 2017 10:44 am


JuergenD
Posts: 6
Joined: Sat Jan 28, 2017 1:09 pm

Re: I2C assert failed,and not work somtimes!

Postby JuergenD » Wed Nov 22, 2017 11:36 am

Hi,

when using the latest IDF from Github, which includes the i2C recovery rework, it recovers properly after a fault without restarting the ESP. So in m application there is no need to hard reset the system to get it run after a fault. A hard reset was necessary in my application, when I was using with the elder esp-idf, without the rework. So recover works for now..

But the root course for the problem is not solved.
The i2c Fails when having Websocket acticities. When there is more activity it fails more often (and recovers now with the latest idf). The more interesting part is why the i2c fails and why the i2c Interrupt times out.
And it does not without websocket activities.

Juergen

abcdcadb
Posts: 36
Joined: Mon Aug 07, 2017 1:28 am

Re: I2C assert failed,and not work somtimes!

Postby abcdcadb » Tue Dec 12, 2017 3:20 am

So, eventually, I2C cant work simultaneously with WLan, it seems that is a bug of SDK or hardware, should we report to company to fix or what else should we do?

Who is online

Users browsing this forum: Majestic-12 [Bot] and 100 guests