Capacitive Multi Touch Adapter and RTCSync conflict

Hello,

i implemented a modified version of the Multitouch Hardware Adapter (just modified the reset and interrupt pins) and seems to work fine (FT5x06 chip). We are using an external RTC (M41T0) and both (touch and RTC) are using the same I2C bus (I2C1). When I modify the system date and restart the module, changes are not persisted in the RTC. If I do this with the touch hardware adapter application stopped, everything works ok.

It seems like there is a conflict between touch hardware adapter and RTCSync accessing the bus without synchronization.

The addresses are 0x38 for touch and 0x68 for RTC so this is ok.

I tried to use the mutex “I2C” like says here and here without success.

Here are the modifications in the touch hard adapter for using the mutex but I suspect there is something wrong.

[upload|aRQ2qM/Qliw1tQmnL8qJGITzqCY=]

Creation of mutex named “I2C”:

[upload|nFF099bVyu4HQOitD+zz3yfJsfA=]

Usage;

[upload|td70sYPsyU3t1i+tbRQbDxm+yXM=]

Any help will be appreciated.

Dear @skabo
I didn’t have time yet to look into the issue. I will get back to you in the next days, sorry for the delay.
Regards, Andy

ok, thanks

Dear @skabo

I can’t see any obvious error. One possible explanatin is, that your interrupt is always triggered, and thus bWaitTouchDataINT() falls through without any delay. If the touch process runs on higher priority than RtcSync, it could lead to the situation that your touch application always owns the “I2C” mutex.

I suggest the following tests

  • measure the i2c signals with a scope or logic analyzer. I expect there should be activity almost only when you apply pressure to the touch screen.
  • Add some debug code to your loop, and sleep, to allow other threads to use the bus, even if they are lower priority. You can find my modifications of your code below:

.

while (1)
{
    if (...)
    {
        ...
    }
    else                                            //real in...
    {   
        /* add timeout and verify that we get the mutex */
        dWaitResult = WaitForSingleObject(ghMutex, /**/200/**/);
        ASSERT (dWaitResult==WAIT_OBJECT_0);
        
        vTouchPanelGetPoint(...);
        ...
        if (...)
        {
            ...
        }
        ReleaseMutex(ghMutex);
        /* check that the previous ReleaseMutex 
           was the only one needed */
        ASSERT(FALSE == ReleaseMutex(ghMutex)); 
    }
    /* Make the touch slow, but for a test 
       leave RTCSync some time to access i2c */
    Sleep(200);    
}

I hope this helps to track down the problem.

Regards,
Andy

Sounds good, let me make some tests and I will get back to you.

Ok, I just test your suggestions and seems to make some effects. Now, I can set the date, but when I apply the changes the touch process stop working. In the log I attached you will see that after RTC date is set, the touch process loose communication with the I2C. Is it like RTSync doesn’t release the mutex?

Toradex Bootloader 2.1 for Tegra Built Feb 20 2018 09:03:40

Press [SPACE] to enter Bootloader Menu

Colibri T20 512MB V1.2A  SerialNo: 4754260
RAM: 512 MB, CarveOut: 64 MB
Locating kernel image in flash...Done(1360)
Decompressing IMAGE(25957446, 50725972) from FLASH(0) to RAM(16000)...Done(567ms
)
Jumping to image at 0x80016000...




