You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by je...@apache.org on 2021/02/01 07:19:45 UTC
[mynewt-core] branch master updated (fdf1055 -> 8b7f0d2)
This is an automated email from the ASF dual-hosted git repository.
jerzy pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git.
from fdf1055 Add nucleo-l073rz BSP
new 403e183 bus/i2c_da1469x: Fix race condition issue
new 8b7f0d2 bus/i2c_da1469x: Small insignificant fixes
The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
hw/bus/drivers/i2c_da1469x/src/i2c_da1469x.c | 41 ++++++++++++----------------
1 file changed, 18 insertions(+), 23 deletions(-)
[mynewt-core] 01/02: bus/i2c_da1469x: Fix race condition issue
Posted by je...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
jerzy pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git
commit 403e1835007f9c15deb89f27d16d93a67a94d2cb
Author: Jerzy Kasenberg <je...@codecoup.pl>
AuthorDate: Tue Jan 5 15:21:23 2021 +0100
bus/i2c_da1469x: Fix race condition issue
STOP condition was correctly handled it could lead to
cases when stop condition from previous transaction was
detected later and disrupted code flow of next transfers.
- i2c_da1469x_clear_int() was called after reading active interrupts
but new interrupts could just pop up in after register was read.
This is the case of stop condition interrupt that has to be clear
by software. Now it is explicitly cleared when it was detected.
- when interrupt was fired for M_RX_FULL and all data requested was
read but stop condition was not detected yet. Transfer was finished
even though NOSTOP flag was not set, and code should wait for
stop M_STOP_DET. This lead to previous stop condition messing with
next transfer.
All this problem surfaced when system was running on 96MHz.
---
hw/bus/drivers/i2c_da1469x/src/i2c_da1469x.c | 37 +++++++++++++---------------
1 file changed, 17 insertions(+), 20 deletions(-)
diff --git a/hw/bus/drivers/i2c_da1469x/src/i2c_da1469x.c b/hw/bus/drivers/i2c_da1469x/src/i2c_da1469x.c
index 79aa2d6..084b762 100644
--- a/hw/bus/drivers/i2c_da1469x/src/i2c_da1469x.c
+++ b/hw/bus/drivers/i2c_da1469x/src/i2c_da1469x.c
@@ -180,7 +180,7 @@ i2c_da1469x_fill_tx_dma_buffer(struct i2c_da1469x_dev_data *dd)
dd->tx_dma_buf[0] = I2C_I2C_DATA_CMD_REG_I2C_CMD_Msk |
I2C_I2C_DATA_CMD_REG_I2C_STOP_Msk;
} else {
- /* Stop requested more send lentght - 1 without stop */
+ /* Stop requested more send length - 1 without stop */
dd->tx_dma_buf[0] = I2C_I2C_DATA_CMD_REG_I2C_CMD_Msk;
--length;
}
@@ -256,8 +256,6 @@ i2c_da1469x_fill_fifo_for_rx(I2C_Type *i2c_regs, struct i2c_da1469x_dev_data *dd
return;
}
- i2c_da1469x_clear_int(i2c_regs);
-
while ((transfer->wlen > 0) &&
i2c_regs->I2C_STATUS_REG & I2C_I2C_STATUS_REG_TFNF_Msk) {
transfer->wlen--;
@@ -266,6 +264,8 @@ i2c_da1469x_fill_fifo_for_rx(I2C_Type *i2c_regs, struct i2c_da1469x_dev_data *dd
} else {
i2c_regs->I2C_DATA_CMD_REG = (1U << I2C_I2C_DATA_CMD_REG_I2C_CMD_Pos) |
(1U << I2C_I2C_DATA_CMD_REG_I2C_STOP_Pos);
+ /* All data in tx buffer, no need for TX interrupt any more */
+ i2c_regs->I2C_INTR_MASK_REG &= ~I2C_I2C_INTR_MASK_REG_M_TX_EMPTY_Msk;
}
}
@@ -275,29 +275,28 @@ i2c_da1469x_fill_fifo_for_rx(I2C_Type *i2c_regs, struct i2c_da1469x_dev_data *dd
*transfer->data++ = (uint8_t)i2c_regs->I2C_DATA_CMD_REG;
transfer->rlen--;
if (transfer->rlen == 0) {
- i2c_regs->I2C_INTR_MASK_REG = 0;
- i2c_da1469x_clear_int(i2c_regs);
- transfer->started = 0;
- os_sem_release(&dd->sem);
+ i2c_regs->I2C_INTR_MASK_REG &= ~I2C_I2C_INTR_MASK_REG_M_RX_FULL_Msk;
+ if (transfer->nostop) {
+ transfer->started = 0;
+ dd->errorsrc = 0;
+ os_sem_release(&dd->sem);
+ }
}
}
}
if (intr_stat & I2C_I2C_INTR_MASK_REG_M_STOP_DET_Msk) {
+ /* Clear STOP condition interrupt */
+ (void)i2c_regs->I2C_CLR_STOP_DET_REG;
i2c_regs->I2C_INTR_MASK_REG = 0;
- assert(transfer->started == 0 && transfer->rlen == 0);
- if (transfer->started || transfer->rlen) {
+ if (transfer->started) {
transfer->started = 0;
+ if (transfer->rlen > 0) {
+ dd->errorsrc = I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_USER_ABRT_Msk;
+ }
transfer->rlen = 0;
- dd->errorsrc = I2C_I2C_TX_ABRT_SOURCE_REG_ABRT_USER_ABRT_Msk;
os_sem_release(&dd->sem);
}
- return;
- }
-
- /* All data in tx buffer, no need for TX interrupt any more */
- if (transfer->wlen == 0) {
- i2c_regs->I2C_INTR_MASK_REG &= ~I2C_I2C_INTR_MASK_REG_M_TX_EMPTY_Msk;
}
}
@@ -332,8 +331,6 @@ i2c_da1469x_fill_fifo_for_tx(I2C_Type *i2c_regs, struct i2c_da1469x_dev_data *dd
return;
}
- i2c_da1469x_clear_int(i2c_regs);
-
while ((transfer->wlen > 0) &&
i2c_regs->I2C_STATUS_REG & I2C_I2C_STATUS_REG_TFNF_Msk) {
transfer->wlen--;
@@ -346,7 +343,6 @@ i2c_da1469x_fill_fifo_for_tx(I2C_Type *i2c_regs, struct i2c_da1469x_dev_data *dd
if (transfer->wlen == 0) {
if (transfer->nostop) {
i2c_regs->I2C_INTR_MASK_REG = 0;
- i2c_da1469x_clear_int(i2c_regs);
transfer->started = 0;
os_sem_release(&dd->sem);
}
@@ -357,6 +353,8 @@ i2c_da1469x_fill_fifo_for_tx(I2C_Type *i2c_regs, struct i2c_da1469x_dev_data *dd
}
if (intr_stat & I2C_I2C_INTR_MASK_REG_M_STOP_DET_Msk) {
+ /* Clear STOP condition interrupt */
+ (void)i2c_regs->I2C_CLR_STOP_DET_REG;
i2c_regs->I2C_INTR_MASK_REG = 0;
if (transfer->started) {
transfer->started = 0;
@@ -563,7 +561,6 @@ i2c_da1469x_write(struct bus_dev *bdev, struct bus_node *bnode,
BUS_DEBUG_VERIFY_DEV(dev);
BUS_DEBUG_VERIFY_NODE(node);
-
i2c_regs = da1469x_i2c[dev->cfg.i2c_num].regs;
dd = &i2c_dev_data[dev->cfg.i2c_num];
[mynewt-core] 02/02: bus/i2c_da1469x: Small insignificant fixes
Posted by je...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
jerzy pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git
commit 8b7f0d2325455634fe4bdc06683826093e484211
Author: Jerzy Kasenberg <je...@codecoup.pl>
AuthorDate: Fri Jan 8 13:14:24 2021 +0100
bus/i2c_da1469x: Small insignificant fixes
- unused wariable warning removed
- inclusion of dma header was unnecessarily conditional
---
hw/bus/drivers/i2c_da1469x/src/i2c_da1469x.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/hw/bus/drivers/i2c_da1469x/src/i2c_da1469x.c b/hw/bus/drivers/i2c_da1469x/src/i2c_da1469x.c
index 084b762..5fb4a2c 100644
--- a/hw/bus/drivers/i2c_da1469x/src/i2c_da1469x.c
+++ b/hw/bus/drivers/i2c_da1469x/src/i2c_da1469x.c
@@ -26,10 +26,7 @@
#include "bus/bus_driver.h"
#include "bus/drivers/i2c_common.h"
#include "mcu/mcu.h"
-
-#if MYNEWT_VAL(I2C_DA1469X_BUS_DRIVER)
#include "mcu/da1469x_dma.h"
-#endif
#if MYNEWT_VAL(I2C_DA1469X_STAT)
#include "stats/stats.h"
@@ -388,6 +385,7 @@ i2c_da1469x_init_node(struct bus_dev *bdev, struct bus_node *bnode, void *arg)
{
struct bus_i2c_node *node = (struct bus_i2c_node *)bnode;
struct bus_i2c_node_cfg *cfg = arg;
+ (void)bdev;
BUS_DEBUG_POISON_NODE(node);