mirror of https://github.com/ARMmbed/mbed-os.git
M263: Fix I2C NACK error
Fix logic error on replying NACK at the end of transfer. This is also to fix FPGA CI test mbed_hal_fpga_ci_test_shield-i2c/ i2c - test single byte read i2c API.pull/11379/head
parent
9d4d99cf34
commit
d15abe5171
|
@ -86,9 +86,10 @@ static void i2c_enable_vector_interrupt(i2c_t *obj, uint32_t handler, int enable
|
|||
static void i2c_rollback_vector_interrupt(i2c_t *obj);
|
||||
#endif
|
||||
|
||||
#define TRANCTRL_STARTED (1)
|
||||
#define TRANCTRL_NAKLASTDATA (1 << 1)
|
||||
#define TRANCTRL_LASTDATANAKED (1 << 2)
|
||||
#define TRANCTRL_STARTED (1) // Guard I2C ISR from data transfer prematurely
|
||||
#define TRANCTRL_NAKLASTDATA (1 << 1) // Request NACK on last data
|
||||
#define TRANCTRL_LASTDATANAKED (1 << 2) // Last data NACKed
|
||||
#define TRANCTRL_RECVDATA (1 << 3) // Receive data available
|
||||
|
||||
uint32_t us_ticker_read(void);
|
||||
|
||||
|
@ -592,11 +593,17 @@ static void i2c_irq(i2c_t *obj)
|
|||
if ((obj->i2c.tran_ctrl & TRANCTRL_STARTED) && obj->i2c.tran_pos) {
|
||||
if (obj->i2c.tran_pos < obj->i2c.tran_end) {
|
||||
if (status == 0x50 || status == 0x58) {
|
||||
*obj->i2c.tran_pos ++ = I2C_GET_DATA(i2c_base);
|
||||
if (obj->i2c.tran_ctrl & TRANCTRL_RECVDATA) {
|
||||
*obj->i2c.tran_pos ++ = I2C_GET_DATA(i2c_base);
|
||||
obj->i2c.tran_ctrl &= ~TRANCTRL_RECVDATA;
|
||||
}
|
||||
}
|
||||
|
||||
if (status == 0x58) {
|
||||
i2c_fsm_tranfini(obj, 1);
|
||||
} else if (obj->i2c.tran_pos == obj->i2c.tran_end) {
|
||||
obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED;
|
||||
i2c_disable_int(obj);
|
||||
} else {
|
||||
uint32_t i2c_ctl = I2C_CTL0_SI_Msk | I2C_CTL0_AA_Msk;
|
||||
if ((obj->i2c.tran_end - obj->i2c.tran_pos) == 1 &&
|
||||
|
@ -605,6 +612,7 @@ static void i2c_irq(i2c_t *obj)
|
|||
i2c_ctl &= ~I2C_CTL0_AA_Msk;
|
||||
}
|
||||
I2C_SET_CONTROL_REG(i2c_base, i2c_ctl);
|
||||
obj->i2c.tran_ctrl |= TRANCTRL_RECVDATA;
|
||||
}
|
||||
} else {
|
||||
obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED;
|
||||
|
@ -659,12 +667,18 @@ static void i2c_irq(i2c_t *obj)
|
|||
if ((obj->i2c.tran_ctrl & TRANCTRL_STARTED) && obj->i2c.tran_pos) {
|
||||
if (obj->i2c.tran_pos < obj->i2c.tran_end) {
|
||||
if (status == 0x80 || status == 0x88) {
|
||||
*obj->i2c.tran_pos ++ = I2C_GET_DATA(i2c_base);
|
||||
if (obj->i2c.tran_ctrl & TRANCTRL_RECVDATA) {
|
||||
*obj->i2c.tran_pos ++ = I2C_GET_DATA(i2c_base);
|
||||
obj->i2c.tran_ctrl &= ~TRANCTRL_RECVDATA;
|
||||
}
|
||||
}
|
||||
|
||||
if (status == 0x88) {
|
||||
obj->i2c.slaveaddr_state = NoData;
|
||||
i2c_fsm_reset(obj, I2C_CTL0_SI_Msk | I2C_CTL0_AA_Msk);
|
||||
} else if (obj->i2c.tran_pos == obj->i2c.tran_end) {
|
||||
obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED;
|
||||
i2c_disable_int(obj);
|
||||
} else {
|
||||
uint32_t i2c_ctl = I2C_CTL0_SI_Msk | I2C_CTL0_AA_Msk;
|
||||
if ((obj->i2c.tran_end - obj->i2c.tran_pos) == 1 &&
|
||||
|
@ -673,6 +687,7 @@ static void i2c_irq(i2c_t *obj)
|
|||
i2c_ctl &= ~I2C_CTL0_AA_Msk;
|
||||
}
|
||||
I2C_SET_CONTROL_REG(i2c_base, i2c_ctl);
|
||||
obj->i2c.tran_ctrl |= TRANCTRL_RECVDATA;
|
||||
}
|
||||
} else {
|
||||
obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED;
|
||||
|
@ -695,12 +710,18 @@ static void i2c_irq(i2c_t *obj)
|
|||
if ((obj->i2c.tran_ctrl & TRANCTRL_STARTED) && obj->i2c.tran_pos) {
|
||||
if (obj->i2c.tran_pos < obj->i2c.tran_end) {
|
||||
if (status == 0x90 || status == 0x98) {
|
||||
*obj->i2c.tran_pos ++ = I2C_GET_DATA(i2c_base);
|
||||
if (obj->i2c.tran_ctrl & TRANCTRL_RECVDATA) {
|
||||
*obj->i2c.tran_pos ++ = I2C_GET_DATA(i2c_base);
|
||||
obj->i2c.tran_ctrl &= ~TRANCTRL_RECVDATA;
|
||||
}
|
||||
}
|
||||
|
||||
if (status == 0x98) {
|
||||
obj->i2c.slaveaddr_state = NoData;
|
||||
i2c_fsm_reset(obj, I2C_CTL0_SI_Msk | I2C_CTL0_AA_Msk);
|
||||
} else if (obj->i2c.tran_pos == obj->i2c.tran_end) {
|
||||
obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED;
|
||||
i2c_disable_int(obj);
|
||||
} else {
|
||||
uint32_t i2c_ctl = I2C_CTL0_SI_Msk | I2C_CTL0_AA_Msk;
|
||||
if ((obj->i2c.tran_end - obj->i2c.tran_pos) == 1 &&
|
||||
|
@ -709,6 +730,7 @@ static void i2c_irq(i2c_t *obj)
|
|||
i2c_ctl &= ~I2C_CTL0_AA_Msk;
|
||||
}
|
||||
I2C_SET_CONTROL_REG(i2c_base, i2c_ctl);
|
||||
obj->i2c.tran_ctrl |= TRANCTRL_RECVDATA;
|
||||
}
|
||||
} else {
|
||||
obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED;
|
||||
|
|
Loading…
Reference in New Issue