Toradex Windows CE 7.0 2.1 for Tegra Built Feb 20 2018 09:03:16
INFO:OALLogSetZones: dpCurSettings.ulZoneMask: 0xb
L2 cache enabled
MainMemoryEndAddress adjusted from 0x86000000 to 0x9C000000
Main Phys Mem: 0x00000000:0x1BFFFFFF
Carveout Phys: 0x1C000000:0x1FFFFFFF
Cold boot selected
SMP: Active CPUs = 2
Chip Id: 0x20 (Handheld SOC) Major: 0x1 Minor: 0x3 SKU: 0x8
NVRM Initialized shmoo database
PllClocks(Mhz): X=1000, M=666, C=600, P=216, A=24.576
SysClocks(Mhz): CPU=1000, AVP=240, SysBus=240, Mem=333, EMem=666
GraphicClocks(Mhz): Host=108, 3D=111, 2D=111, Epp=111, Mpe=111, Vde=240
Loading FlashFileSystem(NAND)...
Micron M71M PS:4KB BS:256KB DS:1024MB BCH16 ECC
INFO: TotalBlocks = 4096, FreeBlocks = 178
BBs: 1
No TAT bad block found.
No TT bad block found.
Done FlashFileSystem(NAND)(124)
Loading Audio...Done
Loading Serial2(UART_B)...Done Serial2(0)
Loading Serial3(UART_C)...Done Serial3(0)
Loading SDIO(SDIO4)...NvDdkSdioSetClockFrequency: Requested: 100 KHz, Actual: 10
1 KHz
NvDdkSdioSetClockFrequency: Requested: 25000 KHz, Actual: 25411 KHz
NvDdkSdioSetClockFrequency: Requested: 50000 KHz, Actual: 48000 KHz
Done(1003)
Loading USBFunction(Port1)...Done
Loading USBHost(Port2)...Done
Loading USBHost(Port3)...Done
Loading DisplayDriver...Done(36)
Set LCD to 1024x600 (63Hz)
Loading Keyboard/MouseDriver...Done
UnfdMutiTchDrv 2.0 loading...done
RTC Time restored (17.12.2018 16:47:43)
AX88772B: instantiate [AX88772B1]
Loading NETUI...
Done NETUI
MultiTchHwAdapt loading...MultiTchAppDriv:I2C Library Version=1.9 Build=3593
MultiTchHwAdapt: Start communication with the touch controller FT5x06
Warning: you are requesting IOCTL_HAL_GET_DEVICE_INFO::SPI_GETPLATFORMTYPE, whic
h has been deprecated.  Use IOCTL_HAL_GET_DEVICE_INFO::SPI_GETPLATFORMNAME inste
ad.
Warning: you are requesting IOCTL_HAL_GET_DEVICE_INFO::SPI_GETPLATFORMTYPE, whic
h has been deprecated.  Use IOCTL_HAL_GET_DEVICE_INFO::SPI_GETPLATFORMNAME inste
ad.
Warning: you are requesting IOCTL_HAL_GET_DEVICE_INFO::SPI_GETPLATFORMTYPE, whic
h has been deprecated.  Use IOCTL_HAL_GET_DEVICE_INFO::SPI_GETPLATFORMNAME inste
ad.
Warning: you are requesting IOCTL_HAL_GET_DEVICE_INFO::SPI_GETPLATFORMTYPE, whic
h has been deprecated.  Use IOCTL_HAL_GET_DEVICE_INFO::SPI_GETPLATFORMNAME inste
ad.
ID_G_THGROUP(0x19) ID_G_THPEAK(0x3C) ID_G_THCAL(0xFC) ID_G_THWATER(0x0) ID_G_THT
EMP(0x6)
done
Warning: you are requesting IOCTL_HAL_GET_DEVICE_INFO::SPI_GETPLATFORMTYPE, whic
h has been deprecated.  Use IOCTL_HAL_GET_DEVICE_INFO::SPI_GETPLATFORMNAME inste
ad.
Warning: you are requesting IOCTL_HAL_GET_DEVICE_INFO::SPI_GETPLATFORMTYPE, whic
h has been deprecated.  Use IOCTL_HAL_GET_DEVICE_INFO::SPI_GETPLATFORMNAME inste
ad.
TipSwitch1 = 1
Calling DeviceIoControl: CeTchInp.TchInp[0].dwFlags = 0a
DeviceIoControl returned

Unknown: DEBUGCHK failed in file .\HwAdapt.c at line 146 
TipSwitch1 = 1
Calling DeviceIoControl: CeTchInp.TchInp[0].dwFlags = 09
DeviceIoControl returned

TipSwitch1 = 1
Calling DeviceIoControl: CeTchInp.TchInp[0].dwFlags = 09
DeviceIoControl returned

TipSwitch1 = 1
Calling DeviceIoControl: CeTchInp.TchInp[0].dwFlags = 09
DeviceIoControl returned

