Dear all,
We are creating a new product using MSP432P401R with I2C connection.
I created the project with CCS and check the sample code from TI.
It can transmit I2C data successfully but error after receive I2C data.
The figures of I2C signal are shown below.
Fig.1 Transmit successfully
Fig.2 Receive successfully and the data is same as the data I saved
Fig.3 Transmit fail after receiving
The codes are shown below.
Each operation,I'll call I2C_Set() for assigning slave address then call I2C_Receive() or I2C_Transmit()
void I2C_Set(unsigned char SlaveAddress) { P1SEL0 |= (SDA + SCL); // I2C pins NVIC->ISER[0] = 1 << ((EUSCIB0_IRQn) & 31); // Enable eUSCIB0 interrupt in NVIC module EUSCI_B0->CTLW0 |= EUSCI_B_CTLW0_SWRST; // put eUSCI_B in reset state EUSCI_B0->CTLW0 = EUSCI_B_CTLW0_SWRST | // Remain eUSCI_B in reset state EUSCI_B_CTLW0_MODE_3 | // I2C mode EUSCI_B_CTLW0_MST | // I2C master mode EUSCI_B_CTLW0_SYNC | // Sync mode EUSCI_B_CTLW0_SSEL__SMCLK; // SMCLK EUSCI_B0->BRW = 480; // baudrate = SMCLK / 480 = 1K EUSCI_B0->CTLW0 &= ~EUSCI_B_CTLW0_SWRST; // clear reset register EUSCI_B0->I2CSA = SlaveAddress; // configure slave address } void I2C_Transmit(unsigned char Address, unsigned char Data) { I2C_Data[0]=Address; I2C_Data[1]=Data; I2C_Length=2; I2C_State=0; EUSCI_B0->IE |= EUSCI_B_IE_TXIE0 | // Enable transmit interrupt EUSCI_B_IE_NACKIE; // Enable NACK interrupt __enable_irq(); // Enable global interrupt while (EUSCI_B0->CTLW0 & EUSCI_B_CTLW0_TXSTP); // Ensure stop condition got sent EUSCI_B0->CTLW0 |= EUSCI_B_CTLW0_TR | // I2C TX EUSCI_B_CTLW0_TXSTT; // Start condition } void I2C_Receive(unsigned char Address, unsigned short Number) { //write address to slave I2C_Data[0]=Address; I2C_Length=1; I2C_State=0; EUSCI_B0->IE |= EUSCI_B_IE_TXIE0 | // Enable transmit interrupt EUSCI_B_IE_NACKIE; // Enable NACK interrupt __enable_irq(); // Enable global interrupt while (EUSCI_B0->CTLW0 & EUSCI_B_CTLW0_TXSTP); // Ensure stop condition got sent EUSCI_B0->CTLW0 |= EUSCI_B_CTLW0_TR | // I2C TX EUSCI_B_CTLW0_TXSTT; // Start condition Delay(1); //read data from slave address for number data EUSCI_B0->CTLW1 |= EUSCI_B_CTLW1_ASTP_2; // Automatic stop generated EUSCI_B0->TBCNT = Number; // number of bytes to be received EUSCI_B0->IE |= EUSCI_A_IE_RXIE | // Enable receive interrupt EUSCI_B_IE_NACKIE | // Enable NACK interrupt EUSCI_B_IE_BCNTIE; // Enable byte counter interrupt __enable_irq(); // Enable global interrupt while (EUSCI_B0->CTLW0 & EUSCI_B_CTLW0_TXSTP); // Ensure stop condition got sent EUSCI_B0->CTLW0 &= ~EUSCI_B_CTLW0_TR; // I2C RX EUSCI_B0->CTLW0 |= EUSCI_B_CTLW0_TXSTT; // I2C start condition } void EUSCIB0_IRQHandler(void) { if (EUSCI_B0->IFG & EUSCI_B_IFG_NACKIFG) { EUSCI_B0->IFG &= ~EUSCI_B_IFG_NACKIFG; EUSCI_B0->CTLW0 |= EUSCI_B_CTLW0_TXSTT;// I2C start condition //UCB0CTL1 |= EUSCI_B_CTLW0_TXSTT; } if (EUSCI_B0->IFG & EUSCI_B_IFG_TXIFG0) { EUSCI_B0->IFG &= ~EUSCI_B_IFG_TXIFG0; if(I2C_Length) { EUSCI_B0->TXBUF = I2C_Data[I2C_State++]; // Load TX buffer I2C_Length--; } else { EUSCI_B0->CTLW0 |= EUSCI_B_CTLW0_TXSTP; // I2C stop condition EUSCI_B0->IFG &= ~EUSCI_B_IFG_TXIFG; // Clear USCI_B0 TX int flag } } else if(EUSCI_B0->IFG & EUSCI_B_IFG_RXIFG0) { EUSCI_B0->IFG &= ~ EUSCI_B_IFG_RXIFG0; I2C_Data[I2C_State++]=EUSCI_B0->RXBUF; } if (EUSCI_B0->IFG & EUSCI_B_IFG_BCNTIFG) { EUSCI_B0->IFG &= ~ EUSCI_B_IFG_BCNTIFG; } }
How can I solve the trouble?
BR,
Norton