|
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) |
| 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