This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

SIMPLELINK-MSP432-SDK: Error transmitting I2C data after receiving using MSP432P401R

Part Number: SIMPLELINK-MSP432-SDK

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.

Transmit successfully 
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

  • Hi Norton,

      A couple of comments.

     - MSP432P is an EOL'ed device that we no longer provide technical support on e2e. I can't review your code that is specific to MSP432P as I have no experience with the device. But I can provide some general feedback about I2C.

     - Your captures are really small. It is really hard to see. What do you mean the 2nd transmit does not work after receive? From your capture, it is sending something out. What is wrong with it? How is the 2nd transmit different to the first successful transmit?

      - I will suggest you make the 2nd transmit identical to the first one and single step your code to see if all the register settings are still the same between them.  

      - There are several i2c examples in the SDK. Have you had a chance to run and reference them?

  • >  EUSCI_B0->CTLW1 |= EUSCI_B_CTLW1_ASTP_2; // Automatic stop generated
    > EUSCI_B0->TBCNT = Number; // number of bytes to be received

    UCASTP isn't cleared by UCSWRST, [Ref TRM (SLAU356I) Sec 26.3.1] so it will still be set (with TBCNT=1) when you do the subsequent transmit, and the Tx transaction will stop after 1 byte.

    I suggest you set UCASTP=0 in I2C_Set. Strictly speaking you should only change UCASTP/TBCNT while UCSWRST=1 [Ref TRM Tables 26-5/26-8] , but  from observed behavior I guess this isn't enforced.

  • Hi Charles,

    Thanks for your replying.

    I have found out where the problem is.

    It should transmit 3 bytes via I2C but it transmit only 2 bytes after I did the receive operation.

    The problem is the register "TBCNT" of EUSCI_B0.

    I enabled the interrupt in the receive operation but the TBCNT is not set to the correct number of transmit.

    It work successfully after I add the code to set the TBCNT register in the transmit operation.

    BTW,

    You said the MSP432P device is an EOL'ed device.

    Does it means that our company will no longer available to purchase the MSP432P401R chip?

    BR,

    Norton

  • You said the MSP432P device is an EOL'ed device.

    Does it means that our company will no longer available to purchase the MSP432P401R chip?

    Hi Norton,

      Glad your problem is resolved. Please contact your local TI sales team for availability. This device is not recommended for for new designs.