Raptor + CP7 : Failed to perform I2C transaction errors

I have both the USB and a separate DC jack plugged into my power module. However, I can use a PowerExt module for the display and see if it changes the behavior.

Roy

OK… First let me give you some background on my code for the display so you know what the log means.

void ProgramStarted()
{
    // I have other code here, but it is removed for brevity

if (this.Display is Display_CP7)
            {
                this.Display.ScreenPressed += _cp7Display_ScreenPressed;
                this.Display.ScreenReleased += _cp7Display_ScreenReleased;
                this.Display.BackPressed += (sender) => { Debug.Print("BackPressed"); };
                this.Display.GestureDetected += (sender, id) => { Debug.Print("GestureDetected: " + id); };
                this.Display.HomePressed += (sender) => { Debug.Print("HomePressed"); };
                this.Display.MenuPressed += (sender) => { Debug.Print("MenuPressed"); };
            }
            else
            {
                GlideTouch.Initialize();
            }
}
        private TouchInput lastTouch = new TouchInput() { X = -1, Y = -1 };
        private bool isTouched = false;

        void _cp7Display_ScreenReleased(Display_CP7 sender)
        {
            if ((isTouched) && (lastTouch.X != -1) && (lastTouch.Y != -1))
            {
                Debug.Print("TouchUp: " + lastTouch.X.ToString() + ", " + lastTouch.Y.ToString());
                GlideTouch.RaiseTouchUpEvent(null, new TouchEventArgs(new GHIElectronics.NETMF.Glide.Geom.Point(lastTouch.X, lastTouch.Y)));

                lastTouch.X = -1;
                lastTouch.Y = -1;

                isTouched = false;
            }
        }
        void _cp7Display_ScreenPressed(Display_CP7 sender, Display_CP7.TouchStatus touchStatus)
        {
            //GHIElectronics.NETMF.Glide.Geom.Point touches;             
            Microsoft.SPOT.Touch.TouchInput[] touches = new Microsoft.SPOT.Touch.TouchInput[] { new TouchInput() };
            if (touchStatus.numTouches > 0)
            {
                //touch input is sent to micorsoft.spot
                touches[0].X = touchStatus.touchPos[0].xPos;
                touches[0].Y = touchStatus.touchPos[0].yPos;

                //touch input is sent to Glide
                int pos_x = touchStatus.touchPos[0].xPos;
                int pos_y = touchStatus.touchPos[0].yPos;

                // Don't raise any events for items bigger then our screen
                if ((pos_x > sender.Width) || (pos_y > sender.Height))
                {
                    return;
                }

                // Turn on the backlight on the first press if it is off
                if (sender.BBackLightOn == false)
                {
                    sender.SetBacklight(true);
                    return;
                }

                // Don't duplicate the events for the same position
                if ((pos_x == lastTouch.X) & (pos_y == lastTouch.Y))
                {
                    return;
                }


                if (isTouched == false)
                {
                    GlideTouch.RaiseTouchDownEvent(sender, new TouchEventArgs(touches));
                    Debug.Print("TouchDown: " + pos_x + " : " + pos_y);

                    lastTouch.X = pos_x;
                    lastTouch.Y = pos_y;

                    isTouched = true;
                }
                else
                {
                    // Filtering of holding down a place on the monitor screen                    
                    if (System.Math.Abs(pos_x - lastTouch.X) > 2 || System.Math.Abs(pos_y - lastTouch.Y) > 2)
                    {
                        touches[0].X = pos_x;
                        touches[0].Y = pos_y;

                        GlideTouch.RaiseTouchMoveEvent(null, new TouchEventArgs(touches));
                        Debug.Print("RaiseTouchMoveEvent: " + pos_x + " : " + pos_y);

                        lastTouch.X = pos_x;
                        lastTouch.Y = pos_y;
                    }
                }
            }
        } 

For these tests, I plugged my display into my PowerExt module so it had dedicated power.

Now, for a simple touch of the screen (pretty close to the center).

TouchDown: 430 : 205
BackPressed
BackPressed
BackPressed
BackPressed
BackPressed
BackPressed
BackPressed
BackPressed
BackPressed
BackPressed
BackPressed
TouchUp: 430, 205

