I²C clock problem
Re: I²C clock problem
Have you enabled Power Management? The DFS might be the cause of the issue as your i2c_master_read_slave doesnt include pm locks.
Re: I²C clock problem
Hi,
Thanks for your reply!
I have tried your suggestion, both using pm locks and disabled DFS in menuconfig:
The clock looks better now but it still behaves strange and do not communicate with the gauge IC with this frequency.
Code: Select all
void Initialize_pm_lock()
{
esp_err_t ret;
if((ret = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 1, "CPU_FREQ_MAX", &pm_lock_handle)) != ESP_OK) {
printf("pm config error %s\n", \
ret == ESP_ERR_INVALID_ARG ? "ESP_ERR_INVALID_ARG" : \
(ret == ESP_ERR_NOT_SUPPORTED ? "ESP_ERR_NOT_SUPPORTED" :\
"ESP_ERR_NO_MEM"));
}
}
esp_err_t i2c_master_read_slave(i2c_port_t i2c_num, uint8_t slave_address, uint8_t registerAddress, uint8_t* data_rd, size_t size)
{
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, slave_address << 1 | I2C_MASTER_WRITE, I2C_ACK_CHECK_EN);
i2c_master_write_byte(cmd, registerAddress, I2C_ACK_CHECK_EN);
i2c_master_start(cmd);
i2c_master_write_byte(cmd, slave_address << 1 | I2C_READ_BIT, I2C_ACK_CHECK_EN);
if (size > 1) {
i2c_master_read(cmd, data_rd, size - 1, I2C_ACK_VAL);
}
i2c_master_read_byte(cmd, data_rd + size - 1, I2C_NACK_VAL);
i2c_master_stop(cmd);
esp_pm_lock_acquire(pm_lock_handle);
esp_err_t ret = i2c_master_cmd_begin(i2c_num, cmd, 100000 / portTICK_RATE_MS);
esp_pm_lock_release(pm_lock_handle);
i2c_cmd_link_delete(cmd);
if(ret != ESP_OK)
ESP_LOGE(TAG, "i2c error: %s", esp_err_to_name(ret));
return ret;
}
Re: I²C clock problem
The last recordings where made using the modefied i2c_master_clear_bus function. Here is a recording using the orginal master branch:persan666 wrote: ↑Mon Jan 28, 2019 9:30 amHi,
Thanks for your reply!
I have tried your suggestion, both using pm locks and disabled DFS in menuconfig:
The clock looks better now but it still behaves strange and do not communicate with the gauge IC with this frequency.DFS turned on with power locksCode: Select all
void Initialize_pm_lock() { esp_err_t ret; if((ret = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 1, "CPU_FREQ_MAX", &pm_lock_handle)) != ESP_OK) { printf("pm config error %s\n", \ ret == ESP_ERR_INVALID_ARG ? "ESP_ERR_INVALID_ARG" : \ (ret == ESP_ERR_NOT_SUPPORTED ? "ESP_ERR_NOT_SUPPORTED" :\ "ESP_ERR_NO_MEM")); } } esp_err_t i2c_master_read_slave(i2c_port_t i2c_num, uint8_t slave_address, uint8_t registerAddress, uint8_t* data_rd, size_t size) { i2c_cmd_handle_t cmd = i2c_cmd_link_create(); i2c_master_start(cmd); i2c_master_write_byte(cmd, slave_address << 1 | I2C_MASTER_WRITE, I2C_ACK_CHECK_EN); i2c_master_write_byte(cmd, registerAddress, I2C_ACK_CHECK_EN); i2c_master_start(cmd); i2c_master_write_byte(cmd, slave_address << 1 | I2C_READ_BIT, I2C_ACK_CHECK_EN); if (size > 1) { i2c_master_read(cmd, data_rd, size - 1, I2C_ACK_VAL); } i2c_master_read_byte(cmd, data_rd + size - 1, I2C_NACK_VAL); i2c_master_stop(cmd); esp_pm_lock_acquire(pm_lock_handle); esp_err_t ret = i2c_master_cmd_begin(i2c_num, cmd, 100000 / portTICK_RATE_MS); esp_pm_lock_release(pm_lock_handle); i2c_cmd_link_delete(cmd); if(ret != ESP_OK) ESP_LOGE(TAG, "i2c error: %s", esp_err_to_name(ret)); return ret; }
DFS on with power locks 100KHz.png
DFS turned off and without power locks.
DFS off 100KHz.png
Re: I²C clock problem
If you disabled DFS, you dont need the locks but Ive found DFS saves quite a bit of power, so its best to leave it on in the future (the PM lock should prevent further scl-messing-up-ness when DFS is turned on). I cant tell without a bit more information on the actual timing of your I2C transaction, but it looks like youre encountering the same issue I had talking to a BQ27621 (another TI battery monitor from the BQ35100 you are using). You should try adding this to right after you initialize I2C master:persan666 wrote: ↑Mon Jan 28, 2019 11:20 amThe last recordings where made using the modefied i2c_master_clear_bus function. Here is a recording using the orginal master branch:persan666 wrote: ↑Mon Jan 28, 2019 9:30 amHi,
Thanks for your reply!
I have tried your suggestion, both using pm locks and disabled DFS in menuconfig:
The clock looks better now but it still behaves strange and do not communicate with the gauge IC with this frequency.DFS turned on with power locksCode: Select all
void Initialize_pm_lock() { esp_err_t ret; if((ret = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 1, "CPU_FREQ_MAX", &pm_lock_handle)) != ESP_OK) { printf("pm config error %s\n", \ ret == ESP_ERR_INVALID_ARG ? "ESP_ERR_INVALID_ARG" : \ (ret == ESP_ERR_NOT_SUPPORTED ? "ESP_ERR_NOT_SUPPORTED" :\ "ESP_ERR_NO_MEM")); } } esp_err_t i2c_master_read_slave(i2c_port_t i2c_num, uint8_t slave_address, uint8_t registerAddress, uint8_t* data_rd, size_t size) { i2c_cmd_handle_t cmd = i2c_cmd_link_create(); i2c_master_start(cmd); i2c_master_write_byte(cmd, slave_address << 1 | I2C_MASTER_WRITE, I2C_ACK_CHECK_EN); i2c_master_write_byte(cmd, registerAddress, I2C_ACK_CHECK_EN); i2c_master_start(cmd); i2c_master_write_byte(cmd, slave_address << 1 | I2C_READ_BIT, I2C_ACK_CHECK_EN); if (size > 1) { i2c_master_read(cmd, data_rd, size - 1, I2C_ACK_VAL); } i2c_master_read_byte(cmd, data_rd + size - 1, I2C_NACK_VAL); i2c_master_stop(cmd); esp_pm_lock_acquire(pm_lock_handle); esp_err_t ret = i2c_master_cmd_begin(i2c_num, cmd, 100000 / portTICK_RATE_MS); esp_pm_lock_release(pm_lock_handle); i2c_cmd_link_delete(cmd); if(ret != ESP_OK) ESP_LOGE(TAG, "i2c error: %s", esp_err_to_name(ret)); return ret; }
DFS on with power locks 100KHz.png
DFS turned off and without power locks.
DFS off 100KHz.png
Org master i2c_master_clear_bus DFS on with power locks 100KHz.png
Code: Select all
#define I2C_MASTER_TRANSACTION_TIMEOUT_MS (10)
...
i2c_set_timeout(I2C_MASTER_PORT, I2C_APB_CLK_FREQ * I2C_MASTER_TRANSACTION_TIMEOUT_MS / 1000)
https://www.esp32.com/viewtopic.php?f=13&t=6203#p37174
Re: I²C clock problem
Thank you for your reply!mrrosen wrote: ↑Mon Jan 28, 2019 11:09 pmIf you disabled DFS, you dont need the locks but Ive found DFS saves quite a bit of power, so its best to leave it on in the future (the PM lock should prevent further scl-messing-up-ness when DFS is turned on). I cant tell without a bit more information on the actual timing of your I2C transaction, but it looks like youre encountering the same issue I had talking to a BQ27621 (another TI battery monitor from the BQ35100 you are using). You should try adding this to right after you initialize I2C master:persan666 wrote: ↑Mon Jan 28, 2019 11:20 amThe last recordings where made using the modefied i2c_master_clear_bus function. Here is a recording using the orginal master branch:persan666 wrote: ↑Mon Jan 28, 2019 9:30 am
Hi,
Thanks for your reply!
I have tried your suggestion, both using pm locks and disabled DFS in menuconfig:
The clock looks better now but it still behaves strange and do not communicate with the gauge IC with this frequency.DFS turned on with power locksCode: Select all
void Initialize_pm_lock() { esp_err_t ret; if((ret = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 1, "CPU_FREQ_MAX", &pm_lock_handle)) != ESP_OK) { printf("pm config error %s\n", \ ret == ESP_ERR_INVALID_ARG ? "ESP_ERR_INVALID_ARG" : \ (ret == ESP_ERR_NOT_SUPPORTED ? "ESP_ERR_NOT_SUPPORTED" :\ "ESP_ERR_NO_MEM")); } } esp_err_t i2c_master_read_slave(i2c_port_t i2c_num, uint8_t slave_address, uint8_t registerAddress, uint8_t* data_rd, size_t size) { i2c_cmd_handle_t cmd = i2c_cmd_link_create(); i2c_master_start(cmd); i2c_master_write_byte(cmd, slave_address << 1 | I2C_MASTER_WRITE, I2C_ACK_CHECK_EN); i2c_master_write_byte(cmd, registerAddress, I2C_ACK_CHECK_EN); i2c_master_start(cmd); i2c_master_write_byte(cmd, slave_address << 1 | I2C_READ_BIT, I2C_ACK_CHECK_EN); if (size > 1) { i2c_master_read(cmd, data_rd, size - 1, I2C_ACK_VAL); } i2c_master_read_byte(cmd, data_rd + size - 1, I2C_NACK_VAL); i2c_master_stop(cmd); esp_pm_lock_acquire(pm_lock_handle); esp_err_t ret = i2c_master_cmd_begin(i2c_num, cmd, 100000 / portTICK_RATE_MS); esp_pm_lock_release(pm_lock_handle); i2c_cmd_link_delete(cmd); if(ret != ESP_OK) ESP_LOGE(TAG, "i2c error: %s", esp_err_to_name(ret)); return ret; }
DFS on with power locks 100KHz.png
DFS turned off and without power locks.
DFS off 100KHz.png
Org master i2c_master_clear_bus DFS on with power locks 100KHz.png
Details can be found here:Code: Select all
#define I2C_MASTER_TRANSACTION_TIMEOUT_MS (10) ... i2c_set_timeout(I2C_MASTER_PORT, I2C_APB_CLK_FREQ * I2C_MASTER_TRANSACTION_TIMEOUT_MS / 1000)
https://www.esp32.com/viewtopic.php?f=13&t=6203#p37174
I almost thought this would be the right medicine for the problem but no there are still problems. I have included recordings with different frequencies and one can see where it goes wrong. I have done test using 10, 100, 400 Khz and only 10KHz works both with version 3.2 and master. I feel that I am close to a solution now but there is still something that is not quite rigth.
This is the 100KHz recording where it goes wrong. This is a recording with 10KHz that works.
-
- Posts: 6
- Joined: Thu Jan 31, 2019 2:53 pm
Re: I²C clock problem
@persan666 did you find any solution to the problem? I'm using a bq27441 fuel gauge and I'm experiencing the exact same problem, DFS is disabled and I increased the timeout time, I have no errors, just inconsistent clock when using 400 kHz.
Re: I²C clock problem
Hi dragondgold,dragondgold wrote: ↑Tue Feb 05, 2019 6:01 pm@persan666 did you find any solution to the problem? I'm using a bq27441 fuel gauge and I'm experiencing the exact same problem, DFS is disabled and I increased the timeout time, I have no errors, just inconsistent clock when using 400 kHz.
Unfortunately I haven't found a solution yet. It seems that the problem is still that the timeout time is too short sometimes. It do gets better if I increase the timeout time but it is not enough when running 100KHz I2c and 240MHz CPU. It works with 50KHz. The recording above shows the timeout at the end.
If you find something, please let me know.
- gunar.kroeger
- Posts: 143
- Joined: Fri Jul 27, 2018 6:48 pm
Re: I²C clock problem
We are also getting all sorts of issues when i2c is set to a clock higher than 10kHz trying to communicate with a GPS module... had to change back to uart, but still looking for a solution.
"Running was invented in 1612 by Thomas Running when he tried to walk twice at the same time."
-
- Posts: 6
- Joined: Thu Jan 31, 2019 2:53 pm
Re: I²C clock problem
I managed to get my bq27441 working with I2C at 400 kHz. As noted in the datasheet to get this working with speeds higher than 100 kHz there's some special sequence needed:
I started experiencing this problem after having my I2C bus working at 400 kHz and then added the bq27441 fuel gauge and started experiencing these issues. After rewriting my driver to take this into account I managed to get it working at 400 kHz with 4 devices attached to the bus and 10k resistors as pull-up. So I guess the problem is mainly due to the fuel gauge and not the I2C driver? At least in my case.
I started experiencing this problem after having my I2C bus working at 400 kHz and then added the bq27441 fuel gauge and started experiencing these issues. After rewriting my driver to take this into account I managed to get it working at 400 kHz with 4 devices attached to the bus and 10k resistors as pull-up. So I guess the problem is mainly due to the fuel gauge and not the I2C driver? At least in my case.
Who is online
Users browsing this forum: No registered users and 109 guests