|
37 | 37 | #include "nrfx_spim.h" |
38 | 38 | #include "nrf_gpio.h" |
39 | 39 |
|
| 40 | +// all TWI instances have the same max size |
| 41 | +// 16 bits for 840, 10 bits for 810, 8 bits for 832 |
| 42 | +#define I2C_MAX_XFER_LEN ((1UL << TWIM0_EASYDMA_MAXCNT_SIZE) - 1) |
| 43 | + |
40 | 44 | STATIC twim_peripheral_t twim_peripherals[] = { |
41 | 45 | #if NRFX_CHECK(NRFX_TWIM0_ENABLED) |
42 | 46 | // SPIM0 and TWIM0 share an address. |
43 | 47 | { .twim = NRFX_TWIM_INSTANCE(0), |
44 | | - .in_use = false, |
45 | | - .max_xfer_size = TWIM0_EASYDMA_MAXCNT_SIZE, |
| 48 | + .in_use = false |
46 | 49 | }, |
47 | 50 | #endif |
48 | 51 | #if NRFX_CHECK(NRFX_TWIM1_ENABLED) |
49 | 52 | // SPIM1 and TWIM1 share an address. |
50 | 53 | { .twim = NRFX_TWIM_INSTANCE(1), |
51 | | - .in_use = false, |
52 | | - .max_xfer_size = TWIM1_EASYDMA_MAXCNT_SIZE, |
| 54 | + .in_use = false |
53 | 55 | }, |
54 | 56 | #endif |
55 | 57 | }; |
@@ -198,49 +200,51 @@ void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self) { |
198 | 200 | } |
199 | 201 |
|
200 | 202 | uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len, bool stopBit) { |
201 | | - if(len == 0) |
| 203 | + if(len == 0) { |
202 | 204 | return common_hal_busio_i2c_probe(self, addr) ? 0 : MP_ENODEV; |
| 205 | + } |
203 | 206 |
|
204 | | - const uint32_t max_xfer_size = self->twim_peripheral->max_xfer_size; |
205 | | - const uint32_t parts = len / max_xfer_size; |
206 | | - const uint32_t remainder = len % max_xfer_size; |
207 | 207 | nrfx_err_t err = NRFX_SUCCESS; |
208 | 208 |
|
209 | 209 | nrfx_twim_enable(&self->twim_peripheral->twim); |
210 | 210 |
|
211 | | - for (uint32_t i = 0; i < parts; ++i) { |
212 | | - err = nrfx_twim_tx(&self->twim_peripheral->twim, addr, data + i * max_xfer_size, max_xfer_size, !stopBit); |
213 | | - if (err != NRFX_SUCCESS) |
| 211 | + // break into MAX_XFER_LEN transaction |
| 212 | + while ( len ) { |
| 213 | + const size_t xact_len = MIN(len, I2C_MAX_XFER_LEN); |
| 214 | + |
| 215 | + if ( NRFX_SUCCESS != (err = nrfx_twim_tx(&self->twim_peripheral->twim, addr, data, xact_len, !stopBit)) ) { |
214 | 216 | break; |
215 | | - } |
| 217 | + } |
216 | 218 |
|
217 | | - if ((remainder > 0) && (err == NRFX_SUCCESS)) |
218 | | - err = nrfx_twim_tx(&self->twim_peripheral->twim, addr, data + parts * max_xfer_size, remainder, !stopBit); |
| 219 | + len -= xact_len; |
| 220 | + data += xact_len; |
| 221 | + } |
219 | 222 |
|
220 | 223 | nrfx_twim_disable(&self->twim_peripheral->twim); |
221 | 224 |
|
222 | 225 | return twi_error_to_mp(err); |
223 | 226 | } |
224 | 227 |
|
225 | 228 | uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *data, size_t len) { |
226 | | - if(len == 0) |
| 229 | + if(len == 0) { |
227 | 230 | return 0; |
| 231 | + } |
228 | 232 |
|
229 | | - const uint32_t max_xfer_size = self->twim_peripheral->max_xfer_size; |
230 | | - const uint32_t parts = len / max_xfer_size; |
231 | | - const uint32_t remainder = len % max_xfer_size; |
232 | 233 | nrfx_err_t err = NRFX_SUCCESS; |
233 | 234 |
|
234 | 235 | nrfx_twim_enable(&self->twim_peripheral->twim); |
235 | 236 |
|
236 | | - for (uint32_t i = 0; i < parts; ++i) { |
237 | | - err = nrfx_twim_rx(&self->twim_peripheral->twim, addr, data + i * max_xfer_size, max_xfer_size); |
238 | | - if (err != NRFX_SUCCESS) |
| 237 | + // break into MAX_XFER_LEN transaction |
| 238 | + while ( len ) { |
| 239 | + const size_t xact_len = MIN(len, I2C_MAX_XFER_LEN); |
| 240 | + |
| 241 | + if ( NRFX_SUCCESS != (err = nrfx_twim_rx(&self->twim_peripheral->twim, addr, data, xact_len)) ) { |
239 | 242 | break; |
240 | | - } |
| 243 | + } |
241 | 244 |
|
242 | | - if ((remainder > 0) && (err == NRFX_SUCCESS)) |
243 | | - err = nrfx_twim_rx(&self->twim_peripheral->twim, addr, data + parts * max_xfer_size, remainder); |
| 245 | + len -= xact_len; |
| 246 | + data += xact_len; |
| 247 | + } |
244 | 248 |
|
245 | 249 | nrfx_twim_disable(&self->twim_peripheral->twim); |
246 | 250 |
|
|
0 commit comments