65
65
#define DEBUG_PRINTF (...)
66
66
#endif
67
67
68
- #define DEFAULT_TIMEOUT_US (1000) // timeout for waiting for address NACK
69
- #define MAXIMUM_TIMEOUT_US (10000) // timeout for waiting for RX
68
+ #define MAXIMUM_TIMEOUT_US (10000) // timeout for waiting for RX/TX
70
69
#define I2C_READ_BIT 0x01 // read bit
71
70
71
+ static uint32_t tick2us = 1 ;
72
+
72
73
/* Keep track of what mode the peripheral is in. On NRF52, Driver mode can use TWIM. */
73
74
typedef enum {
74
75
NORDIC_I2C_MODE_NONE ,
@@ -106,6 +107,9 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl)
106
107
struct i2c_s * config = obj ;
107
108
#endif
108
109
110
+ const ticker_info_t * ti = lp_ticker_get_info ();
111
+ tick2us = 1000000 / ti -> frequency ;
112
+
109
113
/* Get instance from pin configuration. */
110
114
int instance = pin_instance_i2c (sda , scl );
111
115
MBED_ASSERT (instance < NRFX_TWI_ENABLED_COUNT );
@@ -169,6 +173,21 @@ void i2c_frequency(i2c_t *obj, int hz)
169
173
config -> update = true;
170
174
}
171
175
176
+ static uint32_t byte_timeout (nrf_twi_frequency_t frequency )
177
+ {
178
+ uint32_t timeout = 0 ;
179
+ // set timeout in [us] as: 10 [bits] * 1000000 / frequency
180
+ if (frequency == NRF_TWI_FREQ_100K ) {
181
+ timeout = 100 ; // 10 * 10us
182
+ } else if (frequency == NRF_TWI_FREQ_250K ) {
183
+ timeout = 40 ; // 10 * 4us
184
+ } else if (frequency == NRF_TWI_FREQ_400K ) {
185
+ timeout = 25 ; // 10 * 2.5us
186
+ }
187
+
188
+ return timeout ;
189
+ }
190
+
172
191
const PinMap * i2c_master_sda_pinmap ()
173
192
{
174
193
return PinMap_I2C_testing ;
@@ -354,69 +373,71 @@ int i2c_byte_write(i2c_t *obj, int data)
354
373
struct i2c_s * config = obj ;
355
374
#endif
356
375
357
- int instance = config -> instance ;
376
+ NRF_TWI_Type * p_twi = nordic_nrf5_twi_register [ config -> instance ] ;
358
377
int result = 1 ; // default to ACK
378
+ uint32_t start_us , now_us , timeout ;
359
379
360
- /* Check if this is the first byte to be transferred. If it is, then send start signal and address. */
361
380
if (config -> state == NORDIC_TWI_STATE_START ) {
362
381
config -> state = NORDIC_TWI_STATE_BUSY ;
363
382
364
- /* Beginning of new transaction, configure peripheral if necessary. */
383
+ config -> update = true;
365
384
i2c_configure_twi_instance (obj );
366
385
367
- /* Set I2C device address. NOTE: due to hardware limitations only 7-bit addresses are supported. */
368
- nrf_twi_address_set (nordic_nrf5_twi_register [instance ], data >> 1 );
369
-
370
- /* If read bit is set, trigger read task otherwise trigger write task. */
371
386
if (data & I2C_READ_BIT ) {
372
- /* For timing reasons, reading bytes requires shorts to suspend peripheral after each byte. */
373
- nrf_twi_shorts_set (nordic_nrf5_twi_register [instance ], NRF_TWI_SHORT_BB_SUSPEND_MASK );
374
- nrf_twi_task_trigger (nordic_nrf5_twi_register [instance ], NRF_TWI_TASK_STARTRX );
387
+ nrf_twi_event_clear (p_twi , NRF_TWI_EVENT_STOPPED );
388
+ nrf_twi_event_clear (p_twi , NRF_TWI_EVENT_RXDREADY );
389
+ nrf_twi_event_clear (p_twi , NRF_TWI_EVENT_ERROR );
390
+ (void )nrf_twi_errorsrc_get_and_clear (p_twi );
391
+
392
+ nrf_twi_shorts_set (p_twi , NRF_TWI_SHORT_BB_SUSPEND_MASK );
393
+
394
+ nrf_twi_address_set (p_twi , data >> 1 );
395
+ nrf_twi_task_trigger (p_twi , NRF_TWI_TASK_RESUME );
396
+ nrf_twi_task_trigger (p_twi , NRF_TWI_TASK_STARTRX );
375
397
} else {
376
- /* Reset shorts register. */
377
- nrf_twi_shorts_set (nordic_nrf5_twi_register [instance ], 0 );
378
- nrf_twi_task_trigger (nordic_nrf5_twi_register [instance ], NRF_TWI_TASK_STARTTX );
379
- }
398
+ nrf_twi_event_clear (p_twi , NRF_TWI_EVENT_STOPPED );
399
+ nrf_twi_event_clear (p_twi , NRF_TWI_EVENT_TXDSENT );
400
+ nrf_twi_event_clear (p_twi , NRF_TWI_EVENT_ERROR );
401
+ nrf_twi_event_clear (p_twi , NRF_TWI_EVENT_BB );
402
+ (void )nrf_twi_errorsrc_get_and_clear (p_twi );
380
403
381
- /* Setup stop watch for timeout. */
382
- uint32_t start_us = lp_ticker_read ();
383
- uint32_t now_us = start_us ;
404
+ nrf_twi_shorts_set (p_twi , 0 );
384
405
385
- /* Block until timeout or an address error has been detected. */
386
- while (((now_us - start_us ) < DEFAULT_TIMEOUT_US ) &&
387
- !(nrf_twi_event_check (nordic_nrf5_twi_register [instance ], NRF_TWI_EVENT_ERROR ))) {
388
- now_us = lp_ticker_read ();
406
+ nrf_twi_address_set (p_twi , data >> 1 );
407
+ nrf_twi_task_trigger (p_twi , NRF_TWI_TASK_RESUME );
408
+ nrf_twi_task_trigger (p_twi , NRF_TWI_TASK_STARTTX );
389
409
}
410
+ /* Wait two byte duration for address ACK */
411
+ timeout = 2 * byte_timeout (config -> frequency );
412
+ } else {
413
+ nrf_twi_event_clear (p_twi , NRF_TWI_EVENT_TXDSENT );
414
+ nrf_twi_event_clear (p_twi , NRF_TWI_EVENT_ERROR );
415
+ nrf_twi_event_clear (p_twi , NRF_TWI_EVENT_BB );
416
+ (void )nrf_twi_errorsrc_get_and_clear (p_twi );
417
+
418
+ nrf_twi_task_trigger (p_twi , NRF_TWI_TASK_RESUME );
419
+ nrf_twi_txd_set (p_twi , data );
420
+ /* Wait ten byte duration for data ACK */
421
+ timeout = 10 * byte_timeout (config -> frequency );
422
+ }
390
423
391
- /* Check error register and update return value if an address NACK was detected. */
392
- uint32_t error = nrf_twi_errorsrc_get_and_clear ( nordic_nrf5_twi_register [ instance ]) ;
424
+ start_us = tick2us * lp_ticker_read ();
425
+ now_us = start_us ;
393
426
394
- if (error & NRF_TWI_ERROR_ADDRESS_NACK ) {
395
- result = 0 ; // set NACK
396
- } else {
397
- /* Normal write. Send next byte after clearing event flag. */
398
- nrf_twi_event_clear (nordic_nrf5_twi_register [instance ], NRF_TWI_EVENT_TXDSENT );
399
- nrf_twi_txd_set (nordic_nrf5_twi_register [instance ], data );
400
-
401
- /* Setup stop watch for timeout. */
402
- uint32_t start_us = lp_ticker_read ();
403
- uint32_t now_us = start_us ;
404
-
405
- /* Block until timeout or the byte has been sent. */
406
- while (((now_us - start_us ) < MAXIMUM_TIMEOUT_US ) &&
407
- !(nrf_twi_event_check (nordic_nrf5_twi_register [instance ], NRF_TWI_EVENT_TXDSENT ))) {
408
- now_us = lp_ticker_read ();
409
- }
410
-
411
- /* Check the error code to see if the byte was acknowledged. */
412
- uint32_t error = nrf_twi_errorsrc_get_and_clear (nordic_nrf5_twi_register [instance ]);
413
-
414
- if (error & NRF_TWI_ERROR_DATA_NACK ) {
415
- result = 0 ; // set NACK
416
- } else if (now_us - start_us >= MAXIMUM_TIMEOUT_US ) {
417
- result = 2 ; // set timeout
418
- }
419
- }
427
+ /* Block until timeout or an address/data error has been detected. */
428
+ while (((now_us - start_us ) < timeout ) &&
429
+ !nrf_twi_event_check (p_twi , NRF_TWI_EVENT_TXDSENT ) &&
430
+ !nrf_twi_event_check (p_twi , NRF_TWI_EVENT_ERROR )) {
431
+ now_us = tick2us * lp_ticker_read ();
432
+ }
433
+
434
+ /* Check error register and update return value if an address/data NACK was detected. */
435
+ uint32_t error = nrf_twi_errorsrc_get_and_clear (p_twi );
436
+
437
+ if ((error & NRF_TWI_ERROR_ADDRESS_NACK ) || (error & NRF_TWI_ERROR_DATA_NACK )) {
438
+ result = 0 ; // NACK
439
+ } else if (now_us - start_us >= timeout ) {
440
+ result = 2 ; // timeout
420
441
}
421
442
422
443
return result ;
@@ -441,9 +462,6 @@ int i2c_byte_read(i2c_t *obj, int last)
441
462
int instance = config -> instance ;
442
463
int retval = I2C_ERROR_NO_SLAVE ;
443
464
444
- uint32_t start_us = 0 ;
445
- uint32_t now_us = 0 ;
446
-
447
465
/* Due to hardware limitations, the stop condition must triggered through a short before
448
466
* reading the last byte.
449
467
*/
@@ -465,18 +483,20 @@ int i2c_byte_read(i2c_t *obj, int last)
465
483
/* No data available, resume reception. */
466
484
nrf_twi_task_trigger (nordic_nrf5_twi_register [instance ], NRF_TWI_TASK_RESUME );
467
485
486
+ /* Wait ten byte duration for data */
487
+ uint32_t timeout = 10 * byte_timeout (config -> frequency );
468
488
/* Setup timeout */
469
- start_us = lp_ticker_read ();
470
- now_us = start_us ;
489
+ uint32_t start_us = tick2us * lp_ticker_read ();
490
+ uint32_t now_us = start_us ;
471
491
472
492
/* Block until timeout or data ready event has been signaled. */
473
- while (((now_us - start_us ) < MAXIMUM_TIMEOUT_US ) &&
493
+ while (((now_us - start_us ) < timeout ) &&
474
494
!(nrf_twi_event_check (nordic_nrf5_twi_register [instance ], NRF_TWI_EVENT_RXDREADY ))) {
475
- now_us = lp_ticker_read ();
495
+ now_us = tick2us * lp_ticker_read ();
476
496
}
477
497
478
498
/* Retrieve data from buffer. */
479
- if ((now_us - start_us ) < MAXIMUM_TIMEOUT_US ) {
499
+ if ((now_us - start_us ) < timeout ) {
480
500
retval = nrf_twi_rxd_get (nordic_nrf5_twi_register [instance ]);
481
501
nrf_twi_event_clear (nordic_nrf5_twi_register [instance ], NRF_TWI_EVENT_RXDREADY );
482
502
}
@@ -506,12 +526,12 @@ int i2c_stop(i2c_t *obj)
506
526
nrf_twi_task_trigger (nordic_nrf5_twi_register [instance ], NRF_TWI_TASK_STOP );
507
527
508
528
/* Block until stop signal has been generated. */
509
- uint32_t start_us = lp_ticker_read ();
529
+ uint32_t start_us = tick2us * lp_ticker_read ();
510
530
uint32_t now_us = start_us ;
511
531
512
532
while (((now_us - start_us ) < MAXIMUM_TIMEOUT_US ) &&
513
533
!(nrf_twi_event_check (nordic_nrf5_twi_register [instance ], NRF_TWI_EVENT_STOPPED ))) {
514
- now_us = lp_ticker_read ();
534
+ now_us = tick2us * lp_ticker_read ();
515
535
}
516
536
517
537
/* Reset state. */
0 commit comments