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.

I2C - Re-Start Condition

I am using the microcontroller TMS570LS3137.

I have initialized I2C module in order to use it for write/read an accelerometer´s registers through this interface.

My application needs that TMS MCU transmits a repeated start condition, but I can´t obtain it. Another important aspect is that I2C driver is working over TX and RX Interrupt on SCIOPTA RTOS.

 

The sequence that I need apply is described below:

1.- MCU to Accelerometer: Generate a Start Condition, indicate accelerometer slave address and indicate R/W bit for a write.

2.- Accelerometer to MCU: Send ACK.

3.- MCU to Accelerometer: Transmit data (address of register to read).

4.- Accelerometer to MCU: Send ACK.

5.- MCU to Accelerometer: Generate a repeated Start Condition, indicate accelerometer salve address, and indicate R/W bit for a read from the previously selected register.

6.- Accelerometer to MCU: Send ACK and data from the requested register.

7.- MCU to Accelerometer: Generate a stop condition.

I don´t know how to generate a “repeated start condition” or “restart condition”.

I would appreciate so much if someone can help me with an example, please.

Regards…

  • We have received your question. We will get back to you as soon as possible.

    Thanks,

    Jay

  • Some example to use repeat start to read from ram:

    /* Read from a slave device */

    void I2C_Read_IntM(short Slave_Add, short Read_Add, short Count, char *buff )
    {
     if(I2C0_Ptr->SR_UN.SR_ST.bb_B1==0)                   // Test if Bus is Busy
     { 
      I2C0_Ptr->MDR_UN.MDR_ST.stt_B1   = 0;              
      I2C0_Ptr->MDR_UN.MDR_ST.stp_B1   = 0;              
      I2C0_Ptr->MDR_UN.MDR_ST.rm_B1    = 0;               // Not in Repeat Mode

      MasterTransmit();

      SetCount(1);                         
                                                         
      SetSlvAdd(Slave_Add);                     
     
      I2C0_Ptr->DXR_UN.DXR_ST.datatx_B8 = Read_Add;       // data to transmit to Select "Second" Register
     
      I2C0_Ptr->MDR_UN.MDR_ST.stt_B1    = 1;              // Start the transmission
                                                          // Start-Address-Data     ( Start A0,02 )
      while(  (I2C0_Ptr->SR_UN.SR_ST.ardy_B1==0)          //
            &&(I2C0_Ptr->SR_UN.SR_ST.nack_B1==0));        // Wait for SR register ready

      /* ICCNT Value is not counted  */                          
      SetCount(0xC0FF);                                   /* Setting a stupid value */

      if(I2C0_Ptr->SR_UN.SR_ST.nack_B1==0)                // Check for Positive Acknoledge
      {                                                   // Application can continue

       MasterReceive();

       I2C0_Ptr->MDR_UN.MDR_ST.rm_B1    = 1;              // Repeat start mode
       I2C0_Ptr->MDR_UN.MDR_ST.stt_B1   = 1;              // Start-Address-Data
      }                                                  
      else error = -2;
      while(!RxDone);
      }

     else error=-1;                                       // Set error as Bus Busy

     while(I2C0_Ptr->MDR_UN.MDR_ST.stp_B1 == 1);          // Wait for transfer complete

    }   

    In the ISR:

        /*  RXRDY Interrupt */
     if(IVR_Value == 0x04)
     {
      if(ptr->DataCount == 4)                     
         I2C0_Ptr->MDR_UN.MDR_ST.stp_B1   = 1;
         while(I2C0_Ptr->SR_UN.SR_ST.rxrdy_B1==0);
         /* Write next data from the Transmit Buffer */
      *Rxdata = I2C0_Ptr->DRR_UN.DRR_ST.datarx_B8;
         ptr->DataCount++;
        } 

    So, in this code, when DataCount=4, it send out the stop bit (after 5th transmit).

    Regards,

    Haixiao