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.

TMS570LC4357: I2C Write + Read without STOP

Part Number: TMS570LC4357

An IC we're working with (PCA9654E) requires a repeat start condition -- without stop -- between writing a command byte and reading the resultant value from the register.

Here is the code I'm calling to do this. Note that I've removed code that waits for the busy bus, etc, here to save space. (Those functions are working OK when called from functions that exclusively write or read bytes on the bus).

inline int i2cSendGetBytes(uint8_t slaveId, uint32_t out_length, uint8_t *out_data,
                           uint32_t in_length, uint8_t *in_data) {

  i2cBASE_t *i2c = i2cREG1;

  i2cSetMode(i2c, I2C_MASTER | I2C_REPEATMODE);            
  i2cSetSlaveAdd(i2c, slaveId);          
  i2cSetDirection(i2c, I2C_TRANSMITTER);  

  i2cSetStart(i2c);             

  //WaitForTxReady Here

  i2cSend(i2c, out_length, out_data);

  //WaitWhileBusy Here

  //WaitForMasterReady Here
 
  i2cSetMode(i2c, I2C_MASTER);
  i2cSetSlaveAdd(i2c, slaveId);           
  i2cSetDirection(i2c, I2C_RECEIVER);   
  i2cSetCount(i2c, in_length);             

  i2cSetStart(i2c); 

  //WaitForRxReady Here

  i2cReceive(i2c, in_length, in_data);

  // WaitWhileBusy Here

  // WaitForStop here

  //WaitForMasterReady here

  i2cSetStop(i2c);                      

}


Is this the general algorithm? I never get anything but 0x00 from the read operation. I suspect I'm missing setting a mode or state.

  • Hi Joe,

    My suggested code is below:

    inline int i2cSendGetBytes(uint8_t slaveId, uint32_t out_length, uint8_t *out_data,
                               uint32_t in_length, uint8_t *in_data) {
    
      i2cBASE_t *i2c = i2cREG1;
    
      i2cSetMode(i2c, I2C_MASTER | I2C_REPEATMODE);            
      i2cSetSlaveAdd(i2c, slaveId);          
      i2cSetDirection(i2c, I2C_TRANSMITTER);
      i2cSetCount(i2c, out_length);
    
      i2cSetStart(i2c);             
    
      //WaitForTxReady Here
    
      i2cSend(i2c, out_length, out_data);
    
      //WaitWhileBusy Here
      while ( i2cIsBusBusy( i2c ) == TRUE );
    
      //WaitForMasterReady Here
     
      i2cSetMode(i2c, I2C_MASTER);
      i2cSetSlaveAdd(i2c, slaveId);           
      i2cSetDirection(i2c, I2C_RECEIVER);
      i2cSetStop(i2c);    
      i2cSetCount(i2c, in_length);             
    
      i2cSetStart(i2c); 
    
      //WaitForRxReady Here
    
      i2cReceive(i2c, in_length, in_data);
    
      // WaitWhileBusy Here
      while ( i2cIsBusBusy( i2c ) == TRUE );
    
      // WaitForStop here
      while(i2cIsStopDetected(i2c) == 0); 
      
      //Clear Stop condition
      i2cClearSCD( i2cREG2 );
    
      //WaitForMasterReady here                     
    
    }

    --
    Thanks & regards,
    Jagadish.

  • 1. What's the purpose of calling i2cSetStop() in line 25 if I don't want a stop condition between TX and RX?

    2. Since we're in REPEATMODE, aren't calls to i2sSetCount useless?

  • Hi Joe,

    2. Since we're in REPEATMODE, aren't calls to i2sSetCount useless?

    Are you configuring it into REPEATMODE?

    Is it your data not fixed number of bytes? why did you configure it in repeat mode?

    If your application really requires repeat mode then you are correct, I2CCNT useless in the repeat mode.

    --
    Thanks & Regards,
    Jagadish.