TipSwitch1 = 0
Calling DeviceIoControl: CeTchInp.TchInp[0].dwFlags = 04
DeviceIoControl returned

TipSwitch1 = 1
Calling DeviceIoControl: CeTchInp.TchInp[0].dwFlags = 0a
DeviceIoControl returned

TipSwitch1 = 1
Calling DeviceIoControl: CeTchInp.TchInp[0].dwFlags = 09
DeviceIoControl returned

TipSwitch1 = 1
Calling DeviceIoControl: CeTchInp.TchInp[0].dwFlags = 09
DeviceIoControl returned

TipSwitch1 = 1
Calling DeviceIoControl: CeTchInp.TchInp[0].dwFlags = 09
DeviceIoControl returned

TipSwitch1 = 1
Calling DeviceIoControl: CeTchInp.TchInp[0].dwFlags = 09
DeviceIoControl returned

TipSwitch1 = 3
Calling DeviceIoControl: CeTchInp.TchInp[0].dwFlags = 09
DeviceIoControl returned

Warning: you are requesting IOCTL_HAL_GET_DEVICE_INFO::SPI_GETPLATFORMTYPE, whic
h has been deprecated.  Use IOCTL_HAL_GET_DEVICE_INFO::SPI_GETPLATFORMNAME inste
ad.
RTC Time set (03.12.2018 16:48:36)
MultiTchHwAdapt:bReadInRegister() illegale response in I2c_Read()
ERROR: .\TchContr_FT5x06.c line 370: MultiTchHwAdapt:vGetControllerData() I2C re
ad failed
MultiTchHwAdapt:bReadInRegister() illegale response in I2c_Read()
ERROR: .\TchContr_FT5x06.c line 370: MultiTchHwAdapt:vGetControllerData() I2C re
ad failed
MultiTchHwAdapt:bReadInRegister() illegale response in I2c_Read()
ERROR: .\TchContr_FT5x06.c line 370: MultiTchHwAdapt:vGetControllerData() I2C re
ad failed
MultiTchHwAdapt:bReadInRegister() illegale response in I2c_Read()
ERROR: .\TchContr_FT5x06.c line 370: MultiTchHwAdapt:vGetControllerData() I2C re
ad failed
MultiTchHwAdapt:bReadInRegister() illegale response in I2c_Read()
MultiTchHwAdapt: restarts communication with touch controller...
MultiTchHwAdapt: Start communication with the touch controller FT5x06
MultiTchHwAdapt:bReadInRegister() illegale response in I2c_Read()
MultiTchHwAdapt: restarts communication with touch controller...
MultiTchHwAdapt: Start communication with the touch controller FT5x06
MultiTchHwAdapt:bReadInRegister() illegale response in I2c_Read()
MultiTchHwAdapt: restarts communication with touch controller...
MultiTchHwAdapt: Start communication with the touch controller FT5x06
MultiTchHwAdapt:bReadInRegister() illegale response in I2c_Read()
MultiTchHwAdapt: restarts communication with touch controller...
MultiTchHwAdapt: Start communication with the touch controller FT5x06
MultiTchHwAdapt:bReadInRegister() illegale response in I2c_Read()
MultiTchHwAdapt: restarts communication with touch controller...
MultiTchHwAdapt: Start communication with the touch controller FT5x06

Dear @skabo
It’s very unlikely that RtcSync does not release the mutex - I expect we would have gotten many problem reports about this in the past (which we didn’t).

I would focus on another fact: In your log above, line 81, there’s a message
Unknown: DEBUGCHK failed in file .\HwAdapt.c at line 146
Analyze, where it comes from. Is this the new verification I suggested
ASSERT (dWaitResult==WAIT_OBJECT_0);?
If my guess is correct, then it means that your application did not get the mutex. If you ignore this, and continue using i2c anyway, it will very likely generate a mess with unpredictable results.
If my guess was wrong, is it possible you send me your full source file? You can mark the message as private if you don’t want it to be seen by everybody.

Regards, Andy

The message is from

ASSERT(FALSE == ReleaseMutex(ghMutex)); 

