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.

RM46L852: I2C TXRDY interrupts never fire (while the RXRDY works fine)

Part Number: RM46L852
Other Parts Discussed in Thread: HALCOGEN

Related to this other e2e thread.

The I2C TXRDY interrupts never fire (while the RX works fine)

As I mentioned, in my other e2e thread, my i2c bus is working properly. I can receive and send data successfully on the bus.
That said, while the RX interrupts are working correctly, I never receive TX interrupts. Even if they are enabled in halcodegen.

Please note that this issue already has been raised by user5967417:

In this thread, it looks like even with the modified code, they can't receive TX ISR.

Actually, I tried your workaround but not working for me because the i2cInterrupt function is not called by the microcontroller when length = 1. Everything is well when I change the length = 2.
> So I think the problem may be hardware-related. Have you tried your solution? Is this workaround working in your setup?

As the i2c transmission is working fine on my bench, don't think it's a pull-up resistance or bus problem.
I didn't verify the ACK from the slave, but as I received multiple bytes from the slave correctly, it seems unlikely that I would not receive NACK.

Are you sure there's no possibility it's another HalCoGen bug? 

Regards,
Gabriel


  • Hi Gabriel,

    It is holiday here in TI-India, so please expect some delay in my update.

    --
    Thanks & Regards,
    Jagadish.

  • Thanks for the information.

    Happy Holiday! 

  • Hi Gabriel,

    I understood the root cause of the behavior.

     Actually, I tried your workaround but not working for me because the i2cInterrupt function is not called by the microcontroller when length = 1. Everything is well when I change the length = 2.

    Yes, you are right for length=1 the interrupt is not working even after we change the code as QJ mentioned.

    On my understanding this is because of writing 1 to the CNT register.

    Here we are setting CNT register to 1 because to send a stop condition after sending single byte, right?, On my understanding this is creating issue, i mean after sending byte and before creating interrupt it is sending stop condition and bus becoming idle, so no further interrupts getting to generate.

    So, to ensure this i just did this, i commented writing 1 to the CNT register like as highlighted in my above pic. But now how can we generate the stop condition? so i am doing this in my handler.

    I am just enabling Repeat mode and then sending stop condition. This is because only in repeat mode the stop condition will get send immediately, not depending on CNT register.

    And after this again we can OFF the repeat mode if needed to send more data.

    After doing this modification, it seems to working fine.

    I am attaching my code for your reference, please test it with once and let me know your comments.

    2318.I2C_Master_RM46L852.zip

    --

    Thanks & regards,
    Jagadish.

  • Hi Jagadish,

    I hope you had a great holiday!

    Thanks for your answer. I'll be looking at this today. 

  • Hi Jagadish

    Thanks for providing your source files.

    Some questions for you:

    1. Why do you ignore the NACK mode?

    2. What's the purpose of checking  i2cIsStopDetected() in the Interrupt instead of in the main?
    I would prefer not to use a while loop in an ISR.

    3. Is there a reason why you don't reset the MDR register after sending the STOP ?  

    4. Could we clear the stop condition in the ISR instead?

    Regards,

    Gabriel  

  • Hi Gabriel,

    1. Why do you ignore the NACK mode?

    That is not on purpose, actually i took one old code in my database and did modifications to test the interrupt. You can use either of the mode.

    2. What's the purpose of checking  i2cIsStopDetected() in the Interrupt instead of in the main?
    I would prefer not to use a while loop in an ISR.

    You can check on main loop as well. As we already setting one FLAG after data transfer right, so use same flag in main loop and check the stop condition in main loop as well.

    3. Is there a reason why you don't reset the MDR register after sending the STOP ?  

    No reason, we have to reset to MDR transfer further data. I mean we have to off the repeat mode.

    4. Could we clear the stop condition in the ISR instead?

    Yes, you can. But it should always be after the "wait until stop is detected".

    --
    Thanks & regards,
    Jagadish.

  • Hi Jagadish,

    Thanks for your answer.

    I did more testing and I found a problem with our strategy: Ignoring i2cSetCount only works for the first transmission.
    As soon as we transmit another byte, we get stuck.

    Using the project you sent me, I encapsulated the i2c routine inside a function so I could call it twice.

    Here's the sys_main.c  (no other file has been touched)  

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    uint8_t TX_Data_Master[DATA_COUNT] = {0xAA};
    uint8_t FLAG_STATUS = 0x00;
    void transmit_test(void)
    {
    FLAG_STATUS = 0;
    /*Ignore NACK Mode*/
    i2cREG1->EMDR |= 0x2;
    /* Configure address of Slave to talk to */
    i2cSetSlaveAdd(i2cREG1, DAC7574_ADDRESS);
    /* Set direction to Transmitter */
    i2cSetDirection(i2cREG1, I2C_TRANSMITTER);
    /* Set mode as Master */
    i2cSetMode(i2cREG1, I2C_MASTER);
    /* Set Stop after programmed Count */
    i2cSetStop(i2cREG1);
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX


    As you can see here, the ISR never triggers again

      
     

    Can you reproduce the problem on your end?

    Regards,
    Gabriel

  • Hi Gabriel,

    I did small changes to your code:

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    uint8_t TX_Data_Master[DATA_COUNT] = {0xAA};
    uint8_t FLAG_STATUS = 0x00;
    void transmit_test(void)
    {
    FLAG_STATUS = 0;
    /*Ignore NACK Mode*/
    i2cREG1->EMDR |= 0x2;
    /* Configure address of Slave to talk to */
    i2cSetSlaveAdd(i2cREG1, DAC7574_ADDRESS);
    /* Set direction to Transmitter */
    i2cSetDirection(i2cREG1, I2C_TRANSMITTER);
    /* Set mode as Master */
    i2cSetMode(i2cREG1, I2C_MASTER);
    /* Set Stop after programmed Count */
    //i2cSetStop(i2cREG1);
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Can you please test with above code and let me know the result.

    --
    Thanks & Regards,
    Jagadish.

  • Hi Jagadish,

    Thanks for your support. 
    My apologies for my response delay.


    I'm still getting stuck to the while(FLAG_STATUS == 0x00) line for the second transmission.

    Here's the project In the attached file, if you want to do the test on your machine.

    modified_2318.I2C_Master_RM46L852.zip

    Regards,
    Gabriel

     

  • Hi Gabriel,

    My sincere apologies for the delay in my response.

    Actually, we got couple of holidays in TI-india. And i was also stuck with several other issues.

    Are you still stuck with this issue, if yes then i will need to setup and will do testing at my end.

    --

    Thanks & Regards,
    Jagadish.

  • Hi Jagadish,

    I hope you had great holidays.

     

    Yes I'm still stuck on this issue.
    I cannot believe how hard it is to use this peripheral!

    Let me know if you want me to test something else.

    Regards,  

    Gabriel

  • Hi Gabriel,

    My sincere apologies.

    I didn't get a chance to test this again.

    I will try to test it by tomorrow, so you can expect my response by end of the tomorrow.

    --
    Thanks & regards,
    Jagadish.

  • Hi Gabriel,

    I understood the root cause for the issue, 

    The reason is that you didn't modify the Tx interrupt handler code as QJ suggested.

    QJ suggested code:

    (+) TMS570LS1115: I2C interrupt not working - Arm-based microcontrollers forum - Arm-based microcontrollers - TI E2E support forums

    Your Current code:

    We should consider this modification along with the suggestion i told you previously.

    Here is your modified and tested project:

    7220.I2C_Master_RM46L852.zip

    In above code, i also made two more changes:

    I am making FLAG_STATUS to zero each time i am doing a new transfer.

    Clearing repeat mode after sending the stop condition.

    --
    Thanks & regards,
    Jagadish.

  • Hi Jagadish, 

    Sorry I've been busy elsewhere, I'll look at your solution early this week.

  • Hi Jagadish, 

    Sorry for the delay. The project is still going on. And I should have time to test this shortly.

  • Hi Gabriel,

    Sorry for the delay. The project is still going on. And I should have time to test this shortly.

    No problem, take your time and test it. Once you test it then let me know the result.