navienginebsp/ne1_tb/specific/xyin.cpp
changeset 0 5de814552237
equal deleted inserted replaced
-1:000000000000 0:5de814552237
       
     1 /*
       
     2 * Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 * ne1_tb\Specific\xyin.cpp
       
    16 * Implementation of a digitiser (touch-screen) driver.
       
    17 * This code assumes that an interrupt is generated on pen-down and pen-up events.
       
    18 * This file is part of the NE1_TBVariant Base port
       
    19 * We use this driver to exemplify the usage of Resource Management for shared resources, Peripheral "Sleep"
       
    20 * and detection and notification of Wakeup events
       
    21 *
       
    22 */
       
    23 
       
    24 
       
    25 
       
    26 
       
    27 #include <assp.h>
       
    28 #include <naviengine.h>
       
    29 #include <videodriver.h>
       
    30 #include "mconf.h"
       
    31 #include <xyin.h>
       
    32 #include "lcdgce.h"
       
    33 
       
    34 #ifdef USE_PEN_INTERRUPTS
       
    35 #include <gpio.h>
       
    36 const TUint KLcdInterruptPin = 22;
       
    37 #else
       
    38 const TUint KPenEventsPollTime = 30;
       
    39 #endif
       
    40 
       
    41 // digitiser origin & size in pixels
       
    42 const TUint	KConfigXyOffsetX	= 0;		// digitiser origin - same as display area
       
    43 const TUint	KConfigXyOffsetY	= 0;
       
    44 
       
    45 // digitiser dimensions in digitiser co-ordinates
       
    46 const TInt      KConfigXySpreadX = 3600; // maximum valid X spread
       
    47 const TInt      KConfigXySpreadY = 3600; // maximum valid Y spread
       
    48 const TInt		KConfigXyMinX    = 450;  // minimum valid X value
       
    49 const TInt		KConfigXyMinY    = 450;  // minimum valid Y value
       
    50 const TUint		KXYShift         = 4100;
       
    51 
       
    52 const TInt KDigitiserThreadPriority = 26;
       
    53 _LIT(KDigitiserDriverThreadName,"DigitizerThread");
       
    54 
       
    55 // Define a 2x2 matrix and two constants Tx and Ty to convert digitiser co-ordinates
       
    56 // to pixels such that
       
    57 //
       
    58 // (X<<16 Y<<16)	=	(x y)	x	(R11 R12)	+	(Tx Ty)
       
    59 //									(R21 R22)
       
    60 // or :
       
    61 //
       
    62 // X = (x*R11 + y*R21 + TX) >> 16;
       
    63 // Y = (x*R12 + y*R22 + TY) >> 16;
       
    64 
       
    65 //
       
    66 // where x,y are digitiser coordinates, Tx,Ty are constant offsets and X,Y are screen
       
    67 // coordinates. Left shifting by 16 bits is used so as not to lose precision.
       
    68 
       
    69 // After taking a sample, wait for the specified number of nano-kernel ticks (normally 1 ms)
       
    70 // before taking the next sample
       
    71 const TInt		KInterSampleTime	= 1;
       
    72 
       
    73 // After a group of samples has been processed by the DDigitiser::ProcessRawSample() DFC,
       
    74 // wait for the specified number of nano-kernel ticks before taking the next sample
       
    75 const TInt		KInterGroupTime		= 1;
       
    76 
       
    77 // After a pen-down interrupt,
       
    78 // wait for the specified number of nano-kernel ticks before taking the next sample
       
    79 const TInt		KPenDownDelayTime	= 2;
       
    80 
       
    81 // If powering up the device with the pen down,
       
    82 // wait for the specified number of nano-kernel ticks before taking the next sample
       
    83 const TInt		KPenUpPollTime		= 30;
       
    84 
       
    85 // After a pen-up interrupt,
       
    86 // wait for the specified number of nano-kernel ticks before calling PenUp()
       
    87 const TInt		KPenUpDebounceTime	= 10;
       
    88 
       
    89 // number of samples to discard on pen-down
       
    90 const TInt		KConfigXyPenDownDiscard	= 1;
       
    91 
       
    92 // number of samples to discard on pen-up
       
    93 const TInt		KConfigXyPenUpDiscard	= 1;
       
    94 
       
    95 // offset in pixels to cause movement in X direction
       
    96 const TInt		KConfigXyAccThresholdX	= 12;
       
    97 
       
    98 // offset in pixels to cause movement in Y direction
       
    99 const TInt		KConfigXyAccThresholdY	= 12;
       
   100 
       
   101 // number of samples to average - MUST be <= KMaxXYSamples
       
   102 const TInt		KConfigXyNumXYSamples	= 4;
       
   103 
       
   104 // disregard extremal values in each 4-sample group
       
   105 const TBool		KConfigXyDisregardMinMax= ETrue;  //EFalse;
       
   106 
       
   107 // Registers..
       
   108 const TUint KHwPenInterruptRegister = KHwFPGABase + 0x0408; // LCD penInterrupt register
       
   109 const TUint KHwTSPStart             = KHwFPGABase + 0x0608; // TSP Control Register..
       
   110 const TUint KHwTSPXData             = KHwFPGABase + 0x0610; // TSP X Data Register..
       
   111 const TUint KHwTSPYData             = KHwFPGABase + 0x0618; // TSP Y Data Register..
       
   112 
       
   113 // obsolete constants :
       
   114 const TInt KConfigXyDriveXRise = 0;
       
   115 const TInt KConfigXyDriveYRise = 0;
       
   116 const TInt KConfigXyMaxJumpX   = 0;
       
   117 const TInt KConfigXyMaxJumpY   = 0;
       
   118 
       
   119 
       
   120 struct SConfig
       
   121 	{
       
   122 	TUint iConfigXyWidth;
       
   123 	TUint iConfigXyHeight;
       
   124 	TBool iLandscape;
       
   125 
       
   126 	// Calibration Values
       
   127 	TInt iConfigXyR11;
       
   128 	TInt iConfigXyR12;
       
   129 	TInt iConfigXyR21;
       
   130 	TInt iConfigXyR22;
       
   131 	TInt iConfigXyTx;
       
   132 	TInt iConfigXyTy;
       
   133 	};
       
   134 
       
   135 enum TTouchScreenMode
       
   136 	{
       
   137 	TOUCHSCREEN_MODE_NEC_WVGA     = 0,
       
   138 	TOUCHSCREEN_MODE_HITACHI_VGA,
       
   139 	TOUCHSCREEN_MODE_HITACHI_QVGA,
       
   140 
       
   141 	TOUCHSCREEN_MODE_NONE = 255,
       
   142 	};
       
   143 
       
   144 static const SConfig Mode_Config[]=
       
   145 	{
       
   146 	// NEC WVGA - default mode
       
   147 		{
       
   148 		800,
       
   149 		480,
       
   150 		ETrue,
       
   151 
       
   152 		// Calibration values; these are set manually using the TechView calibration app
       
   153 		17722,      // R11
       
   154 		1239,       // R12
       
   155 		399,        // R21
       
   156 		12352,      // R22
       
   157 		-11623449,  // Tx
       
   158 		-10468471,  // Ty
       
   159 		},
       
   160 
       
   161 
       
   162 	// LCD, Portrait VGA
       
   163 		{
       
   164 		480,
       
   165 		640,
       
   166 		EFalse,
       
   167 
       
   168 		// Calibration values; these are set manually using the TechView calibration app
       
   169 		11346,      // R11
       
   170 		538,        // R12
       
   171 		-682,       // R21
       
   172 		14703,      // R22
       
   173 		-5683258,   // Tx
       
   174 		-9913475,   // Ty
       
   175 		},
       
   176 
       
   177 	// LCD, Portrait QVGA
       
   178 		{
       
   179 		240,
       
   180 		320,
       
   181 		EFalse,
       
   182 
       
   183 		// Calibration values; these are set manually using the TechView calibration app
       
   184 		5873,		//iConfigXyR11;
       
   185 		651,		//iConfigXyR12;
       
   186 		-250,		//iConfigXyR21;
       
   187 		7366,		//iConfigXyR22;
       
   188 		-3591097,	//iConfigXyTx;
       
   189 		-5181791,	//iConfigXyTy;
       
   190 		},
       
   191 	};
       
   192 
       
   193 
       
   194 /******************************************************
       
   195  * Main Digitiser Class
       
   196  ******************************************************/
       
   197 NONSHARABLE_CLASS(DNE1_TBDigitiser) : public DDigitiser
       
   198 	{
       
   199 public:
       
   200 	enum TState
       
   201 		{
       
   202 		E_HW_PowerUp,
       
   203 		E_HW_PenUpDebounce,
       
   204 		E_HW_CollectSample
       
   205 		};
       
   206 
       
   207 public:
       
   208 	// from DDigitiser - initialisation
       
   209 	DNE1_TBDigitiser();
       
   210 	virtual TInt DoCreate();
       
   211 	void SetDefaultConfig();
       
   212 
       
   213 	// from DDigitiser - signals to hardware-dependent code
       
   214 	virtual void WaitForPenDown();
       
   215 	virtual void WaitForPenUp();
       
   216 	virtual void WaitForPenUpDebounce();
       
   217 	virtual void DigitiserOn();
       
   218 	virtual void DigitiserOff();
       
   219 	virtual void FilterPenMove(const TPoint& aPoint);
       
   220 	virtual void ResetPenMoveFilter();
       
   221 
       
   222 	// from DDigitiser - machine-configuration related things
       
   223 	virtual TInt DigitiserToScreen(const TPoint& aDigitiserPoint, TPoint& aScreenPoint);
       
   224 	virtual void ScreenToDigitiser(TInt& aX, TInt& aY);
       
   225 	virtual TInt SetXYInputCalibration(const TDigitizerCalibration& aCalibration);
       
   226 	virtual TInt CalibrationPoints(TDigitizerCalibration& aCalibration);
       
   227 	virtual TInt SaveXYInputCalibration();
       
   228 	virtual TInt RestoreXYInputCalibration(TDigitizerCalibrationType aType);
       
   229 	virtual void DigitiserInfo(TDigitiserInfoV01& aInfo);
       
   230 
       
   231 	// from DPowerHandler
       
   232 	virtual void PowerDown(TPowerState);
       
   233 	virtual void PowerUp();
       
   234 
       
   235 	// implementation
       
   236 	void TakeSample();
       
   237 	void PenInterrupt();
       
   238 	void DigitiserPowerUp();
       
   239 	void PowerUpDfc();
       
   240 
       
   241 	// callbacks
       
   242 	static void TimerExpired(TAny* aPtr);
       
   243 	static void TimerIntExpired(TAny* aPtr);
       
   244 	static void PenIsr(TAny* aPtr);
       
   245 	static void TakeReading(TAny* aPtr);
       
   246 	static void PowerDown(TAny* aPtr);
       
   247 	static void PowerUp(TAny* aPtr);
       
   248 
       
   249 private:
       
   250 	NTimer iTimer;
       
   251 	NTimer iTimerInt;
       
   252 	TDfc   iTakeReadingDfc;
       
   253 	TDfc   iPowerDownDfc;
       
   254 	TDfc   iPowerUpDfc;
       
   255 	TInt   iSamplesCount;
       
   256 	TState iState;
       
   257 	TUint8 iPoweringDown;
       
   258 	TSize  iScreenSize;
       
   259 #ifndef USE_PEN_INTERRUPTS
       
   260 	NTimer iPollingTimer;
       
   261 #endif
       
   262 	TActualMachineConfig& iMachineConfig;
       
   263 	TTouchScreenMode      iCurrentMode;
       
   264 	TInt                  iInterruptId;
       
   265 	};
       
   266 
       
   267 /******************************************************
       
   268  * Digitiser main code
       
   269  ******************************************************/
       
   270 /**
       
   271 Sample timer callback
       
   272 Schedules a DFC to take a sample
       
   273 
       
   274 @param aPtr	a pointer to DNE1_TBDigitiser
       
   275 */
       
   276 void DNE1_TBDigitiser::TimerExpired(TAny* aPtr)
       
   277 	{
       
   278 	DNE1_TBDigitiser* pD=(DNE1_TBDigitiser*)aPtr;
       
   279 	__KTRACE_OPT(KHARDWARE, Kern::Printf("TimerExpired"));
       
   280 	pD->iTakeReadingDfc.Add();
       
   281 	}
       
   282 
       
   283 /**
       
   284 Debounce timer callback
       
   285 schedules a DFC to process a pen-down interrupt
       
   286 
       
   287 @param aPtr	a pointer to DNE1_TBDigitiser
       
   288 */
       
   289 void DNE1_TBDigitiser::TimerIntExpired(TAny* aPtr)
       
   290 	{
       
   291 	DNE1_TBDigitiser* pD=(DNE1_TBDigitiser*)aPtr;
       
   292 	__KTRACE_OPT(KHARDWARE, Kern::Printf("TIntExpired"));
       
   293 	pD->iTakeReadingDfc.Add();
       
   294 	}
       
   295 
       
   296 /**
       
   297 Pen-up/down interrupt handler
       
   298 
       
   299 @param aPtr	a pointer to DNE1_TBDigitiser
       
   300 */
       
   301 void DNE1_TBDigitiser::PenIsr(TAny* aPtr)
       
   302 	{
       
   303 	DNE1_TBDigitiser* pD=(DNE1_TBDigitiser*)aPtr;
       
   304 
       
   305 	//check the status of the interrupt:
       
   306 	TUint16 status = AsspRegister::Read16(KHwPenInterruptRegister);
       
   307 
       
   308 	if (!(status & 0x100)) // Pen is down..
       
   309 		{
       
   310 #ifdef USE_PEN_INTERRUPTS
       
   311 		GPIO::DisableInterrupt(pD->iInterruptId);
       
   312 #endif
       
   313 		pD->PenInterrupt();
       
   314 		}
       
   315 
       
   316 #ifndef USE_PEN_INTERRUPTS
       
   317 		// kick-off the timer again..
       
   318 		pD->iPollingTimer.Again(KPenEventsPollTime);
       
   319 #endif
       
   320 
       
   321 	}
       
   322 
       
   323 /**
       
   324 DFC for taking a sample
       
   325 
       
   326 @param aPtr	a pointer to DNE1_TBDigitiser
       
   327 */
       
   328 void DNE1_TBDigitiser::TakeReading(TAny* aPtr)
       
   329 	{
       
   330 	DNE1_TBDigitiser* pD=(DNE1_TBDigitiser*)aPtr;
       
   331 	pD->TakeSample();
       
   332 	}
       
   333 
       
   334 /**
       
   335 DFC for powering down the device
       
   336 
       
   337 @param aPtr	a pointer to DNE1_TBDigitiser
       
   338 */
       
   339 void DNE1_TBDigitiser::PowerDown(TAny* aPtr)
       
   340 	{
       
   341 	DNE1_TBDigitiser* pD=(DNE1_TBDigitiser*)aPtr;
       
   342 	pD->DigitiserOff();
       
   343 	}
       
   344 
       
   345 /**
       
   346 DFC for powering up the device
       
   347 
       
   348 @param aPtr	a pointer to DNE1_TBDigitiser
       
   349 */
       
   350 void DNE1_TBDigitiser::PowerUp(TAny* aPtr)
       
   351 	{
       
   352 	DNE1_TBDigitiser* pD=(DNE1_TBDigitiser*)aPtr;
       
   353 	pD->PowerUpDfc();
       
   354 	}
       
   355 
       
   356 
       
   357 /**
       
   358 Creates a new instance of DDigitiser.
       
   359 Called by extension entry point (PIL) to create a DDigitiser-derived object.
       
   360 
       
   361 @return	a pointer to a DNE1_TBDigitiser object
       
   362 */
       
   363 DDigitiser* DDigitiser::New()
       
   364 	{
       
   365 	return new DNE1_TBDigitiser;
       
   366 	}
       
   367 
       
   368 /**
       
   369 Default constructor
       
   370 */
       
   371 DNE1_TBDigitiser::DNE1_TBDigitiser() :
       
   372 		iTimer(TimerExpired,this),
       
   373 		iTimerInt(TimerIntExpired,this),
       
   374 		iTakeReadingDfc(TakeReading,this,5),
       
   375 		iPowerDownDfc(PowerDown,this,5),
       
   376 		iPowerUpDfc(PowerUp,this,5),
       
   377 #ifndef USE_PEN_INTERRUPTS
       
   378 		iPollingTimer(PenIsr, this),
       
   379 #endif
       
   380 		iMachineConfig(TheActualMachineConfig())
       
   381 	{
       
   382 	}
       
   383 
       
   384 /**
       
   385 Perform hardware-dependent initialisation
       
   386 
       
   387 Called by platform independent layer
       
   388 */
       
   389 TInt DNE1_TBDigitiser::DoCreate()
       
   390 	{
       
   391 	__KTRACE_OPT(KEXTENSION,Kern::Printf("DNE1_TBDigitiser::DoCreate"));
       
   392 	if (Kern::ColdStart())
       
   393 		{
       
   394 		__KTRACE_OPT(KEXTENSION,Kern::Printf("Resetting digitiser calibration"));
       
   395 
       
   396 		// Emergency digitiser calibration values
       
   397 		TInt mode = ReadDipSwitchDisplayMode();
       
   398 		switch (mode)
       
   399 			{
       
   400 			case DISPLAY_MODE_HITACHI_VGA: // Hitachi display in VGA
       
   401 				iCurrentMode = TOUCHSCREEN_MODE_HITACHI_VGA;
       
   402 				break;
       
   403 			case DISPLAY_MODE_HITACHI_QVGA: // Hitachi display in QVGA
       
   404 				iCurrentMode = TOUCHSCREEN_MODE_HITACHI_QVGA;
       
   405 				break;
       
   406 			case DISPLAY_MODE_NEC_WVGA:	// NEC display in WVGA
       
   407 				iCurrentMode = TOUCHSCREEN_MODE_NEC_WVGA;
       
   408 				break;
       
   409 
       
   410 			// In all ANALOG modes - don't use the digitiser
       
   411 			case DISPLAY_MODE_ANALOG_VGA:
       
   412 			case DISPLAY_MODE_ANALOG_QVGA_LANDSCAPE_OLD:
       
   413 			case DISPLAY_MODE_ANALOG_QVGA_PORTRAIT:
       
   414 			case DISPLAY_MODE_ANALOG_QVGA_LANDSCAPE:
       
   415 				iCurrentMode = TOUCHSCREEN_MODE_NONE;
       
   416 				break;
       
   417 
       
   418 			default:    // In all other modes, use the NEC WVGA settings
       
   419 				iCurrentMode = TOUCHSCREEN_MODE_NEC_WVGA;
       
   420 				break;
       
   421 
       
   422 			}
       
   423 		iMachineConfig.iCalibration.iR11 = Mode_Config[iCurrentMode].iConfigXyR11;
       
   424 		iMachineConfig.iCalibration.iR12 = Mode_Config[iCurrentMode].iConfigXyR12;
       
   425 		iMachineConfig.iCalibration.iR21 = Mode_Config[iCurrentMode].iConfigXyR21;
       
   426 		iMachineConfig.iCalibration.iR22 = Mode_Config[iCurrentMode].iConfigXyR22;
       
   427 		iMachineConfig.iCalibration.iTx  = Mode_Config[iCurrentMode].iConfigXyTx;
       
   428 		iMachineConfig.iCalibration.iTy  = Mode_Config[iCurrentMode].iConfigXyTy;
       
   429 		}
       
   430 
       
   431 	TDynamicDfcQue* dfcq;
       
   432 	// Create a dedicated DFC queue for this driver
       
   433 	TInt r = Kern::DynamicDfcQCreate(dfcq, KDigitiserThreadPriority, KDigitiserDriverThreadName);
       
   434 	if (r != KErrNone)
       
   435 		{
       
   436 		__KTRACE_OPT(KEXTENSION,Kern::Printf("Could not create a DFCQue, r %d", r));
       
   437 		return r;
       
   438 		}
       
   439 
       
   440 #ifdef CPU_AFFINITY_ANY
       
   441 	NKern::ThreadSetCpuAffinity((NThread*)(iDfcQ->iThread), KCpuAffinityAny);
       
   442 #endif
       
   443 
       
   444 	// and DFCs to use it..
       
   445 	iDfcQ = dfcq;
       
   446 	iTakeReadingDfc.SetDfcQ(iDfcQ);
       
   447 	iPowerDownDfc.SetDfcQ(iDfcQ);
       
   448 	iPowerUpDfc.SetDfcQ(iDfcQ);
       
   449 
       
   450 
       
   451 	// stop at this point, if the LCD panel is not present
       
   452 	if (iCurrentMode == TOUCHSCREEN_MODE_NONE)
       
   453 		{
       
   454 		__KTRACE_OPT(KEXTENSION,Kern::Printf("xyin.cpp: LCD panel not switched on...\nwill not start the driver"));
       
   455 		return KErrNone;
       
   456 		}
       
   457 
       
   458 	// register power handler
       
   459 	Add();
       
   460 	DigitiserPowerUp();
       
   461 
       
   462 #ifdef USE_PEN_INTERRUPTS
       
   463    // set up interrupts
       
   464 	iInterruptId = KLcdInterruptPin;
       
   465 	r = GPIO::BindInterrupt(iInterruptId, PenIsr, this);
       
   466 	if (r != KErrNone)
       
   467 		{
       
   468 		__KTRACE_OPT(KEXTENSION,Kern::Printf("Error binding the interrupt: r %d", r));
       
   469 		return r;
       
   470 		}
       
   471 #endif
       
   472 
       
   473 	// set up the default configuration
       
   474 	SetDefaultConfig();
       
   475 
       
   476 	return KErrNone;
       
   477 	}
       
   478 
       
   479 /**
       
   480 Initialise the DDigitiser::iCfg structure
       
   481 */
       
   482 void DNE1_TBDigitiser::SetDefaultConfig()
       
   483 	{
       
   484 	iCfg.iPenDownDiscard  = KConfigXyPenDownDiscard;  // number of samples to discard on pen-down
       
   485 	iCfg.iPenUpDiscard    = KConfigXyPenUpDiscard;    // number of samples to discard on pen-up
       
   486 	iCfg.iDriveXRise      = KConfigXyDriveXRise;      // number of milliseconds to wait when driving horizontal edges
       
   487 	iCfg.iDriveYRise      = KConfigXyDriveYRise;      // number of milliseconds to wait when driving vertical edges
       
   488 	iCfg.iMinX            = KConfigXyMinX;            // minimum valid X value
       
   489 	iCfg.iMaxX            = KConfigXySpreadX - 1;     // maximum valid X value
       
   490 	iCfg.iSpreadX         = KConfigXySpreadX;         // maximum valid X spread
       
   491 	iCfg.iMinY            = KConfigXyMinY;            // minimum valid Y value
       
   492 	iCfg.iMaxY            = KConfigXySpreadY - 1;     // maximum valid Y value
       
   493 	iCfg.iSpreadY         = KConfigXySpreadY;         // maximum valid Y spread
       
   494 	iCfg.iMaxJumpX        = KConfigXyMaxJumpX;        // maximum X movement per sample (pixels)
       
   495 	iCfg.iMaxJumpY        = KConfigXyMaxJumpY;        // maximum Y movement per sample (pixels)
       
   496 	iCfg.iAccThresholdX   = KConfigXyAccThresholdX;   // offset in pixels to cause movement in X direction
       
   497 	iCfg.iAccThresholdY   = KConfigXyAccThresholdY;   // offset in pixels to cause movement in Y direction
       
   498 	iCfg.iNumXYSamples    = KConfigXyNumXYSamples;    // number of samples to average
       
   499 	iCfg.iDisregardMinMax = KConfigXyDisregardMinMax; // disregard extremal values in each 4-sample group
       
   500 	}
       
   501 
       
   502 /**
       
   503 Takes a sample from the digitiser.
       
   504 Called in the context of a DFC thread.
       
   505 */
       
   506 void DNE1_TBDigitiser::TakeSample()
       
   507 	{
       
   508 //	TNE1_TBPowerController::WakeupEvent();	// notify of pendown (wakeup event) and let the power controller sort
       
   509 												// out if it needs propagation
       
   510 	TBool penDown = EFalse;
       
   511 
       
   512     //check the touch panel interrupt state
       
   513     TUint16 status = AsspRegister::Read16(KHwPenInterruptRegister);
       
   514     if(!(status & 0x100))  //Panel touched
       
   515         penDown = ETrue;
       
   516 
       
   517 	__KTRACE_OPT(KHARDWARE,Kern::Printf("TS: S%d PD%d Sp%d", (TInt)iState, penDown?1:0, iSamplesCount));
       
   518 
       
   519 	if (iState==E_HW_PowerUp)
       
   520 		{
       
   521 		// waiting for pen to go up after switch on due to pen down or through the HAL
       
   522 		if (!penDown)		// pen has gone up -> transition to new state
       
   523 			{
       
   524 			iState=E_HW_CollectSample;
       
   525 			iSamplesCount=0;     // reset sample buffer
       
   526 #ifdef USE_PEN_INTERRUPTS
       
   527 			// clear and enable pen-down interrupt
       
   528 			GPIO::EnableInterrupt(iInterruptId);
       
   529 #endif
       
   530 			}
       
   531 		else	// pen is still down, wait a bit longer in this state
       
   532 			{
       
   533 			iTimer.OneShot(KPenUpPollTime);
       
   534 			}
       
   535 		return;
       
   536 		}
       
   537 
       
   538 	if (!penDown)
       
   539 		{
       
   540 		if (iState==E_HW_PenUpDebounce)
       
   541 			{
       
   542 			iState=E_HW_CollectSample;	// back to initial state, no samples collected
       
   543 			iSamplesCount=0;			// reset sample buffer
       
   544 			iPenUpDfc.Enque();
       
   545 			}
       
   546 		else							// iState=E_HW_CollectSample
       
   547 			{
       
   548 			iState=E_HW_PenUpDebounce;
       
   549 			iTimer.OneShot(KPenUpDebounceTime);		// wait a bit to make sure pen still up
       
   550 			}
       
   551 		return;
       
   552 		}
       
   553 	else if (iState==E_HW_PenUpDebounce)	// pen down
       
   554 		{
       
   555 		// false alarm - pen is down again
       
   556 		iState=E_HW_CollectSample;		// take a new set of samples
       
   557 		iSamplesCount=0;				// reset sample buffer
       
   558 		}
       
   559 	// default: pen down and iState=E_HW_CollectSample
       
   560 	// Read from appropriate hardware register to get the current digitiser coordinates
       
   561 	// of the point that is being touched
       
   562 
       
   563     //start A/D conversion
       
   564     AsspRegister::Write16(KHwTSPStart, 1);
       
   565 
       
   566     // and wait for its completion(0x1 bit should be cleared)
       
   567     TUint timeout=100;
       
   568     while((AsspRegister::Read16(KHwPenInterruptRegister)&0x1) && --timeout);
       
   569 
       
   570     // Read values (Reading will clear interrupt status)
       
   571     TInt16 X = AsspRegister::Read16(KHwTSPXData);
       
   572     TInt16 Y = AsspRegister::Read16(KHwTSPYData);
       
   573 
       
   574 	if(Mode_Config[iCurrentMode].iLandscape)
       
   575 		{
       
   576 		iX[iSamplesCount] = KXYShift - X;
       
   577 		iY[iSamplesCount] = Y;
       
   578 		}
       
   579 	else
       
   580 		{
       
   581 		iX[iSamplesCount] =  KXYShift - X;
       
   582 		iY[iSamplesCount] =  KXYShift - Y;
       
   583 		}
       
   584 
       
   585 	__KTRACE_OPT(KHARDWARE,Kern::Printf("Raw: X=%d Y=%d",iX[iSamplesCount],iY[iSamplesCount]));
       
   586 
       
   587 	// count samples collected - if it's less than minimum,
       
   588 	// schedule the reading of another sample
       
   589 	if (++iSamplesCount < iCfg.iNumXYSamples)	// iX[] and iY[] are 4 levels deep in xyin.h...
       
   590 		{
       
   591 		if(KInterSampleTime > 0)
       
   592 			{
       
   593 			iTimer.OneShot(KInterSampleTime);	// haven't got a complete group yet, so queue timer to sample again
       
   594 			}
       
   595 		else
       
   596 		    {
       
   597 		    iTakeReadingDfc.Enque();
       
   598 		    }
       
   599 		return;
       
   600 		}
       
   601 
       
   602 	// Have a complete group of samples so pass up to processing layer (PIL)
       
   603 	iSampleDfc.Enque(); // adds DFC
       
   604 
       
   605 	}
       
   606 
       
   607 /**
       
   608 Request for an interrupt to be generated when the pen is next down
       
   609 Called by PIL at startup or when pen leaves digitiser after pen-up event issued
       
   610 */
       
   611 void DNE1_TBDigitiser::WaitForPenDown()
       
   612 	{
       
   613 	// Called at startup or when pen leaves digitiser after pen-up event issued
       
   614 	__KTRACE_OPT(KHARDWARE,Kern::Printf("WD: PowerDownMask %x",iPoweringDown));
       
   615 	if (iPoweringDown)
       
   616 		{
       
   617 		// powering down
       
   618 
       
   619 		// Enable touch panel interrupt to allow the hardware
       
   620 		// to detect when the digitiser panel is touched and wakes up the system if in standby
       
   621 	    AsspRegister::Write16(KHwPenInterruptRegister, 0);
       
   622 
       
   623 		// Relinquish request on power resources
       
   624         //...
       
   625 
       
   626 		iPoweringDown = EFalse;
       
   627 		PowerDownDone();
       
   628 		}
       
   629 	else
       
   630 		{
       
   631 		if (!iTimer.IsPending() &&
       
   632 		    !iTimerInt.IsPending() &&
       
   633 		    iCurrentMode != TOUCHSCREEN_MODE_NONE)
       
   634 		    {
       
   635 #ifndef USE_PEN_INTERRUPTS
       
   636 		    iPollingTimer.OneShot(KPenEventsPollTime,ETrue);
       
   637 #else
       
   638 		    // enable pen-down interrupt
       
   639 		    GPIO::EnableInterrupt(iInterruptId);
       
   640 #endif
       
   641 		    }
       
   642 		}
       
   643 	}
       
   644 
       
   645 /**
       
   646 Called by PIL after it has processed a group of raw samples while pen is down.
       
   647 Used to indicate that the iX, iY buffers may be re-used
       
   648 */
       
   649 void DNE1_TBDigitiser::WaitForPenUp()
       
   650 	{
       
   651 	__KTRACE_OPT(KHARDWARE,Kern::Printf("WU"));
       
   652 	iState = E_HW_CollectSample;
       
   653 	iSamplesCount = 0;					// reset sample buffer
       
   654 	if(KInterGroupTime > 0)				// need to check this config param as it might be zero!
       
   655 		iTimer.OneShot(KInterGroupTime);
       
   656 	else
       
   657 		iTakeReadingDfc.Enque();
       
   658 
       
   659 	}
       
   660 
       
   661 /**
       
   662 Called by PIL if the group of samples collected is not good enough
       
   663 Used to indicate that the iX, iY buffers may be re-used
       
   664 */
       
   665 void DNE1_TBDigitiser::WaitForPenUpDebounce()
       
   666 	{
       
   667 	__KTRACE_OPT(KHARDWARE,Kern::Printf("WUDB"));
       
   668 	iState = E_HW_CollectSample;
       
   669 	iSamplesCount = 0;			// reset sample buffer
       
   670 	if(KInterGroupTime > 0)					// need to check this config param as it might be zero!
       
   671 		iTimer.OneShot(KInterGroupTime);
       
   672 	else
       
   673 		iTakeReadingDfc.Enque();
       
   674 	}
       
   675 
       
   676 /**
       
   677 Pen up/down interrupt service routine (ISR)
       
   678 */
       
   679 void DNE1_TBDigitiser::PenInterrupt()
       
   680     {
       
   681 	__KTRACE_OPT(KHARDWARE, Kern::Printf("PenInterrupt"));
       
   682 
       
   683 	if (KPenDownDelayTime>0)					// need to check this config param as it might be zero!
       
   684 		iTimerInt.OneShot(KPenDownDelayTime);	// start a debounce timer which will queue a DFC to process the interrupt
       
   685 	else
       
   686 		{
       
   687         iTakeReadingDfc.Add();
       
   688 		}
       
   689 	}
       
   690 
       
   691 /**
       
   692 DPowerHandler pure virtual
       
   693 */
       
   694 void DNE1_TBDigitiser::PowerUp()
       
   695 	{
       
   696 	iPowerUpDfc.Enque();			// queue a DFC in this driver's context
       
   697 	}
       
   698 
       
   699 /**
       
   700 Called by power up DFC
       
   701 */
       
   702 void DNE1_TBDigitiser::PowerUpDfc()
       
   703 	{
       
   704 	__KTRACE_OPT(KPOWER, Kern::Printf("DNE1_TBDigitiser::PowerUpDfc()"));
       
   705 	DigitiserOn();
       
   706 	PowerUpDone();			// must be called from a different thread than PowerUp()
       
   707 	}
       
   708 
       
   709 /**
       
   710 Turn the digitiser on
       
   711 May be called as a result of a power transition or from the HAL
       
   712 If called from HAL, then the digitiser may be already be on (iPointerOn == ETrue)
       
   713 */
       
   714 void DNE1_TBDigitiser::DigitiserOn()
       
   715 	{
       
   716 	__KTRACE_OPT(KPOWER,Kern::Printf("DNE1_TBDigitiser::DigitiserOn() iPointerOn=%d", iPointerOn));
       
   717 
       
   718 	if (!iPointerOn)				// may have been powered up already
       
   719 		DigitiserPowerUp();
       
   720 	}
       
   721 
       
   722 /**
       
   723 Power-up the digitiser. Assumes digitiser is off.
       
   724 */
       
   725 void DNE1_TBDigitiser::DigitiserPowerUp()
       
   726 	{
       
   727 	__KTRACE_OPT(KPOWER, Kern::Printf("DigitiserPowerUp"));
       
   728 	iPointerOn = ETrue;		// now turned on
       
   729 
       
   730 	// Re-assert request on power resources
       
   731 	// This will move the peripheral hardware out of low power "Sleep" mode back to fully operational
       
   732     // ...
       
   733 
       
   734     // Select Clock by writing clk_div
       
   735     // (TSP_CLK = 30MHz/((clk_div+1)*2) (should be >=2)
       
   736     AsspRegister::Write16(KHwTSPBase, 2);
       
   737 
       
   738     // ensure, that touch-panel interrupt is enabled
       
   739     AsspRegister::Write16(KHwPenInterruptRegister, 0);
       
   740 
       
   741     iState = E_HW_PowerUp;	// so we wait for pen up if necessary
       
   742 	iTakeReadingDfc.Enque();
       
   743 	}
       
   744 
       
   745 /**
       
   746 DPowerHandler pure virtual
       
   747 
       
   748 @param aPowerState the current power state
       
   749 */
       
   750 void DNE1_TBDigitiser::PowerDown(TPowerState /*aPowerState*/)
       
   751 	{
       
   752 	iPoweringDown = ETrue;
       
   753 	iPowerDownDfc.Enque();						// queue a DFC in this driver's context
       
   754 	}
       
   755 
       
   756 /**
       
   757 Turn the digitiser off
       
   758 May be called as a result of a power transition or from the HAL
       
   759 If called from Power Manager, then the digitiser may be already be off (iPointerOn == EFalse)
       
   760 if the platform is in silent running mode
       
   761 */
       
   762 void DNE1_TBDigitiser::DigitiserOff()
       
   763 	{
       
   764 	__KTRACE_OPT(KPOWER,Kern::Printf("DNE1_TBDigitiser::DigitiserOff() iPointerOn=%d", iPointerOn));
       
   765 	if (iPointerOn)		// can have been powered down from HAL
       
   766 		{
       
   767 		iPointerOn = EFalse;
       
   768 #ifdef USE_PEN_INTERRUPTS
       
   769 		GPIO::DisableInterrupt(iInterruptId);
       
   770 #else
       
   771 		iPollingTimer.Cancel();
       
   772 #endif
       
   773 		// disable the digitiser interrupt
       
   774 		AsspRegister::Write16(KHwPenInterruptRegister, 1);
       
   775 
       
   776 		iTimer.Cancel();
       
   777 		iTimerInt.Cancel();
       
   778 		iTakeReadingDfc.Cancel();
       
   779 		if (iState != E_HW_CollectSample)
       
   780 			{
       
   781 #ifdef USE_PEN_INTERRUPTS
       
   782 			iPenUpDfc.Add();
       
   783 #else
       
   784 			iPenUpDfc.Enque();
       
   785 #endif
       
   786 			}
       
   787 		else
       
   788 			{
       
   789 			//
       
   790 			// TO DO: (optional)
       
   791 			//
       
   792 			// Relinquish request on power resources as we are being powered down
       
   793 			// This will place the peripheral hardware in a low power "Sleep" mode which is Interrupt detection capable
       
   794 			// EXAMPLE ONLY
       
   795 			//
       
   796             // ...
       
   797 
       
   798 			if (iPoweringDown)			// came here through PowerDown
       
   799 				{
       
   800 				iPoweringDown = EFalse;
       
   801 				PowerDownDone();
       
   802 				}
       
   803 			}
       
   804 		}
       
   805 	else	// already powered down (by HAL)
       
   806 		{
       
   807 			if (iPoweringDown)			// came here through PowerDown
       
   808 				{
       
   809 				iPoweringDown = EFalse;
       
   810 				PowerDownDone();
       
   811 				}
       
   812 		}
       
   813 	}
       
   814 
       
   815 
       
   816 /**
       
   817 Convert digitiser coordinates to screen coordinates
       
   818 
       
   819 @param aDigitiserPoint the digitiser coordinates
       
   820 @param aScreenPoint A TPoint supplied by the caller.
       
   821 					On return, set to the converted screen coordinates in pixels.
       
   822 
       
   823 @return KErrNone if successful
       
   824 */
       
   825 TInt DNE1_TBDigitiser::DigitiserToScreen(const TPoint& aDigitiserPoint, TPoint& aScreenPoint)
       
   826 	{
       
   827 	NKern::LockSystem();
       
   828 	TInt R11 = iMachineConfig.iCalibration.iR11;
       
   829 	TInt R12 = iMachineConfig.iCalibration.iR12;
       
   830 	TInt R21 = iMachineConfig.iCalibration.iR21;
       
   831 	TInt R22 = iMachineConfig.iCalibration.iR22;
       
   832 	TInt TX  = iMachineConfig.iCalibration.iTx;
       
   833 	TInt TY  = iMachineConfig.iCalibration.iTy;
       
   834 	NKern::UnlockSystem();
       
   835 	TInt X = aDigitiserPoint.iX;
       
   836 	TInt Y = aDigitiserPoint.iY;
       
   837 
       
   838 	aScreenPoint.iX = (X*R11 + Y*R21 + TX) >> 16;
       
   839 	aScreenPoint.iY = (X*R12 + Y*R22 + TY) >> 16;
       
   840 
       
   841 	__KTRACE_OPT(KHARDWARE,	Kern::Printf("DtS: Dp.x %d, Dp.y %d, Sp.x %d, Sp.y %d", X,Y,aScreenPoint.iX,aScreenPoint.iY));
       
   842 
       
   843 	return KErrNone;
       
   844 	}
       
   845 
       
   846 /**
       
   847 Convert screen coordinates back into digitiser coordinates
       
   848 using the current constants from the superpage
       
   849 
       
   850 @param aX The screen X coordinate in pixels; On return, set to the digitiser X coordinate.
       
   851 @param aY The screen Y coordinate in pixels; On return, set to the digitiser Y coordinate.
       
   852 */
       
   853 void DNE1_TBDigitiser::ScreenToDigitiser(TInt& aX, TInt& aY)
       
   854 	{
       
   855 
       
   856 	NKern::LockSystem();
       
   857 	Int64 R11 = iMachineConfig.iCalibration.iR11;
       
   858 	Int64 R12 = iMachineConfig.iCalibration.iR12;
       
   859 	Int64 R21 = iMachineConfig.iCalibration.iR21;
       
   860 	Int64 R22 = iMachineConfig.iCalibration.iR22;
       
   861 	Int64 TX  = iMachineConfig.iCalibration.iTx;
       
   862 	Int64 TY  = iMachineConfig.iCalibration.iTy;
       
   863 	NKern::UnlockSystem();
       
   864 	Int64 X = aX;
       
   865 	Int64 Y = aY;
       
   866 	//
       
   867 	// Xd=(Xs<<16)*R22-(Ys<<16)*R21-(TX*R22)+(TY*R21)
       
   868 	//	  -------------------------------------------
       
   869 	//				   (R22*R11)-(R21*R12)
       
   870 	//
       
   871 	//
       
   872 	// Yd=(Xs<<16)*R12-(Ys<<16)*R11-(TX*R12)+(TY*R11)
       
   873 	//	  -------------------------------------------
       
   874 	//				   (R21*R12)-(R22*R11)
       
   875 	//
       
   876 	// where Xd and Yd are digitiser coordinates
       
   877 	//		 Xs and Ys are supplied screen coordinates
       
   878 	//
       
   879 	X <<= 16;
       
   880 	Y <<= 16;
       
   881 
       
   882 	Int64 d = Int64(R21) * Int64(R12) - Int64(R22) * Int64(R11);
       
   883 
       
   884 	Int64 r = (X*R12) - (Y*R11) - (TX*R12) + (TY*R11);
       
   885 
       
   886 	if (d != 0)
       
   887 		{
       
   888 		r = r/d;
       
   889 		}
       
   890 	else
       
   891 		{
       
   892 		r = 0;
       
   893 		}
       
   894 
       
   895 	aY = (TInt)r;
       
   896 
       
   897 	r = (X*R22)-(Y*R21)-(TX*R22)+(TY*R21);
       
   898 
       
   899 	if (d != 0)
       
   900 		{
       
   901 		r = r/(-d);
       
   902 		}
       
   903 	else
       
   904 		{
       
   905 		r = 0;
       
   906 		}
       
   907 
       
   908 	aX=(TInt)r;
       
   909 	}
       
   910 
       
   911 /**
       
   912 Calculate values for R11, R12, R21, R22, TX and TY
       
   913 
       
   914 @param aCalibration the screen coordinates of points touched
       
   915 @return KErrNone if successful
       
   916 */
       
   917 TInt DNE1_TBDigitiser::SetXYInputCalibration(const TDigitizerCalibration& aCalibration)
       
   918 	{
       
   919 	TInt R11,R12,R21,R22,TX,TY;
       
   920 	//
       
   921 	// Get coords of expected points
       
   922 	//
       
   923 	TDigitizerCalibration cal;
       
   924 	TInt ret=CalibrationPoints(cal);
       
   925 	if (ret != KErrNone)
       
   926 		return ret;
       
   927 
       
   928 	TInt Xp1 = cal.iTl.iX;
       
   929 	TInt Yp1 = cal.iTl.iY;
       
   930 	TInt Xp2 = cal.iBl.iX;
       
   931 	TInt Yp2 = cal.iBl.iY;
       
   932 	TInt Xp3 = cal.iBr.iX;
       
   933 	TInt Yp3 = cal.iBr.iY;
       
   934 
       
   935 	//
       
   936 	// Get coords of points touched in screen coordinates
       
   937 	//
       
   938 	TInt X1 = aCalibration.iTl.iX;
       
   939 	TInt Y1 = aCalibration.iTl.iY;
       
   940 	TInt X2 = aCalibration.iBl.iX;
       
   941 	TInt Y2 = aCalibration.iBl.iY;
       
   942 	TInt X3 = aCalibration.iBr.iX;
       
   943 	TInt Y3 = aCalibration.iBr.iY;
       
   944 
       
   945 
       
   946 	//
       
   947 	// Convert back to raw digitiser coordinates
       
   948 	//
       
   949 	ScreenToDigitiser(X1,Y1);
       
   950 	ScreenToDigitiser(X2,Y2);
       
   951 	ScreenToDigitiser(X3,Y3);
       
   952 	//
       
   953 	// (Y1-Y2)(Xp1-Xp3) - (Y1-Y3)(Xp1-Xp2)
       
   954 	// ----------------------------------- = R11
       
   955 	// (Y1-Y2)(X1-X3)	- (Y1-Y3)(X1-X2)
       
   956 
       
   957 	Int64 temp;      // temporary variable to prevent divide by zero faults
       
   958 	Int64 r = ((Int64(Y1-Y2)*Int64(Xp1-Xp3))-(Int64(Y1-Y3)*Int64(Xp1-Xp2)));
       
   959 	r <<= 16;
       
   960 	temp = (Int64(Y1-Y2) * Int64(X1-X3) - Int64(Y1-Y3) * Int64(X1-X2));
       
   961 	if (temp == 0)
       
   962 		{
       
   963 		r = 0;
       
   964 		}
       
   965 	else
       
   966 		{
       
   967 		r /= temp;
       
   968 		}
       
   969 	R11 = (TInt)r;
       
   970 	//
       
   971 	// (Y1-Y2)(Yp1-Yp3) - (Y1-Y3)(Yp1-Yp2)
       
   972 	// ----------------------------------- = R12
       
   973 	// (Y1-Y2)(X1-X3)	- (Y1-Y3)(X1-X2)
       
   974 	//
       
   975 	r = ((Int64(Y1-Y2) * Int64(Yp1-Yp3)) - (Int64(Y1-Y3) * Int64(Yp1-Yp2)));
       
   976 	r <<= 16;
       
   977 	temp = (Int64(Y1-Y2) * Int64(X1-X3) - Int64(Y1-Y3) * Int64(X1-X2));
       
   978 	if (temp == 0)
       
   979 		{
       
   980 		r = 0;
       
   981 		}
       
   982 	else
       
   983 		{
       
   984 		r /= temp;
       
   985 		}
       
   986 	R12 = (TInt)r;
       
   987 	//
       
   988 	// (X1-X3)(Xp2-Xp3) - (X2-X3)(Xp1-Xp3)
       
   989 	// ----------------------------------- = R21
       
   990 	// (Y2-Y3)(X1-X3)	- (Y1-Y3)(X2-X3)
       
   991 	//
       
   992 	r = (((X1-X3) * (Xp2-Xp3)) - ((X2-X3) * (Xp1-Xp3)));
       
   993 	r <<= 16;
       
   994 	temp = (Int64(Y2-Y3) * Int64(X1-X3) - Int64(Y1-Y3) * Int64(X2-X3));
       
   995 	if (temp == 0)
       
   996 		{
       
   997 		r = 0;
       
   998 		}
       
   999 	else
       
  1000 		{
       
  1001 		r /= temp;
       
  1002 		}
       
  1003 	R21=(TInt)r;
       
  1004 	//
       
  1005 	// (X1-X3)(Yp2-Yp3) - (X2-X3)(Yp1-Yp3)
       
  1006 	// ----------------------------------- = R22
       
  1007 	// (Y2-Y3)(X1-X3)	- (Y1-Y3)(X2-X3)
       
  1008 	//
       
  1009 	r = ((Int64(X1-X3) * Int64(Yp2-Yp3)) - (Int64(X2-X3) * Int64(Yp1-Yp3)));
       
  1010 	r <<= 16;
       
  1011 	temp = (Int64(Y2-Y3) * Int64(X1-X3) - Int64(Y1-Y3) * Int64(X2-X3));
       
  1012 	if (temp==0)
       
  1013 		{
       
  1014 		r = 0;
       
  1015 		}
       
  1016 	else
       
  1017 		{
       
  1018 		r/=temp;
       
  1019 		}
       
  1020 	R22 = (TInt)r;
       
  1021 	//
       
  1022 	// TX = Xp1 - X1*R11 - Y1*R21
       
  1023 	//
       
  1024    TX = (Xp1<<16) - (X1*R11) - (Y1*R21);
       
  1025 	//
       
  1026 	// TY = Yp1 - X1*R12 - Y1*R22
       
  1027 	//
       
  1028 	TY = (Yp1<<16) - (X1*R12) - (Y1*R22);
       
  1029 
       
  1030 	//
       
  1031 	// Write new values into the superpage
       
  1032 	//
       
  1033 	NKern::LockSystem();
       
  1034 	iMachineConfig.iCalibration.iR11 = R11;
       
  1035 	iMachineConfig.iCalibration.iR12 = R12;
       
  1036 	iMachineConfig.iCalibration.iR21 = R21;
       
  1037 	iMachineConfig.iCalibration.iR22 = R22;
       
  1038 	iMachineConfig.iCalibration.iTx  = TX;
       
  1039 	iMachineConfig.iCalibration.iTy  = TY;
       
  1040 	NKern::UnlockSystem();
       
  1041 
       
  1042 	return(KErrNone);
       
  1043 	}
       
  1044 
       
  1045 /**
       
  1046 Informs the user-side calibration application where to draw
       
  1047 the cross-hairs on the screen
       
  1048 
       
  1049 @param aCalibration On return contains the for points on the screen (in screen coordinates)
       
  1050 					where the cross-hairs should be drawn
       
  1051 @return KErrNone if succcessful
       
  1052 */
       
  1053 TInt DNE1_TBDigitiser::CalibrationPoints(TDigitizerCalibration& aCalibration)
       
  1054 	{
       
  1055 	TVideoInfoV01Buf buf;
       
  1056 	TVideoInfoV01& vidinfo = buf();
       
  1057 	TInt r = Kern::HalFunction(EHalGroupDisplay, EDisplayHalCurrentModeInfo, (TAny*)&buf, NULL);
       
  1058 	if (r != KErrNone)
       
  1059 		return r;
       
  1060 	iScreenSize=vidinfo.iSizeInPixels;
       
  1061 
       
  1062     aCalibration.iBl.iX = aCalibration.iTl.iX = iScreenSize.iWidth/10;
       
  1063     aCalibration.iTr.iY = aCalibration.iTl.iY = iScreenSize.iHeight/10;
       
  1064     aCalibration.iBr.iY = aCalibration.iBl.iY = iScreenSize.iHeight-iScreenSize.iHeight/10;
       
  1065     aCalibration.iTr.iX = aCalibration.iBr.iX = iScreenSize.iWidth-iScreenSize.iWidth/10;
       
  1066     return r;
       
  1067 	}
       
  1068 /**
       
  1069 Saves the digitiser calibration to the persistent machine configuration area
       
  1070 so that it can be restored after a power-down/up
       
  1071 
       
  1072 @return KErrNone if succcessful
       
  1073 */
       
  1074 TInt DNE1_TBDigitiser::SaveXYInputCalibration()
       
  1075 	{
       
  1076 	NKern::LockSystem();
       
  1077 	iMachineConfig.iCalibrationSaved = iMachineConfig.iCalibration;
       
  1078 	NKern::UnlockSystem();
       
  1079 	return(KErrNone);
       
  1080 	}
       
  1081 
       
  1082 /**
       
  1083 Restores the digitiser calibration from the persistent machine configuration area
       
  1084 following a power-up
       
  1085 
       
  1086 @param aType indicates whether to restore factory or saved settings
       
  1087 @return KErrNone if succcessful
       
  1088 */
       
  1089 TInt DNE1_TBDigitiser::RestoreXYInputCalibration(TDigitizerCalibrationType aType)
       
  1090 	{
       
  1091 	TInt r=KErrNone;
       
  1092 	NKern::LockSystem();
       
  1093 	switch (aType)
       
  1094 		{
       
  1095 		case EFactory:
       
  1096 			iMachineConfig.iCalibration = iMachineConfig.iCalibrationFactory;
       
  1097 			break;
       
  1098 		case ESaved:
       
  1099 			iMachineConfig.iCalibration = iMachineConfig.iCalibrationSaved;
       
  1100 			break;
       
  1101 		default:
       
  1102 			r = KErrNotSupported;
       
  1103 			break;
       
  1104 		}
       
  1105 	NKern::UnlockSystem();
       
  1106 	return r;
       
  1107 	}
       
  1108 
       
  1109 /**
       
  1110 Gets the digitiser configuration information
       
  1111 
       
  1112 @param aInfo On return, contains information about the digitiser's dimensions etc.
       
  1113 */
       
  1114 void DNE1_TBDigitiser::DigitiserInfo(TDigitiserInfoV01& aInfo)
       
  1115 	{
       
  1116 	__KTRACE_OPT(KEXTENSION,Kern::Printf("DNE1_TBDigitiser::DigitiserInfo"));
       
  1117 
       
  1118 	if (iCurrentMode != TOUCHSCREEN_MODE_NONE)
       
  1119 		{
       
  1120 		aInfo.iDigitiserSize.iWidth  = Mode_Config[iCurrentMode].iConfigXyWidth;
       
  1121 		aInfo.iDigitiserSize.iHeight = Mode_Config[iCurrentMode].iConfigXyHeight;
       
  1122 		}
       
  1123 	else
       
  1124 		{
       
  1125 		aInfo.iDigitiserSize.iWidth  = 0;
       
  1126 		aInfo.iDigitiserSize.iHeight = 0;
       
  1127 		}
       
  1128 
       
  1129 	aInfo.iOffsetToDisplay.iX    = KConfigXyOffsetX;
       
  1130 	aInfo.iOffsetToDisplay.iY    = KConfigXyOffsetY;
       
  1131 	}
       
  1132 
       
  1133 /**
       
  1134 Issues a pen move event if the distance from the last point is greater than the threshold
       
  1135 
       
  1136 @param aPoint the pen position in screen coordinates
       
  1137 */
       
  1138 void DNE1_TBDigitiser::FilterPenMove(const TPoint& aPoint)
       
  1139 	{
       
  1140 	TPoint offset=aPoint;
       
  1141 	offset.iX -= iLastPos.iX;
       
  1142 	offset.iY -= iLastPos.iY;
       
  1143 	if (Abs(offset.iX)>=iCfg.iAccThresholdX || Abs(offset.iY)>=iCfg.iAccThresholdY)
       
  1144 		{
       
  1145 		iLastPos=aPoint;
       
  1146 		IssuePenMoveEvent(aPoint);
       
  1147 		}
       
  1148 	}
       
  1149 
       
  1150 /**
       
  1151 Reset the pen move filter
       
  1152 */
       
  1153 void DNE1_TBDigitiser::ResetPenMoveFilter()
       
  1154 	{
       
  1155 	}
       
  1156 
       
  1157