Skip to content

Commit 1e7fe74

Browse files
committed
Fix a bug that there is a case that can not be normal communication in I2C.
When the following conditions, may not be the normal communication in I2C. 1. A device for I2C address was not found 2. Set "repeated = true".
1 parent dc0b26d commit 1e7fe74

File tree

1 file changed

+31
-46
lines changed
  • libraries/mbed/targets/hal/TARGET_RENESAS/TARGET_RZ_A1H

1 file changed

+31
-46
lines changed

libraries/mbed/targets/hal/TARGET_RENESAS/TARGET_RZ_A1H/i2c_api.c

Lines changed: 31 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ volatile struct st_riic *RIIC[] = RIIC_ADDRESS_LIST;
5858
#define SR2_TEND (1 << 6)
5959
#define SR2_TDRE (1 << 7)
6060

61-
#define TIMEOUT_1S (3600000) /* Loop counter : Time-out is about 1s. By 3600000 loops, measured value is 969ms. */
61+
#define WAIT_TIMEOUT (4200) /* Loop counter : Time-out is about 1ms. By 4200 loops, measured value is 1009ms. */
6262

6363
static const PinMap PinMap_I2C_SDA[] = {
6464
{P1_1 , I2C_0, 1},
@@ -108,7 +108,7 @@ static inline int i2c_wait_RDRF(i2c_t *obj) {
108108
/* There is no timeout, but the upper limit value is set to avoid an infinite loop. */
109109
while (!(i2c_status(obj) & SR2_RDRF)) {
110110
timeout ++;
111-
if (timeout >= TIMEOUT_1S) {
111+
if (timeout >= WAIT_TIMEOUT) {
112112
return -1;
113113
}
114114
}
@@ -122,7 +122,7 @@ static int i2c_wait_TDRE(i2c_t *obj) {
122122
/* There is no timeout, but the upper limit value is set to avoid an infinite loop. */
123123
while (!(i2c_status(obj) & SR2_TDRE)) {
124124
timeout ++;
125-
if (timeout >= TIMEOUT_1S) {
125+
if (timeout >= WAIT_TIMEOUT) {
126126
return -1;
127127
}
128128
}
@@ -136,7 +136,7 @@ static int i2c_wait_TEND(i2c_t *obj) {
136136
/* There is no timeout, but the upper limit value is set to avoid an infinite loop. */
137137
while (!(i2c_status(obj) & SR2_TEND)) {
138138
timeout ++;
139-
if (timeout >= TIMEOUT_1S) {
139+
if (timeout >= WAIT_TIMEOUT) {
140140
return -1;
141141
}
142142
}
@@ -151,7 +151,7 @@ static int i2c_wait_START(i2c_t *obj) {
151151
/* There is no timeout, but the upper limit value is set to avoid an infinite loop. */
152152
while (!(i2c_status(obj) & SR2_START)) {
153153
timeout ++;
154-
if (timeout >= TIMEOUT_1S) {
154+
if (timeout >= WAIT_TIMEOUT) {
155155
return -1;
156156
}
157157
}
@@ -165,7 +165,7 @@ static int i2c_wait_STOP(i2c_t *obj) {
165165
/* There is no timeout, but the upper limit value is set to avoid an infinite loop. */
166166
while (!(i2c_status(obj) & SR2_STOP)) {
167167
timeout ++;
168-
if (timeout >= TIMEOUT_1S) {
168+
if (timeout >= WAIT_TIMEOUT) {
169169
return -1;
170170
}
171171
}
@@ -265,17 +265,11 @@ inline int i2c_stop(i2c_t *obj) {
265265
return 0;
266266
}
267267

268-
static void i2c_set_err_noslave(i2c_t *obj, int stop) {
269-
if (stop) {
270-
(void)i2c_stop(obj);
271-
(void)i2c_wait_STOP(obj);
272-
i2c_set_SR2_NACKF_STOP(obj);
273-
} else {
274-
(void)i2c_restart(obj);
275-
(void)i2c_wait_START(obj);
276-
/* SR2.START = 0 */
277-
REG(SR2.UINT32) &= ~SR2_START;
278-
}
268+
static void i2c_set_err_noslave(i2c_t *obj) {
269+
(void)i2c_stop(obj);
270+
(void)i2c_wait_STOP(obj);
271+
i2c_set_SR2_NACKF_STOP(obj);
272+
obj->last_stop_flag = 1;
279273
}
280274

281275
static inline int i2c_do_write(i2c_t *obj, int value) {
@@ -287,7 +281,7 @@ static inline int i2c_do_write(i2c_t *obj, int value) {
287281
while (!(i2c_status(obj) & SR2_TDRE)) {
288282
/* RIICnSR2.TDRE=0 */
289283
timeout ++;
290-
if (timeout >= TIMEOUT_1S) {
284+
if (timeout >= WAIT_TIMEOUT) {
291285
return -1;
292286
}
293287
if (i2c_status(obj) & SR2_NACKF) {
@@ -432,37 +426,28 @@ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
432426
if (obj->last_stop_flag != 0) {
433427
status = i2c_start(obj);
434428
if (status != 0) {
435-
i2c_set_err_noslave(obj, stop);
429+
i2c_set_err_noslave(obj);
436430
return I2C_ERROR_BUS_BUSY;
437431
}
438432
}
439433
obj->last_stop_flag = stop;
440434
/* Send Slave address */
441435
status = i2c_read_address_write(obj, (address | 0x01));
442436
if (status != 0) {
443-
i2c_set_err_noslave(obj, stop);
437+
i2c_set_err_noslave(obj);
444438
return I2C_ERROR_NO_SLAVE;
445439
}
446440
/* wait RDRF */
447441
status = i2c_wait_RDRF(obj);
448442
/* check ACK/NACK */
449443
if ((status != 0) || (REG(SR2.UINT32) & SR2_NACKF == 1)) {
450444
/* Slave sends NACK */
451-
/* If not repeated start, send stop. */
452-
if (stop) {
453-
i2c_stop(obj);
454-
/* dummy read */
455-
value = REG(DRR.UINT32);
456-
(void)i2c_wait_STOP(obj);
457-
i2c_set_SR2_NACKF_STOP(obj);
458-
} else {
459-
(void)i2c_restart(obj);
460-
/* dummy read */
461-
value = REG(DRR.UINT32);
462-
(void)i2c_wait_START(obj);
463-
/* SR2.START = 0 */
464-
REG(SR2.UINT32) &= ~SR2_START;
465-
}
445+
i2c_stop(obj);
446+
/* dummy read */
447+
value = REG(DRR.UINT32);
448+
(void)i2c_wait_STOP(obj);
449+
i2c_set_SR2_NACKF_STOP(obj);
450+
obj->last_stop_flag = 1;
466451
return I2C_ERROR_NO_SLAVE;
467452
}
468453
/* Read in all except last byte */
@@ -473,7 +458,7 @@ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
473458
/* wait for it to arrive */
474459
status = i2c_wait_RDRF(obj);
475460
if (status != 0) {
476-
i2c_set_err_noslave(obj, stop);
461+
i2c_set_err_noslave(obj);
477462
return I2C_ERROR_NO_SLAVE;
478463
}
479464
/* Recieve the data */
@@ -494,7 +479,7 @@ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
494479
/* wait for it to arrive */
495480
status = i2c_wait_RDRF(obj);
496481
if (status != 0) {
497-
i2c_set_err_noslave(obj, stop);
482+
i2c_set_err_noslave(obj);
498483
return I2C_ERROR_NO_SLAVE;
499484
}
500485
i2c_set_MR3_NACK(obj);
@@ -511,7 +496,7 @@ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
511496
/* wait for it to arrive */
512497
status = i2c_wait_RDRF(obj);
513498
if (status != 0) {
514-
i2c_set_err_noslave(obj, stop);
499+
i2c_set_err_noslave(obj);
515500
return I2C_ERROR_NO_SLAVE;
516501
}
517502

@@ -552,29 +537,29 @@ int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) {
552537
if (obj->last_stop_flag != 0) {
553538
status = i2c_start(obj);
554539
if (status != 0) {
555-
i2c_set_err_noslave(obj, stop);
540+
i2c_set_err_noslave(obj);
556541
return I2C_ERROR_BUS_BUSY;
557542
}
558543
}
559544
obj->last_stop_flag = stop;
560545
/* Send Slave address */
561546
status = i2c_do_write(obj, address);
562547
if (status != 0) {
563-
i2c_set_err_noslave(obj, stop);
548+
i2c_set_err_noslave(obj);
564549
return I2C_ERROR_NO_SLAVE;
565550
}
566551
/* Send Write data */
567552
for (cnt=0; cnt<length; cnt++) {
568553
status = i2c_do_write(obj, data[cnt]);
569554
if(status != 0) {
570-
i2c_set_err_noslave(obj, stop);
555+
i2c_set_err_noslave(obj);
571556
return cnt;
572557
}
573558
}
574559
/* Wait send end */
575560
status = i2c_wait_TEND(obj);
576561
if (status != 0) {
577-
i2c_set_err_noslave(obj, stop);
562+
i2c_set_err_noslave(obj);
578563
return I2C_ERROR_NO_SLAVE;
579564
}
580565
/* If not repeated start, send stop. */
@@ -605,7 +590,7 @@ int i2c_byte_read(i2c_t *obj, int last) {
605590
/* wait for it to arrive */
606591
status = i2c_wait_RDRF(obj);
607592
if (status != 0) {
608-
i2c_set_err_noslave(obj, 1);
593+
i2c_set_err_noslave(obj);
609594
return I2C_ERROR_NO_SLAVE;
610595
}
611596

@@ -618,7 +603,7 @@ int i2c_byte_write(i2c_t *obj, int data) {
618603

619604
status = i2c_do_write(obj, (data & 0xFF));
620605
if (status != 0) {
621-
i2c_set_err_noslave(obj, 1);
606+
i2c_set_err_noslave(obj);
622607
ack = 0;
623608
} else {
624609
ack = 1;
@@ -682,7 +667,7 @@ int i2c_slave_read(i2c_t *obj, char *data, int length) {
682667
break;
683668
}
684669
timeout ++;
685-
if (timeout >= TIMEOUT_1S) {
670+
if (timeout >= WAIT_TIMEOUT) {
686671
return -1;
687672
}
688673
}
@@ -730,7 +715,7 @@ int i2c_slave_write(i2c_t *obj, const char *data, int length) {
730715
/* Wait send end */
731716
status = i2c_wait_TEND(obj);
732717
if (status != 0) {
733-
i2c_set_err_noslave(obj, 1);
718+
i2c_set_err_noslave(obj);
734719
return 0;
735720
}
736721
}

0 commit comments

Comments
 (0)