How could the “BackPressed” even have gotten raised… I was no where near it… and it fired numerous times.

Here is another with me just touching the screen, and then releasing (from the same spot)

TouchDown: 521 : 137
Failed to perform I2C transaction
RaiseTouchMoveEvent: 520 : 0
TouchUp: 520, 0

And this is touching the screen, sliding my finger to the right, then letting up (notice the move event that is way off position).

TouchDown: 293 : 276
RaiseTouchMoveEvent: 297 : 276
RaiseTouchMoveEvent: 302 : 275
RaiseTouchMoveEvent: 311 : 274
RaiseTouchMoveEvent: 66 : 273
RaiseTouchMoveEvent: 335 : 272
RaiseTouchMoveEvent: 342 : 272
RaiseTouchMoveEvent: 355 : 271
RaiseTouchMoveEvent: 370 : 270
RaiseTouchMoveEvent: 377 : 269
RaiseTouchMoveEvent: 393 : 268
RaiseTouchMoveEvent: 422 : 267
RaiseTouchMoveEvent: 437 : 267
RaiseTouchMoveEvent: 456 : 266
RaiseTouchMoveEvent: 472 : 265
RaiseTouchMoveEvent: 487 : 264
RaiseTouchMoveEvent: 512 : 262
RaiseTouchMoveEvent: 519 : 262
RaiseTouchMoveEvent: 529 : 261
RaiseTouchMoveEvent: 533 : 261
RaiseTouchMoveEvent: 536 : 261
RaiseTouchMoveEvent: 539 : 261
RaiseTouchMoveEvent: 543 : 260
TouchUp: 543, 260

And if I touch the home button, I get the event raised MANY times (I know it may do it more than once, but THIS many). If there was a “HomeReleased” event to go with it, it might make sense, but without it, I have no way to know if it was a single press, or multiple press and releases.

HomePressed
HomePressed
HomePressed
HomePressed
HomePressed
HomePressed
HomePressed
HomePressed
HomePressed
HomePressed
HomePressed
HomePressed
HomePressed
HomePressed
HomePressed
HomePressed
HomePressed
HomePressed

Using the code you provided, I was able to reproduce the behavior you described, minus the random BackPressed events. It appears to be caused with an interaction with Glide, which I was not using in my tests. The code below is how I was testing. Does it produce as many Failed to perform I2C transaction messages for you?


using Microsoft.SPOT;

namespace GadgeteerApp2
{
    public partial class Program
    {
        void ProgramStarted()
        {
            this.display_CP7.ScreenPressed += (a, b) => display_CP7.SimpleGraphics.DisplayEllipse(Gadgeteer.Color.Red, (uint)b.touchPos[0].xPos, (uint)b.touchPos[0].yPos, 5, 5);
            this.display_CP7.ScreenReleased += (a) => Debug.Print("R");
            this.display_CP7.MenuPressed += (a) => Debug.Print("M");
            this.display_CP7.HomePressed += (a) => Debug.Print("H");
            this.display_CP7.BackPressed += (a) => Debug.Print("B");
        }
    }
}

I dont get the I2C errors with your code, but i do get the odd X/Y positions on occasion. Here is an example of just dragging my finger across the screen a bit (I added a Debug.Print to show the X/Y along with the ellipse).

TouchDown: 247 : 216
TouchDown: 248 : 224
TouchDown: 248 : 233
TouchDown: 248 : 240
TouchDown: 248 : 248
TouchDown: 248 : 0
TouchDown: 248 : 256
TouchDown: 248 : 263
TouchDown: 247 : 270
TouchDown: 247 : 277
TouchDown: 248 : 285

and

TouchDown: 250 : 404
TouchDown: 252 : 408
TouchDown: 252 : 410
TouchDown: 254 : 414
TouchDown: 255 : 417
TouchDown: 1 : 420
TouchDown: 257 : 423
TouchDown: 259 : 423
TouchDown: 259 : 425
TouchDown: 261 : 428

and

