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.

TMS570 I2C Initiation

Other Parts Discussed in Thread: HALCOGEN

Hi,

I'm having some issues understanding the I2C initialisation.  I based my code on that generated by Halcogen but after finding it does not work I've looked into the code and I have a few questions.

Here is the Halcogen Code:

/** - i2c Enter reset */
i2cREG1->MDR = (uint32)((uint32)0U << 5U);

/** - i2c Out of reset */
i2cREG1->MDR = (uint32)I2C_RESET_OUT;

/** - set i2c mode */
i2cREG1->MDR = (uint32)((uint32)0U << 15U) /* nack mode */
| (uint32)((uint32)0U << 14U) /* free running */
| (uint32)(0U) /* start condition - master only */
| (uint32)((uint32)0U <<11U) /* stop condition */
| (uint32)((uint32)1U <<10U) /* Master/Slave mode */
| (uint32)((uint32)I2C_TRANSMITTER) /* Transmitter/receiver */
| (uint32)((uint32)I2C_7BIT_AMODE) /* xpanded address */
| (uint32)((uint32)0U << 7U) /* repeat mode */
| (uint32)((uint32)0U << 6U) /* digital loop back */
| (uint32)(I2C_RESET_OUT) /* Bring Out of Reset */
| (uint32)((uint32)0U << 4U) /* start byte - master only */
| (uint32)(1U) /* free data format */
| (uint32)(I2C_8_BIT); /* bit count */

This code disagrees with the TRM in a number of ways.

1.

TRM states "IRS must be 0 while the I2C module is being configured."

However Halcogen has IRS = 1 during configuration.

2.

TRM has FDF as bit 3

Halcogen has FDF as bit 0

Outside of this i have a few more questions

3.

When FDF is used please confirm that the I2C module does not need to have any data written within the I2CSAR or I2CCNT registers, as I understand it they would not contain useful information.

Cheers

