Skip to content

Commit fd5634e

Browse files
authored
Merge pull request adafruit#992 from arturo182/nrf_i2c_fix
nrf: Fix I2C transfers with data larger than HW allows
2 parents 8985b1a + da27253 commit fd5634e

File tree

1 file changed

+29
-2
lines changed
  • ports/nrf/common-hal/busio

1 file changed

+29
-2
lines changed

ports/nrf/common-hal/busio/I2C.c

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include "nrf_gpio.h"
3535

3636
#define INST_NO 0
37+
#define MAX_XFER_SIZE ((1U << NRFX_CONCAT_3(TWIM, INST_NO, _EASYDMA_MAXCNT_SIZE)) - 1)
3738

3839
static uint8_t twi_error_to_mp(const nrfx_err_t err) {
3940
switch (err) {
@@ -152,8 +153,21 @@ uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const u
152153
if(len == 0)
153154
return common_hal_busio_i2c_probe(self, addr) ? 0 : MP_ENODEV;
154155

156+
const uint32_t parts = len / MAX_XFER_SIZE;
157+
const uint32_t remainder = len % MAX_XFER_SIZE;
158+
nrfx_err_t err = NRFX_SUCCESS;
159+
155160
nrfx_twim_enable(&self->twim);
156-
const nrfx_err_t err = nrfx_twim_tx(&self->twim, addr, data, len, !stopBit);
161+
162+
for (uint32_t i = 0; i < parts; ++i) {
163+
err = nrfx_twim_tx(&self->twim, addr, data + i * MAX_XFER_SIZE, MAX_XFER_SIZE, !stopBit);
164+
if (err != NRFX_SUCCESS)
165+
break;
166+
}
167+
168+
if ((remainder > 0) && (err == NRFX_SUCCESS))
169+
err = nrfx_twim_tx(&self->twim, addr, data + parts * MAX_XFER_SIZE, remainder, !stopBit);
170+
157171
nrfx_twim_disable(&self->twim);
158172

159173
return twi_error_to_mp(err);
@@ -163,8 +177,21 @@ uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t
163177
if(len == 0)
164178
return 0;
165179

180+
const uint32_t parts = len / MAX_XFER_SIZE;
181+
const uint32_t remainder = len % MAX_XFER_SIZE;
182+
nrfx_err_t err = NRFX_SUCCESS;
183+
166184
nrfx_twim_enable(&self->twim);
167-
const nrfx_err_t err = nrfx_twim_rx(&self->twim, addr, data, len);
185+
186+
for (uint32_t i = 0; i < parts; ++i) {
187+
err = nrfx_twim_rx(&self->twim, addr, data + i * MAX_XFER_SIZE, MAX_XFER_SIZE);
188+
if (err != NRFX_SUCCESS)
189+
break;
190+
}
191+
192+
if ((remainder > 0) && (err == NRFX_SUCCESS))
193+
err = nrfx_twim_rx(&self->twim, addr, data + parts * MAX_XFER_SIZE, remainder);
194+
168195
nrfx_twim_disable(&self->twim);
169196

170197
return twi_error_to_mp(err);

0 commit comments

Comments
 (0)