TouchDown: 236 : 245
TouchDown: 248 : 237
TouchDown: 252 : 234
TouchDown: 2 : 232
TouchDown: 258 : 224
TouchDown: 274 : 218
TouchDown: 287 : 213

Its not often, but it does still happen. Much better then using it with Glide. I also don’t get the odd Back/Menu/Home events.

A pattern that may be noticed in the X/Y is that when the value goes over the “byte” boundary (255), it can happen All of my tests show that (not just the ones I posted above). Its not always, but when it does happen, that is where it is.

Roy

I’m still encountering the same issue with new firmware and SDK.

@ John - if I use your test code then I do not get any I2C errors being reported, but if I replace



with


```cs]this.display_CP7.ScreenPressed += (a, b) => Debug.Print("P");[/code


then I continue to get the errors.

Thanks. We will let both of you know once we have found out more or resolved this issue.

@ RoySalisbury -
@ Keith

Go somewhere on this forum, learn how to modify a gadgeteer module if you don’t know how.

Then go to file
http://gadgeteer.codeplex.com/SourceControl/latest#Main/Modules/GHIElectronics/Display_CP7/Software/Display_CP7/Display_CP7_42/Display_CP7_42.cs

Replace the function:



by these code below:


```cs
static byte ReadRegister(byte Address)
        {
			int timeout=0x10;
            I2CDevice.I2CTransaction[] xActions = new I2CDevice.I2CTransaction[2];

            // create write buffer (we need one byte)
            byte[] RegisterAddress = new byte[1] { Address };
            xActions[0] = I2CDevice.CreateWriteTransaction(RegisterAddress);
            // create read buffer to read the register
            byte[] RegisterValue = new byte[1];
            xActions[1] = I2CDevice.CreateReadTransaction(RegisterValue);
			while(timeout>0)
			{
				if (i2cBus.Execute(xActions, 100) == 0)
				{
					//Debug.Print("Failed to perform I2C transaction");
					Thread.sleep(10);
					timeout--;
				}
				else
				{
					//Debug.Print("Register value: " + RegisterValue[0].ToString());
					timeout = 0;
				}
				
				
			}
            return RegisterValue[0];
        }

I am not in office so this code is not tested yet but it should work.

Let me know your result!
Thanks

I’ve been unable to find any post that you speak of. The search here does not return anything of value that I can find.

Also, I can’t see how putting a retry loop in the code will prevent it from returning bad data as I have indicated.

Roy

@ RoySalisbury -

It relates to clock stretching between 7 inch Display and G400 so sometime I2C transaction failed.

The problem in that driver, even I2C transaction was failed, it still send wrong data to user.

So what I improved that is, when it failed, try to send another transaction. It will be good at the second transaction if the first was failed. But I still add 0x10 for sure.

I reduced the timeout to 100ms, it won’t let you feel any lag or delay, because I don’t think you can touch 10 times per second. If you feel any lag, try with smaller value.

I think it is here:

https://www.ghielectronics.com/docs/122/gadgeteer-driver-modification

Hi Dat,

I have updated the module code and the error is no longer happening with the simple sample code.

Thanks,

Keith.

@ Keith -

:smiley:

I’ve just been following this after I found it in a Google Search.

I am seeing a larger number of failed I2C transactions with a G400D running with a 5" LCD with capacitive touch.

It also has the same failures if I try to communicate with the I2C ADC I have on the board.

Has anything been done to fix the issue with the G400 and I2C failures?

I’m interested in if there will be a fix for the G400 I2c Problems as well. I worked around the issue with glide by manually registering to events but the failed i2c transaction still rears it’s head occasionally on touch events. I just added a Hub AP5 to my setup and moved all of my sensors and relays onto it but every now and then the sensors will fail or come back with a reading that’s way out of the ball park. I’m guessing this is the I2c error happening behind the scenes and causing the sensors to return garbage. When I’m debugging I haven’t been able to replicate the behavior aside from the temperature humidity sensor randomly failing with a message logged to console or the I2C error message. If i detach the debugger and unplug it from the computer then power it up and let it run for 20 minutes other weird stuff happens like random screen touched events firing and causing buttons to ghost click or sensors to randomly fail.