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 2021/06/29 21:15:22 UTC

[mynewt-core] branch master updated: nrf5340/i2c: Fix STOP event handling

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 f6c1534  nrf5340/i2c: Fix STOP event handling
     new d1404c1  Merge pull request #2632 from kasjer/kasjer/nrf5340-i2c-stop-fix
f6c1534 is described below

commit f6c15346ea9eafbb5e7d1dae2fdfa5db78f53bb4
Author: Jerzy Kasenberg <je...@codecoup.pl>
AuthorDate: Fri Jun 25 16:36:53 2021 +0200

    nrf5340/i2c: Fix STOP event handling
    
    After read or write that ended with error (address nack)
    interrupts are blocked and stop condition is generated
    that will rise EVENTS_STOP later on.
    
    Read or write finishes with this event active.
    
    On next write or read interrupt were enabled before EVENTS_STOP
    was cleared resulting in interrupt handling that would signal
    semaphore.
    In some cases that may lead to data corruption when code reuses buffer
    while I2C transaction is ongoing.
    
    This changes clears old events before enabling interrupts.
---
 hw/bus/drivers/i2c_nrf5340/src/i2c_nrf5340.c | 23 +++++++++++++----------
 1 file changed, 13 insertions(+), 10 deletions(-)

diff --git a/hw/bus/drivers/i2c_nrf5340/src/i2c_nrf5340.c b/hw/bus/drivers/i2c_nrf5340/src/i2c_nrf5340.c
index 11e3c90..a3b9c45 100644
--- a/hw/bus/drivers/i2c_nrf5340/src/i2c_nrf5340.c
+++ b/hw/bus/drivers/i2c_nrf5340/src/i2c_nrf5340.c
@@ -270,15 +270,17 @@ bus_i2c_nrf5340_read(struct bus_dev *bdev, struct bus_node *bnode,
     nrf_twim->RXD.PTR = (uint32_t)buf;
     nrf_twim->RXD.MAXCNT = length;
     nrf_twim->RXD.LIST = 0;
-    nrf_twim->INTEN = TWIM_INTEN_ERROR_Msk | TWIM_INTENCLR_STOPPED_Msk;
-    nrf_twim->SHORTS = TWIM_SHORTS_LASTRX_STOP_Msk;
 
     nrf_twim->EVENTS_STOPPED = 0;
     nrf_twim->EVENTS_ERROR = 0;
     nrf_twim->EVENTS_SUSPENDED = 0;
     nrf_twim->EVENTS_RXSTARTED = 0;
-    nrf_twim->TASKS_RESUME = 1;
     nrf_twim->EVENTS_LASTRX = 0;
+
+    nrf_twim->INTEN = TWIM_INTEN_ERROR_Msk | TWIM_INTENCLR_STOPPED_Msk;
+    nrf_twim->SHORTS = TWIM_SHORTS_LASTRX_STOP_Msk;
+
+    nrf_twim->TASKS_RESUME = 1;
     nrf_twim->TASKS_STARTRX = 1;
 
     rc = os_sem_pend(&dd->sem, timeout);
@@ -324,7 +326,14 @@ bus_i2c_nrf5340_write(struct bus_dev *bdev, struct bus_node *bnode,
 
     nrf_twim->TXD.PTR = (uint32_t)buf;
     nrf_twim->TXD.LIST = 0;
-    nrf_twim->INTENSET = TWIM_INTEN_ERROR_Msk;
+
+    nrf_twim->EVENTS_ERROR = 0;
+    nrf_twim->EVENTS_STOPPED = 0;
+    nrf_twim->EVENTS_SUSPENDED = 0;
+    nrf_twim->EVENTS_TXSTARTED = 0;
+    nrf_twim->EVENTS_LASTTX = 0;
+
+    nrf_twim->INTEN = TWIM_INTEN_ERROR_Msk;
     if (last_op) {
         nrf_twim->INTENSET = TWIM_INTENSET_STOPPED_Msk;
         nrf_twim->SHORTS = TWIM_SHORTS_LASTTX_STOP_Msk;
@@ -332,13 +341,7 @@ bus_i2c_nrf5340_write(struct bus_dev *bdev, struct bus_node *bnode,
         nrf_twim->INTENSET = TWIM_INTENSET_SUSPENDED_Msk;
         nrf_twim->SHORTS = TWIM_SHORTS_LASTTX_SUSPEND_Msk;
     }
-
-    nrf_twim->EVENTS_ERROR = 0;
-    nrf_twim->EVENTS_STOPPED = 0;
-    nrf_twim->EVENTS_SUSPENDED = 0;
-    nrf_twim->EVENTS_TXSTARTED = 0;
     nrf_twim->TASKS_RESUME = 1;
-    nrf_twim->EVENTS_LASTTX = 0;
     nrf_twim->TASKS_STARTTX = 1;
 
     rc = os_sem_pend(&dd->sem, timeout);