Problem with a shared I2C bus using ThreadX and Framework

I have two peripheral devices on the same I2C port.   One device is an OLED display and the other device is temperature sensor.    Because I am using ThreadX (RTOS) to divide the time between the two devices, I have to make sure that the bus is locked to one device at a time.   I learned that the framework is supposed to do automatically and makes the code much simpler than the lock/unlock method.

But, one a while, the first or second OLED i2c write call (after temperature sensor reading is done) will break and return with an error.      How can I debug my code and fix this issue?   

tx_event_flags_get(&g_system_event_flags, SENSOR_BUS_READY_FLAG, TX_AND, &event_flags, TX_WAIT_FOREVER);  // I have this line in both device threads.                                                                                                                                                                            // it is supposed to ensure when the bus is                                                                                                                                                                                   // available and clear to use.

 

Thank you,

Michael

PS: SSP 1.3.0, S5D9 IOT board

 

  • Hello Mike,

    could you check if the problem can be solved by changing the r_riic priorities: Transmit Interrupt Priority and Transmit End Interrupt Priority. Please refer to the following document for details:
    SSP v1.3.0 Release Notes > section 9.7 r_riic
    SSP v1.3.2 Release Notes > section 9.7 r_riic

    Please also look at the description of Issue ID: 9734 in the above resource which explains how to provide sufficient delay for the data transaction.

    Best regards,
    anper

  • In reply to anper:

    Hi Anper,

    Thank you for your response. That is a good link to a document that I need to read for known SSP issues! After searching through the V1.3.0 release notes, I discovered that r_riic is in section 9.11. There are no mention of the r_riic priorities. I also could not find Issue ID: 9734 in the document.

    Can you help me again? I checked the link. The document title seems right. Need help.

    Thank you,
    Michael
  • In reply to Mike:

    Hi Michael,

    I provided incorrect link in my previous post - it supposed to be SSP v1.3.2 Release Notes. I corrected it. I do have in mind that you are using SSP 1.3.0, however it is worth trying also the workarounds proposed in the above document. Please also review the:
    SSP v1.3.0 Release Notes > sections 9 and 10
    for possible issues with I2C.

    Please try to use SSP 1.3.2, if you can, as it may solve some problems.

    Another thing I noticed is that you use TX_AND option in the tx_event_flags_get() function call. Could you try using TX_AND_CLEAR option? This will cause the flags which match SENSOR_BUS_READY_FLAG to be cleared after being retrieved. For details please refer to:
    X-Ware Component Documents for Renesas Synergy > ThreadX User’s Manual: Software > Event Flags (p.80)
    X-Ware Component Documents for Renesas Synergy > ThreadX User’s Manual: Software > tx_event_flags_get (p.146)

    Best regards,
    anper

  • In reply to anper:

    Hi Anper,

    Thank you for writing me again! I appreciate it. Yeah. Now, I see what you said.

    In the meantime, I narrowed down the problem by making things as simple as possible because only OLED display device has this issue. Other I2C devices have no such issue.

    New setup:
    1. 2 Threads, 2 separate I2C bus driver (r_iic and r_sci_i2c). No framework is used.
    2. Don't share the I2C bus. OLED display is connected to one I2C port while the external temperature sensor to another I2C port. (Remove Event, Mutex,....because I don't share the I2C bus anymore and I don't need to lock/unlock a device bus.)

    The I2C OLED display still fails. The temperature sensor is always good. So, I used the scope to see whether S5D9 or OLED display was faulted for the I2C failure (when stucked in a endless loop).

    Scope just when the firmware stuck in a endless loop: At the end of data write and after ACK, S5D9 did not put a STOP as expected. Instead, it initiates a RESTART. So, it is S5D9 doing unusual things on I2C bus.

    Moreover, it fails with a certain range of temperature data values only. I don't understand this part. I wonder if I might have overwritten beyond the boundary of an array in the thread. For example, dispalybuffer[position] if position value is out of the legal range. I am looking at this now.

    Hope these clues help.

    Michael
  • In reply to anper:

    Hi Anper,

    I verified my mistake in the code by running the debugger. The index went outside of the upper max value (SSD1306_LCDWIDTH-1) and the firmware entered an infinite loop.

    Original code:

    buffer[xhist] = ....;
    if (xhist < SSD1306_LCDWIDTH){
    xhist++;
    } else {
    xhist = HISTXPOS;
    }

    fix code:

    buffer[xhist] = ....;
    if (xhist < SSD1306_LCDWIDTH-1){
    xhist++;
    } else {
    xhist = HISTXPOS;
    }

    I was writing outside the buffer array. It seemed to cause I2C communication problem indirectly. After I fixed the code, the problem is gone.

    I will go back to my first firmware and hardware setup with a shared I2C bus. If this is the problem, I will be able to get my first firmware to work right. I hope that the root cause was just my mistake. I keep in mind of your sharing.

    I appreciate the SSP document (that you shared) very much!

    Best,
    Michael
  • In reply to anper:

    Hi Anper,

    I confirmed that the fix in my OLED display code seems to be very good for all three firmware I wrote. There is no issue with SSP 1.3.0 and framework. All the problems are gone after I removed the bug in my code.

    Firmware #1 : Two separate I2C bus ports, ThreadX, two I2C devices drivers
    Firmware #2 : A single shared I2C bus port, ThreadX, two I2C shared device drivers, TX Event Flag, TX Mutex, TX semaphore.
    Firmware #3: A single shared I2C bus port, ThreadX, two I2C shared device drivers framework, TX Event Flag, TX Mutex, TX semaphore.

    I am happy with using Renesas SSP/Framework and ExpressLogic ThreadX for all the above projects with different configurations.

    Best,
    Michael

    PS: TX_AND works fine in my example. Thank you for sharing an idea with me.
  • In reply to Mike:

    Hi Michael,

    it's good to hear that you managed to solve the problem.

    Best regards,
    anper

  • In reply to anper:

    Thank you so much!