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 protocol, in the first read transaction i read more byte then i expected.

Other Parts Discussed in Thread: MSP430F5438A

Hello,

 

I work with processor msp430f5438A.

And with IDE CCS 5.3.

My question is regarding the operation of the I2C.

The processor is the master and the slave is serial ADC (ADS).

 

The master read the from one of the serial ADC (ADS).

The data length is 16 bit. Therefore after the address is set the

Processor reading 16 bit ( of data ) .

 

But the problem was that I pay attention that In the first transaction ONLY that I read from the ADS I get 3 bytes ( instead of 2) .

Like in the next picture. Last byte (0xFF) should not be appear.

 

 

I understand that the problem is that :

when the processor send the START (start the transaction) , it send the address and (aotumaticaly Without an explicit request)   bring the first byte from the ADS. And due to the fact that the processor has to read 2 more bytes, the total

data from the ADS is 3 ( insted of 2) .

as I say, this problem apear just in the first transaction,

in all the other transction the problem disapear.

 

I have aguss than due to the fact that the last byte is not been read, therefore the flag (UCRXIFG) is still set , and that is the reason the in the secong transation

the processor read just 2 bytes.

 

I try to solve the problem by setting UCB1IFG |= UCRXIFG before I read the data ( see  below, (in the code) in function I2cRdMng () in the 3 code line, i mark the line ) , and that solve the problem.

Like in the second picture.

This is the normal reading that I expected for.

the code that I use is bellow.

In main I config the i2c with

I2cCnfg();

I2C_ADDRESS(0x48);

And then call the function:

I2cRdMng(2, buf);// the number of reading is 2 ( bytes).

 

 

My question is

  1. Is it obligate that after sending the address , the first data will be read/requsted ?
  2. In case that I want to assure always that my initial conditions will start from clean , how I do it? If I clear the UCRXIFG flag before I start reading , or after I end to read all my data , it not work (I don’t get data , something stuck ) I see just the read address with out any afterwards data.

thanks.

--- code

#define I2C_ADDRESS(address) 	(UCB1I2CSA = (unsigned char)(address))

void I2cCnfg (void)
{
	 UCB1CTL1 |= UCSWRST;// Enable SW reset

	 UCB1CTL0 = UCMST + UCMODE_3 + UCSYNC;     // I2C, Master, synchronous mode

	 UCB1CTL1 = UCSSEL__SMCLK + UCSWRST;// Use SMCLK, keep SW reset
	 UCB1BR0 = 160;            // fSCL = SMCLK/160 = ~100kHz
	 UCB1BR1 = 0;
	 UCB1CTL1 &= ~UCSWRST;  // Clear SW reset, resume operation
//	 UCB1IE |= UCRXIE;     // Enable RX interrupt

}


Uint16 I2cRdMng (Uint16 numRd, unsigned char * I2cRdbuf)
{
	Uint16 rslt;
//	UCB1IFG &= ~UCRXIFG;
//	UCB1IFG |= UCRXIFG;// <<<< HERE IN THE CODE i set the flag  in order to solve the problem of extra reading.<<<!!!!!!!!!!
	UCB1CTL1 &= ~UCTR;// config as read.
	I2CWaitToStop ();
	UCB1CTL1 |=  UCTXSTT;// transmit the address with the start condition.
	I2CWaitToStart ();

	/* 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;
	}
	I2CRdData( numRd, I2cRdbuf);
	I2CEndTrns ();
	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 I2CWaitToStart (void)
{
	Uint32 I2CWatchCounter = I2C_BUSY_CYCLES;
//	   UCB1CTL1 |= UCTXSTT;  // I2C Set Start condition/transaction.
//	   __no_operation();
	   //------------------------------------------
	   I2CWatchCounter = I2C_BUSY_CYCLES;
		while (((UCB1CTL1 & UCTXSTT))&& (--I2CWatchCounter));// Start condition sent?
		if (I2CWatchCounter==0)// then error
		{
			I2CErrNum = SET;
		//  return FAIL;
		}
		return OK;
}

Uint16 I2CRdData(Uint16 numRd, unsigned char * I2cRdbuf)
{
	Uint16 I2cRdIndx = 0;
	Uint16 NumOfRd = numRd;
	Uint32 I2CWatchCounter = I2C_BUSY_CYCLES;
	   while (NumOfRd--){// number of reading, without repeated start
//		   while (!(UCB1IFG & UCRXIFG));//UCRXIFG is automatically reset when UCxRXBUF is read
		   /* wait for the  data to receive.
		    * the slave transmit the data and the master put the ack,
		    * that the reason that no need to wait for ack from the slave.
		    */
		   I2CWatchCounter = 10*I2C_BUSY_CYCLES;
		   //UCRXIFG is automatically reset when UCxRXBUF is read
	 		while ((((UCB1IFG & UCRXIFG)==0))&& (--I2CWatchCounter));
	 		if (I2CWatchCounter==0)// then error
	 		{
	 			I2CErrNum = SET;
	 		//  return FAIL;
	 		}

		   //-----------------------------
		   I2cRdbuf [I2cRdIndx] = UCB1RXBUF;////UCRXIFG is automatically reset when UCxRXBUF is read
//		   UCB1IFG &= ~UCRXIFG;// //UCRXIFG is automatically reset when UCxRXBUF is read
		   	I2cRdIndx++;
		   	//I2cRdIndx%=I2C_RX_BUF_SIZE;
	   }
	   return OK;

}
Uint16 I2CEndTrns (void)// end transaction.
{
	   UCB1CTL1 |= UCTXSTP;// I2C stop transaction
//	   while ((UCB1CTL1 & UCTXSTP));// wait until the bit is cleared.
	   	   // instead of repeated start.
	   	   //UCTXSTP is automatically cleared after STOP is generated.
	   //----------------------
		 I2CWaitToStop ();
		   //-----------------------------
		__delay_cycles(I2C_STANDARD_DLY_BETWEEN_TRNSC); // for debug,
		return OK;
}

 

 

  • sory,
    i try to edit my post , and i see that i duplicate it in the forum .
    how the delete all those duplicates posts??
  • Hi Asher,

    On the bottom of the post, there is a button marked "More" - I think when you click this one of your options should be delete. I'm a moderator so I can delete these duplicates for you though - just letting you know how to do it in the future.

    Before I delete them however, I am thinking this could be a bug with our forum that should be reported. Can you please let me know:

    1. what browser and browser version you are using
    2. what sequence of events happened - did you click More > Edit, and edit your post, then click post, but it showed up as a duplicate? Or did you do something else?

    -Katie

  • first of all, i found the problem in my code and fix it.
    i have no bug any more .

    about your question:
    i work with firefox.
    i don't remember exactly the sequence of events that happen.
    but i try to edit the post after i send it.
    i still don't know how to do it.
    i remember that that this was possible ( before some month's) , but know i don't find this option.
    it seem that after i send the post i can't update it or edit it ( if i need to ) any more.
  • Hi asher,

    If you go to the post at this link: http://e2e.ti.com/support/microcontrollers/msp430/f/166/p/398264/1410324

    You should be able to scroll to directly below your first post and see a button that says "More" (I've marked it in green here):

    When you click on this button More, then there should be a list that pops up that shows options including "Edit" - click that option and you should be able to edit the post.

    Regards,

    Katie

  • You can't delete a post if someone else has already replied to it.
    It shall prevent the case that there is an answer left to no question. (however, you can still edit the and remove the content the answer was referring to) i guess it was blocked so the forum software won't choke if the replier wants to edit his text and the page wants to load the original post he was replying to.

**Attention** This is a public forum