Skip to content

Commit 57a22cd

Browse files
committed
[NUC472/M453] Fix CI I2C EEPROM failed
1 parent f4890f6 commit 57a22cd

File tree

2 files changed

+41
-27
lines changed

2 files changed

+41
-27
lines changed

targets/TARGET_NUVOTON/TARGET_M451/i2c_api.c

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ static void i2c0_vec(void);
4848
static void i2c1_vec(void);
4949
static void i2c_irq(i2c_t *obj);
5050
static void i2c_fsm_reset(i2c_t *obj, uint32_t i2c_ctl);
51+
static void i2c_fsm_tranfini(i2c_t *obj, int tran_pos_adv);
5152

5253
static struct nu_i2c_var i2c0_var = {
5354
.obj = NULL,
@@ -615,32 +616,30 @@ static void i2c_irq(i2c_t *obj)
615616
I2C_SET_CONTROL_REG(i2c_base, I2C_CTL_SI_Msk | I2C_CTL_AA_Msk);
616617
}
617618
else {
618-
if (status == 0x18) {
619-
obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED;
620-
i2c_disable_int(obj);
621-
break;
622-
}
623-
// Go Master Repeat Start
624-
i2c_fsm_reset(obj, I2C_CTL_STA_Msk | I2C_CTL_SI_Msk);
619+
i2c_fsm_tranfini(obj, 0);
625620
}
626621
}
627622
else {
628623
i2c_disable_int(obj);
629624
}
630625
break;
626+
631627
case 0x30: // Master Transmit Data NACK
628+
i2c_fsm_tranfini(obj, 0);
629+
break;
630+
632631
case 0x20: // Master Transmit Address NACK
633-
// Go Master Repeat Start
634-
i2c_fsm_reset(obj, I2C_CTL_STA_Msk | I2C_CTL_SI_Msk);
632+
i2c_fsm_tranfini(obj, -1); // Roll back data position to indicate slave address not ACKed
635633
break;
634+
636635
case 0x38: // Master Arbitration Lost
637636
i2c_fsm_reset(obj, I2C_CTL_SI_Msk | I2C_CTL_AA_Msk);
638637
break;
639638

640639
case 0x48: // Master Receive Address NACK
641-
// Go Master Repeat Start
642-
i2c_fsm_reset(obj, I2C_CTL_STA_Msk | I2C_CTL_SI_Msk);
640+
i2c_fsm_tranfini(obj, -1); // Roll back data position to indicate slave address not ACKed
643641
break;
642+
644643
case 0x40: // Master Receive Address ACK
645644
case 0x50: // Master Receive Data ACK
646645
case 0x58: // Master Receive Data NACK
@@ -657,8 +656,7 @@ static void i2c_irq(i2c_t *obj)
657656
while (1);
658657
}
659658
#endif
660-
// Go Master Repeat Start
661-
i2c_fsm_reset(obj, I2C_CTL_STA_Msk | I2C_CTL_SI_Msk);
659+
i2c_fsm_tranfini(obj, 0);
662660
}
663661
else {
664662
uint32_t i2c_ctl = I2C_CTL_SI_Msk | I2C_CTL_AA_Msk;
@@ -825,6 +823,16 @@ static void i2c_fsm_reset(i2c_t *obj, uint32_t i2c_ctl)
825823
obj->i2c.slaveaddr_state = NoData;
826824
}
827825

826+
static void i2c_fsm_tranfini(i2c_t *obj, int tran_pos_adv)
827+
{
828+
if (obj->i2c.tran_pos) {
829+
obj->i2c.tran_pos += tran_pos_adv;
830+
}
831+
832+
obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED;
833+
i2c_disable_int(obj);
834+
}
835+
828836
#if DEVICE_I2C_ASYNCH
829837

830838
void i2c_transfer_asynch(i2c_t *obj, const void *tx, size_t tx_length, void *rx, size_t rx_length, uint32_t address, uint32_t stop, uint32_t handler, uint32_t event, DMAUsage hint)

targets/TARGET_NUVOTON/TARGET_NUC472/i2c_api.c

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ static void i2c3_vec(void);
5151
static void i2c4_vec(void);
5252
static void i2c_irq(i2c_t *obj);
5353
static void i2c_fsm_reset(i2c_t *obj, uint32_t i2c_ctl);
54+
static void i2c_fsm_tranfini(i2c_t *obj, int tran_pos_adv);
5455

5556
static struct nu_i2c_var i2c0_var = {
5657
.obj = NULL,
@@ -645,33 +646,30 @@ static void i2c_irq(i2c_t *obj)
645646
I2C_SET_CONTROL_REG(i2c_base, I2C_CTL_SI_Msk | I2C_CTL_AA_Msk);
646647
}
647648
else {
648-
if (status == 0x18) {
649-
obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED;
650-
i2c_disable_int(obj);
651-
break;
652-
}
653-
// Go Master Repeat Start
654-
i2c_fsm_reset(obj, I2C_CTL_STA_Msk | I2C_CTL_SI_Msk);
649+
i2c_fsm_tranfini(obj, 0);
655650
}
656651
}
657652
else {
658653
i2c_disable_int(obj);
659654
}
660655
break;
656+
661657
case 0x30: // Master Transmit Data NACK
658+
i2c_fsm_tranfini(obj, 0);
659+
break;
660+
662661
case 0x20: // Master Transmit Address NACK
663-
// Go Master Repeat Start
664-
i2c_fsm_reset(obj, I2C_CTL_STA_Msk | I2C_CTL_SI_Msk);
662+
i2c_fsm_tranfini(obj, -1); // Roll back data position to indicate slave address not ACKed
665663
break;
664+
666665
case 0x38: // Master Arbitration Lost
667666
i2c_fsm_reset(obj, I2C_CTL_SI_Msk | I2C_CTL_AA_Msk);
668667
break;
669668

670669
case 0x48: // Master Receive Address NACK
671-
// Go Master Stop.
672-
// Go Master Repeat Start
673-
i2c_fsm_reset(obj, I2C_CTL_STA_Msk | I2C_CTL_SI_Msk);
670+
i2c_fsm_tranfini(obj, -1); // Roll back data position to indicate slave address not ACKed
674671
break;
672+
675673
case 0x40: // Master Receive Address ACK
676674
case 0x50: // Master Receive Data ACK
677675
case 0x58: // Master Receive Data NACK
@@ -688,8 +686,7 @@ static void i2c_irq(i2c_t *obj)
688686
while (1);
689687
}
690688
#endif
691-
// Go Master Repeat Start
692-
i2c_fsm_reset(obj, I2C_CTL_STA_Msk | I2C_CTL_SI_Msk);
689+
i2c_fsm_tranfini(obj, 0);
693690
}
694691
else {
695692
uint32_t i2c_ctl = I2C_CTL_SI_Msk | I2C_CTL_AA_Msk;
@@ -856,6 +853,15 @@ static void i2c_fsm_reset(i2c_t *obj, uint32_t i2c_ctl)
856853
obj->i2c.slaveaddr_state = NoData;
857854
}
858855

856+
static void i2c_fsm_tranfini(i2c_t *obj, int tran_pos_adv)
857+
{
858+
if (obj->i2c.tran_pos) {
859+
obj->i2c.tran_pos += tran_pos_adv;
860+
}
861+
862+
obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED;
863+
i2c_disable_int(obj);
864+
}
859865

860866
#if DEVICE_I2C_ASYNCH
861867

0 commit comments

Comments
 (0)