[NUC472/M453] Fix CI I2C EEPROM failed

pull/3309/head
ccli8 2016-11-21 17:05:57 +08:00
parent f4890f68f1
commit 57a22cd4ab
2 changed files with 43 additions and 29 deletions

View File

@ -48,6 +48,7 @@ static void i2c0_vec(void);
static void i2c1_vec(void); static void i2c1_vec(void);
static void i2c_irq(i2c_t *obj); static void i2c_irq(i2c_t *obj);
static void i2c_fsm_reset(i2c_t *obj, uint32_t i2c_ctl); static void i2c_fsm_reset(i2c_t *obj, uint32_t i2c_ctl);
static void i2c_fsm_tranfini(i2c_t *obj, int tran_pos_adv);
static struct nu_i2c_var i2c0_var = { static struct nu_i2c_var i2c0_var = {
.obj = NULL, .obj = NULL,
@ -615,32 +616,30 @@ static void i2c_irq(i2c_t *obj)
I2C_SET_CONTROL_REG(i2c_base, I2C_CTL_SI_Msk | I2C_CTL_AA_Msk); I2C_SET_CONTROL_REG(i2c_base, I2C_CTL_SI_Msk | I2C_CTL_AA_Msk);
} }
else { else {
if (status == 0x18) { i2c_fsm_tranfini(obj, 0);
obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED;
i2c_disable_int(obj);
break;
}
// Go Master Repeat Start
i2c_fsm_reset(obj, I2C_CTL_STA_Msk | I2C_CTL_SI_Msk);
} }
} }
else { else {
i2c_disable_int(obj); i2c_disable_int(obj);
} }
break; break;
case 0x30: // Master Transmit Data NACK case 0x30: // Master Transmit Data NACK
case 0x20: // Master Transmit Address NACK i2c_fsm_tranfini(obj, 0);
// Go Master Repeat Start
i2c_fsm_reset(obj, I2C_CTL_STA_Msk | I2C_CTL_SI_Msk);
break; break;
case 0x20: // Master Transmit Address NACK
i2c_fsm_tranfini(obj, -1); // Roll back data position to indicate slave address not ACKed
break;
case 0x38: // Master Arbitration Lost case 0x38: // Master Arbitration Lost
i2c_fsm_reset(obj, I2C_CTL_SI_Msk | I2C_CTL_AA_Msk); i2c_fsm_reset(obj, I2C_CTL_SI_Msk | I2C_CTL_AA_Msk);
break; break;
case 0x48: // Master Receive Address NACK case 0x48: // Master Receive Address NACK
// Go Master Repeat Start i2c_fsm_tranfini(obj, -1); // Roll back data position to indicate slave address not ACKed
i2c_fsm_reset(obj, I2C_CTL_STA_Msk | I2C_CTL_SI_Msk);
break; break;
case 0x40: // Master Receive Address ACK case 0x40: // Master Receive Address ACK
case 0x50: // Master Receive Data ACK case 0x50: // Master Receive Data ACK
case 0x58: // Master Receive Data NACK case 0x58: // Master Receive Data NACK
@ -657,8 +656,7 @@ static void i2c_irq(i2c_t *obj)
while (1); while (1);
} }
#endif #endif
// Go Master Repeat Start i2c_fsm_tranfini(obj, 0);
i2c_fsm_reset(obj, I2C_CTL_STA_Msk | I2C_CTL_SI_Msk);
} }
else { else {
uint32_t i2c_ctl = I2C_CTL_SI_Msk | I2C_CTL_AA_Msk; 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)
obj->i2c.slaveaddr_state = NoData; obj->i2c.slaveaddr_state = NoData;
} }
static void i2c_fsm_tranfini(i2c_t *obj, int tran_pos_adv)
{
if (obj->i2c.tran_pos) {
obj->i2c.tran_pos += tran_pos_adv;
}
obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED;
i2c_disable_int(obj);
}
#if DEVICE_I2C_ASYNCH #if DEVICE_I2C_ASYNCH
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) 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)