and seems to be only the first time the interrupt is triggered.

In respect with the first ASSERT, I’m checking for

dWaitResult==WAIT_OBJECT_0

so if couldn’tget the mutex I’m not using I2C.

I’m a bit confused, I attached you a new debug log and the source code.

source and log

Dear @skabo

Forget everything we discussed so far. It was all based on my wrong assumption that you are using our old WinCe Libraries.

For the new libraries the concept is much simpler:
Your application takes the mutex on I2c_Open() and releases the mutex on I2c_Close(). Therefore what you need to do is:

  • remove all the mutex-related code from your WinMain()
  • remove I2c_Open() / I2c_Close() from your functions bI2C_Init()/bI2C_Deinit()
  • Enclose reasonable groups of i2c operations into a I2c_Open() / I2c_Close() combination. Make sure that the close function is always called, also in any error condition.
    • Initialization ( bInitFT5x06() )
    • Communication test ( bCommunicationTestFT5x06() )
    • Reading coordinates ( bCommunicationTestFT5x06() )

I didn’t verify whether my list is complete, but I hope it is sufficient to explain you the concept.

Regards, Andy

Understood the concept.

I did what you say and this is the result:

  • bInitFT5x06() : result OK,
  • vTouchPanelGetPoint() : fail in bReadInRegister()…specifically when trying to do I2c_Read()

It’s like the first time I do a I2c_Open() / I2c_Close() combination (inside bInitFT5x06()) seems to work, but from there it doesn’t work anymore. I’m sure the close function is called.

I’m using toradexcelibraries_v1_9_3609

Source code

Dear @skabo

At a first glance your code looks fine. Unfortunately I don’t have a similar touch screen around to debug the project you sent me.

I suggest the following two steps to track down the problem:

  1. Try to simplify the system for a test.
    For example simply read one particular register of the FT5x06 in a simple loop (just open / read / close) once every second or every 100ms,.
  2. The Libraries V1.9 are quite old. We implemented a number of fixes and improvements, some especially for the Tegra. Try to use our latest libraries V2.2.

Do you still see the problem?

Regards, Andy

ok, I will try something like that.

Finally I tested what you suggested me. I made a basic test where I open/read/close in a loop (100 ms) and the behaviour is the same, the first time works and next times failed. In this case the general structure is:

I2c_init()
I2c_SetConfigInt()
while
{
I2c_Open()
I2c_Write()
I2c_Read()
I2c_Close()
}
I2c_Deinit()

Then I tested including the init and set config inside the while loop like this:

while
{
    I2c_init()
    I2c_SetConfigInt()

    I2c_Open()
    I2c_Write()
    I2c_Read()
    
    I2c_Close()
    I2c_Deinit()
}

And works!

Sholdn’t be the init and setconfig operations run once at the begining? Because thats the way is implemented in the HardAdapt application, but it doesn`t work.

Hi Skabo

Your first approach is expected to work. It looks like a library bug that requires you to
go through an Init/Deinit sequence each time.
I will look into it and get back to you next week.

Regards, Andy

Hi @skabo

I tested your application, and for me it works perfectly fine, with only the open/close inside the loop. Can you please repeat your test with the modified c file (ideally on an evaluation board).

  • HwAdapt.c
    From your original demo (i2c.7z) I only did the following changes
    • I changed the slave address to 0x68 in order to address the M41T0 RTC on the Evalboard
    • I moved the I2c_Open() command after the I2c_SetConfigInt() block.
    • I moved the while(1) { and } to exclude the I2c_Init(), I2c_SetConfigInt() and I2c_Deinit() from the
      loop.
    • I used the latest Toradex CE Libraries V2.3.4555

Then I did the following test:

  1. I activated the debug messages on the Colibri T20
  2. I started the modified test application
  3. While the test was running I changed the system time and monitored the debug output to get the confirmation that setting the time was successful.
  4. I also verified that setting the time failed, when my test application was sitting in a breakpoint between I2c_Open() and I2c_Close() .

There was no i2c error, and also setting the RTC time worked flawlessly.

Regards,
Andy

ok, let me make some test, thanks