@@ -86,9 +86,10 @@ static void i2c_enable_vector_interrupt(i2c_t *obj, uint32_t handler, int enable
8686static void i2c_rollback_vector_interrupt (i2c_t * obj );
8787#endif
8888
89- #define TRANCTRL_STARTED (1)
90- #define TRANCTRL_NAKLASTDATA (1 << 1)
91- #define TRANCTRL_LASTDATANAKED (1 << 2)
89+ #define TRANCTRL_STARTED (1) // Guard I2C ISR from data transfer prematurely
90+ #define TRANCTRL_NAKLASTDATA (1 << 1) // Request NACK on last data
91+ #define TRANCTRL_LASTDATANAKED (1 << 2) // Last data NACKed
92+ #define TRANCTRL_RECVDATA (1 << 3) // Receive data available
9293
9394uint32_t us_ticker_read (void );
9495
@@ -592,11 +593,17 @@ static void i2c_irq(i2c_t *obj)
592593 if ((obj -> i2c .tran_ctrl & TRANCTRL_STARTED ) && obj -> i2c .tran_pos ) {
593594 if (obj -> i2c .tran_pos < obj -> i2c .tran_end ) {
594595 if (status == 0x50 || status == 0x58 ) {
595- * obj -> i2c .tran_pos ++ = I2C_GET_DATA (i2c_base );
596+ if (obj -> i2c .tran_ctrl & TRANCTRL_RECVDATA ) {
597+ * obj -> i2c .tran_pos ++ = I2C_GET_DATA (i2c_base );
598+ obj -> i2c .tran_ctrl &= ~TRANCTRL_RECVDATA ;
599+ }
596600 }
597601
598602 if (status == 0x58 ) {
599603 i2c_fsm_tranfini (obj , 1 );
604+ } else if (obj -> i2c .tran_pos == obj -> i2c .tran_end ) {
605+ obj -> i2c .tran_ctrl &= ~TRANCTRL_STARTED ;
606+ i2c_disable_int (obj );
600607 } else {
601608 uint32_t i2c_ctl = I2C_CTL0_SI_Msk | I2C_CTL0_AA_Msk ;
602609 if ((obj -> i2c .tran_end - obj -> i2c .tran_pos ) == 1 &&
@@ -605,6 +612,7 @@ static void i2c_irq(i2c_t *obj)
605612 i2c_ctl &= ~I2C_CTL0_AA_Msk ;
606613 }
607614 I2C_SET_CONTROL_REG (i2c_base , i2c_ctl );
615+ obj -> i2c .tran_ctrl |= TRANCTRL_RECVDATA ;
608616 }
609617 } else {
610618 obj -> i2c .tran_ctrl &= ~TRANCTRL_STARTED ;
@@ -659,12 +667,18 @@ static void i2c_irq(i2c_t *obj)
659667 if ((obj -> i2c .tran_ctrl & TRANCTRL_STARTED ) && obj -> i2c .tran_pos ) {
660668 if (obj -> i2c .tran_pos < obj -> i2c .tran_end ) {
661669 if (status == 0x80 || status == 0x88 ) {
662- * obj -> i2c .tran_pos ++ = I2C_GET_DATA (i2c_base );
670+ if (obj -> i2c .tran_ctrl & TRANCTRL_RECVDATA ) {
671+ * obj -> i2c .tran_pos ++ = I2C_GET_DATA (i2c_base );
672+ obj -> i2c .tran_ctrl &= ~TRANCTRL_RECVDATA ;
673+ }
663674 }
664675
665676 if (status == 0x88 ) {
666677 obj -> i2c .slaveaddr_state = NoData ;
667678 i2c_fsm_reset (obj , I2C_CTL0_SI_Msk | I2C_CTL0_AA_Msk );
679+ } else if (obj -> i2c .tran_pos == obj -> i2c .tran_end ) {
680+ obj -> i2c .tran_ctrl &= ~TRANCTRL_STARTED ;
681+ i2c_disable_int (obj );
668682 } else {
669683 uint32_t i2c_ctl = I2C_CTL0_SI_Msk | I2C_CTL0_AA_Msk ;
670684 if ((obj -> i2c .tran_end - obj -> i2c .tran_pos ) == 1 &&
@@ -673,6 +687,7 @@ static void i2c_irq(i2c_t *obj)
673687 i2c_ctl &= ~I2C_CTL0_AA_Msk ;
674688 }
675689 I2C_SET_CONTROL_REG (i2c_base , i2c_ctl );
690+ obj -> i2c .tran_ctrl |= TRANCTRL_RECVDATA ;
676691 }
677692 } else {
678693 obj -> i2c .tran_ctrl &= ~TRANCTRL_STARTED ;
@@ -695,12 +710,18 @@ static void i2c_irq(i2c_t *obj)
695710 if ((obj -> i2c .tran_ctrl & TRANCTRL_STARTED ) && obj -> i2c .tran_pos ) {
696711 if (obj -> i2c .tran_pos < obj -> i2c .tran_end ) {
697712 if (status == 0x90 || status == 0x98 ) {
698- * obj -> i2c .tran_pos ++ = I2C_GET_DATA (i2c_base );
713+ if (obj -> i2c .tran_ctrl & TRANCTRL_RECVDATA ) {
714+ * obj -> i2c .tran_pos ++ = I2C_GET_DATA (i2c_base );
715+ obj -> i2c .tran_ctrl &= ~TRANCTRL_RECVDATA ;
716+ }
699717 }
700718
701719 if (status == 0x98 ) {
702720 obj -> i2c .slaveaddr_state = NoData ;
703721 i2c_fsm_reset (obj , I2C_CTL0_SI_Msk | I2C_CTL0_AA_Msk );
722+ } else if (obj -> i2c .tran_pos == obj -> i2c .tran_end ) {
723+ obj -> i2c .tran_ctrl &= ~TRANCTRL_STARTED ;
724+ i2c_disable_int (obj );
704725 } else {
705726 uint32_t i2c_ctl = I2C_CTL0_SI_Msk | I2C_CTL0_AA_Msk ;
706727 if ((obj -> i2c .tran_end - obj -> i2c .tran_pos ) == 1 &&
@@ -709,6 +730,7 @@ static void i2c_irq(i2c_t *obj)
709730 i2c_ctl &= ~I2C_CTL0_AA_Msk ;
710731 }
711732 I2C_SET_CONTROL_REG (i2c_base , i2c_ctl );
733+ obj -> i2c .tran_ctrl |= TRANCTRL_RECVDATA ;
712734 }
713735 } else {
714736 obj -> i2c .tran_ctrl &= ~TRANCTRL_STARTED ;
0 commit comments