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.

TMS320C5535: CSL Library I2C read with repeated start

Part Number: TMS320C5535

I'm currently trying to communicate with a slave device using I2C which expects the following protocol: 

"The read data protocol is used to transmit data from IC memory locations 000h to 1FFh . Addresses 000h to 0FFh and 180h to 1FFh can be read as a block. Addresses 100h to 17Fh must be read as individual words. The memory address is sent by the bus master as a single byte value immediately after the slave address. Immediately following the memory address, the bus master issues a REPEATED START followed by the slave address. The MAX17201/MAX17205 acknowlege the address and begin transmitting data. A word of data is read as two separate bytes that the master must ACK. Because the address is automatically incremented after the least significant bit (LSb) of each word received by the IC, the MSB of the data at the next memory address can be read immediately after the acknowledgment of the LSB of data at the previous address. The master indicates the end of a read transaction by sending a NACK followed by a STOP."

Using the CSL library, I've configured the I2C as follows: 

    /* Setup I2C peripheral */
    i2cSetup.addrMode    = CSL_I2C_ADDR_7BIT;
    i2cSetup.bitCount    = CSL_I2C_BC_8BITS;
    i2cSetup.loopBack    = CSL_I2C_LOOPBACK_DISABLE;
    i2cSetup.freeMode    = CSL_I2C_FREEMODE_DISABLE;
    i2cSetup.repeatMode  = CSL_I2C_REPEATMODE_DISABLE;
    i2cSetup.ownAddr     = (0x2F);
    i2cSetup.sysInputClk = CSL_I2C_SYS_CLK;  // 100 Mhz
    i2cSetup.i2cBusFreq  = CSL_I2C_BUS_FREQ; // 10 Khz

and the code I use to drive the communication is: 

    CSL_Status status = CSL_ESYS_FAIL;
    Uint16 regADDR = 0x0000;
    Uint16 Rx[2] = {0};

    regADDR = DataBlock_regADDR & 0x00FF;  // Extract LSB to send

    do {
    status = I2C_write(&regADDR,
                       1,
                       DataBlock_SlaveADDR,
                       TRUE,
                       (CSL_I2C_START),
                       CSL_I2C_MAX_TIMEOUT);
    } while( status != CSL_SOK );

    status = I2C_read(Rx,
                      2,
                      DataBlock_SlaveADDR,
                      NULL,
                      0,
                      TRUE,
                      (CSL_I2C_START)|(CSL_I2C_STOP),
                      CSL_I2C_MAX_TIMEOUT,
                      FALSE);

//    if( status == CSL_I2C_BUS_BUSY_ERR){while(1){}}
//    if( status == CSL_I2C_NACK_ERR){while(1){}}
//    if( status == CSL_I2C_TIMEOUT_ERROR){while(1){}}

    *(Rx_data) = ( (Rx[1]<<8) | Rx[0]  );

    return status;

The I2C_write() is SUCCESSFUL and returns CSL_SOK. However, I2C_read returns a value of -200 ( "CSL_I2C_TIMEOUT_ERROR"). I have tried to follow the protocol as closely as possible, please notice that:

1) For I2C_write, I set the CSL_I2C_START parameter but NOT the CSL_I2C_STOP parameter because the protocol doesn't call for a stop condition after the I2C write().

2) I use I2C_write() to send the memory address ("regADDR") as the data to write, which is what the protocol seems to want.  

3) For I2C_read, I set the CSL_I2C_START parameter AND the CSL_I2C_STOP parameter because the protocol calls for a repeated START and finally a STOP. 

I also have tried different combinations of enabling and disabling repeat mode in i2cSetup.repeatMode, but I2C_read continues to return CSL_I2C_TIMEOUT_ERROR. Any guidance and advice would be greatly appreciated! I will continue to work out the problem and update if I find a solution. 

Best, 

Eddie

  • Hi Eddie,

    I suggest you to take a look at CSL_I2C_PollExample_Out for reference about I2C initialization, writing and reading.

    Also my first suggesting is to try to make some short delay between writing and reading:

    	/* Give some delay */
    	for(looper = 0; looper < CSL_I2C_MAX_TIMEOUT; looper++){;}

    Regards,

    Tsvetolin Shulev