29
29
*/
30
30
#include "mbed_assert.h"
31
31
#include "i2c_api.h"
32
+ #include "platform/wait_api.h"
32
33
33
34
#if DEVICE_I2C
34
35
41
42
not remain stuck if the I2C communication is corrupted. */
42
43
#define FLAG_TIMEOUT ((int)0x1000)
43
44
#define LONG_TIMEOUT ((int)0x8000)
45
+ /* Timeout values are based on core clock and I2C clock.
46
+ The BYTE_TIMEOUT is computed as twice the number of cycles it would
47
+ take to send 10 bits over I2C. Most Flags should take less than that.
48
+ This is for immediate FLAG or ACK check.
49
+ */
50
+ #define BYTE_TIMEOUT ((SystemCoreClock / handle->Init.ClockSpeed) * 2 * 10)
51
+ /* Timeout values based on I2C clock.
52
+ The BYTE_TIMEOUT_US is computed as 3x the time in us it would
53
+ take to send 10 bits over I2C. Most Flags should take less than that.
54
+ This is for complete transfers check.
55
+ */
56
+ #define BYTE_TIMEOUT_US ((SystemCoreClock / handle->Init.ClockSpeed) * 3 * 10)
44
57
45
58
#if DEVICE_I2C_ASYNCH
46
59
#define I2C_S (obj ) (struct i2c_s *) (&((obj)->i2c))
@@ -266,8 +279,8 @@ void i2c_frequency(i2c_t *obj, int hz)
266
279
MBED_ASSERT ((hz > 0 ) && (hz <= 400000 ));
267
280
268
281
// wait before init
269
- timeout = LONG_TIMEOUT ;
270
- while ((__HAL_I2C_GET_FLAG (handle , I2C_FLAG_BUSY )) && (timeout -- != 0 ));
282
+ timeout = BYTE_TIMEOUT ;
283
+ while ((__HAL_I2C_GET_FLAG (handle , I2C_FLAG_BUSY )) && (-- timeout != 0 ));
271
284
272
285
// I2C configuration
273
286
handle -> Init .AddressingMode = I2C_ADDRESSINGMODE_7BIT ;
@@ -307,7 +320,7 @@ inline int i2c_start(i2c_t *obj) {
307
320
308
321
// Wait the STOP condition has been previously correctly sent
309
322
// This timeout can be avoid in some specific cases by simply clearing the STOP bit
310
- timeout = FLAG_TIMEOUT ;
323
+ timeout = BYTE_TIMEOUT ;
311
324
while ((handle -> Instance -> CR1 & I2C_CR1_STOP ) == I2C_CR1_STOP ) {
312
325
if ((timeout -- ) == 0 ) {
313
326
return 1 ;
@@ -318,7 +331,7 @@ inline int i2c_start(i2c_t *obj) {
318
331
handle -> Instance -> CR1 |= I2C_CR1_START ;
319
332
320
333
// Wait the START condition has been correctly sent
321
- timeout = FLAG_TIMEOUT ;
334
+ timeout = BYTE_TIMEOUT ;
322
335
while (__HAL_I2C_GET_FLAG (handle , I2C_FLAG_SB ) == RESET ) {
323
336
if ((timeout -- ) == 0 ) {
324
337
return 1 ;
@@ -448,7 +461,7 @@ int i2c_byte_read(i2c_t *obj, int last) {
448
461
}
449
462
450
463
// Wait until the byte is received
451
- timeout = FLAG_TIMEOUT ;
464
+ timeout = BYTE_TIMEOUT ;
452
465
while (__HAL_I2C_GET_FLAG (handle , I2C_FLAG_RXNE ) == RESET ) {
453
466
if ((timeout -- ) == 0 ) {
454
467
return -1 ;
@@ -467,7 +480,7 @@ int i2c_byte_write(i2c_t *obj, int data) {
467
480
handle -> Instance -> DR = (uint8_t )data ;
468
481
469
482
// Wait until the byte (might be the address) is transmitted
470
- timeout = FLAG_TIMEOUT ;
483
+ timeout = BYTE_TIMEOUT ;
471
484
while ((__HAL_I2C_GET_FLAG (handle , I2C_FLAG_TXE ) == RESET ) &&
472
485
(__HAL_I2C_GET_FLAG (handle , I2C_FLAG_BTF ) == RESET ) &&
473
486
(__HAL_I2C_GET_FLAG (handle , I2C_FLAG_ADDR ) == RESET )) {
@@ -493,8 +506,8 @@ void i2c_reset(i2c_t *obj) {
493
506
handle -> Instance = (I2C_TypeDef * )(obj_s -> i2c );
494
507
495
508
// wait before reset
496
- timeout = LONG_TIMEOUT ;
497
- while ((__HAL_I2C_GET_FLAG (handle , I2C_FLAG_BUSY )) && (timeout -- != 0 ));
509
+ timeout = BYTE_TIMEOUT ;
510
+ while ((__HAL_I2C_GET_FLAG (handle , I2C_FLAG_BUSY )) && (-- timeout != 0 ));
498
511
499
512
if (obj_s -> i2c == I2C_1 ) {
500
513
__I2C1_FORCE_RESET ();
@@ -615,17 +628,20 @@ int i2c_slave_read(i2c_t *obj, char *data, int length) {
615
628
I2C_HandleTypeDef * handle = & (obj_s -> handle );
616
629
int count = 0 ;
617
630
int ret = 0 ;
631
+ uint32_t timeout = 0 ;
618
632
619
633
/* Always use I2C_NEXT_FRAME as slave will just adapt to master requests */
620
634
ret = HAL_I2C_Slave_Sequential_Receive_IT (handle , (uint8_t * ) data , length , I2C_NEXT_FRAME );
621
635
622
- if (ret ! = HAL_OK ) {
623
- count = 0 ;
624
- } else {
625
- count = length ;
626
- }
636
+ if (ret = = HAL_OK ) {
637
+ timeout = BYTE_TIMEOUT_US * length ;
638
+ while ( obj_s -> pending_slave_rx_maxter_tx && ( -- timeout != 0 )) {
639
+ wait_us ( 1 ) ;
640
+ }
627
641
628
- while (obj_s -> pending_slave_rx_maxter_tx );
642
+ if (timeout != 0 )
643
+ count = length ;
644
+ }
629
645
630
646
return count ;
631
647
}
@@ -635,17 +651,20 @@ int i2c_slave_write(i2c_t *obj, const char *data, int length) {
635
651
I2C_HandleTypeDef * handle = & (obj_s -> handle );
636
652
int count = 0 ;
637
653
int ret = 0 ;
654
+ uint32_t timeout = 0 ;
638
655
639
656
/* Always use I2C_NEXT_FRAME as slave will just adapt to master requests */
640
657
ret = HAL_I2C_Slave_Sequential_Transmit_IT (handle , (uint8_t * ) data , length , I2C_NEXT_FRAME );
641
658
642
- if (ret ! = HAL_OK ) {
643
- count = 0 ;
644
- } else {
645
- count = length ;
646
- }
659
+ if (ret = = HAL_OK ) {
660
+ timeout = BYTE_TIMEOUT_US * length ;
661
+ while ( obj_s -> pending_slave_tx_master_rx && ( -- timeout != 0 )) {
662
+ wait_us ( 1 ) ;
663
+ }
647
664
648
- while (obj_s -> pending_slave_tx_master_rx );
665
+ if (timeout != 0 )
666
+ count = length ;
667
+ }
649
668
650
669
return count ;
651
670
}
0 commit comments