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.

HALCOGEN: i2C example with repeated START condition, using HALCoGen api

Part Number: HALCOGEN

I have an I2C device that requires a restart condition

Here's the expected start of the I2C conversation.

What would be the sequence of HALCoGen I2C API calls to perform this restart (avoid a STOP being generated?
What combination of i2cSetCount, i2cSetStop, i2cSetStart and i2cClearSCD do I have to use to get this behaviour?

  • Hello Jan,
    Plase follow this thread and tell me whether it is helpful for you: e2e.ti.com/.../520353 .

    Best regards,
    Miro
  • I have followed it before I logged this topic.

    It does not result in  a valid i2c exchange.

  • Hi Jan,

    This is my code to read/write data from/to RTC.

    /* Read from a slave device */
    int I2C_Read_M(short Slave_Add, short Read_Add, short Count, uint8 *buff)
    {
    int i, error, dummy;
    error = 0;

    if((i2cREG1->STR & I2C_BUSBUSY ) == 0) //test if Busy is busy
    {
    /* Clear Stop bit */
    i2cREG1->MDR &= ~(I2C_STOP_COND);
    /* Clear Start bit */
    i2cREG1->MDR &= ~(I2C_START_COND);
    /* Clear Repeat mode bit */
    i2cREG1->MDR &= ~(I2C_REPEATMODE);

    /* Set direction to Transmitter */
    i2cSetDirection(i2cREG1, I2C_TRANSMITTER);
    /* Set mode as Master */
    i2cSetMode(i2cREG1, I2C_MASTER);
    /* Configure Data count */
    i2cSetCount(i2cREG1, 0x01); //for 1-byte read address

    /* Configure address of Slave to talk to */
    i2cSetSlaveAdd(i2cREG1, Slave_Add);

    /* send the read address */
    i2cSendByte(i2cREG1, Read_Add);

    /* Start transmit*/
    i2cSetStart(i2cREG1); // Start the transmission:
    //I2C Bus: Start--Slave Addr--Read Addr

    while( ((i2cREG1->STR & I2C_NACK) == 0) && ((i2cREG1->STR & I2C_ARDY) == 0) );

    if((i2cREG1->STR & I2C_NACK) == 0) // Check for Positive Acknoledge
    { // Application can continue
    /* Set mode as Master, and Receiver */
    i2cSetMode(i2cREG1, I2C_MASTER); // Switch to Master Receiver
    i2cSetDirection(i2cREG1, I2C_RECEIVER);
    /* Set Repeat start mode */
    i2cREG1->MDR |= I2C_REPEATMODE;

    /* Start transmit*/
    i2cSetStart(i2cREG1); //I2C BUS: Start--Slave Addr

    for (i=0; i<Count; i++)
    {
    buff[i] = i2cReceiveByte(i2cREG1); // Read incoming data and store in array
    if (i == Count-2){
    i2cSetStop(i2cREG1); //to generate a STOP
    }
    }
    }
    else
    {
    dummy = i2cREG1->IVR; // Clear nack flag
    i2cSetStop(i2cREG1); // to generate a STOP
    error=-2; // Set error as NoAck
    }
    }
    else{
    error = -1; // Set error as Bus Busy
    }

    while((i2cREG1->MDR & I2C_STOP_COND) ==1);

    return error;
    }


    /* Write to a slave device */
    int I2C_Write_M(short Slave_Add, short Write_Add, short Count, uint8 *buff )
    {
    int error, dummy; // Return code
    error = 0x00; // Default, no error

    if((i2cREG1->STR & I2C_BUSBUSY ) == 0) //test if Busy is busy
    {
    /* Set direction to Transmitter */
    i2cSetDirection(i2cREG1, I2C_TRANSMITTER);
    /* Set mode as Master */
    i2cSetMode(i2cREG1, I2C_MASTER);

    /* Clear Start bit */
    i2cREG1->MDR &= ~(I2C_START_COND);
    /* Set Stop after programmed Count */
    i2cSetStop(i2cREG1);

    /* Clear RM bit */
    i2cREG1->MDR &= ~(I2C_REPEATMODE); // Not in Repeat Mode

    /* Configure Data count */
    i2cSetCount(i2cREG1, Count+1);

    /* Configure address of Slave to talk to */
    i2cSetSlaveAdd(i2cREG1, Slave_Add);

    /* Transmit Start Condition */
    i2cSetStart(i2cREG1); //I2C Bus: Start--Slave Addr

    /* send the write address */
    i2cSendByte(i2cREG1, Write_Add); // Transmit data to Select Destination Register

    if((i2cREG1->STR & I2C_NACK) == 0) // Check for Positive Acknoledge
    {
    /* Tranmit DATA_COUNT number of data in Polling mode */
    i2cSend(i2cREG1, Count, buff);
    }
    else{
    dummy = i2cREG1->IVR; // Clear nack flag
    i2cSetStop(i2cREG1); // to generate a STOP
    error=-2; // Set error as NoAck
    }
    }
    else{
    error = -1; // Set error as Bus Busy
    }

    while((i2cREG1->MDR & I2C_STOP_COND) ==1);

    return error;
    }

    /* USER CODE END */
  • I will try. What instruction makes that restart without performing a STOP (see my table at the begin, row 5) ?

  • Hello Jan,
    Did you try the code?
    When module is in repeated mode (RM bit in I2CMDR register - i2cREG1->MDR |= I2C_REPEATMODE;) the stop condition is generated when STP bit is 1. When RM=0 stop condition is generated according to I2CCNT register.

    Best regards,
    Miro
  • Not yet - on a business travel spree. I will check at the earliest.
  • heads-up: I am testing this now. Currently adapting my code to the example above.
  • Wow, it works!

    Here's a capture of the conversation from the TMS570LC03 with the slave.

    The restart occurs exactly where I need it. Without a stop first:

    To be honest, I don't fully understand the example code yet. I'll study deeper to learn why this does what I was hoping it would do - and why my own code didn't.
    Thank you for your support, Hercules team!