/*---------------------------------------------------------------------------* * 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 }
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))
/*---------------------------------------------------------------------------* * 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; } }
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; }
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. */ }
/*---------------------------------------------------------------------------* * 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; }