Analog input dispose

Hello All,

I am trying to upgrade from EMX to G120E since EMX module is obsolete.
I use the module on a custom board and everything works fine with G120E except that I use pins P0_23 to P0_26 as both analog inputs and output ports. After I use them as analog input I dispose of them and do the same thing when I use them as output ports. Dispose function works fine for the output ports, but with analog inputs it works a few times and after that the analog input reads a fixed value and does not change based on the input voltage. I use these pins for resistive touch screen and this code has been working fine with EMX module. Here is a piece of the code where I use the pins and dispose them.

public static int GetTouchYInput()
{
int value = 0;
int[] array = new int[6];
AnalogInput TOUCH3;
OutputPort TOUCH4;
AnalogInput TOUCH1;
OutputPort TOUCH2;
try
{
TOUCH3 = new AnalogInput(GHI.Pins.G120E.AnalogInput.P0_25);
TOUCH4 = new OutputPort(G120E.Gpio.P0_24, false);
TOUCH1 = new AnalogInput(GHI.Pins.G120E.AnalogInput.P0_23);
TOUCH2 = new OutputPort(GHI.Pins.G120E.Gpio.P0_26, true);
Thread.Sleep(20); // was 10
for (int idx = 0; idx < 6; idx++)
{
array[idx] = (TOUCH1.ReadRaw() + TOUCH3.ReadRaw());
}

               if (((ABS(array[4] - array[1])) < 20) && ((ABS(array[4] - array[2])) < 20) && ((ABS(array[4] - array[3])) < 20) && ((ABS(array[2] - array[3])) < 20))
               {
                   for (int i = 1; i < (array.Length - 1); i++)
                   value += array[i];
                   value = value /24;
               }
            TOUCH1.Dispose();
            GC.SuppressFinalize(TOUCH1);
            TOUCH2.Dispose();
            TOUCH3.Dispose();
            GC.SuppressFinalize(TOUCH3);
            TOUCH4.Dispose();
        }

This is very puzzling to me and I appreciate your help.

what firmware version are you using so we can try here please?

.NETMF version is 4.3.

Which specific version please?

2016 R1
G120 Version:
- 4.3.8.1 Firmware
- 4.3.8.1 Loader

Is there any real reason you need to assign and dispose of them each time you read the touch?

Would it not be better to assign them once at startup and make them global and then use them as required for each touch test?

Hello Gus,

I am just checking to make sure I provided the information you needed and if you were able to reproduce the issue I am seeing?
I appreciate your help on this.

Hello Dave,

Thanks for your reply.
The reason that I assign and dispose the ports is that I am reading X and Y positions of the touch with these ports. When I am reading Y two ports are outputs providing 0v and 3.3v and two ports are analog inputs to read Y value. When I am reading X the ports that were analog inputs are now output ports and the other two are analog inputs.
The code I provided is only for reading X touch. I do the same thing for reading Y touch except that the ports change.
Is there any other way to use the ports as output port and analog input?

@Dat_Tran is looking into it

Thank you.

Ah, got you now. I’ve never found the ADC reliable enough for consistent touch so I always used the ADS7843 or similar for handling touch. It also has the advantage of generating an interrupt when someone touches the panel.

Hello Dat_Tran,

Were you able to look into this?
I appreciate it if you send me an update on it.
Thanks.

We were able to reproduce the behavior, but unfortunately we do not have a work around at this time.

One possible solution in the mean time is to use register access to directly manipulate the IO registers instead of going through our abstraction. It may turn out to be slightly quicker too.

John,

Thanks for your response.
I took your advice and used the registers, but now I am facing another issue.
Reading from ADC0 (P0-23) and ADC2 (P0-25) is working ok. But reading from ADC1 (P0-24) and ADC3 (P0-26) does not work.
Is there an issue with these two ports?

Here is what I do:
public static int touchY()
{
int value = 0; int value1 = 0; int value2 = 0;
GHI.Processor.Register IOCON_P0_25 = new GHI.Processor.Register(0x4002C064); //TOUCH3
GHI.Processor.Register IOCON_P0_24 = new GHI.Processor.Register(0x4002C060); //TOUCH4
GHI.Processor.Register IOCON_P0_23 = new GHI.Processor.Register(0x4002C05C); //TOUCH1
GHI.Processor.Register IOCON_P0_26 = new GHI.Processor.Register(0x4002C068); //TOUCH2
GHI.Processor.Register DIR0 = new GHI.Processor.Register(0x20098000);
GHI.Processor.Register SET0 = new GHI.Processor.Register(0x20098018);
GHI.Processor.Register CLR0 = new GHI.Processor.Register(0x2009801C);
GHI.Processor.Register MASK0 = new GHI.Processor.Register(0x20098010);
GHI.Processor.Register PIN0 = new GHI.Processor.Register(0x20098014);
GHI.Processor.Register CR = new GHI.Processor.Register(0x40034000);
GHI.Processor.Register GDR = new GHI.Processor.Register(0x40034004);
//clear analog bits for touch3
IOCON_P0_25.ClearBits(0x0000009F);;
//set to analog
IOCON_P0_25.SetBits(0x00000001);
// set touch4 to GPIO
IOCON_P0_24.ClearBits(0x0000049F);
IOCON_P0_24.SetBits(0x00000480);
//clear analog bits for touch1
IOCON_P0_23.ClearBits(0x0000009F);
//set to analog
IOCON_P0_23.SetBits(0x00000001);
// set touch2 to GPIO
IOCON_P0_26.ClearBits(0x0000049F);
IOCON_P0_26.SetBits(0x00000080);

        MASK0.ClearBits(0x07800000);
        //MASK0.SetBits(0xF87FFFFF);
        DIR0.SetBits(0x05000000);    //touch2 and touch4 output
        DIR0.ClearBits(0x02800000);    //touch1 and touch3 set to input
       
        //set touch4 to low
        CLR0.SetBits(0x01000000);
        //set touch2 to high
        PIN0.SetBits(0x04000000);
        //PIN0.ClearBits(0x01000000);
        SET0.SetBits(0x04000000);
        CR.SetBits(0x00200001);
        CR.SetBits(0x01000000); ;//START CONVERSION
        while ((GDR & (0x80000000) == 0)) ;//WAIT FOR END OF CONVERSION
        value1 = (GDR >> 4) & 0xfff;//SHIFT TO RIGHT 4 BITS GLOBAL REGISTER
        CR.SetBits(0x00200004);
        CR.SetBits(0x01000000); ;//START CONVERSION
        while ((GDR & (0x80000000) == 0)) ;//WAIT FOR END OF CONVERSION
        value2 = (GDR >> 4) & 0xfff;//SHIFT TO RIGHT 4 BITS GLOBAL REGISTER
        value = value1 + value2; 
        //ScreenPrint("touch2 dir = " + DIR0.ToString());
       //ScreenPrint("touch2 pin = " + PIN0.ToString());
        ScreenPrint("Y value = " + value.ToString());
        return value;
    }

    public static int touchX()
    {
        int value = 0; int value1 = 0; int value2 = 0;
       GHI.Processor.Register IOCON_P0_25 = new GHI.Processor.Register(0x4002C064);        //TOUCH3
        GHI.Processor.Register IOCON_P0_24 = new GHI.Processor.Register(0x4002C060);        //TOUCH4
        GHI.Processor.Register IOCON_P0_23 = new GHI.Processor.Register(0x4002C05C);        //TOUCH1
        GHI.Processor.Register IOCON_P0_26 = new GHI.Processor.Register(0x4002C068);        //TOUCH2
        GHI.Processor.Register DIR0 = new GHI.Processor.Register(0x20098000);
        GHI.Processor.Register SET0 = new GHI.Processor.Register(0x20098018);
        GHI.Processor.Register CLR0 = new GHI.Processor.Register(0x2009801C);
        GHI.Processor.Register MASK0 = new GHI.Processor.Register(0x20098010);
        GHI.Processor.Register PIN0 = new GHI.Processor.Register(0x20098014);
        GHI.Processor.Register CR = new GHI.Processor.Register(0x40034000);
        GHI.Processor.Register GDR = new GHI.Processor.Register(0x40034004);
        //clear analog bits for touch4
        IOCON_P0_24.ClearBits(0x0000009F); ;
        //set to analog 
        IOCON_P0_24.SetBits(0x00000001);
        // set touch3 to GPIO
        IOCON_P0_25.ClearBits(0x0000049F);
        IOCON_P0_25.SetBits(0x00000480);
        //clear analog bits for touch2
        IOCON_P0_26.ClearBits(0x0000009F);
        //set to analog 
        IOCON_P0_26.SetBits(0x00000001);
        // set touch1 to GPIO
        IOCON_P0_23.ClearBits(0x0000049F);
        IOCON_P0_23.SetBits(0x00000080);

        MASK0.ClearBits(0x07800000);
        //MASK0.SetBits(0xF87FFFFF);
        DIR0.SetBits(0x02800000);    //touch1 and touch3 output
        DIR0.ClearBits(0x05000000);    //touch2 and touch4 set to input

        //set touch3 to low
        CLR0.SetBits(0x02000000);
        //set touch1 to high
        PIN0.SetBits(0x00800000);
        //PIN0.ClearBits(0x01000000);
        SET0.SetBits(0x00800000);
        CR.SetBits(0x00200002);
       CR.SetBits(0x01000000); ;//START CONVERSION
        while ((GDR & (0x80000000) == 0)) ;//WAIT FOR END OF CONVERSION
        value1 = (GDR >> 4) & 0xfff;//SHIFT TO RIGHT 4 BITS GLOBAL REGISTER
        CR.SetBits(0x00200008);
        CR.SetBits(0x01000000); ;//START CONVERSION
        while ((GDR & (0x80000000) == 0)) ;//WAIT FOR END OF CONVERSION
        value2 = (GDR >> 4) & 0xfff;//SHIFT TO RIGHT 4 BITS GLOBAL REGISTER
        value = value1 + value2;
       //ScreenPrint("touch2 dir = " + DIR0.ToString());
        //ScreenPrint("touch2 pin = " + PIN0.ToString());
        ScreenPrint("X value = " + value.ToString());
        return value;
    }

Y value changes based on voltages on pins 9 and 11, but X value reads a very low value regardless of the analog voltage changes on pins 8 and 10. The analog voltage on these pins changes from 3.3v to zero volts.

Thanks,
Sarira

It’s hard to say without having a complete program that shows the issue.

That said, we did observe a few issues with your code and made a few corrections below. One particular thing we noticed is that using the touchY function prevented the touchX function from working properly, but either in isolation was fine, so something in Y killed X. Before testing the below code, make sure to completely erase and remove power from the board to clear any previous corruption.

public static uint touchY() {
    uint value = 0; uint value1 = 0; uint value2 = 0;
    GHI.Processor.Register IOCON_P0_25 = new GHI.Processor.Register(0x4002C064);        //TOUCH3
    GHI.Processor.Register IOCON_P0_24 = new GHI.Processor.Register(0x4002C060);        //TOUCH4
    GHI.Processor.Register IOCON_P0_23 = new GHI.Processor.Register(0x4002C05C);        //TOUCH1
    GHI.Processor.Register IOCON_P0_26 = new GHI.Processor.Register(0x4002C068);        //TOUCH2
    GHI.Processor.Register DIR0 = new GHI.Processor.Register(0x20098000);
    GHI.Processor.Register SET0 = new GHI.Processor.Register(0x20098018);
    GHI.Processor.Register CLR0 = new GHI.Processor.Register(0x2009801C);
    GHI.Processor.Register MASK0 = new GHI.Processor.Register(0x20098010);
    GHI.Processor.Register PIN0 = new GHI.Processor.Register(0x20098014);
    GHI.Processor.Register CR = new GHI.Processor.Register(0x40034000);
    GHI.Processor.Register GDR = new GHI.Processor.Register(0x40034004);
    //clear analog bits for touch3
    IOCON_P0_25.ClearBits(0x0000009F); ;
    //set to analog
    IOCON_P0_25.SetBits(0x00000001);
    // set touch4 to GPIO
    IOCON_P0_24.ClearBits(0x0000049F);
    IOCON_P0_24.SetBits(0x00000480);
    //clear analog bits for touch1
    IOCON_P0_23.ClearBits(0x0000009F);
    //set to analog
    IOCON_P0_23.SetBits(0x00000001);
    // set touch2 to GPIO
    IOCON_P0_26.ClearBits(0x0000049F);
    IOCON_P0_26.SetBits(0x00000080);
    MASK0.ClearBits(0x07800000);
    //MASK0.SetBits(0xF87FFFFF);
    DIR0.SetBits(0x05000000);    //touch2 and touch4 output
    DIR0.ClearBits(0x02800000);    //touch1 and touch3 set to input
                                    //set touch4 to low
    CLR0.SetBits(0x01000000);
    //set touch2 to high
    PIN0.SetBits(0x04000000);
    //PIN0.ClearBits(0x01000000);
    SET0.SetBits(0x04000000);
    CR.SetBits(0x00200001);
    CR.SetBits(0x01000000); ;//START CONVERSION
    while ((GDR.Value & 0x80000000) == 0) ;//WAIT FOR END OF CONVERSION
    value1 = (GDR.Value >> 4) & 0xfff;//SHIFT TO RIGHT 4 BITS GLOBAL REGISTER
                                        //CR.SetBits(0x00200004);
                                        //CR.SetBits(0x01000000); ;//START CONVERSION
                                        //while ((GDR & (0x80000000) == 0)) ;//WAIT FOR END OF CONVERSION
                                        //value2 = (GDR >> 4) & 0xfff;//SHIFT TO RIGHT 4 BITS GLOBAL REGISTER
                                        //value = value1 + value2;

    Debug.Print("ADC0 pin5 Y value = " + value1.ToString());
    CR.ClearBits(0x01000001); // STOP
    return value1;
}
public static uint touchX() {
    uint value = 0; uint value1 = 0; uint value2 = 0;
    GHI.Processor.Register IOCON_P0_25 = new GHI.Processor.Register(0x4002C064);        //TOUCH3
    GHI.Processor.Register IOCON_P0_24 = new GHI.Processor.Register(0x4002C060);        //TOUCH4
    GHI.Processor.Register IOCON_P0_23 = new GHI.Processor.Register(0x4002C05C);        //TOUCH1
    GHI.Processor.Register IOCON_P0_26 = new GHI.Processor.Register(0x4002C068);        //TOUCH2
    GHI.Processor.Register DIR0 = new GHI.Processor.Register(0x20098000);
    GHI.Processor.Register SET0 = new GHI.Processor.Register(0x20098018);
    GHI.Processor.Register CLR0 = new GHI.Processor.Register(0x2009801C);
    GHI.Processor.Register MASK0 = new GHI.Processor.Register(0x20098010);
    GHI.Processor.Register PIN0 = new GHI.Processor.Register(0x20098014);
    GHI.Processor.Register CR = new GHI.Processor.Register(0x40034000);
    GHI.Processor.Register GDR = new GHI.Processor.Register(0x40034004);
    //clear analog bits for touch4
    IOCON_P0_24.ClearBits(0x0000009F); ;
    //set to analog
    IOCON_P0_24.SetBits(0x00000001);
    // set touch3 to GPIO
    IOCON_P0_25.ClearBits(0x0000049F);
    IOCON_P0_25.SetBits(0x00000480);
    //clear analog bits for touch2
    IOCON_P0_26.ClearBits(0x0000009F);
    //set to analog
    IOCON_P0_26.SetBits(0x00000001);
    // set touch1 to GPIO
    IOCON_P0_23.ClearBits(0x0000049F);
    IOCON_P0_23.SetBits(0x00000080);

    MASK0.ClearBits(0x07800000);
    //MASK0.SetBits(0xF87FFFFF);
    DIR0.SetBits(0x02800000);    //touch1 and touch3 output
    DIR0.ClearBits(0x05000000);    //touch2 and touch4 set to input

    //set touch3 to low
    CLR0.SetBits(0x02000000);
    //set touch1 to high
    PIN0.SetBits(0x00800000);
    //PIN0.ClearBits(0x01000000);
    SET0.SetBits(0x00800000);
    CR.SetBits(0x00200002);
    CR.SetBits(0x01000000); ;//START CONVERSION
    while ((GDR.Value & 0x80000000) == 0) ;//WAIT FOR END OF CONVERSION
    value1 = (GDR.Value >> 4) & 0xfff;//SHIFT TO RIGHT 4 BITS GLOBAL REGISTER
                                        //CR.SetBits(0x00200008);
                                        //CR.SetBits(0x01000000); ;//START CONVERSION
                                        //while ((GDR & (0x80000000) == 0)) ;//WAIT FOR END OF CONVERSION
                                        //value2 = (GDR >> 4) & 0xfff;//SHIFT TO RIGHT 4 BITS GLOBAL REGISTER
                                        //value = value1 + value2;
                                        //ScreenPrint("touch2 dir = " + DIR0.ToString());
                                        //ScreenPrint("touch2 pin = " + PIN0.ToString());
    Debug.Print("ADC1 pin4 X value = " + value1.ToString());
    CR.ClearBits(0x01000002); // STOP
    return value1;
}

John,

Thanks for your response and help. The code works very well.