View File

@ -51,6 +51,7 @@ static void i2c3_vec(void);
static void i2c4_vec(void); static void i2c4_vec(void);
static void i2c_irq(i2c_t *obj); static void i2c_irq(i2c_t *obj);
static void i2c_fsm_reset(i2c_t *obj, uint32_t i2c_ctl); static void i2c_fsm_reset(i2c_t *obj, uint32_t i2c_ctl);
static void i2c_fsm_tranfini(i2c_t *obj, int tran_pos_adv);
static struct nu_i2c_var i2c0_var = { static struct nu_i2c_var i2c0_var = {
.obj = NULL, .obj = NULL,
@ -645,33 +646,30 @@ static void i2c_irq(i2c_t *obj)
I2C_SET_CONTROL_REG(i2c_base, I2C_CTL_SI_Msk | I2C_CTL_AA_Msk); I2C_SET_CONTROL_REG(i2c_base, I2C_CTL_SI_Msk | I2C_CTL_AA_Msk);
} }
else { else {
if (status == 0x18) { i2c_fsm_tranfini(obj, 0);
obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED;
i2c_disable_int(obj);
break;
}
// Go Master Repeat Start
i2c_fsm_reset(obj, I2C_CTL_STA_Msk | I2C_CTL_SI_Msk);
} }
} }
else { else {
i2c_disable_int(obj); i2c_disable_int(obj);
} }
break; break;
case 0x30: // Master Transmit Data NACK case 0x30: // Master Transmit Data NACK
case 0x20: // Master Transmit Address NACK i2c_fsm_tranfini(obj, 0);
// Go Master Repeat Start
i2c_fsm_reset(obj, I2C_CTL_STA_Msk | I2C_CTL_SI_Msk);
break; break;
case 0x20: // Master Transmit Address NACK
i2c_fsm_tranfini(obj, -1); // Roll back data position to indicate slave address not ACKed
break;
case 0x38: // Master Arbitration Lost case 0x38: // Master Arbitration Lost
i2c_fsm_reset(obj, I2C_CTL_SI_Msk | I2C_CTL_AA_Msk); i2c_fsm_reset(obj, I2C_CTL_SI_Msk | I2C_CTL_AA_Msk);
break; break;
case 0x48: // Master Receive Address NACK case 0x48: // Master Receive Address NACK
// Go Master Stop. i2c_fsm_tranfini(obj, -1); // Roll back data position to indicate slave address not ACKed
// Go Master Repeat Start
i2c_fsm_reset(obj, I2C_CTL_STA_Msk | I2C_CTL_SI_Msk);
break; break;
case 0x40: // Master Receive Address ACK case 0x40: // Master Receive Address ACK
case 0x50: // Master Receive Data ACK case 0x50: // Master Receive Data ACK
case 0x58: // Master Receive Data NACK case 0x58: // Master Receive Data NACK
@ -688,8 +686,7 @@ static void i2c_irq(i2c_t *obj)
while (1); while (1);
} }
#endif #endif
// Go Master Repeat Start i2c_fsm_tranfini(obj, 0);
i2c_fsm_reset(obj, I2C_CTL_STA_Msk | I2C_CTL_SI_Msk);
} }
else { else {
uint32_t i2c_ctl = I2C_CTL_SI_Msk | I2C_CTL_AA_Msk; 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)
obj->i2c.slaveaddr_state = NoData; obj->i2c.slaveaddr_state = NoData;
} }
static void i2c_fsm_tranfini(i2c_t *obj, int tran_pos_adv)
{
if (obj->i2c.tran_pos) {
obj->i2c.tran_pos += tran_pos_adv;
}
obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED;
i2c_disable_int(obj);
}
#if DEVICE_I2C_ASYNCH #if DEVICE_I2C_ASYNCH