Example #1
0
/*---------------------------------------------------------------------------*
 * Routine:  PlayAudio
 *---------------------------------------------------------------------------*
 * Description:
 *      Play a tone for the given length, staying here until done.
 * Inptus:
 *      TUInt32 aHz                 -- Tone in Hz
 *      TUInt32 aMS                 -- Duration of tone
 *---------------------------------------------------------------------------*/
void PlayAudio(TUInt32 aHz, TUInt32 aMS)
{

#if OPTION_USE_GPIO_LINES_FOR_AUDIO
    static HAL_GPIOPort **p_gpio0;
    TUInt32 n;
    TUInt32 start = UEZTickCounterGet();
    TUInt32 count;

    HALInterfaceFind("GPIO0", (T_halWorkspace **)&p_gpio0);
    (*p_gpio0)->SetOutputMode(p_gpio0, (1<<26));

    // Wait for the parameters to be ready
    n = (G_subTickCount*1000/2)/aHz;
    taskDISABLE_INTERRUPTS();
    G_dummyCounter = 0;
    // Wait for first tick count
    while ((T1IR&2)==0)
        {}
    while (aMS--) {
        T1IR = 2;
        while (!(T1IR & 2)) {
            count = n;
            while (count--)
                { G_dummyCounter++; }
            (*p_gpio0)->Clear(p_gpio0, (1<<26));
            count = n;
            while (count--)
                { G_dummyCounter++; }
            (*p_gpio0)->Set(p_gpio0, (1<<26));
        }
    }

    taskENABLE_INTERRUPTS();
#else
    if (!G_tg)
        CalibrateAudioTiming();
    //PWMAudio(aHz, (aMS+10)/10, 0);
    if (G_tg)
        UEZToneGeneratorPlayTone(
                G_tg,
                TONE_GENERATOR_HZ(aHz),
                aMS);
    else
        UEZTaskDelay(aMS);
#endif
}
Example #2
0
static T_uezError SDCard_MS_MCI_Init(void *aWorkspace, TUInt32 aAddress)
{
    T_MassStorage_SDCard_MCI_Workspace *p =
        (T_MassStorage_SDCard_MCI_Workspace *)aWorkspace;
    TUInt16 cmd;
    TUInt32 n;
    TUInt32 response[4];
    TUInt8 type;
    TUInt32 timeStart;
    T_msSizeInfo si;
    T_uezError error;

    /* No card in the socket? */
    if (p->iStat & STA_NODISK)
        return UEZ_ERROR_DEVICE_NOT_FOUND;

    // If already initialized, we are done!
    if (p->iInitPerformed)
        return UEZ_ERROR_NONE;

    (*p->iMCI)->PowerOn(p->iMCI); /* Force socket power on */
    (*p->iMCI)->SetClockRate(p->iMCI, SDCARD_MCI_RATE_FOR_ID_STATE, EFalse);
    UEZTaskDelay(2);
    (*p->iMCI)->SendCommand(p->iMCI, MCI_CMD0, 0, 0, NULL); /* Put the card into idle state */
    p->iRCA = 0;

    /*---- Card is 'idle' state ----*/

    /* Initialization timeout of SDCARD_INIT_TIMEOUT msec */
//    Timer[0] = 1000;
    timeStart = UEZTickCounterGet();

    if ((*p->iMCI)->SendCommand(p->iMCI, MCI_CMD8, 0x1AA, 1, response)
        && (response[0] & 0xFFF) == 0x1AA) {
        /* Card is SDC Ver2 */
        /* The card can work at vdd range of 2.7-3.6V */

        /* Wait while card is busy state (use MCI_ACMD41 with HCS bit) */
        do {
            /* This loop will take a time. Insert task rotation here for multitask envilonment. */
            UEZTaskDelay(1);
            if (UEZTickCounterGetDelta(timeStart) >= SDCARD_INIT_TIMEOUT)
                goto di_fail;
        } while (!(*p->iMCI)->SendCommand(p->iMCI, MCI_ACMD41, 0x40FF8000, 1,
            response) || !(response[0] & 0x80000000));
        type = (response[0] & 0x40000000) ? CT_SD2 | CT_BLOCK : CT_SD2; /* Check CCS bit in the OCR */
    } else {
        /* Card is SDC Ver1 or MMC */
        if ((*p->iMCI)->SendCommand(p->iMCI, MCI_ACMD41, 0x00FF8000, 1,
            response)) {
            type = CT_SD1;
            cmd = MCI_ACMD41; /* MCI_ACMD41 is accepted -> SDC Ver1 */
        } else {
            type = CT_MMC;
            cmd = MCI_CMD1; /* MCI_ACMD41 is rejected -> MMC */
        }

        /* Wait while card is busy state (use MCI_ACMD41 or MCI_CMD1) */
        do {
            /* This loop will take a time. Insert task rotation here for multitask envilonment. */
            UEZTaskDelay(1);
            if (UEZTickCounterGetDelta(timeStart) >= SDCARD_INIT_TIMEOUT)
                goto di_fail;
        } while (!(*p->iMCI)->SendCommand(p->iMCI, cmd, 0x00FF8000, 1, response)
            || !(response[0] & 0x80000000));
    }

    /* Save card type */
    p->iCardType = type;
    bswap_cp(&p->iCardInfo[32], response); /* Save OCR */

    /*---- Card is 'ready' state ----*/
    if (!(*p->iMCI)->SendCommand(p->iMCI, MCI_CMD2, 0, 2, response))
        goto di_fail;

    /* Enter ident state */
    for (n = 0; n < 4; n++)
        bswap_cp(&p->iCardInfo[n * 4 + 16], &response[n]); /* Save CID */

    /*---- Card is 'ident' state ----*/
    if (type & CT_SDC) {
        /* SDC: Get generated RCA and save it */
        if (!(*p->iMCI)->SendCommand(p->iMCI, MCI_CMD3, 0, 1, response))
            goto di_fail;
        p->iRCA = (TUInt16)(response[0] >> 16);
    } else {
        /* MMC: Assign RCA to the card */
        if (!(*p->iMCI)->SendCommand(p->iMCI, MCI_CMD3, 1 << 16, 1, response))
Example #3
0
/*---------------------------------------------------------------------------*
 * Routine:  TestModeTouchscreenProcedure
 *---------------------------------------------------------------------------*
 * Description:
 *      Step the user through the calibration process.  A target is shown
 *      at each of 3 locations and waits for the user to touch the
 *      target.
 * Inputs:
 *      TUInt16 *aPixels            -- Pointer to pixel memory
 *      TUInt16 aX, aY              -- Coordinate of target to draw
 *---------------------------------------------------------------------------*/
void TestModeTouchscreenProcedure(
                T_pixelColor *aPixels,
                T_uezDevice ts)
{
    static const T_uezTSReading G_coord[5] = {
        { 0,    0+TP_INSET,                 TP_INSET,                   1 }, // 0
        { 0,    DISPLAY_WIDTH-TP_INSET,     TP_INSET,                   1 }, // 1
        { 0,    0+TP_INSET,                 DISPLAY_HEIGHT-TP_INSET,    1 }, // 2
        { 0,    DISPLAY_WIDTH-TP_INSET,     DISPLAY_HEIGHT-TP_INSET,    1 }, // 3
        { 0,    DISPLAY_WIDTH/2,            DISPLAY_HEIGHT/2,           1 }, // 4
    };

    // List of expected results (based on a single screen)
#if ((UEZ_DEFAULT_LCD_CONFIG==LCD_CONFIG_SHARP_LQ043T3DG01) || (UEZ_DEFAULT_LCD_CONFIG==LCD_CONFIG_SHARP_LQ043T1DG28))
    static const T_uezTSReading G_expectedReadings[5] = {
        { 0,    0x13f6,                     0x58ec,                     1 }, // 0
        { 0,    0x6aa3,                     0x58f0,                     1 }, // 1
        { 0,    0x12d8,                     0x22cd,                     1 }, // 2
        { 0,    0x6616,                     0x1f62,                     1 }, // 3
        { 0,    0x3f47,                     0x3de0,                     1 }, // 4
    };
#elif (UEZ_DEFAULT_LCD_CONFIG==LCD_CONFIG_INTELTRONIC_LMIX0560NTN53V1)
    static const T_uezTSReading G_expectedReadings[5] = {
        { 0,    0x6D64,                     0x62F8,                     1 }, // 0
        { 0,    0x0F3A,                     0x63D7,                     1 }, // 1
        { 0,    0x6BFD,                     0x1B4B,                     1 }, // 2
        { 0,    0x0F6D,                     0x1880,                     1 }, // 3
        { 0,    0x3CC8,                     0x3C98,                     1 }, // 4
    };
#elif ((UEZ_DEFAULT_LCD_CONFIG==LCD_CONFIG_SEIKO_70WVW2T))
    static const T_uezTSReading G_expectedReadings[5] = {
        { 0,    0x6F1C,                     0x620D,                     1 }, // 0
        { 0,    0x118B,                     0x628A,                     1 }, // 1
        { 0,    0x6F01,                     0x1BF4,                     1 }, // 2
        { 0,    0x11D7,                     0x1BFB,                     1 }, // 3
        { 0,    0x4036,                     0x3F62,                     1 }, // 4
    };
#elif (UEZ_DEFAULT_LCD_CONFIG==LCD_CONFIG_TIANMA_TM070RBHG04)
        static const T_uezTSReading G_expectedReadings[5] = {
        { 0,    0x0C04,                     0x204C,                     1 }, // 0
        { 0,    0x6F2A,                     0x2134,                     1 }, // 1
        { 0,    0x0C58,                     0x6012,                     1 }, // 2
        { 0,    0x6F2C,                     0x5DBA,                     1 }, // 3
        { 0,    0x3C6A,                     0x4098,                     1 }, // 4
    };
#elif (UEZ_DEFAULT_LCD_CONFIG == LCD_CONFIG_MICROTIPS_UMSH_8596MD_20T)
    //TODO : update numbers
            static const T_uezTSReading G_expectedReadings[5] = {
        { 0,    0x0C04,                     0x204C,                     1 }, // 0
        { 0,    0x6F2A,                     0x2134,                     1 }, // 1
        { 0,    0x0C58,                     0x6012,                     1 }, // 2
        { 0,    0x6F2C,                     0x5DBA,                     1 }, // 3
        { 0,    0x3C6A,                     0x4098,                     1 }, // 4
    };
#endif

    // The raw X range is 0x560A (left) to 0x2908 (right)
    //      100% = 0x2D02
    //       20% = 0x0900
    //       10% = 0x0480
    // The raw Y range is 0x5A7A (top) to 0x24A1 (bottom)
    //      100% = 0x35D9
    //       20% = 0x0AC5
    //       10% = 0x0562
    #define READING_X_TOLERANCE         0x0900
    #define READING_Y_TOLERANCE         0x0AC5

    T_uezTSReading readings[5];
    T_uezTSReading reading;
    T_uezTSReading sum;
    TUInt32 count;
    int i;
    T_uezError error;
    TBool sawNoTouch;
    TUInt32 timeoutCount=0;
    TUInt32 timeoutStart;

    G_mmTestModeTouchscreenCalibrationValid = EFalse;
    while (1) {
        // Put the touch screen into calibration mode
        UEZTSCalibrationStart(ts);

        // Clear the screen
        //CalibrateScreen();

        // Show 5 different targets
        timeoutStart = UEZTickCounterGet();
        for (i=0; i<5; i++)  {
            // Make sure we see the screen is not being touched
            // when we start.  This ensures if the unit is being held at power
            // up that we don't go into calibration and get a bogus
            // starting reading.
            sawNoTouch = EFalse;

            // Show target to touch
            IDrawTarget(aPixels, G_coord[i].iX, G_coord[i].iY);

            // Wait for the pen to touch (while not in test mode)
            for (;;) {
                sum.iX = 0;
                sum.iY = 0;

                for (count=0; count<4; ) {
                    if (UEZTSGetReading(ts, &reading)==UEZ_ERROR_NONE)  {
                        if (reading.iFlags & TSFLAG_PEN_DOWN)  {
                            // Only accept reading if we originally
                            // were not touching the screen.
                            if (sawNoTouch) {
                                sum.iX += reading.iX;
                                sum.iY += reading.iY;
                                count++;
                                timeoutStart = UEZTickCounterGet();
                                timeoutCount = 0;
                            }
                        } else {
                            sawNoTouch = ETrue;
                            // Reset the timeout
                            timeoutStart = UEZTickCounterGet();
                            timeoutCount = 0;
                        }
                    }
                    if (!sawNoTouch) {
                        timeoutCount = UEZTickCounterGet() - timeoutStart;
                        if (timeoutCount > 10000)
                            break;
                    }
                    UEZTaskDelay(50);
                }
                reading.iX = sum.iX/count;
                reading.iY = sum.iY/count;

                // Remember this reading
                readings[i] = reading;

                if (i < 3) {
                    // If one of the first 3 points, store the data
                    UEZTSCalibrationAddReading(ts, &reading, &G_coord[i]);
                    G_nonvolatileSettings.iReadings[i] = reading;
                    G_nonvolatileSettings.iNum = i+1;
                }
                ButtonClick();
                break;
            }

            // Erase target to signal the user touched the target
            IEraseTarget(aPixels, G_coord[i].iX, G_coord[i].iY);

            if (timeoutCount < 10000) {
                // Wait for the pen to lift
                timeoutCount = 0;
                for (;;) {
                    if (UEZTSGetReading(ts, &reading)==UEZ_ERROR_NONE)  {
                        if (!(reading.iFlags & TSFLAG_PEN_DOWN))  {
                            break;
                        }
                    }
                    UEZTaskDelay(50);
                    timeoutCount += 50;
                    if (timeoutCount >= 10000)
                        break;
                }
            }
        }

        // Calibration is complete.  Put the new calibration into effect.
        error = UEZTSCalibrationEnd(ts);
        if (timeoutCount >= 10000)
            error = UEZ_ERROR_TIMEOUT;


        // Determine if this is valid or not
        if (error) {
            G_mmTestModeTouchscreenCalibrationValid = EFalse;
        } else {
            // Check the validity of the readings
            G_mmTestModeTouchscreenCalibrationValid = ETrue;
            for (i=0; i<5; i++) {
                if ((readings[i].iX < G_expectedReadings[i].iX-READING_X_TOLERANCE) ||
                        (readings[i].iX > G_expectedReadings[i].iX+READING_X_TOLERANCE)) {
                    // Outside along X
                    G_mmTestModeTouchscreenCalibrationValid = EFalse;
                    break;
                }
                if ((readings[i].iY < G_expectedReadings[i].iY-READING_Y_TOLERANCE) ||
                        (readings[i].iY > G_expectedReadings[i].iY+READING_Y_TOLERANCE)) {
                    // Outside along Y
                    G_mmTestModeTouchscreenCalibrationValid = EFalse;
                    break;
                }
            }
        }

        NVSettingsSave();
        break;
    }
}
Example #4
0
int GUI_X_GetTime(void) {
  return UEZTickCounterGet();
}
/*---------------------------------------------------------------------------*
 * Routine:  Accelerometer_Freescale_MMA7455_I2C_ReadXYZ
 *---------------------------------------------------------------------------*
 * Description:
 *      Try to get the XYZ reading of the accelerometer
 * Inputs:
 *      void *aW                    -- Workspace
 *      AccelerometerReading *aReading -- Place to store reading
 *      TUInt32 aTimeout            -- Time to wait until reading is ready
 * Outputs:
 *      T_uezError                  -- Error code, UEZ_ERROR_TIMEOUT if no
 *                                      reading.
 *---------------------------------------------------------------------------*/
T_uezError Accelerometer_Freescale_MMA7455_I2C_ReadXYZ(
        void *aWorkspace,
        AccelerometerReading *aReading,
        TUInt32 aTimeout)
{
    TUInt8 status;
    T_uezError error;
    T_Accelerometer_Freescale_MMA7455_I2C_Workspace *p =
            (T_Accelerometer_Freescale_MMA7455_I2C_Workspace *)aWorkspace;
    TUInt8 accdata[0x20];
    TUInt32 start;
    TBool success = EFalse;

    aReading->iX = 0;
    aReading->iY = 0;
    aReading->iZ = 0;

    // Allow only one transfer at a time
    error = UEZSemaphoreGrab(p->iSem, aTimeout);
    if (error)
        return error;

    // A reading is available every 4 ms
    start = UEZTickCounterGet();
    while (UEZTickCounterGetDelta(start) < 10) { // try up to 10 ms
        memset(accdata, 0xCC, sizeof(accdata));
        error = IReadData(p, accdata + Freescale_MMA7455_REG_STATUS, 0x00, 1,
                100);
        if (!error) {
            status = accdata[Freescale_MMA7455_REG_STATUS];
            if (status & Freescale_MMA7455_STATUS_DRDY) {
                error = IReadData(p, accdata, 0x00, 9, 100);
                if (!error) {
#if (FREESCALE_MMA7455_G_MODE==8)
#if 0
                    printf("x:%02X%02X y:%02X%02X z:%02X%02X\r\n",
                            accdata[Freescale_MMA7455_REG_XOUT10_MSB],
                            accdata[Freescale_MMA7455_REG_XOUT10_LSB],
                            accdata[Freescale_MMA7455_REG_YOUT10_MSB],
                            accdata[Freescale_MMA7455_REG_YOUT10_LSB],
                            accdata[Freescale_MMA7455_REG_ZOUT10_MSB],
                            accdata[Freescale_MMA7455_REG_ZOUT10_LSB]);
#endif												
                    aReading->iX = ICalc10Bit8G(
                            accdata[Freescale_MMA7455_REG_XOUT10_MSB],
                            accdata[Freescale_MMA7455_REG_XOUT10_LSB]);
                    aReading->iY = ICalc10Bit8G(
                            accdata[Freescale_MMA7455_REG_YOUT10_MSB],
                            accdata[Freescale_MMA7455_REG_YOUT10_LSB]);
                    aReading->iZ = ICalc10Bit8G(
                            accdata[Freescale_MMA7455_REG_ZOUT10_MSB],
                            accdata[Freescale_MMA7455_REG_ZOUT10_LSB]);
#elif (FREESCALE_MMA7455_G_MODE==2)
                    aReading->iX = ICalc8Bit2G(
                            accdata[Freescale_MMA7455_REG_XOUT8]);
                    aReading->iY = ICalc8Bit2G(
                            accdata[Freescale_MMA7455_REG_YOUT8]);
                    aReading->iZ = ICalc8Bit2G(
                            accdata[Freescale_MMA7455_REG_ZOUT8]);
#endif
                    p->iLastReading = *aReading;
                    success = ETrue;
                    break; // break if successful
                }
            }
        }
        // Let another task run awhile as we wait for a response
        UEZTaskDelay(1);
    }
    if (!success) {
        // Go with the last reading
        *aReading = p->iLastReading;
    }
    UEZSemaphoreRelease(p->iSem);

    return error;
}
Example #6
0
void TimeDateMode(const T_choice *aChoice)
{
    T_uezDevice ts;
    static T_uezQueue queue = NULL;
    const T_choice *p_choice;
    static T_timeDateWorkspace *G_ws = NULL;
    TUInt32 timeLastTouch = UEZTickCounterGet();
    TBool lastShowButtons;
#if ENABLE_UEZ_BUTTON
    T_uezDevice keypadDevice;
#endif
#ifdef NO_DYNAMIC_MEMORY_ALLOC	
	if (NULL == G_ws)
	{
		G_ws = UEZMemAlloc(sizeof(*G_ws));
	}
#else
	G_ws = UEZMemAlloc(sizeof(*G_ws));
#endif
    if (!G_ws)
        return;
    memset(G_ws, 0, sizeof(*G_ws));
    G_ws->iExit = EFalse;
    G_ws->iField = 0; // none selected
    G_ws->iShowButtons = EFalse;
    lastShowButtons = EFalse;

#ifdef NO_DYNAMIC_MEMORY_ALLOC	
	if (NULL == queue)
	{
	  	if (UEZQueueCreate(1, sizeof(T_uezInputEvent), &queue) != UEZ_ERROR_NONE)
		{
		  	queue = NULL;
		}
	}
	
    if (NULL != queue) {
		/* Register the queue so that the IAR Stateviewer Plugin knows about it. */
	  	UEZQueueAddToRegistry( queue, "TimeDate TS" );	
#else
	if (UEZQueueCreate(1, sizeof(T_uezInputEvent), &queue) == UEZ_ERROR_NONE) {
#if UEZ_REGISTER
        UEZQueueSetName(queue, "TimeDate", "\0");
#endif

#endif
#if ENABLE_UEZ_BUTTON
        UEZKeypadOpen("BBKeypad", &keypadDevice, &queue);
#endif
        // Open up the touchscreen and pass in the queue to receive events
        if (UEZTSOpen("Touchscreen", &ts, &queue)==UEZ_ERROR_NONE)  {
            // Open the LCD and get the pixel buffer
            if (UEZLCDOpen("LCD", &G_ws->iLCD) == UEZ_ERROR_NONE)  {
                // Put the draw screen up
                TDMScreen(G_ws);

                // Sit here in a loop until we are done
                while (!G_ws->iExit) {
                    // Do choices and updates
                    p_choice = ChoicesUpdate(&G_ws->iWin, G_ws->iChoices, queue, 500);
                    if (G_ws->iShowButtons) {
                        if (p_choice) {
                            // Reset time since last touch
                            timeLastTouch = UEZTickCounterGet();
                        } else {
                            if (UEZTickCounterGetDelta(timeLastTouch) >= 3000) {
                                // Timed out, turn off buttons and redraw
                                G_ws->iShowButtons = EFalse;
                                G_ws->iField = 0;
                            }
                        }
                    }
                    if (lastShowButtons != G_ws->iShowButtons) {
                        TDMScreen(G_ws);
                        lastShowButtons = G_ws->iShowButtons;
                    }
                    TDMUpdate(G_ws);
                }
                UEZLCDClose(G_ws->iLCD);
            }
            UEZTSClose(ts, queue);
        }
#if ENABLE_UEZ_BUTTON
        UEZKeypadClose(keypadDevice, &queue);
#endif
#ifndef NO_DYNAMIC_MEMORY_ALLOC	
	    UEZQueueDelete(queue);
#endif
    }
	/* <<< WHIS >>> Potential memory leak in FreeRTOS version as G_ws is not
	free'd. */
}
Example #7
0
/*---------------------------------------------------------------------------*
 * Routine:  TS_EXC7200_Poll
 *---------------------------------------------------------------------------*
 * Description:
 *      Take a reading from the TSC2406 and put in reading structure.
 * Inputs:
 *      void *aW                    -- Workspace
 *      T_uezTSReading *aReading     -- Pointer to final reading
 * Outputs:
 *      T_uezError                   -- Error code
 *---------------------------------------------------------------------------*/
T_uezError TS_EXC7200_Poll(void *aWorkspace, T_uezTSReading *aReading)
{
    T_EXC7200Workspace *p = (T_EXC7200Workspace *)aWorkspace;
    T_uezError error;
    I2C_Request r;
    T_uezDevice i2c0;
    TUInt8 dataIn[11];
    TUInt8 dataOut[5];
    TUInt32 Read = 0;
    TUInt32 x;
    TUInt32 y;
    static TBool loop = EFalse;
    TUInt32 start = UEZTickCounterGet();
    TUInt8 i;

    error = UEZI2COpen(p->iI2CBus, &i2c0);

    //while (UEZTickCounterGetDelta(start) < 2) {
    for(i = 0; i < 10; i++){
        // Try to grab the semaphore -- do we have new data?
        if (UEZSemaphoreGrab(p->iSemWaitForTouch, 0) == UEZ_ERROR_NONE) {
            // Got new data!
            Read = 1;
        } else {
            Read = 0;
        }

        if (Read == 0 && !loop) {
            aReading->iFlags = p->iLastTouch;
            aReading->iX = p->iLastX;
            aReading->iY = p->iLastY;

            TS_EXC7200_ApplyCalibration(p, (p->iLastX), (p->iLastY),
                    (TUInt32 *)&aReading->iX, (TUInt32 *)&aReading->iY);
            return UEZ_ERROR_NONE;
        } else {
//            dataOut[0] = 0x00;
//            error = UEZI2CWrite(i2c0,
//                    EXC7200_I2C_ADDRESS,
//                    EXC7200_I2C_SPEED,
//                    dataOut,
//                    1,
//                    50);

            memset((void*)dataIn, 0, sizeof(dataIn));
            error = UEZI2CRead(i2c0, EXC7200_I2C_ADDRESS, EXC7200_I2C_SPEED,
                    dataIn, 0x0A, 50);

            x = (((dataIn[3] & 0xFF) << 8) | dataIn[2]) / 51;

            y = (((dataIn[5] & 0xFF) << 8) | dataIn[4]) / 70;

            if ((dataIn[1] & 0x81) == 0x81 && (dataIn[0] == 0x04) && ((dataIn[1] & 0x7C) == 0)) {
                loop = ETrue;
                (aReading->iFlags) = (p->iLastTouch) = TSFLAG_PEN_DOWN;
                (aReading->iX) = (p->iLastX) = x;
                (aReading->iY) = (p->iLastY) = y;
                if ((!p->iIsCalibrating) && (p->iHaveCalibration)) {
                    // Convert X & Y coordinates
                    TS_EXC7200_ApplyCalibration(p, x, y,
                            (TUInt32 *)&aReading->iX, (TUInt32 *)&aReading->iY);
                }
            } else if (((dataIn[1] & 0x81) == 0x80) && (dataIn[0] == 0x04) && ((dataIn[1] & 0x7C) == 0)) {
                (aReading->iFlags) = (p->iLastTouch) = 0;
                (aReading->iX) = (p->iLastX);
                (aReading->iY) = (p->iLastY);
                UEZGPIOClearIRQ(p->iInteruptPin);
            } else { //if ((dataIn[3] & 0xC0) == 0x40){
                (aReading->iFlags) = (p->iLastTouch);
                (aReading->iX) = (p->iLastX);
                (aReading->iY) = (p->iLastY);

                TS_EXC7200_ApplyCalibration(p, (p->iLastX), (p->iLastY),
                        (TUInt32 *)&aReading->iX, (TUInt32 *)&aReading->iY);
            }

            if (!UEZGPIORead(p->iInteruptPin)) {
                loop = ETrue;
            } else {
                loop = EFalse;
                break;
            }

            if (((dataIn[1] & 0x81) == 0x80) && (dataIn[0] == 0x04)) {
              i = i + 1;
              i = i -1;
                break;
            }
        }
#if 0
        TUInt32 count = 0;
        while (!UEZGPIORead(p->iInteruptPin)) {
            error = UEZI2CRead(i2c0,
                    EXC7200_I2C_ADDRESS,
                    EXC7200_I2C_SPEED,
                    dataIn,
                    0x0A,
                    50);
            count++;
        }
#endif

    }
    return error;
}
/*---------------------------------------------------------------------------*
 * Routine:  ChoicesUpdateByReading
 *---------------------------------------------------------------------------*
 * Description:
 *      An input event has been received.  Check the event and change
 *      the state of the choices.
 * Inputs:
 *      SWIM_WINDOW_T *aWin         -- Window to draw within
 *      const T_choice *aChoices    -- Choices to use
 *      T_uezQueue aTouchQueue      -- Touchscreen queue
 *      TUInt32 aTimeout            -- Time to wait for touchscreen event
 * Outputs:
 *      const T_choice *            -- Last choice selected or 0 for none.
 *---------------------------------------------------------------------------*/
const T_choice *ChoicesUpdateByReading(
    SWIM_WINDOW_T *aWin,
    const T_choice *aChoices,
    T_uezInputEvent *p_inputEvent)
{
    INT_32 winX, winY;
    static TUInt16 lastX = 0, lastY = 0;
    static const T_choice *p_lastChoice = 0;
    static const T_choice *p_buttonChoice = 0;
    static const T_choice *p_nextButtonChoice = 0;
    const T_choice *p_choice = 0;
    const T_choice *p_choiceCalled = 0;

    winX = p_inputEvent->iEvent.iXY.iX;
    winY = p_inputEvent->iEvent.iXY.iY;
    swim_get_virtual_xy(aWin, &winX, &winY);

    // Is this a touching event?
    if(p_inputEvent->iType == INPUT_EVENT_TYPE_XY) {
        // Is this a press or hold event?
        if (p_inputEvent->iEvent.iXY.iAction == XY_ACTION_PRESS_AND_HOLD) {
            // We are touching the screen.
            // Is this a different position than before?
            if ((p_inputEvent->iEvent.iXY.iX != lastX) || (p_inputEvent->iEvent.iXY.iY != lastY)) {
                // Determine which choice we are in
                p_choice = IFindChoice(aChoices, winX, winY);
                if (p_choice != p_lastChoice) {
    #if HAPTIC_FEEDBACK              
                    hapticFeedback(DEFAULT_HAPTIC_TIME_MS);
    #endif                
                    if (p_lastChoice) {
                        // Un-invert the last choice 
                        swim_set_fill_color(aWin, G_settings.iUnselectColor);
                        swim_set_pen_color(aWin, G_settings.iUnselectColor);
                        swim_set_fill_transparent(aWin, 1);
                        swim_put_box(aWin, p_lastChoice->iLeft, p_lastChoice->iTop,
                            p_lastChoice->iRight, p_lastChoice->iBottom);
                        swim_set_fill_transparent(aWin, 0);
                    }
    
                    // Turn off button repeating when we leave focus
                    G_repeatOn = EFalse;
                    if (p_choice) {
                        // Invert the new choice
                        swim_set_pen_color(aWin, G_settings.iSelectColor);
                        swim_set_fill_transparent(aWin, 1);
                        swim_put_box(aWin, p_choice->iLeft, p_choice->iTop,
                            p_choice->iRight, p_choice->iBottom);
                        swim_set_fill_transparent(aWin, 0);
    
                        // If the option we are over is repeating,
                        // turn on repeating.
                        if (p_choice->iFlags & SUI_FLAG_REPEAT)
                            G_repeatOn = ETrue;
                    }
                    p_lastChoice = p_choice;
                    p_choice = 0;
                }
            }
    
            // Are we allowed to repeat?
            if (G_repeatOn) {
                if (!G_repeating) {
                    G_repeating = ETrue;
                    G_repeatLastTouch = UEZTickCounterGet();
                    G_repeatTime = REPEAT_TIME_1; // first repeat is slow
                } else {
                    // Time to repeat?
                    if (UEZTickCounterGetDelta(G_repeatLastTouch) >= G_repeatTime) {
                        if (G_repeatTime == REPEAT_TIME_1)
                            G_repeatTime = REPEAT_TIME_2;
                        else if (G_repeatTime == REPEAT_TIME_2)
                            G_repeatTime = REPEAT_TIME_3;
                        G_repeatLastTouch = UEZTickCounterGet();
    
                        // Cause a repeat by signalling a non-touch event below
                        //p_reading->iFlags &= ~TSFLAG_PEN_DOWN;
                    }
                }
            }
        } else {
            // Really not touching?
            // Are we repeating?
            if (G_repeating) {
                // Stop that.
                G_repeating = EFalse;
            }
        }
    
        // Release event (real for faked above?)
        if (p_inputEvent->iEvent.iXY.iAction == XY_ACTION_RELEASE) {
            // The screen is no longer being touched.
            // Determine which choice we are in
            p_choice = p_lastChoice;
            if (p_choice) {
                // Same as when we pressed
                // Do the action
                if (p_choice->iAction) {
                    const T_choice *p_prevChoice = p_lastChoice;
                    p_lastChoice = 0;
                    p_choiceCalled = p_choice;
                    // Un-invert the last choice
                    swim_set_fill_transparent(aWin, 1);
                    swim_set_pen_color(aWin, G_settings.iUnselectColor);
                    swim_put_box(aWin, p_prevChoice->iLeft, p_prevChoice->iTop,
                        p_prevChoice->iRight, p_prevChoice->iBottom);
                    swim_set_fill_transparent(aWin, 0);
    
                    p_choice->iAction(p_choice);
    
                    p_lastChoice = 0;
                }
            }
        }
    } else {
        
        
        // This is a button event
        if(p_inputEvent->iEvent.iButton.iAction == BUTTON_ACTION_PRESS) {
            
            if(p_buttonChoice == 0){
                p_buttonChoice = IFindChoiceTopLeft(aChoices);
            } else {
                // Un-invert the last choice 
                swim_set_fill_color(aWin, G_settings.iUnselectColor);
                swim_set_pen_color(aWin, G_settings.iUnselectColor);
                swim_set_fill_transparent(aWin, 1);
                swim_put_box(aWin, p_buttonChoice->iLeft, p_buttonChoice->iTop,
                    p_buttonChoice->iRight, p_buttonChoice->iBottom);
                swim_set_fill_transparent(aWin, 0);
                
                if(p_inputEvent->iEvent.iButton.iKey == KEY_ARROW_RIGHT) {
                    p_nextButtonChoice = IFindChoiceRight(aChoices, p_buttonChoice, 2);
                    if(p_nextButtonChoice == p_buttonChoice)
                        p_buttonChoice = IFindChoiceRight(aChoices, p_buttonChoice, 1);
                    else
                        p_buttonChoice = p_nextButtonChoice;
                } else if(p_inputEvent->iEvent.iButton.iKey == KEY_ARROW_LEFT) {
                    p_nextButtonChoice = IFindChoiceLeft(aChoices, p_buttonChoice, 2);
                    if(p_nextButtonChoice == p_buttonChoice)
                        p_buttonChoice = IFindChoiceLeft(aChoices, p_buttonChoice, 1);
                    else
                        p_buttonChoice = p_nextButtonChoice;
                } else if(p_inputEvent->iEvent.iButton.iKey == KEY_ARROW_UP) {
                    p_nextButtonChoice = IFindChoiceUp(aChoices, p_buttonChoice, 2);
                    if(p_nextButtonChoice == p_buttonChoice)
                        p_buttonChoice = IFindChoiceUp(aChoices, p_buttonChoice, 1);
                    else
                        p_buttonChoice = p_nextButtonChoice;
                } else if(p_inputEvent->iEvent.iButton.iKey == KEY_ARROW_DOWN) {
                    p_nextButtonChoice = IFindChoiceDown(aChoices, p_buttonChoice, 2);
                    if(p_nextButtonChoice == p_buttonChoice)
                        p_buttonChoice = IFindChoiceDown(aChoices, p_buttonChoice, 1);
                    else
                        p_buttonChoice = p_nextButtonChoice;
                } else if(p_inputEvent->iEvent.iButton.iKey == KEY_ENTER) {
                    p_choice = p_buttonChoice;
                    p_buttonChoice = 0;
                    p_choiceCalled = p_choice;
                    p_choice->iAction(p_choice);
                }

            }
            
            // Invert the new choice
            swim_set_pen_color(aWin, G_settings.iSelectColor);
            swim_set_fill_transparent(aWin, 1);
            swim_put_box(aWin, p_buttonChoice->iLeft, p_buttonChoice->iTop,
                p_buttonChoice->iRight, p_buttonChoice->iBottom);
            swim_set_fill_transparent(aWin, 0);
            
        } else /* BUTTON_ACTION_RELEASE */{
        }
    }
    return p_choiceCalled;
}