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);