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.

I2c , the master read single byte , the flag UCRXIFG is not reset as it should be. Why?

Other Parts Discussed in Thread: MSP430F5438A

Hello,

 

I work with processor msp430f5438A.

And with IDE CCS 5.3.

The issue of the question is about I2C, UCRXIFG flag is not reset when reading from UCB1RXBUF ( single byte).

 

The system description:

The processor is the master in receive mode ( receive data from slave). The procedure of reading is depict in the user’s guide : slau208n.pdf page 960..

I attach the code ( see below).

The function work fine, The question is about the behavior of the flag UCRXIFG in register UCB1IFG ( will be call from now UCB1IFG. UCRXIFG) just in the case of reading 1 byte only ( there is no problem when I read more then 1 byte).

 

This flag according the user’s guide suppose to reset automatically after reading from UCB1RXBUF .

when I read at least 2 bytes , it work fine ( the UCB1IFG. UCRXIFG flag is clear after reading from ).

But when I read 1 byte only , the UCRXIFG flag is not reset. althogh the routine read 1 byte of data as I expected ( and I see in the scope that only 1 byte was sent from the slave to the master). the UCB1IFG. UCRXIFG is still set. ( and it suppose to clear).

 

This problem dosn't exist when I run step by step.

When I run step by step the UCB1IFG. UCRXIFG is always clear .

 

I would like to note that I was working by the book ( the user guide), which relate to the case of reading only one byte.

 

And I quote ( page 960) :

“If a master wants to receive a single byte only, the UCTXSTP bit must be set while the byte is being received. For this case, the UCTXSTT may be polled to determine when it is cleared:

 ///------------------

BIS.B #UCTXSTT, &UCB0CTL1 ;Transmit START cond.

POLL_STT     BIT.B #UCTXSTT, &UCB0CTL1 ;Poll UCTXSTT bit

              JC        POLL_STT ;When cleared,

BIS.B #UCTXSTP, &UCB0CTL1 ;transmit STOP cond.

//----------------------------

 

1) Is there any one have an idea why the UCB1IFG. UCRXIFG not reset after I read from UCB1RXBUF?

2) And why when I run step by step the flag is reset ( like it should be) .

 

 // ------ calling the routine :

 i call to the routine : I2cRdMng_4 (2, Rdbuf);

---the code

Uint16 I2CWaitToStart (void)
{
	Uint32 I2CWatchCounter = I2C_BUSY_CYCLES;
	   I2CWatchCounter = I2C_BUSY_CYCLES;
		while (((UCB1CTL1 & UCTXSTT))&& (--I2CWatchCounter));// Start condition sent?
		if (I2CWatchCounter==0)// then error
		{
			I2CErrNum = SET;
		//  return FAIL;
		}
		return OK;
}

Uint16 I2CWaitToStop (void)
{
	Uint32 I2CWatchCounter = I2C_BUSY_CYCLES;
	I2CWatchCounter = I2C_BUSY_CYCLES;
	while (((UCB1CTL1 & UCTXSTP))&& (--I2CWatchCounter));
	if (I2CWatchCounter==0)// then error
	{
		I2CErrNum = SET;
	   return FAIL;
	}
	return OK;

}
Uint16 I2cRdMng_4 (Uint16 numRd, unsigned char * Rdbuf)
{
	Uint16 rslt;
	Uint32 I2CWatchCounter = I2C_BUSY_CYCLES;
	Uint16 RdIndx = 0;
	Uint16 NumOfRd = numRd;
	Rdbuf [0] = Rdbuf [1] = 0;// for debug only. forbid in the operation state<<<<<<<.
	if (NumOfRd == 0 )
	{
		return TRUE;
	}

	UCB1CTL1 &= ~UCTR;// config as read.
	I2CWaitToStop ();
	UCB1CTL1 |=  UCTXSTT;// transmit the address with the start condition.
	I2CWaitToStart ();
	//--this section deal with reading single byte only, --------------------
	if (NumOfRd == 1) /* if need to get only one byte
						* the procedure is a little different.
						*/
	{
		UCB1CTL1 |= UCTXSTP;// generate stop condition.
		Rdbuf [0] = UCB1RXBUF;//UCRXIFG is automatically reset when UCxRXBUF is read
		return TRUE;
	}
	//----------------------------------------------------------------------------

	/* after the start condition ( the transmitted with the address)
	 * the master need to wait for the ack from the slave.
	 * ( after that neck, the master receive the data and send ack,
	 * therefore the only ack that the master received is after sending
	 * the address.
	 */
	rslt = I2CCheckNack ();/* if nack then the transaction is end here
						* the address need to be ack.
						*/
	if (rslt == TEST_FAIL)// receive nack, and stop the transaction.
	{
		return FAIL;
	}
	while (NumOfRd)
	{
		NumOfRd--;

		I2CWatchCounter = 2*I2C_BUSY_CYCLES;
 		while ((((UCB1IFG & UCRXIFG)==0))&& (--I2CWatchCounter));
 		if (I2CWatchCounter==0)// then error
 		{
 			I2CErrNum = SET;
 		//  return FAIL;
 		}
 		if (NumOfRd)
 		{
 			Rdbuf [RdIndx] = UCB1RXBUF;//UCRXIFG is automatically reset when UCxRXBUF is read
 			RdIndx++;
 			if(NumOfRd == 1 )// only one byte left.
 			{
 			   UCB1CTL1 |= UCTXSTP;// generate stop condition.
 			   _no_operation();// for debug.
 			}
 		}
 		else //NumOfRd == 0
 		{
 			Rdbuf [RdIndx] = UCB1RXBUF;
 			//I2CWaitToStop ();// check it before the next transaction.
 		}
	}
	__delay_cycles(I2C_STANDARD_DLY_BETWEEN_TRNSC); // for debug,

	_no_operation();
	return OK;
}



thanks.

  • Your special code for receiving just one byte is reading RXBUF immediately after TXSTT clears and TXSTP is set. It doesn't wait for RXIFG. So it reads the current (outdated) content of RXBUF. The RXIFG you see indicates that the first byte has arrived (which you never read).

**Attention** This is a public forum