drivers: i2c: i2c_nrfx_twim: fail gracefully on dma max size
Different nRF52 devices have different maximum TWI DMA transfer size, and it's easy to hit the limit with i2c displays on nrf52832 (8 bit) and nrf52810 (10 bit). Currently neither the driver or the hal validate the limit, leading to random NACK errors when trying to transfer more data. Add a check on the driver to fail gracefully when going over the limit. Signed-off-by: Fabio Baltieri <fabiobaltieri@google.com>
This commit is contained in:
parent
591c1bb867
commit
6f0a5961e3
12 changed files with 39 additions and 0 deletions
|
@ -38,6 +38,7 @@ struct i2c_nrfx_twim_config {
|
|||
uint16_t msg_buf_size;
|
||||
void (*irq_connect)(void);
|
||||
const struct pinctrl_dev_config *pcfg;
|
||||
uint16_t max_transfer_size;
|
||||
};
|
||||
|
||||
static int i2c_nrfx_twim_recover_bus(const struct device *dev);
|
||||
|
@ -124,6 +125,14 @@ static int i2c_nrfx_twim_transfer(const struct device *dev,
|
|||
cur_xfer.type = (msgs[i].flags & I2C_MSG_READ) ?
|
||||
NRFX_TWIM_XFER_RX : NRFX_TWIM_XFER_TX;
|
||||
|
||||
if (cur_xfer.primary_length > dev_config->max_transfer_size) {
|
||||
LOG_ERR("Trying to transfer more than the maximum size "
|
||||
"for this device: %d > %d",
|
||||
cur_xfer.primary_length,
|
||||
dev_config->max_transfer_size);
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
nrfx_err_t res = nrfx_twim_xfer(&dev_config->twim,
|
||||
&cur_xfer,
|
||||
(msgs[i].flags & I2C_MSG_STOP) ?
|
||||
|
@ -412,6 +421,8 @@ static int i2c_nrfx_twim_init(const struct device *dev)
|
|||
.msg_buf_size = MSG_BUF_SIZE(idx), \
|
||||
.irq_connect = irq_connect##idx, \
|
||||
.pcfg = PINCTRL_DT_DEV_CONFIG_GET(I2C(idx)), \
|
||||
.max_transfer_size = BIT_MASK( \
|
||||
DT_PROP(I2C(idx), easydma_maxcnt_bits)), \
|
||||
}; \
|
||||
PM_DEVICE_DT_DEFINE(I2C(idx), twim_nrfx_pm_action); \
|
||||
I2C_DEVICE_DT_DEFINE(I2C(idx), \
|
||||
|
|
|
@ -99,6 +99,7 @@
|
|||
reg = <0x40003000 0x1000>;
|
||||
clock-frequency = <I2C_BITRATE_STANDARD>;
|
||||
interrupts = <3 NRF_DEFAULT_IRQ_PRIORITY>;
|
||||
easydma-maxcnt-bits = <8>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
|
@ -126,6 +127,7 @@
|
|||
reg = <0x40004000 0x1000>;
|
||||
clock-frequency = <I2C_BITRATE_STANDARD>;
|
||||
interrupts = <4 NRF_DEFAULT_IRQ_PRIORITY>;
|
||||
easydma-maxcnt-bits = <8>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
|
|
|
@ -110,6 +110,7 @@
|
|||
reg = <0x40003000 0x1000>;
|
||||
clock-frequency = <I2C_BITRATE_STANDARD>;
|
||||
interrupts = <3 NRF_DEFAULT_IRQ_PRIORITY>;
|
||||
easydma-maxcnt-bits = <14>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
|
|
|
@ -114,6 +114,7 @@
|
|||
reg = <0x40003000 0x1000>;
|
||||
clock-frequency = <I2C_BITRATE_STANDARD>;
|
||||
interrupts = <3 NRF_DEFAULT_IRQ_PRIORITY>;
|
||||
easydma-maxcnt-bits = <10>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
|
|
|
@ -126,6 +126,7 @@
|
|||
reg = <0x40003000 0x1000>;
|
||||
clock-frequency = <I2C_BITRATE_STANDARD>;
|
||||
interrupts = <3 NRF_DEFAULT_IRQ_PRIORITY>;
|
||||
easydma-maxcnt-bits = <14>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
|
|
|
@ -122,6 +122,7 @@
|
|||
reg = <0x40003000 0x1000>;
|
||||
clock-frequency = <I2C_BITRATE_STANDARD>;
|
||||
interrupts = <3 NRF_DEFAULT_IRQ_PRIORITY>;
|
||||
easydma-maxcnt-bits = <15>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
|
@ -157,6 +158,7 @@
|
|||
reg = <0x40004000 0x1000>;
|
||||
clock-frequency = <I2C_BITRATE_STANDARD>;
|
||||
interrupts = <4 NRF_DEFAULT_IRQ_PRIORITY>;
|
||||
easydma-maxcnt-bits = <15>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
|
|
|
@ -114,6 +114,7 @@
|
|||
reg = <0x40003000 0x1000>;
|
||||
clock-frequency = <I2C_BITRATE_STANDARD>;
|
||||
interrupts = <3 NRF_DEFAULT_IRQ_PRIORITY>;
|
||||
easydma-maxcnt-bits = <8>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
|
@ -149,6 +150,7 @@
|
|||
reg = <0x40004000 0x1000>;
|
||||
clock-frequency = <I2C_BITRATE_STANDARD>;
|
||||
interrupts = <4 NRF_DEFAULT_IRQ_PRIORITY>;
|
||||
easydma-maxcnt-bits = <8>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
|
|
|
@ -121,6 +121,7 @@
|
|||
reg = <0x40003000 0x1000>;
|
||||
clock-frequency = <I2C_BITRATE_STANDARD>;
|
||||
interrupts = <3 NRF_DEFAULT_IRQ_PRIORITY>;
|
||||
easydma-maxcnt-bits = <16>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
|
@ -156,6 +157,7 @@
|
|||
reg = <0x40004000 0x1000>;
|
||||
clock-frequency = <I2C_BITRATE_STANDARD>;
|
||||
interrupts = <4 NRF_DEFAULT_IRQ_PRIORITY>;
|
||||
easydma-maxcnt-bits = <16>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
|
|
|
@ -116,6 +116,7 @@
|
|||
reg = <0x40003000 0x1000>;
|
||||
clock-frequency = <I2C_BITRATE_STANDARD>;
|
||||
interrupts = <3 NRF_DEFAULT_IRQ_PRIORITY>;
|
||||
easydma-maxcnt-bits = <16>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
|
@ -151,6 +152,7 @@
|
|||
reg = <0x40004000 0x1000>;
|
||||
clock-frequency = <I2C_BITRATE_STANDARD>;
|
||||
interrupts = <4 NRF_DEFAULT_IRQ_PRIORITY>;
|
||||
easydma-maxcnt-bits = <16>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
|
|
|
@ -78,6 +78,7 @@ i2c0: i2c@8000 {
|
|||
reg = <0x8000 0x1000>;
|
||||
clock-frequency = <I2C_BITRATE_STANDARD>;
|
||||
interrupts = <8 NRF_DEFAULT_IRQ_PRIORITY>;
|
||||
easydma-maxcnt-bits = <16>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
|
@ -118,6 +119,7 @@ i2c1: i2c@9000 {
|
|||
reg = <0x9000 0x1000>;
|
||||
clock-frequency = <I2C_BITRATE_STANDARD>;
|
||||
interrupts = <9 NRF_DEFAULT_IRQ_PRIORITY>;
|
||||
easydma-maxcnt-bits = <16>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
|
@ -171,6 +173,7 @@ i2c2: i2c@b000 {
|
|||
reg = <0xb000 0x1000>;
|
||||
clock-frequency = <I2C_BITRATE_STANDARD>;
|
||||
interrupts = <11 NRF_DEFAULT_IRQ_PRIORITY>;
|
||||
easydma-maxcnt-bits = <16>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
|
@ -211,6 +214,7 @@ i2c3: i2c@c000 {
|
|||
reg = <0xc000 0x1000>;
|
||||
clock-frequency = <I2C_BITRATE_STANDARD>;
|
||||
interrupts = <12 NRF_DEFAULT_IRQ_PRIORITY>;
|
||||
easydma-maxcnt-bits = <16>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
|
|
|
@ -158,6 +158,7 @@ i2c0: i2c@8000 {
|
|||
reg = <0x8000 0x1000>;
|
||||
clock-frequency = <I2C_BITRATE_STANDARD>;
|
||||
interrupts = <8 NRF_DEFAULT_IRQ_PRIORITY>;
|
||||
easydma-maxcnt-bits = <13>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
|
@ -173,6 +174,7 @@ i2c1: i2c@9000 {
|
|||
reg = <0x9000 0x1000>;
|
||||
clock-frequency = <I2C_BITRATE_STANDARD>;
|
||||
interrupts = <9 NRF_DEFAULT_IRQ_PRIORITY>;
|
||||
easydma-maxcnt-bits = <13>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
|
@ -188,6 +190,7 @@ i2c2: i2c@a000 {
|
|||
reg = <0xa000 0x1000>;
|
||||
clock-frequency = <I2C_BITRATE_STANDARD>;
|
||||
interrupts = <10 NRF_DEFAULT_IRQ_PRIORITY>;
|
||||
easydma-maxcnt-bits = <13>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
|
@ -203,6 +206,7 @@ i2c3: i2c@b000 {
|
|||
reg = <0xb000 0x1000>;
|
||||
clock-frequency = <I2C_BITRATE_STANDARD>;
|
||||
interrupts = <11 NRF_DEFAULT_IRQ_PRIORITY>;
|
||||
easydma-maxcnt-bits = <13>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
|
|
|
@ -15,3 +15,10 @@ properties:
|
|||
|
||||
pinctrl-0:
|
||||
required: true
|
||||
|
||||
easydma-maxcnt-bits:
|
||||
type: int
|
||||
required: true
|
||||
description: |
|
||||
Maximum number of bits available in the EasyDMA MAXCNT register. This
|
||||
property must be set at SoC level DTS files.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue