6565#define DEBUG_PRINTF (...)
6666#endif
6767
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
7069#define I2C_READ_BIT 0x01 // read bit
7170
7271static uint32_t tick2us = 1 ;
@@ -174,6 +173,21 @@ void i2c_frequency(i2c_t *obj, int hz)
174173 config -> update = true;
175174}
176175
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+
177191const PinMap * i2c_master_sda_pinmap ()
178192{
179193 return PinMap_I2C_testing ;
@@ -359,69 +373,71 @@ int i2c_byte_write(i2c_t *obj, int data)
359373 struct i2c_s * config = obj ;
360374#endif
361375
362- int instance = config -> instance ;
376+ NRF_TWI_Type * p_twi = nordic_nrf5_twi_register [ config -> instance ] ;
363377 int result = 1 ; // default to ACK
378+ uint32_t start_us , now_us , timeout ;
364379
365- /* Check if this is the first byte to be transferred. If it is, then send start signal and address. */
366380 if (config -> state == NORDIC_TWI_STATE_START ) {
367381 config -> state = NORDIC_TWI_STATE_BUSY ;
368382
369- /* Beginning of new transaction, configure peripheral if necessary. */
383+ config -> update = true;
370384 i2c_configure_twi_instance (obj );
371385
372- /* Set I2C device address. NOTE: due to hardware limitations only 7-bit addresses are supported. */
373- nrf_twi_address_set (nordic_nrf5_twi_register [instance ], data >> 1 );
374-
375- /* If read bit is set, trigger read task otherwise trigger write task. */
376386 if (data & I2C_READ_BIT ) {
377- /* For timing reasons, reading bytes requires shorts to suspend peripheral after each byte. */
378- nrf_twi_shorts_set (nordic_nrf5_twi_register [instance ], NRF_TWI_SHORT_BB_SUSPEND_MASK );
379- 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 );
380397 } else {
381- /* Reset shorts register. */
382- nrf_twi_shorts_set (nordic_nrf5_twi_register [instance ], 0 );
383- nrf_twi_task_trigger (nordic_nrf5_twi_register [instance ], NRF_TWI_TASK_STARTTX );
384- }
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 );
385403
386- /* Setup stop watch for timeout. */
387- uint32_t start_us = tick2us * lp_ticker_read ();
388- uint32_t now_us = start_us ;
404+ nrf_twi_shorts_set (p_twi , 0 );
389405
390- /* Block until timeout or an address error has been detected. */
391- while (((now_us - start_us ) < DEFAULT_TIMEOUT_US ) &&
392- !(nrf_twi_event_check (nordic_nrf5_twi_register [instance ], NRF_TWI_EVENT_ERROR ))) {
393- now_us = tick2us * 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 );
394409 }
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+ }
395423
396- /* Check error register and update return value if an address NACK was detected. */
397- 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 ;
398426
399- if (error & NRF_TWI_ERROR_ADDRESS_NACK ) {
400- result = 0 ; // set NACK
401- } else {
402- /* Normal write. Send next byte after clearing event flag. */
403- nrf_twi_event_clear (nordic_nrf5_twi_register [instance ], NRF_TWI_EVENT_TXDSENT );
404- nrf_twi_txd_set (nordic_nrf5_twi_register [instance ], data );
405-
406- /* Setup stop watch for timeout. */
407- uint32_t start_us = tick2us * lp_ticker_read ();
408- uint32_t now_us = start_us ;
409-
410- /* Block until timeout or the byte has been sent. */
411- while (((now_us - start_us ) < MAXIMUM_TIMEOUT_US ) &&
412- !(nrf_twi_event_check (nordic_nrf5_twi_register [instance ], NRF_TWI_EVENT_TXDSENT ))) {
413- now_us = tick2us * lp_ticker_read ();
414- }
415-
416- /* Check the error code to see if the byte was acknowledged. */
417- uint32_t error = nrf_twi_errorsrc_get_and_clear (nordic_nrf5_twi_register [instance ]);
418-
419- if (error & NRF_TWI_ERROR_DATA_NACK ) {
420- result = 0 ; // set NACK
421- } else if (now_us - start_us >= MAXIMUM_TIMEOUT_US ) {
422- result = 2 ; // set timeout
423- }
424- }
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
425441 }
426442
427443 return result ;
@@ -446,9 +462,6 @@ int i2c_byte_read(i2c_t *obj, int last)
446462 int instance = config -> instance ;
447463 int retval = I2C_ERROR_NO_SLAVE ;
448464
449- uint32_t start_us = 0 ;
450- uint32_t now_us = 0 ;
451-
452465 /* Due to hardware limitations, the stop condition must triggered through a short before
453466 * reading the last byte.
454467 */
@@ -470,18 +483,20 @@ int i2c_byte_read(i2c_t *obj, int last)
470483 /* No data available, resume reception. */
471484 nrf_twi_task_trigger (nordic_nrf5_twi_register [instance ], NRF_TWI_TASK_RESUME );
472485
486+ /* Wait ten byte duration for data */
487+ uint32_t timeout = 10 * byte_timeout (config -> frequency );
473488 /* Setup timeout */
474- start_us = tick2us * lp_ticker_read ();
475- now_us = start_us ;
489+ uint32_t start_us = tick2us * lp_ticker_read ();
490+ uint32_t now_us = start_us ;
476491
477492 /* Block until timeout or data ready event has been signaled. */
478- while (((now_us - start_us ) < MAXIMUM_TIMEOUT_US ) &&
493+ while (((now_us - start_us ) < timeout ) &&
479494 !(nrf_twi_event_check (nordic_nrf5_twi_register [instance ], NRF_TWI_EVENT_RXDREADY ))) {
480495 now_us = tick2us * lp_ticker_read ();
481496 }
482497
483498 /* Retrieve data from buffer. */
484- if ((now_us - start_us ) < MAXIMUM_TIMEOUT_US ) {
499+ if ((now_us - start_us ) < timeout ) {
485500 retval = nrf_twi_rxd_get (nordic_nrf5_twi_register [instance ]);
486501 nrf_twi_event_clear (nordic_nrf5_twi_register [instance ], NRF_TWI_EVENT_RXDREADY );
487502 }
0 commit comments