You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by vi...@apache.org on 2018/05/23 01:15:12 UTC
[mynewt-core] branch master updated: Fix/nrf52 i2c hang (#1108)
This is an automated email from the ASF dual-hosted git repository.
vipulrahane pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git
The following commit(s) were added to refs/heads/master by this push:
new 17279ad Fix/nrf52 i2c hang (#1108)
17279ad is described below
commit 17279ad8a4ea38b6b3f95bf4e2054b8e0f013a48
Author: Ben McCrea <be...@users.noreply.github.com>
AuthorDate: Tue May 22 18:15:08 2018 -0700
Fix/nrf52 i2c hang (#1108)
* Workaround for TWI hang which can occur when slave exhibits bad behavior on the bus
* Revise fix and comments for better clarity
---
hw/mcu/nordic/nrf52xxx/src/hal_i2c.c | 33 ++++++++++++++++++++++++++++++---
1 file changed, 30 insertions(+), 3 deletions(-)
diff --git a/hw/mcu/nordic/nrf52xxx/src/hal_i2c.c b/hw/mcu/nordic/nrf52xxx/src/hal_i2c.c
index 9104ad4..8ac5eea 100644
--- a/hw/mcu/nordic/nrf52xxx/src/hal_i2c.c
+++ b/hw/mcu/nordic/nrf52xxx/src/hal_i2c.c
@@ -290,12 +290,14 @@ hal_i2c_master_write(uint8_t i2c_num, struct hal_i2c_master_data *pdata,
int rc = -1;
int i;
uint32_t start;
+ int retry_once = 1;
NRF52_HAL_I2C_RESOLVE(i2c_num, i2c);
regs = i2c->nhi_regs;
regs->ADDRESS = pdata->address;
+retry:
regs->EVENTS_ERROR = 0;
regs->EVENTS_STOPPED = 0;
regs->EVENTS_SUSPENDED = 0;
@@ -311,7 +313,19 @@ hal_i2c_master_write(uint8_t i2c_num, struct hal_i2c_master_data *pdata,
while (!regs->EVENTS_TXDSENT && !regs->EVENTS_ERROR) {
if (os_time_get() - start > timo) {
regs->TASKS_STOP = 1;
- goto err;
+ if (retry_once) {
+ /*
+ * Some I2C slave peripherals cause a glitch on the bus when
+ * they reset which puts the TWI in an unresponsive state.
+ * Disabling and re-enabling the TWI returns it to normal operation.
+ */
+ retry_once = 0;
+ regs->ENABLE = TWI_ENABLE_ENABLE_Disabled;
+ regs->ENABLE = TWI_ENABLE_ENABLE_Enabled;
+ goto retry;
+ } else {
+ goto err;
+ }
}
}
if (regs->EVENTS_ERROR) {
@@ -350,10 +364,12 @@ hal_i2c_master_read(uint8_t i2c_num, struct hal_i2c_master_data *pdata,
int rc = -1;
int i;
uint32_t start;
+ int retry_once = 1;
NRF52_HAL_I2C_RESOLVE(i2c_num, i2c);
regs = i2c->nhi_regs;
+retry:
start = os_time_get();
if (regs->EVENTS_RXDREADY) {
@@ -379,12 +395,23 @@ hal_i2c_master_read(uint8_t i2c_num, struct hal_i2c_master_data *pdata,
for (i = 0; i < pdata->len; i++) {
regs->TASKS_RESUME = 1;
-
while (!regs->EVENTS_RXDREADY && !regs->EVENTS_ERROR) {
if (os_time_get() - start > timo) {
regs->SHORTS = TWI_SHORTS_BB_STOP_Msk;
regs->TASKS_STOP = 1;
- goto err;
+ if (retry_once) {
+ /*
+ * Some I2C slave peripherals cause a glitch on the bus when
+ * they reset which puts the TWI in an unresponsive state.
+ * Disabling and re-enabling the TWI returns it to normal operation.
+ */
+ retry_once = 0;
+ regs->ENABLE = TWI_ENABLE_ENABLE_Disabled;
+ regs->ENABLE = TWI_ENABLE_ENABLE_Enabled;
+ goto retry;
+ } else {
+ goto err;
+ }
}
}
if (regs->EVENTS_ERROR) {
--
To stop receiving notification emails like this one, please contact
vipulrahane@apache.org.