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.

TMS320DM643: problems receiving data through I2C

Part Number: TMS320DM643

Hello there,

We had an old design where we used to read data as a I2C master device. The code was prepared to read only 1 byte, now that we have changed the I2C slave device we require to read 2 data bytes for some registers.

The writing sequence of the register address is done correctly. However, the reading sequence has some problems.

The NACK in not sent after getting the last data byte, it sends an extra byte (seen through the oscilloscope). I don't know if we are doing it correctly but we set the NACKMOD register bit to 1 just after reading the second to last byte. Here is the code of the function, any suggestion is welcome:

Int16 i2c_OEM_readX( Uint8 deviceAddr, Uint8* RegAddr, Uint8 regLen, Uint8* data, Uint8 dataLen){

  Uint16 ret = 0;
  Uint8 tempByte;
  int i;

  while(I2C_REG0->ICSTR.bit.BB);    //wait for bus to be not busy
  
  //Just send SLA+R if no register bytes to send
if(regLen !=0){

  //SET BYTE COUNT (dataLen+1)
  I2C_REG0->ICCNT.bit.ICDC = regLen;

  I2C_REG0->ICMDR.bit.MST = 1;	//make sure we're in master mode
  I2C_REG0->ICMDR.bit.TRX = 1;	//make sure we're in transmit mode to send register address

  //set up the slave address
  I2C_REG0->ICSAR.bit.SADDR = deviceAddr >> 1;

  //send the START condition and the slave address
  I2C_REG0->ICMDR.bit.STT = 1;

  //wait for START condition and slave address to go out
  waitloop(10000);

  //check for a NACK
  if(I2C_REG0->ICSTR.bit.NACK)
    {
	I2C_REG0->ICMDR.bit.STP = 1;
    return(-1);
	}

  waitloop(2000);
  //wait for transmitter to be ready then send the register address
  	//SEND DATA BYTES	
	for(i=0;i<regLen;i++){
  		//get the current byte
		tempByte = RegAddr[i];
  		
  		//wait for transmitter to be ready then send the upper byte of data
  		while(I2C_REG0->ICSTR.bit.ICXRDY == 0);
		I2C_REG0->ICDXR.bit.D = tempByte;

  		//wait for data to go out
 		 waitloop(4000);

  		//check for a NACK
  		if(I2C_REG0->ICSTR.bit.NACK){
			I2C_REG0->ICMDR.bit.STP = 1;
    		return(-1);
		}
	}
}

/****************************/
//setup device for read 
/****************************/

  //now set up to receive the upper byte of data
  I2C_REG0->ICMDR.bit.MST = 1;		//make sure we're in master mode
  I2C_REG0->ICMDR.bit.TRX = 0;		//make sure we're in receive mode
  I2C_REG0->ICMDR.bit.NACKMOD = 0;	//send NACK at end
  I2C_REG0->ICCNT.bit.ICDC =  0; // 

  //set up the slave address
  I2C_REG0->ICSAR.bit.SADDR = deviceAddr >> 1;

  //send the START condition and the slave address
  I2C_REG0->ICMDR.bit.STT = 1;
  
  waitloop(10000);
  //check for a NACK
	if(I2C_REG0->ICSTR.bit.NACK){
			I2C_REG0->ICMDR.bit.STP = 1;
    		return(-1);
		}
  
  //Loop through and collect reads
	for(i=0;i<dataLen;i++){
		if(i==dataLen - 1){
			I2C_REG0->ICMDR.bit.NACKMOD = 1;
		}
		
		waitloop(10000);
		//wait for byte to show up in recieve buffer
  		while(I2C_REG0->ICSTR.bit.ICRRDY == 0);
		data[dataLen-1-i] = I2C_REG0->ICDRR.bit.D;
	}
	
I2C_REG0->ICMDR.bit.STP = 1;

}