fsl_i2c/fsl_i2c_freertos performing partial read

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

fsl_i2c/fsl_i2c_freertos performing partial read

737 Views
michaelellis
Contributor II

I am trying to implement a PMBUS BlocK Read routine on a KV5 processor using the fsl_i2c_freertos driver.  The I2C sequence for this routine is as follows:

 

1) Master sends START

2) Master sends slave address with lsb cleared (write), slave sends ACK

3) Master sends command byte, slave sends ACK

4) Master sends REPEATED START

5) Master sends slave address with lsb set (read), slave sends ACK

6) Slave sends byte count N, master sends ACK

7) for i = 1 to N-1

7)    Slave sends data(i), master sends ACK

8) Slave sends data(N), master sends NACK

9) Master sends STOP

 

My routine is as follows:

bool psReadBlock(uint8_t cmd, uint8_t *pVal)
{
   ps_data_t *pParms = (ps_data_t *)&ps_data; // get pointer to data
   i2c_master_transfer_t *pXfer = &(pParms->i2c_xfer); // point to transfer structure
   status_t status;
   uint8_t count;

 

   pXfer->direction = kI2C_Write; // send command
   pXfer->data = &cmd;
   pXfer->dataSize = 1;
   pXfer->flags = kI2C_TransferNoStopFlag;
   status = I2C_RTOS_Transfer(&pParms->i2c_handle, pXfer);
   if (status != kStatus_Success)
      return (false);

 

   pXfer->direction = kI2C_Read; // read count value
   pXfer->data = &count;
   pXfer->dataSize = 1;
   pXfer->flags = kI2C_TransferRepeatedStartFlag | kI2C_TransferNoStopFlag;
   status = I2C_RTOS_Transfer(&pParms->i2c_handle, pXfer);
   if (status != kStatus_Success)
      return(false);

 

   pXfer->direction = kI2C_Read; // read data
   pXfer->data = pVal;
   pXfer->dataSize = count;
   pXfer->flags = kI2C_TransferNoStartFlag;
   status = I2C_RTOS_Transfer(&pParms->i2c_handle, pXfer);
   return (status == kStatus_Success);
}

 

The first transaction works as expected but I have a problem with the second transaction.  I set the kI2C_TransferRepeatedStartFlag and kI2C_TransferNoStopFlag.  The REPEATED START is sent (as expected) and no STOP is sent (as expected) but the master sends a NACK instead of an ACK.  This causes the slave device to terminate the sequence and I cannot retrieve the remaining data.

 

I believe that the driver should only send a NACK after reading the final byte of data only if a STOP sequence is to be sent.  if no STOP has been requested then the driver should ACK all bytes being read.

Labels (1)
0 Kudos
1 Reply

464 Views
michaelellis
Contributor II

While digging into the driver I have found that the kI2C_TransferNoStartFlag ignored.  Every transaction started through I2C_MasterTransferNonBlocking will generate a START or REPEATED START sequence.  This is not going to be easy...

0 Kudos