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.

Hercules RM48L952ZWT TI I2C Halcogen Master sourceexample

Other Parts Discussed in Thread: HALCOGEN, RM48L952

Hi. We are using the Hercules board RM48L952ZWT with the TI HalCoGen Master source code example.  We have connected to I2C bus 2 slaves.  The question is, when we try to send a read or write byte (even only 1 byte), it is always getting stuck in the example code endless loop. Is there more configuration in HalCoGen that needs to be done?

while(i2cIsStopDetected(i2cREG1) == 0);

 

why is this the case when there is no other traffic on the I2C bus (we are just running a test). Thank you.

  • Hi Tammy,

    I am checking into this and will get back to you soon.

    Regards,
    Sunil
  • Hi Sunil - Any news?
  • Hi Tammy,

    Sorry I lost track of this one. It appears that the SDA line is getting stuck low. Do you have the required external pull-up on the PCB on the I2C SCL and SDA lines?

    Regards,
    Sunil
  • Hi Sunil,

    Please see below for our schematic on the I2C.  We have 10k pull-ups near the terminals (B2 and C3).  We also have 50k pull-ups near the target I2C devices.  Are we having too much of pull-ups?  Hardware else, anywhere we need to check?

    Thank you

    Derrick

  • I'm using two LP Hercules RM 46 examples I2C master and slave of HalCoGen, and run, have the same problem and also a loop when I send data with the function

    void I2CSEND (i2cBASE_t * i2c, uint32 length, uint8 * data);

    /* send the data */
    while (length > 0U)
    {


    /*SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found - Hardware Status check for execution sequence" */
    while ((i2c->STR & (uint32)I2C_TX_INT) == 0U)
    {
    } /* Wait */


    /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are only allowed in this driver" */
    i2c->DXR = (uint32)(*data);
    /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are only allowed in this driver" */
    /*SAFETYMCUSW 567 S MR:17.1,17.4 <APPROVED> "Pointer increment needed" */
    data++;
    length--;
    }

  • Hello Sunil,

    Can we escalate the support of this ticket please?  I2C functionality is a gating issue and we need an understanding on a resolution ASAP.

    Also, it appears more than one customer need guidance on this.

    Thanks.

    Ubaid

  • You have been awesome in supporting us in the past, and it seems Sunil maybe busy. Can you guide us on how to escalate this issue? Multiple customers have this same problem.

    Thanks.
    Ubaid
  • Hi,

    We ran the Halcogen I2C communication example on Hercules HDK with RM48L952.  

    1)  Upon powered up, both SDA and SCL are held high.  (CH1 is SDA and CH2 is SCL).

    2)  After executing the loopback, the SCL is stuck on low.

     

    3)  However, the program is not stuck as we could execute the loopback again and again.  Captured during loopback test.

    This seems very strange to me as the SCL should return to high after data is transferred (loopback completed and stop condition for I2C).  Is this normal for the loopback test?

    Thanks

    Derrick

  • Hi

    I have created this examples ( this contains the CCS + HALCoGen project too, you can look at the configurations of HALCoGen by opening the HALCoGen project) using 2 Hercules Board ( 1 acting as Master and other acting as Slave.). I tried both Master/Slave Transmit and Receive functionality and it worked fine.. My lines contain 10k pull each connected to 3.3V. Note: Please use HALCoGen 4.03.00, if using 4.02.00, there is a bug in I2C.c, the details are in the link below.

  • Hi Prapthap,

    We do have 10k pull-ups on our SDA and SCL lines.  Please see below and let us if you see any problems.  Thanks

  • Hi Derrick,

    I noticed the schematic.. What i would recommend you to check is the I2C module configurations that I did in the SAmple project in the Link I sent earlier.

    Probable reason could be I2C pinmux configuration if any, or the I2C module setting it self. The Sample project I did was no Loopback, it is actually a Master and Slave setup. Download the " I2C_Master_Slave.zip " file from the link I posted in my previous reply and have a look.
    I think the sample code is also for RM48L952 device. Check PinMUX and I2C configuration in HALCoGen by opening the HALCoGen project.

    Questions
    1) Are you using HALCoGen 4.03.00 or 4.02.00?
    2) What is your Slave?
  • Hi Prathap,

    So can you confirm the 10k pull-ups we have are okay?  R457 on C3_I2CSCL and R456 on B2_I2CSDA?  I'll have my SW group look at your comments right now.  But I need you or your HW team to confirm the pull-ups we have are okay.

    Thanks

    Derrick

  • Hi Prathap,

    Thank you. We are using HalCoGen 4.03.00 and the 2  slaves are a DAC MCP4728 and IOExpander PCA6416A parts.   Can you please verify the hardware is implemented Ok as to what you described on your board with the pull up resistor, or if you have a different recommendation . Are the pullup resistors placed in the correct location as in the boards you tested, or do they need to be moved? If you read at the start of this blog, one of your colleagues Sunil write

    "In reply to Tammy Noergaard:
    Hi Tammy,

    Sorry I lost track of this one. It appears that the SDA line is getting stuck low. Do you have the required external pull-up on the PCB on the I2C SCL and SDA lines?

    Regards,
    Sunil"

  • Hi Prathap,

    Just in case if it's confusing on schematic, the name of the net for B2 is called B2_I2CSDA. And B2_I2CSDA is connected to R456 (10k pull-up) on top.

    The name of the net for C3 is called C3_I2CSCL. And C3_I2CSCL is connected to R457 on top.
  • Derick/Tammy,

    There is no issue with verifying the pull-ups you have on the PCB. It is clear enough and looks okay. As Prathap mentioned, the investigation should be on the software configuration now: I/O multiplexing, I2C module configuration.

    It would be really great if you could use Prathap's example as reference for master/slave communication.

    Regards,
    Sunil
  • Hi Sunil,

    Thank you. We know loopback works. So, we will first start with 2 TI Hercules RM48L952 board as master and slave and run Prathap's test as he did it with 2 boards. The TI Hercules boards we will add the pullups is necessary. When that works, we then will swap out one of the TI boards for Derrick's boards as he posted the schematic board. When that works, then we go back and add each of the slave processors one by one. We will come back if there are questions or we see strange behavior in the process. Thank you again.
  • Thank you for confirming Sunil! Now we'll try what you and Sunil and Prathap suggested. Thanks again.

    Derrick
  • Hi Prathap,

    So we have downloaded the I2C_Master_Slave.zip. When we unzipped, there are 2 directories (slave and master). The master directory contains a HalCoGen project. The slave directory does not contain a HalCoGen project. should both TI board be configured according to the HalCoGen project in the master directory (though of course the main look contains the different test code). Or what should the differences HalCoGen configuration be for the TI slave board (i.e., on I2C tab disabled the master mode, etc.).

    (Update.) Until we get the HalCoGen project for I2C slave, I have attached both projects with how we have configured both I2C master and I2C slave boards.  The I2C slave is actually modified manually (you can see the i2cInit) for now until we get the I2CSlave HalCoGen project that generated that library

     /** - 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)0U <<10U)      /* Master/Slave mode                 */
                       | (uint32)((uint32)I2C_RECEIVER)     /* Transmitter/receiver              */
                       | (uint32)((uint32)I2C_7BIT_AMODE)      /* xpanded address                   */
                       | (uint32)((uint32)0U << 7U)      /* repeat mode                       */
                       | (uint32)((uint32)0U << 6U)     /* digital loop back                  */
                       | (uint32)((uint32)0U << 4U)     /* start byte - master only          */
                       | (uint32)((uint32)0U << 3U)           /* free data format                  */
                       | (uint32)(I2C_8_BIT);   /* bit count                         */

     Note, we are using 2 Revision  E, RM48L952ZWT Hercules boards in the test (you can see in the picture below, SDA is connected J11 pin72, SCL connected J11 pin71 on Hercules TI boards) and HalCoGen 4.03.00  We get the same results with the hanging in while loop (also the other customer Martin Valencia posted on here did with their RM46 board). Exact behavior.

    1. TI Slave board is running with your test code, using CCS debugger, TI I2C slave board looping in I2CReceive function (i2c.c) at

              /*SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found - Hardware Status check for execution sequence" */
                while ((i2c->STR & (uint32)I2C_RX_INT) == 0U)
                {
                } /* Wait */

    2. we start the TI master running. stepping through your test code.

      2.1. loop 1 of for(repeat = 0; repeat < 2; repeat++)

          2.1.1  /* Transmit Start Condition */
                    i2cSetStart(i2cREG1);

                   Connecting with scope, SCL and SDA lines both go low.

          2.1.2 /* Transmit DATA_COUNT number of data in Polling mode */
                   i2cSend(i2cREG1, DATA_COUNT, TX_Data_Master);

                   Connecting with scope, SCL pulses HIGH -> LOW several times as looping to transmit bytes

        2.1.3 /* Wait until Bus Busy is cleared */
                 while(i2cIsBusBusy(i2cREG1) == true);

                 Connecting with cope SCL Line toggles HIGH->LOW a few times, then SCL Line stays at HIGH

       2.2. loop 2 of for(repeat = 0; repeat < 2; repeat++)

           

          2.2.1  /* Transmit Start Condition */
                    i2cSetStart(i2cREG1);

                   Connecting with scope, SCL stays HIGH.

          2.2.2 /* Transmit DATA_COUNT number of data in Polling mode */
                   i2cSend(i2cREG1, DATA_COUNT, TX_Data_Master);

                   Connecting with scope, SCL stays HIGH and stuck in infinite loop of

                    /*SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found - Hardware Status check for execution sequence" */
                    while ((i2c->STR & (uint32)I2C_TX_INT) == 0U)
                    {
                    } /* Wait */

    I2CMaster halcogen project zip:  8182.I2CMasterHalCoGen.zip

    I2CSlave halcogen project zip:7418.I2CSlaveHalCoGen.zip

    Setup Picture1 of 2 TI boards connected as I2C master and I2C slave:

    Setup Picture2, connections on schematics:

  • Hello Tammy,

    Looking at your Picture, I see no Pull up connected.. The manual change you made for I2C.c in slave side is correct. I had the below connection when I tested. 

  • Hi Parthap,

    Thank you so much for your help on this.  The schematic on HDK showed two external 10k pull-ups (R83 and R84) connected on the SDA and SCL lines.  I also checked the physical HDK and they have both R83 and R84 populated.  I also checked R83 and R84 are in fact connected to 3.3V and SDA and SCL lines.  Were you using the RM48L952ZWT HDK?

    First thing tomorrow morning, I'll try installing additional external 10k pull-ups exactly like your setup and test it again.  I'll keep you posted.

    Thanks again

    Derrick

  • Hello Prathap,

    I reconnected our setup per the diagram you provided.  I put in two external 10k resistors connected to 3.3V and SDA and SCL lines.  We are still experiencing the same issues as Tammy described yesterday.  The ground on both boards are connected.  We even tried removing R83 and R84 from the slave board so the SDA and SCL lines are pull-up from the same 3.3V from the master.  Tammy mentioned there was no HalCoGen project included for the slave.  Could you kindly provide us your Halcogen project for the slave for us to test?  Can you think of anything else that would possibly help resolve our issues?  If possible, could you take a picture of how you setup your boards so we can check if there's differences how we setup?

    Thank you so much.

    Derrick

  • Hi Derrick,

    Sorry I suggested the Pull up, without realizing that RM48x HDK had pull already.. My setup was based on different board that did not had pull. I take back my pull recommendation. 

    OK.... 

    I took 2 RM48x HDK's. Connected SDA, SCL and GND lines between these boards as shown in the Image Below.( NO EXTERNAL PULL NEEDED .. I used the one already in the board) I have two PCin my Cube, so in one PC I connected 1 board and other board to other PC via the USB cable ( XDS100v2). My project worked fine.. ( Attaching again here... 3060.I2C_Master_Slave_RM48x_.zip

    Master Side PC: 

    1) I opened CCS project I2C_Master
    2) Downloaded the .out and reached Main.
    3) Keep Break point at while(1) line inside main().

    Slave Side PC: 

    1) I opened CCS project I2C_Slave
    2) Downloaded the .out and reached Main.
    3) Keep Break point at while(1) line inside main().

    Execution Flow:

    1) Run the Slave side First. ( This is for Sync, Make sure Slave is ready when Master is about to start).

    2) Run the Master side. 

    3) YOu could see both sides hitting the break point. 

    4) In Slave Side : Check that the RX_Data_Salve array contains TX_Data_Master array contents

    4) In Master Side : Check that the RX_Data_Master array contains TX_Data_Slave array contents

    Connection Snap


  • Hello Prathap, 

    No problem!  I knew the additional pull-ups weren't needed but I decided to try it anyway because we had spent hours troubleshooting it and were stuck.  

    Thank you so much for showing us a screenshot of your setup.  We'll try your execution flow with two PCs first thing tomorrow morning.  We did not know we had to have 2 PCs running the boards at the same time.  Hopefully, we'll have good news tomorrow.

    Thanks again for your help!

    Derrick

  • Hi Prathap,

      Thank you for the feedback. We will doublecheck today, but I am 99.9% certain the slave test code on the other TI board never reaches the while(1); loop at the end of your test code (it is stuck also looping at the i2Creceive function the same while loop as in the i2cSend on the master).  That is why I asked about your HalCoGen slave project, if you could send this.  On both boards, they are stuck in the similar loops in the I2C driver.  Thank you again.

  • Hi Prathap.

    Update. We ran your test on 2 different PCs with 2 different CCS (one connected to TI Slave and one TI Master) . When we import your projects as-is. The tests work with the code in the HalCoGen source and include directory. When we load your example Master HalCoGen project (HCG) in HalCoGen 4.3.00 and just select "generate code" (because that is what we used as guidance for our HalCoGen project  to configure I2C, since we include more then I2C driver), then your example project does not work (we get stuck in the same i2CSend on Master and i2C Receive on slave. This means the HCG project master example in the TI example directory did not generate the HalCoGen code in the course and include trees that actually resulted in a working example.  So, what other changes to the I2C library to you recall that could have been made manually (outside of HalCoGen) that we need to include?  I had uploaded what HalCoGen generated for us already. I do not just want to copy and paste i2c.c and i2c.h and overwrite it with what halCoGen generated for us, without you saying we need to do that because what we get from halCoGen is not working.  Can you try the same in the example you sent us. Instead of running the code as-is, blast away the HalCoGen driver library (except your .c sample code of course), generate your the driver code in HalCoGen with the HCG project in the code you gave us, rebuild in your CCS and download the master code again. 

    What else was manually modified in I2C in drivers (outside of HalCoGen) to get this example to work?

  • Hi Tammy,

    Sorry I totally Forgot... The function i2cSetMode have a Bug in 4.03.00, it is there is our Bug tracking system.

    Current 4.03.00

    void i2cSetMode(i2cBASE_t *i2c, uint32 mode)
    {
    uint32 temp_mdr;
    /* USER CODE BEGIN (34) */
    /* USER CODE END */

    /* set Master or Slave Mode */
    temp_mdr = (i2c->MDR & (~I2C_MASTER));
    i2c->MDR |= temp_mdr;

    /* USER CODE BEGIN (35) */
    /* USER CODE END */
    }

    It must be Fixed to 

    void i2cSetMode(i2cBASE_t *i2c, uint32 mode)
    {
    uint32 temp_mdr;
    /* USER CODE BEGIN (34) */
    /* USER CODE END */

    /* set Master or Slave Mode */
    temp_mdr = i2c->MDR & ~((uint32)(I2C_MASTER));
    i2c->MDR = temp_mdr | mode;

    /* USER CODE BEGIN (35) */
    /* USER CODE END */
    }

  • Tammy,

    I checked with HALCoGen team, HALCoGen release 4.04.00 already have this fix, it is going through the test cycles. The release is planned for next week. 

  • Hi Prathap. Thank you. We will use your I2C.c and I2C.h until then.  So now we have 2 TI Hercules boards. 1 master TI Board connected to 2 slaves (1 is other TI board slave 0x8 and one is a real IC slave DAC 0xC0) . What changes in your test if we have a real slave IC to test connected to TI Hercules I2C Master board rather then a 2nd TI Slave I2C board slave?   We run your test with TI Hercules master, and 2 slaves connected to I2C bus -- 1 is 2nd TI board and other an IC.  When we run your test with the TI board as slave it is Ok as you know. But we must deploy our product with a real i2C slave, but Hercules TI Master has problems sending bytes to the 2nd slave.

    So when we ran your test code with the other slave connected with TI board slave, it will be again stuck in i2cSend while loop in i2c.c on the second byte of the data array (we also tried changing the data bytes in array).

              /*SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found - Hardware Status check for execution sequence" */

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

               {

               } /* Wait */

    If we only send one test byte to DAC I2C slave, then it is stuck in your actual test code after transmitting the 1 byte to

    /* Wait until Bus Busy is cleared */

    while(i2cIsBusBusy(i2cREG1) == true);  

    Datasheet for DAC slave is connected on same I2C bus as TI Board slave :  8004.I2C 12 bit DAC.pdf

  • Hi Tammy,

    Is it possible for me to know the sequence in which you talk to DAC.

    There is one major difference between TI-Hercules acting as Slave and the External I2C Slave like memory etc.. in your case DAC.

    TI Hercules Slave does not need any specific sequence to read or write, meaning , you address the Slave and just send the data and read the data - Because it's a Active Slave where there is an MCU + Software to do all address and data handling.  So it is straight forward for Master to write or Read data. This is what my Example code does.

    Where as the "real I2C Salve" is what I call as passive Slave, which requires certain sequence for write and Read..  You cannot directly use my example. Are you sure you are following the Write and Read sequence recommended in the MCP4728..

    Below are sequence for PCF8570 I2C slave Chip mentioned in their datasheet and the Software flow to perform Read and Write. 

    Software Flow:

    ----------------
    Write Operation
    ----------------
    write_to_PC8570(address,data)
    {
    i2c_start();
    i2c_write(SLAVE_ADDRESS_WRITE); // Slave address, with LSB 0 ( r/w bit)
    i2c_write(address); // Actual word Address
    i2c_write(data);
    i2c_stop();
    }

    ----------------
    Read Operation
    ----------------
    uint8 read_to_PC8570(address)
    {
    BYTE data;

    i2c_start();
    i2c_write(SLAVE_ADDRESS_WRITE); // Slave address, with LSB 0 ( r/w bit)
    i2c_write(address); // Word Address
    i2c_start();
    i2c_write(SLAVE_ADDRESS_READ); // Slave address, with LSB 1 ( r/w bit)
    data=i2c_read(0);
    i2c_stop();
    return(data);
    }

    So My example I sent cannot be directly used for read and write to a passive slave, you must tweak it as per the Slave Command sequence recommended in their datasheet.

  • Hi Thank you. Yes I understood that. You showed the sequence above for PC8570 but it does not use the HalCoGen autogenerated I2C library APIs as your other example did. i.e.,

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

    /* Set direction to Transmitter */
    /* Note: Optional - It is done in Init */
    i2cSetDirection(i2cREG1, I2C_TRANSMITTER);

    /* Configure Data count */
    /* Note: Optional - It is done in Init, unless user want to change */
    i2cSetCount(i2cREG1, IOEDATA_COUNT);

    /* Set mode as Master */
    i2cSetMode(i2cREG1, I2C_MASTER);

    /* Set Stop after programmed Count */
    i2cSetStop(i2cREG1);

    /* Transmit Start Condition */
    i2cSetStart(i2cREG1);

    .....

    Shouldn't we be using the same HalCoGen APIs regardless of what the slave is? Don't we need to still call i.e., i2cSetSlaveAdd, i2cSetDirection, etc. in the master code for transmitting data to the i.e., PC8570 ? When we use the HalCoGen I2C library to send, after the 1st byte (address of the I2C slave), it goes back to hanging again in the I2CSend while loop.  We tried 2 different slave ICs to be sure there is no hardware issue, same results when we use the HalCoGen function where after we send the 1st address byte it is stuck in this while loop when trying to send a 2nd byte. Our hardware engineer already posted for you that we have also the pullup resistors (let me know if you need us to post again for you to verify). Thank you again.

  • Hi Tammy,

    I posted just the function flow in general, not specific to HALCoGen.

    Give me a days time, I have to hunt down my PC8570 board and develop a sample code for you.

    There is nothing wrong with Pull settings you have. 

  • Hi Tammy,

    Attachment details: 

    1) I2C_PCF8570.c --> Hercules acting as Master and PCF8570 as Slave. Master Sends 10 Bytes of Data, and read them back from Slave at 100KHz baud rate.7612.I2C_PCF8570.c

    2) i2c.c  --> 4.03.00 generated HALCoGen's i2c.c driver file with bug fix in i2cSetMode function. 7446.i2c.c

  • Hi Prathap. Thank you. We did this test connecting the TI Hercules RM48L952ZWT board to the slave I2C processors. We  replaced i2c.c with your newest i2c.c file in our drivers that you sent above, and your test code as-is from main is executed. Same issue as we saw before - after the 1st byte transmitted (i2cSendByte) in your test code then it is stuck in the endless while loop. In void i2cSend(i2cBASE_t *i2c, uint32 length, uint8 * data) in i2c.c - it gets stuck on that same while loop:

    /*SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found - Hardware Status check for execution sequence" */

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

    {

    } /* Wait */

  • Hi Tammy,

    The example I sent will work with PCF8570, I developed it and tested it today.

    I remember you mentioned MCP4728 and PCA6416A are the Slave that you have, Is it right? If yes, then you cannot use my example as is.
    i2c.c file is fine, but  I2C_PCF8570.c cannot be used directly... You must tweak it to suit MCP4728 and PCA6416A. Especially the Slave address info and read/ write sequences. These information will be available as part of MCP4728 and PCA6416A data sheets.

  • Hi Prathap,

    What board did you use? Was it a TI Hercules rev E RM48L952ZWT board?

    Yes we understand (the slave addresses change to C0 and 40, instead of the slave address of the PCF8570 in your example ). But just sending the 1st byte (the slave address) using the TI Hercules board, the i2c driver is not sending any more bytes (the code never gets that far) because it is stuck in the endless loop after just transmitting 1 byte in I2CSend that I described above. We even used the off-the-shelf I2C test board from Microchip for an I2C slave connected to our TI Hercules board (we can pick the slave address we want), and it is still the same behavior. We transmit only 1 byte and then it is locked in the loop when we go to transmit a 2nd byte. What version of TI master board did you test with? Thank you again.

    Here was how we modified the test code (and we are now also tried between TI board and Microchip i2c slave test board directly)

    #define DACSlave_Address 0xC0

    #define DACDATA_COUNT 9

    uint8_t DACTX_Data[DACDATA_COUNT] = {0xC0, 0x07,0xFF,0x07,0xFF,0x07,0xFF,0x07,0xFF};

     

    void main(void)

    {

    /* USER CODE BEGIN (3) */

    int repeat = 0; int delay =0;

    i2cInit();

    /* Set mode as Master */

    i2cSetMode(i2cREG1, I2C_MASTER);

    /* Configure address of Slave to talk to */

    i2cSetSlaveAdd(i2cREG1, DACSlave_Address);

    /* Set direction to Transmitter */

    /* Note: Optional - It is done in Init */

    i2cSetDirection(i2cREG1, I2C_TRANSMITTER);

    /* Configure Data count */

    /* Note: Optional - It is done in Init, unless user want to change */

    i2cSetCount(i2cREG1, DACDATA_COUNT+1);

    /* Set mode as Master */

    i2cSetMode(i2cREG1, I2C_MASTER);

    /* Set Stop after programmed Count */

    i2cSetStop(i2cREG1);

    /* Transmit Start Condition */

    i2cSetStart(i2cREG1);

    /* Transmit DATA_COUNT number of data in Polling mode */

    i2cSend(i2cREG1, DACDATA_COUNT, DACTX_Data);

    /* Wait until Bus Busy is cleared */

    while(i2cIsBusBusy(i2cREG1) == true);

    /* Wait until Stop is detected */

    while(i2cIsStopDetected(i2cREG1) == 0);

    /* Clear the Stop condition */

    i2cClearSCD(i2cREG1);

    /* Simple Dealya before starting Next Block */

    /* Depends on how quick the Slave gets ready */

    for(delay=0;delay<100000;delay++);

    asm(" nop");

    asm(" nop");

    asm(" nop");

    while(1);

    /* USER CODE END */

    }

    from Microchip support, they gave us the quick write sequence in email:

    Microchip Engineering Support has added comments to support Ticket 288279.

    Comments:
    Hello Tammy,

    Thank you for the update.

    Can you tell me what device is generating the I2C? Is it a microcontroller?
     
     
     Fast Write, Here's what I sent.

    <S><0xC0><0x07><0xFF><0x07><0xFF><0x07><0xFF><0x07><0xFF><P>
     |          |     ----------------------  --------------------  --------------------  ---------------------    |
     |          |               |                       |                     |                      |              ---> Stop
     |          |               |                       |                     |                      ----> DAC_D
     |          |               |                       |                     -----> DAC_C
     |          |               |                       ---->DAC_B
     |          |               ----> DAC_A
     |          ----> Device Address
     ----> Start bit

    I got 2.408V on my DAC. If I change 0x7FF to 0xFFF, DAC is about 4.8V.

    In the i2cSend function, after writing the 1st byte, every time it is locked up in the while loop in that function:

    /*SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found - Hardware Status check for execution sequence" */

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

    {

    } /* Wait */


     
      

  • Hi Tammy,

    I did the test in RevE RM48L952ZWT. You mentioned when testing with 2 Hercules TI Boards the communication Worked? So no problem with the Board or PinMUX settings.

    The only reason I see for stuck at i2cSend function is that Slave not ACKing/ responding. Have you tried capturing in scope to see Proper Address is been issued? Or you see no toggle in the Bus at all.

    Please send me your contact info, We can take it offline, I need more info's to understand the failure.
    If you do not want to provide your contact info in this thread, You can respond to me using privately message.
  • Hi Prathap. Thank you it is "tnoergaard@biolase.com".
    On the scope we do not see normal behavior, but I did add this if ((i2cREG1->STR & I2C_NACK) == I2C_NACK) code to the i2cSend, and with debugger it does not go into the if statement, so we assume at least the software thinks there was an ACK from slave. On power up, SDA and SCL are both High, after we send start condition, SDA H and SCL L, then when we send 1st byte both SDA L and SCL L. Then it locks up and we cannot transmit any more bytes from the master to the DAC. See C Code below where I used Microchip fast write sequence with your test code of <S><0xC0><0x07><0xFF><0x07><0xFF><0x07><0xFF><0x07><0xFF><P>:

    void i2cSend(i2cBASE_t *i2c, uint32 length, uint8 * data)
    {

    /* USER CODE BEGIN (17) */
    /* USER CODE END */

    if ((g_i2cTransfer_t.mode & (uint32)I2C_TX_INT) != 0U)
    {
    /* Interrupt mode */
    /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are only allowed in this driver" */
    g_i2cTransfer_t.data = data;
    /* start transmit by sending first byte */
    /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are only allowed in this driver" */
    i2c->DXR = (uint32)(*g_i2cTransfer_t.data);
    /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are only allowed in this driver" */
    /*SAFETYMCUSW 567 S MR:17.1,17.4 <APPROVED> "Pointer increment needed" */
    g_i2cTransfer_t.data++;

    /* Length -1 since one data is written already */
    g_i2cTransfer_t.length = (length - 1U);

    /* Enable Transmit Interrupt */
    i2c->IMR |= (uint32)I2C_TX_INT;
    }
    else
    {
    /* send the data */
    while (length > 0U)
    {
    /*SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found - Hardware Status check for execution sequence" */
    while ((i2c->STR & (uint32)I2C_TX_INT) == 0U)
    {
    } /* Wait */
    /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are only allowed in this driver" */
    i2c->DXR = (uint32)(*data);
    /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are only allowed in this driver" */
    /*SAFETYMCUSW 567 S MR:17.1,17.4 <APPROVED> "Pointer increment needed" */
    data++;
    length--;

    if ((i2cREG1->STR & I2C_NACK) == I2C_NACK)
    {
    /* NACK detected during transmision
    *
    * According to I2C Spec the reason could be:
    * 1. No receiver is present on the bus with the transmitted address so there is no device to respond with an acknowledge.
    * 2. The receiver is unable to receive or transmit because it is performing some real-time function and is not ready to start communication with the master.
    * 3. During the transfer, the receiver gets data or commands that it does not understand.
    * 4. During the transfer, the receiver cannot receive any more data bytes.
    */

    i2cREG1->MDR |= I2C_STOP_COND; /* Send stop condition so SCL isn't held low */

    /* Wait for Busy Bit to go Low --> The bus is free and stop was send */
    while((i2cREG1->STR & I2C_BUSBUSY) == I2C_BUSBUSY);
    i2cREG1->STR = I2C_SCD | I2C_TX | I2C_NACK; /* Clear SCD, NACK and set TXRDY flag to indicate that a new transfer is possible. */
    }
    }
    }
    /* USER CODE BEGIN (18) */
    /* USER CODE END */
    }
    Here was how we modified the test code (and we are now also tried between TI board and Microchip i2c slave test board directly)



    #define DACSlave_Address 0xC0

    #define DACDATA_COUNT 9

    uint8_t DACTX_Data[DACDATA_COUNT] = {0xC0, 0x07,0xFF,0x07,0xFF,0x07,0xFF,0x07,0xFF};



     

    void main(void)

    {

    /* USER CODE BEGIN (3) */



    int repeat = 0; int delay =0;



    i2cInit();

    /* Set mode as Master */

    i2cSetMode(i2cREG1, I2C_MASTER);



    /* Configure address of Slave to talk to */

    i2cSetSlaveAdd(i2cREG1, DACSlave_Address);

    /* Set direction to Transmitter */

    /* Note: Optional - It is done in Init */

    i2cSetDirection(i2cREG1, I2C_TRANSMITTER);



    /* Configure Data count */

    /* Note: Optional - It is done in Init, unless user want to change */

    i2cSetCount(i2cREG1, DACDATA_COUNT+1);

    /* Set mode as Master */

    i2cSetMode(i2cREG1, I2C_MASTER);



    /* Set Stop after programmed Count */

    i2cSetStop(i2cREG1);

    /* Transmit Start Condition */

    i2cSetStart(i2cREG1);

    /* Transmit DATA_COUNT number of data in Polling mode */

    i2cSend(i2cREG1, DACDATA_COUNT, DACTX_Data);

    /* Wait until Bus Busy is cleared */

    while(i2cIsBusBusy(i2cREG1) == true);



    /* Wait until Stop is detected */

    while(i2cIsStopDetected(i2cREG1) == 0);



    /* Clear the Stop condition */

    i2cClearSCD(i2cREG1);

    /* Simple Dealya before starting Next Block */

    /* Depends on how quick the Slave gets ready */

    for(delay=0;delay<100000;delay++);



    asm(" nop");

    asm(" nop");

    asm(" nop");



    while(1);



    /* USER CODE END */

    }



    from Microchip support, they gave us the quick write sequence in email:

    Microchip Engineering Support has added comments to support Ticket 288279.

    Comments:
    Hello Tammy,

    Thank you for the update.

    Can you tell me what device is generating the I2C? Is it a microcontroller?


    Fast Write, Here's what I sent.

    <S><0xC0><0x07><0xFF><0x07><0xFF><0x07><0xFF><0x07><0xFF><P>
    | | ---------------------- -------------------- -------------------- --------------------- |
    | | | | | | ---> Stop
    | | | | | ----> DAC_D
    | | | | -----> DAC_C
    | | | ---->DAC_B
    | | ----> DAC_A
    | ----> Device Address
    ----> Start bit

    I got 2.408V on my DAC. If I change 0x7FF to 0xFFF, DAC is about 4.8V.

    In the i2cSend function, after writing the 1st byte, every time it is locked up in the while loop in that function:

    /*SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found - Hardware Status check for execution sequence" */

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

    {

    } /* Wait */
  • Hi Tammy,

    Can you try the Below Code....

    If you want 0xC0, that is 11000000, Last bit is R/W, bit which will be automatically added by the module, so the 7bit address should be 1100000 which is 0x60. Also I removed the 0xc0 from the array since the Address will be transmitted from different register which is handled in i2cSetSlaveAdd API.

    -------------

    define DACSlave_Address 0x60

    #define DACDATA_COUNT 8

    uint8_t DACTX_Data[DACDATA_COUNT] = {0x07,0xFF,0x07,0xFF,0x07,0xFF,0x07,0xFF};



    void main(void)

    {

    /* USER CODE BEGIN (3) */

    int repeat = 0; int delay =0;

    i2cInit();

    /* Set mode as Master */

    i2cSetMode(i2cREG1, I2C_MASTER);

    /* Configure address of Slave to talk to */

    i2cSetSlaveAdd(i2cREG1, DACSlave_Address);

    /* Set direction to Transmitter */

    /* Note: Optional - It is done in Init */

    i2cSetDirection(i2cREG1, I2C_TRANSMITTER);

    /* Configure Data count */

    /* Note: Optional - It is done in Init, unless user want to change */

    i2cSetCount(i2cREG1, DACDATA_COUNT);

    /* Set mode as Master */

    i2cSetMode(i2cREG1, I2C_MASTER);

    /* Set Stop after programmed Count */

    i2cSetStop(i2cREG1);

    /* Transmit Start Condition */

    i2cSetStart(i2cREG1);

    /* Transmit DATA_COUNT number of data in Polling mode */

    i2cSend(i2cREG1, DACDATA_COUNT, DACTX_Data);

    /* Wait until Bus Busy is cleared */

    while(i2cIsBusBusy(i2cREG1) == true);

    /* Wait until Stop is detected */

    while(i2cIsStopDetected(i2cREG1) == 0);

    /* Clear the Stop condition */

    i2cClearSCD(i2cREG1);

    /* Simple Dealya before starting Next Block */

    /* Depends on how quick the Slave gets ready */

    for(delay=0;delay<100000;delay++);

    asm(" nop");

    asm(" nop");

    asm(" nop");

    while(1);

    /* USER CODE END */

    }
    ---------------------
  • Hi Prathap, Thank you. Works great now. Thank you again.