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 <jerzy.kasenb...@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);