Alan

  • I've check with the scope, trigger on SCL.

    Start condition does not occur.  No output of clock or data.

    This is with the Halcogen way of setting I2C up as well as using the TRM settings discussed in the previous post.

    PINMUX is set for I2C.

    Code structure in FDF:

    i2cCustomInit(5U);
    i2cSetStart(i2cREG1);
    i2cSendByte(i2cREG1, 0xA8); //address of dut and write (0)
    i2cSendByte(i2cREG1, 0x00); //write address
    i2cSendByte(i2cREG1, 0x00); //write address
    i2cSendByte(i2cREG1, 0xAA); //data
    i2cSetStop(i2cREG1);

    Using i2cSend:

    i2cInit();

    i2cSetSlaveAdd(i2cREG1,0xA8);
    i2cSetStart(i2cREG1);
    i2cSend(i2cREG1,3,i2cstuff);

    i2cSetStop(i2cREG1);

    That am I missing?

    Cheers,

    Alan

  • Alan,

    Sorry for the delay in answering. I have asked an I2C expert to comment.

    Regards, Sunil

  • Alan,

    The discussion in this thread would show you how to set up I2C. However, the example code does not use Halcogen.

    http://e2e.ti.com/support/microcontrollers/hercules/f/312/p/329591/1168896.aspx

    Thanks and regards,

    Zhaohong

  • Hi Zhaohong,

    Thanks for the link, I will amend my code with the corrections I could see and report back.  

    I advise an update of Halcogen is needed as it does not follow the setup described in the TRM or the code in the link you provided.

    Cheers

    Alan 

  • Hi,

    I've tried the code suggested but the I2C is still not working. the TMS570 is connected to a single FM24CL64B with a pull up of 2k2 on both the SDA and SCL lines, the WP is set to logic low.

    Setup is as follows:

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    i2cREG1->MDR = 0x0000;

    i2cREG1->PFNC = 0x0000;

    i2cREG1->DOUT = (uint32)((uint32)0U << 1U) //SDA
    | (uint32)(0U); //SCL

    i2cREG1->DIR = (uint32)((uint32)1U << 1U) //SDA - Output
    | (uint32)(1U); //SCL - Output

    i2cREG1->PDR = (uint32)((uint32)0U << 1U) //SDA
    | (uint32)(0U); //SCL

    i2cREG1->PDIS = (uint32)((uint32)0U << 1U) //SDA
    | (uint32)(0U); //SCL

    i2cREG1->PSEL = (uint32)((uint32)1U << 1U) //SDA
    | (uint32)(1U); //SCL

    i2cREG1->EMDR = 0U;

    i2cREG1->OAR = 0x7F;

    i2cREG1->PSC = 10U;

    i2cREG1->CKH = 5U;

    i2cREG1->CKL = 5U;

    i2cREG1->MDR = (uint32)((uint32)0U << 15U) //NACK mode
    | (uint32)((uint32)0U << 14U) //Free running
    | (uint32)((uint32)0U << 13U) //Start condition
    | (uint32)((uint32)1U <<11U) //Stop condition
    | (uint32)((uint32)1U <<10U) //Master/Slave mode
    | (uint32)((uint32)I2C_TRANSMITTER) //Transmitter/Receiver
    | (uint32)((uint32)I2C_7BIT_AMODE) //Expanded address
    | (uint32)((uint32)0U << 7U) //Repeat mode
    | (uint32)((uint32)0U << 6U) //Digital loop back
    | (uint32)((uint32)0U << 4U) //Start Byte
    | (uint32)((uint32)1U << 3U) //Free Data Format
    | (uint32)(I2C_8_BIT); //Bit Count

    i2cREG1->IMR = (uint32)((uint32)0U << 6U) //Address as slave interrupt
    | (uint32)((uint32)0U << 5U) //Stop Condition detect interrupt
    | (uint32)((uint32)0U << 4U) //Transmit data ready interrupt
    | (uint32)((uint32)0U << 3U) //Receive data ready interrupt
    | (uint32)((uint32)0U << 2U) //Register Access ready interrupt
    | (uint32)((uint32)0U << 1U) //No Acknowledgement interrupt
    | (uint32)((uint32)0U); //Arbitration Lost interrupt

    i2cREG1->DMACR = 0x00U;

    i2cREG1->MDR |= (uint32)I2C_RESET_OUT;

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    After this the start condition is then set

    i2cSetStart(i2cREG1);

    Both SDA and SCL go to logic low

    STR register reads 0x1010

    Then the address & write bit for the FM24CL64B is sent

    i2cSendByte(i2cREG1, 0xA8);

    STR register reads 0x1410

    Next, the address to start write from is sent

    i2cSendByte(i2cREG1, 0x05);

    STR register reads 0x1400

    at which point the code understandably halts at

    while ((i2c->STR & (uint32)I2C_TX_INT) == 0U){}

    When sending 0xA8, my oscilloscope picks up the following:

    where blue = SCL, yellow = SDA

    Thoughts?

    Cheers,

    Alan

  • Hi,

    From what I can see on the oscilloscope I believe I have got the I2C to transmit, however I can not check as the receive part is causing issues.

    After i2cSetStop(i2cREG1); I have the following code

    i2cSetStart(i2cREG1);
    i2cSendByte(i2cREG1, 0xA9); //address of dut ((0x4) <<1) and read (1)
    i2cSendByte(i2cREG1, 0x05); //read address
    i2cSendByte(i2cREG1, 0x00); //read address
    i2cREG1->MDR &= ~I2C_TRANSMITTER; //change to Receive mode
    i2cstuff = i2cReceiveByte(i2cREG1);
    i2cstuff = i2cReceiveByte(i2cREG1);
    i2cSetStop(i2cREG1);

    however it stops because RXRDY in STR is not 1

    From the link you sent me it looks like it should be possible.

    Setting I2C to receiver mode seems to set another start condition, is this correct?

    During successive reads is it possible to leave the I2C inactive, carry out another process on the TMS570 and then continue on the I2C where I left off?

    Cheers

    Alan

  • Hi,

    It seems the master is not setting the stop condition, both SDA and SCL stay low.

    This is after calling i2cSetStop(i2cREG1);

    Later on in the code I setup to receive data with

    i2cREG1->MDR = (i2cREG1->MDR & ~I2C_TRANSMITTER) | I2C_RESET_OUT | I2C_STOP_COND | I2C_MASTER;

    which produces MDR = 0x2C28;

    with the line i2cstuff = i2cReceiveByte(i2cREG1);

    I see this on the lines

    but the code hangs at 

    while ((i2c->STR & (uint32)I2C_RX_INT) == 0U)

    as STR = 0x1010

    Looking at it i would guess that the i2c module is out of sync and is instead transmitting the previous line

    i2cSendByte(i2cREG1, 0xA9);

    Why is i2c not issuing the stop condition and why is it out of sync?

    Cheers,

    Alan

  • to everyone that is new to i2c and finds the halcogen code and trm lacking, the code posted here by Daniel on the 14th May works with only a few alterations (mainly changing upper-case letters to lower-case) in CCSv5.5 and TMS570. Personally I would not bother with the code linked by Zhaohong, it is so far removed I found it extremely hard to follow.

    One thing to look out for is the address, the code linked only uses a 8 bit address so you need to repeat that stage if your device is larger, also increase CNT to suite.

    From this code I was able to complete what I needed and I believe it is very easy to follow.

    Cheers,

    Alan