tchpdd.cpp
资源名称:SMDK2440.rar [点击查看]
上传用户:qiulin1960
上传日期:2013-10-16
资源大小:2844k
文件大小:38k
源码类别:
Windows CE
开发平台:
Windows_Unix
- /*++
- THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
- ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
- PARTICULAR PURPOSE.
- Copyright (c) 2002. Samsung Electronics, co. ltd All rights reserved.
- Module Name:
- tchpdd.cpp
- Abstract:
- This module contains the DDSI implementation and PDD support routines
- for the touch panel for the P2 implementation.
- Functions:
- TouchDriverCalibrationPointGet
- DdsiTouchPanelGetDeviceCaps
- DdsiTouchPanelSetMode
- DdsiTouchPanelEnable
- DdsiTouchPanelDisable
- DdsiTouchPanelAttach
- DdsiTouchPanelDetach
- DdsiTouchPanelGetPoint
- DdsiTouchPanelPowerHandler
- Notes:
- Revision History:
- --*/
- #define DBGPOINTS1 1
- #define TRACE_TIP_STATE
- #include <windows.h>
- #include <types.h>
- #include <memory.h>
- #include <nkintr.h>
- #include <oalintr.h>
- #include <tchddsi.h>
- #include <tchpdd.h>
- #include <drv_glob.h>
- //#include <p2debug.h>
- #include <S2440.H>
- #include "reg.h"
- #define SYS_TIMER_PRESCALER 24
- //#define SYS_TIMER_DIVIDER 4 // 2
- //#define OEM_CLOCK_FREQ (S2440PCLK / (SYS_TIMER_PRESCALER+1) / SYS_TIMER_DIVIDER)
- #define JYLEE_TEST 0
- #define JYLEE_TEST1 0
- //#define TFT240_320 1
- //#define TFT640_480 4
- //#define LCD_TYPE TFT240_320
- //#define LCD_TYPE TFT640_480
- #if ( LCD_TYPE == TFT640_480 )
- #define ADC_DELAY_TIME 65530
- #else
- #define ADC_DELAY_TIME 40000 // yhkim
- #endif
- DWORD gIntrTouch = SYSINTR_TOUCH;
- DWORD gIntrTouchChanged = SYSINTR_TOUCH_CHANGED;
- #ifdef TRACE_TIP_STATE
- BOOL PenIsUp = TRUE;
- #endif
- #if defined(MIPS) || defined(PPC821) || defined(PPC823) || defined(ARM) || defined(SH4)
- #define PAGE_MASK 0x0fff
- #define PAGE_SIZE 0x1000
- volatile static PVOID pTmpRegs;
- #endif
- static void TouchPanelPowerOff();
- static void TouchPanelPowerOn();
- static BOOL Touch_Timer0_Setup(void) ;
- static BOOL Touch_Pen_filtering(INT *px, INT *py);
- // The MDD requires a minimum of MIN_CAL_COUNT consecutive samples before
- // it will return a calibration coordinate to GWE. This value is defined
- // in the PDD so that each OEM can control the behaviour of the touch
- // panel and still use the Microsoft supplied MDD. Note that the extern "C"
- // is required so that the variable name doesn't get decorated, and
- // since we have an initializer the 'extern' is actually ignored and
- // space is allocated.
- extern "C" const int MIN_CAL_COUNT = 40;
- INT CurrentSampleRateSetting = 0; // Low sample rate setting
- // @globalvar PTCHAUD_ASIC_REGISTERS | v_pTchAudAsicRegisters | Pointer to Asic regs
- PTCHAUD_ASIC_REGISTERS v_pTchAudAsicRegisters = NULL;
- // @globalvar PTOUCHPANEL_POINT_SAMPLE | v_pPenSamples | Pointer to pen samples area
- PDRIVER_GLOBALS v_pDriverGlobals = NULL;
- volatile static PVOID v_pCpuRegs = NULL;
- TOUCH_PANEL_SAMPLE_FLAGS SampleFlags;
- #ifdef CHECK_RATE
- UINT32 tmp_leds = 0x55;
- #endif
- // Mutex to prevent contention with audio while accessing shared registers
- static HANDLE v_hTchAudMutex;
- // Global flag to indicate whether we are in power handler routine, so
- // we know to avoid system calls.
- static BOOL bInPowerHandler = FALSE;
- // Macros for aquiring semaphore for shared access to ASIC registers. If
- // we are in the power handler routines, we don't need/want to aquire semaphore,
- // since we are serialized at that point, and can't make any system calls.
- #define TCHAUD_SEM_LOCK()
- if (!bInPowerHandler) {
- DEBUGMSG(ZONE_TIPSTATE,(TEXT("TchPDD Getting semaphore...rn")));
- TchAudLock(v_hTchAudMutex, &(v_pDriverGlobals->tch.semaphore));
- }
- #define TCHAUD_SEM_UNLOCK()
- if (!bInPowerHandler) {
- DEBUGMSG(ZONE_TIPSTATE,(TEXT("TchPDD Releasing semaphore...rn")));
- TchAudUnlock(v_hTchAudMutex, &(v_pDriverGlobals->tch.semaphore));
- }
- // Macros for accessing registers on the touch audio ASIC. The code for
- // these functions is in drvlib so it can be shared between touch and audio.
- #define ASIC_READ_REG(reg, pval)
- TchAudReadReg(reg, pval, v_pTchAudAsicRegisters, bInPowerHandler)
- #define ASIC_WRITE_REG(reg, val)
- TchAudWriteReg(reg, val, v_pTchAudAsicRegisters, bInPowerHandler)
- #define ASIC_AND_REG(reg, val)
- TchAudAndReg(reg, val, v_pTchAudAsicRegisters, bInPowerHandler)
- #define ASIC_OR_REG(reg, val)
- TchAudOrReg(reg, val, v_pTchAudAsicRegisters, bInPowerHandler)
- volatile IOPreg *v_pIOPregs;
- volatile ADCreg *v_pADCregs;
- volatile PWMreg *v_pPWMregs;
- volatile INTreg *v_pINTregs;
- volatile unsigned short xbuf[10], ybuf[10];
- static unsigned int touch_down = 1;
- //#define ADCPRS 49 // 200Mhz
- #define ADCPRS 49 // 200Mhz
- //#define ADCPRS 65 // 532Mhz
- /*++
- Routine Description:
- Deallocates the virtual memory reserved for the Touch/Audio Asic registers,
- and the pen samples dma area.
- Arguments:
- None.
- Return Value:
- None.
- Autodoc Information:
- @doc IN_TOUCH_DDSI INTERNAL DRIVERS PDD TOUCH_PANEL
- @func VOID | PddpTouchPanelDeallocateVm |
- Deallocates the virtual memory reserved for the Touch/Audio Asic registers,
- and the pen samples dma area.
- --*/
- static
- void
- PddpTouchPanelDeallocateVm(
- VOID
- )
- {
- if(v_pIOPregs)
- {
- VirtualFree((void*)v_pIOPregs, sizeof(IOPreg), MEM_RELEASE);
- v_pIOPregs=NULL;
- }
- if(v_pADCregs)
- {
- VirtualFree((void*)v_pADCregs, sizeof(ADCreg), MEM_RELEASE);
- v_pADCregs = NULL;
- }
- if ( v_pDriverGlobals )
- {
- VirtualFree( v_pDriverGlobals,
- DRIVER_GLOBALS_PHYSICAL_MEMORY_SIZE ,
- MEM_RELEASE
- );
- v_pDriverGlobals = NULL;
- }
- }
- //
- // PDD Internal Support Routines
- //
- /*++
- @doc IN_TOUCH_DDSI INTERNAL DRIVERS PDD TOUCH_PANEL
- @func VOID | PddpTouchPanelGetSamples |
- Copies from the pen dma area the most recent point sample into the location
- pointed to by pPointSamples. During the copy the sample information is
- adjusted to be consistent with the 12 bit pen data format.
- Has the side effect of reinitializing ioPenPointer if we are near the
- end of the pen sample area.
- --*/
- static
- void
- PddpTouchPanelGetSamples(
- PTOUCHPANEL_POINT_SAMPLE pPointSamples //@PARM Pointer to where the samples will be stored.
- )
- {
- // ULONG devDrvPointer;
- ULONG irg;
- //
- // Copy the samples to our buffer munging the data for the 12 bit
- // pen data format.
- //
- for ( irg = 0; irg < NUMBER_SAMPLES_PER_POINT; irg++ )
- {
- pPointSamples[ irg ].XSample = xbuf[irg];
- pPointSamples[ irg ].YSample = ybuf[irg];
- }
- }
- /*++
- Routine Description:
- Gathers the most recent sample and evaluates the sample returing
- the determined tip state and the `best guess' for the X and Y coordinates.
- Note: Determined empirically that the variance of the X coordinate of the
- first sample from all other samples is large enough that in order
- to keep the nominal variance small, we discard the first sample.
- Cases of a light touch that locks the ADC into
- seeing X and Y coordinate samples of 0x277 regardless of how the pen
- moves or presses have been seen. XXXXX
- Arguments:
- pTipState Pointer to where the tip state information will be returned.
- pUnCalX Pointer to where the x coordinate will be returned.
- pUnCalY Pointer to where the y coordinate will be returned.
- Return Value:
- None.
- Autodoc Information:
- @doc IN_TOUCH_DDI INTERNAL DRIVERS PDD TOUCH_PANEL
- @func VOID | PddpTouchPanelEvaluateSamples |
- Gathers the most recent sample and evaluates the sample returing
- the determined tip state and the `best guess' for the X and Y coordinates.
- --*/
- static
- void
- PddpTouchPanelEvaluateSamples(
- TOUCH_PANEL_SAMPLE_FLAGS *pSampleFlags, //@PARM Pointer to where the tip state information will be returned.
- INT *pUncalX, //@PARM Pointer to where the x coordinate will be returned.
- INT *pUncalY //@PARM Pointer to where the y coordinate will be returned.
- )
- {
- LONG dlXDiff0;
- LONG dlXDiff1;
- LONG dlXDiff2;
- LONG dlYDiff0;
- LONG dlYDiff1;
- LONG dlYDiff2;
- TOUCHPANEL_POINT_SAMPLES rgPointSamples;
- //
- // Get the sample.
- //
- PddpTouchPanelGetSamples( rgPointSamples );
- //
- // Calcuate the differences for the X samples and insure that
- // the resulting number is positive.
- //
- dlXDiff0 = rgPointSamples[ 0 ].XSample - rgPointSamples[ 1 ].XSample;
- dlXDiff1 = rgPointSamples[ 1 ].XSample - rgPointSamples[ 2 ].XSample;
- dlXDiff2 = rgPointSamples[ 2 ].XSample - rgPointSamples[ 0 ].XSample;
- dlXDiff0 = dlXDiff0 > 0 ? dlXDiff0 : -dlXDiff0;
- dlXDiff1 = dlXDiff1 > 0 ? dlXDiff1 : -dlXDiff1;
- dlXDiff2 = dlXDiff2 > 0 ? dlXDiff2 : -dlXDiff2;
- //
- // Calcuate the differences for the Y samples and insure that
- // the resulting number is positive.
- //
- dlYDiff0 = rgPointSamples[ 0 ].YSample - rgPointSamples[ 1 ].YSample;
- dlYDiff1 = rgPointSamples[ 1 ].YSample - rgPointSamples[ 2 ].YSample;
- dlYDiff2 = rgPointSamples[ 2 ].YSample - rgPointSamples[ 0 ].YSample;
- dlYDiff0 = dlYDiff0 > 0 ? dlYDiff0 : -dlYDiff0;
- dlYDiff1 = dlYDiff1 > 0 ? dlYDiff1 : -dlYDiff1;
- dlYDiff2 = dlYDiff2 > 0 ? dlYDiff2 : -dlYDiff2;
- //
- // The final X coordinate is the average of coordinates of
- // the two MIN of the differences.
- //
- if ( dlXDiff0 < dlXDiff1 )
- {
- if ( dlXDiff2 < dlXDiff0 )
- {
- *pUncalX = (ULONG)( ( ( rgPointSamples[ 0 ].XSample + rgPointSamples[ 2 ].XSample ) >> 1 ) );
- }
- else
- {
- *pUncalX = (ULONG)( ( ( rgPointSamples[ 0 ].XSample + rgPointSamples[ 1 ].XSample ) >> 1 ) );
- }
- }
- else if ( dlXDiff2 < dlXDiff1 )
- {
- *pUncalX = (ULONG)( ( ( rgPointSamples[ 0 ].XSample + rgPointSamples[ 2 ].XSample ) >> 1 ) );
- }
- else
- {
- *pUncalX = (ULONG)( ( ( rgPointSamples[ 1 ].XSample + rgPointSamples[ 2 ].XSample ) >> 1 ) );
- }
- //
- //
- // The final Y coordinate is the average of coordinates of
- // the two MIN of the differences.
- //
- if ( dlYDiff0 < dlYDiff1 )
- {
- if ( dlYDiff2 < dlYDiff0 )
- {
- *pUncalY = (ULONG)( ( ( rgPointSamples[ 0 ].YSample + rgPointSamples[ 2 ].YSample ) >> 1 ) );
- }
- else
- {
- *pUncalY = (ULONG)( ( ( rgPointSamples[ 0 ].YSample + rgPointSamples[ 1 ].YSample ) >> 1 ) );
- }
- }
- else if ( dlYDiff2 < dlYDiff1 )
- {
- *pUncalY = (ULONG)( ( ( rgPointSamples[ 0 ].YSample + rgPointSamples[ 2 ].YSample ) >> 1 ) );
- }
- else
- {
- *pUncalY = (ULONG)( ( ( rgPointSamples[ 1 ].YSample + rgPointSamples[ 2 ].YSample ) >> 1 ) );
- }
- //
- // Validate the coordinates and set the tip state accordingly.
- //
- if ( dlXDiff0 > DELTA_X_COORD_VARIANCE ||
- dlXDiff1 > DELTA_X_COORD_VARIANCE ||
- dlXDiff2 > DELTA_X_COORD_VARIANCE ||
- dlYDiff0 > DELTA_Y_COORD_VARIANCE ||
- dlYDiff1 > DELTA_Y_COORD_VARIANCE ||
- dlYDiff2 > DELTA_Y_COORD_VARIANCE )
- {
- //#ifdef DBGPOINTS1
- DEBUGMSG( ZONE_SAMPLES, (TEXT("Sample 0: X 0x%x Y 0x%xrn"),
- rgPointSamples[ 0 ].XSample, rgPointSamples[ 0 ].YSample) );
- DEBUGMSG( ZONE_SAMPLES, (TEXT("Sample 1: X 0x%x Y 0x%xrn"),
- rgPointSamples[ 1 ].XSample, rgPointSamples[ 1 ].YSample) );
- DEBUGMSG( ZONE_SAMPLES, (TEXT("Sample 2: X 0x%x Y 0x%xrn"),
- rgPointSamples[ 2 ].XSample, rgPointSamples[ 2 ].YSample) );
- if ( dlXDiff0 > DELTA_X_COORD_VARIANCE )
- DEBUGMSG( ZONE_SAMPLES, (TEXT("XDiff0 too large 0x%xrn"), dlXDiff0) );
- if ( dlXDiff1 > DELTA_X_COORD_VARIANCE )
- DEBUGMSG( ZONE_SAMPLES, (TEXT("XDiff1 too large 0x%xrn"), dlXDiff1) );
- if ( dlXDiff2 > DELTA_X_COORD_VARIANCE )
- DEBUGMSG( ZONE_SAMPLES, (TEXT("XDiff2 too large 0x%xrn"), dlXDiff2) );
- if ( dlYDiff0 > DELTA_Y_COORD_VARIANCE )
- DEBUGMSG( ZONE_SAMPLES, (TEXT("YDiff0 too large 0x%xrn"), dlYDiff0) );
- if ( dlYDiff1 > DELTA_Y_COORD_VARIANCE )
- DEBUGMSG( ZONE_SAMPLES, (TEXT("YDiff1 too large 0x%xrn"), dlYDiff1) );
- if ( dlYDiff2 > DELTA_Y_COORD_VARIANCE )
- DEBUGMSG( ZONE_SAMPLES, (TEXT("YDiff2 too large 0x%xrn"), dlYDiff2) );
- //#endif // DBGPOINTS1
- }
- else
- {
- //
- // Sample is valid. Set tip state accordingly.
- //
- *pSampleFlags = TouchSampleValidFlag | TouchSampleDownFlag;
- }
- DEBUGMSG( ZONE_SAMPLES, (TEXT("Filtered - SampleFlags: 0x%x X: 0x%x Y: 0x%xrn"),
- *pSampleFlags, *pUncalX, *pUncalY) );
- }
- //
- // PddpSetupPenDownIntr()
- //
- // Set up the UCB to give pen down interrupts. If EnableIntr flag is set, enable
- // the interrupt, otherwise, leave it disabled. Note: - Caller must hold semaphore
- // when this function is called to protect access to the shared UCB registers.
- //
- BOOL
- PddpSetupPenDownIntr(BOOL EnableIntr)
- {
- // USHORT intrMask;
- // I don't know why we enable the interrupt here.
- //
- // Setup ADC register
- //
- // kang code
- // Enable Prescaler,Prescaler,AIN5/7 fix,Normal,Disable read start,No operation
- // Down,YM:GND,YP:AIN5,XM:Hi-z,XP:AIN7,XP pullup En,Normal,Waiting for interrupt mode
- // kang code end
- // Down Int, YMON:0, nYPON:1, XMON:0;nXPON:1, Pullup:1, Auto Conv.,Waiting.
- v_pADCregs->rADCTSC =(0<<8)|(1<<7)|(1<<6)|(0<<5)|(1<<4)|(0<<3)|(0<<2)|(3);
- //v_pADCregs->rADCTSC=(1<<3)|(1<<2);
- v_pADCregs->rADCDLY = ADC_DELAY_TIME;//default value for delay.
- v_pADCregs->rADCCON = (1<<14)|(ADCPRS<<6)|(7<<3); //setup channel, ADCPRS, Touch Input
- return TRUE;
- }
- //
- // PddpDisableClearPenDownIntr(void)
- //
- // Tell the UCB to clear pen down interrupts
- //
- BOOL
- PddpDisableClearPenDownIntr(void)
- {
- // Acquire semaphore to prevent contention with audio driver while accessing UCB regs
- TCHAUD_SEM_LOCK();
- // Clear bit 12 in UCB address 3 to disable interrupts on falling tspx (tspx_fal_int)
- // Read data from UCB address 0x03
- if (! ASIC_AND_REG(3, ~((USHORT)0x1000)))
- goto error_return;
- // Clear the pen down interrupt
- // Write UCB address 4 bit 12 to a 0
- if (! ASIC_WRITE_REG(4, 0))
- goto error_return;
- // Write UCB address 4 bit 12 to a 1, to clear tspx interrupts
- if (! ASIC_WRITE_REG(4, 0x1000))
- goto error_return;
- TCHAUD_SEM_UNLOCK();
- return TRUE;
- error_return:
- RETAILMSG(1,(TEXT("TchPdd: Error accessing UCB register!rn")));
- TCHAUD_SEM_UNLOCK();
- return FALSE;
- }
- //
- // DDSI Implementation
- //
- // @DOC EX_TOUCH_DDSI EXTERNAL DRIVERS TOUCH_DRIVER
- /* @FUNC BOOL | TouchDriverCalibrationPointGet |
- Gives a single calibration point.
- @XREF
- <l TouchPanelReadCalibrationPoint.TouchPanelReadCalibrationPoint>
- <l TouchPanelSetCalibration.TouchPanelSetCalibration>
- <l TouchPanelReadCalibrationAbort.TouchPanelReadCalibrationAbort>
- @COMM
- This function is called to get a single calibration point, in screen
- coordinates, when the input system is calibrating the touch driver. The input system
- will then draw a target on the screen for the user to press on.
- The driver may use the cDisplayX and cDisplayY to compute a coordinate.
- It does not need to remember this computed value internally since it will
- be passed back when the input system has collected all of the points and
- calls <l TouchPanelSetCalibration.TouchPanelSetCalibration>.
- */
- extern "C"
- BOOL
- TouchDriverCalibrationPointGet(
- TPDC_CALIBRATION_POINT *pTCP //@PARM pointer to returned calibration point
- )
- {
- INT32 cDisplayWidth = pTCP -> cDisplayWidth;
- INT32 cDisplayHeight = pTCP -> cDisplayHeight;
- int CalibrationRadiusX = cDisplayWidth/20;
- int CalibrationRadiusY = cDisplayHeight/20;
- switch (pTCP -> PointNumber)
- {
- case 0:
- pTCP -> CalibrationX = cDisplayWidth/2;
- pTCP -> CalibrationY = cDisplayHeight/2;
- break;
- case 1:
- pTCP -> CalibrationX = CalibrationRadiusX*2;
- pTCP -> CalibrationY = CalibrationRadiusY*2;
- break;
- case 2:
- pTCP -> CalibrationX = CalibrationRadiusX*2;
- pTCP -> CalibrationY = cDisplayHeight - CalibrationRadiusY*2;
- break;
- case 3:
- pTCP -> CalibrationX = cDisplayWidth - CalibrationRadiusX*2;
- pTCP -> CalibrationY = cDisplayHeight - CalibrationRadiusY*2;
- break;
- case 4:
- pTCP -> CalibrationX = cDisplayWidth - CalibrationRadiusX*2;
- pTCP -> CalibrationY = CalibrationRadiusY*2;
- break;
- default:
- pTCP -> CalibrationX = cDisplayWidth/2;
- pTCP -> CalibrationY = cDisplayHeight/2;
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
- RETAILMSG(0,(TEXT("TouchDriverCalibrationPointGetrn")));
- RETAILMSG(0,(TEXT("cDisplayWidth : %4Xrn"),cDisplayWidth));
- RETAILMSG(0,(TEXT("cDisplayHeight : %4Xrn"),cDisplayHeight));
- RETAILMSG(0,(TEXT("CalibrationRadiusX : %4drn"),CalibrationRadiusX));
- RETAILMSG(0,(TEXT("CalibrationRadiusY : %4drn"),CalibrationRadiusY));
- RETAILMSG(0,(TEXT("pTCP -> PointNumber : %4drn"),pTCP -> PointNumber));
- RETAILMSG(0,(TEXT("pTCP -> CalibrationX : %4drn"),pTCP -> CalibrationX));
- RETAILMSG(0,(TEXT("pTCP -> CalibrationY : %4drn"),pTCP -> CalibrationY));
- return TRUE;
- }
- // @doc EX_TOUCH_DDSI EXTERNAL DRIVERS DDSI TOUCH_PANEL
- //
- // @func ULONG | DdsiTouchPanelGetDeviceCaps |
- //
- // Queries capabilities about the physical touch panel device.
- //
- // @parm ULONG | iIndex |
- //
- // Specifies the capability to query. They are one of the following:
- //
- // @flag TPDC_SAMPLERATE_ID |
- // The sample rate.
- // @flag TPDC_CALIBRATIONPOINTS_ID |
- // The X and Y coordinates used for calibration.
- // @flag TPDC_CALIBRATIONDATA_ID |
- // The X and Y coordinates used for calibration mapping.
- //
- // @parm LPVOID | lpOutput |
- // Points to the memory location(s) where the queried information
- // will be placed. The format of the memory referenced depends on
- // the setting of iIndex. If 0, returns the number of words
- // required for the output data.
- //
- // @rdesc
- // The return values is set to the amount of information supplied and depends
- // on the setting of the iIndex argument.
- //
- // @comm
- // Implemented in the PDD.
- //
- extern "C"
- BOOL
- DdsiTouchPanelGetDeviceCaps(
- INT iIndex,
- LPVOID lpOutput
- )
- {
- if ( lpOutput == NULL )
- {
- ERRORMSG(1, (__TEXT("TouchPanelGetDeviceCaps: invalid parameter.rn")));
- SetLastError(ERROR_INVALID_PARAMETER);
- DebugBreak();
- return FALSE;
- }
- switch ( iIndex )
- {
- case TPDC_SAMPLE_RATE_ID:
- {
- TPDC_SAMPLE_RATE *pTSR = (TPDC_SAMPLE_RATE*)lpOutput;
- pTSR -> SamplesPerSecondLow = TOUCHPANEL_SAMPLE_RATE_LOW;
- pTSR -> SamplesPerSecondHigh = TOUCHPANEL_SAMPLE_RATE_HIGH;
- pTSR -> CurrentSampleRateSetting = CurrentSampleRateSetting;
- }
- break;
- case TPDC_CALIBRATION_POINT_COUNT_ID:
- {
- TPDC_CALIBRATION_POINT_COUNT *pTCPC = (TPDC_CALIBRATION_POINT_COUNT*)lpOutput;
- pTCPC -> flags = 0;
- pTCPC -> cCalibrationPoints = 5;
- }
- break;
- case TPDC_CALIBRATION_POINT_ID:
- return(TouchDriverCalibrationPointGet((TPDC_CALIBRATION_POINT*)lpOutput));
- default:
- ERRORMSG(1, (__TEXT("TouchPanelGetDeviceCaps: invalid parameter.rn")));
- SetLastError(ERROR_INVALID_PARAMETER);
- DebugBreak();
- return FALSE;
- }
- return TRUE;
- }
- //
- // @doc EX_TOUCH_DDSI EXTERNAL DRIVERS DDSI TOUCH_PANEL
- //
- // @func BOOL | DdsiTouchPanelSetMode |
- // Sets information about the physical touch panel device.
- //
- // @parm ULONG | iIndex |
- // Specifies the mode to set. They are one of the following:
- //
- // @flag TPSM_SAMPLERATE_HIGH_ID |
- // Sets the sample rate to the high rate.
- // @flag TPSM_SAMPLERATE_LOW_ID |
- // Sets the sample rate to the low rate.
- //
- // @parm LPVOID | lpInput |
- // Points to the memory location(s) where the update information
- // resides. The format of the memory referenced depends on the
- // Points to the memory location(s) where the queried information
- // will be placed.
- //
- // @rdesc
- // If the function succeeds the return value is TRUE, otherwise, it is FALSE.
- //
- // @comm
- // Implemented in the PDD.
- //
- BOOL
- DdsiTouchPanelSetMode(
- INT iIndex,
- LPVOID lpInput
- )
- {
- BOOL ReturnCode = FALSE;
- switch ( iIndex )
- {
- case TPSM_SAMPLERATE_LOW_ID:
- case TPSM_SAMPLERATE_HIGH_ID:
- SetLastError( ERROR_SUCCESS );
- ReturnCode = TRUE;
- break;
- default:
- SetLastError( ERROR_INVALID_PARAMETER );
- break;
- }
- return ( ReturnCode );
- }
- //
- // @doc EX_TOUCH_DDSI EXTERNAL DRIVERS DDSI TOUCH_PANEL
- //
- // @func BOOL | DdsiTouchPanelEnable |
- // Powers up and initializes the touch panel hardware for operation.
- //
- // @rdesc
- // If the function succeeds, the return value is TRUE; otherwise, it is FALSE.
- //
- // @comm
- // Implemented in the PDD.
- //
- BOOL
- DdsiTouchPanelEnable(
- VOID
- )
- {
- BOOL Ret;
- if(v_pIOPregs == NULL) {
- v_pIOPregs = (volatile IOPreg *)
- VirtualAlloc(0,sizeof(IOPreg),MEM_RESERVE, PAGE_NOACCESS);
- if(v_pIOPregs == NULL) {
- ERRORMSG(1,(TEXT("For IOPreg: VirtualAlloc failed!rn")));
- return (FALSE);
- }
- else {
- if(!VirtualCopy((PVOID)v_pIOPregs,(PVOID)(IOP_BASE),sizeof(IOPreg),
- PAGE_READWRITE | PAGE_NOCACHE )) {
- ERRORMSG(1,(TEXT("For pIOPregs: VirtualCopy failed!rn")));
- PddpTouchPanelDeallocateVm();
- return (FALSE);
- }
- }
- }
- if(v_pADCregs == NULL) {
- v_pADCregs = (volatile ADCreg *)
- VirtualAlloc(0,sizeof(ADCreg),MEM_RESERVE, PAGE_NOACCESS);
- if(v_pADCregs == NULL) {
- ERRORMSG(1,(TEXT("For ADCreg: VirtualAlloc failed!rn")));
- return (FALSE);
- }
- else {
- if(!VirtualCopy((PVOID)v_pADCregs,(PVOID)(ADC_BASE),sizeof(ADCreg),
- PAGE_READWRITE | PAGE_NOCACHE )) {
- ERRORMSG(1,(TEXT("For pADCregs: VirtualCopy failed!rn")));
- PddpTouchPanelDeallocateVm();
- return (FALSE);
- }
- }
- }
- if(v_pPWMregs == NULL) {
- v_pPWMregs = (volatile PWMreg *)
- VirtualAlloc(0,sizeof(PWMreg),MEM_RESERVE, PAGE_NOACCESS);
- if(v_pPWMregs == NULL) {
- ERRORMSG(1,(TEXT("For PWMreg: VirtualAlloc failed!rn")));
- return (FALSE);
- }
- else {
- if(!VirtualCopy((PVOID)v_pPWMregs,(PVOID)(PWM_BASE),sizeof(PWMreg),
- PAGE_READWRITE | PAGE_NOCACHE )) {
- ERRORMSG(1,(TEXT("For PWMreg: VirtualCopy failed!rn")));
- return (FALSE);
- }
- }
- }
- if(v_pINTregs == NULL) {
- v_pINTregs = (volatile INTreg *)
- VirtualAlloc(0,sizeof(INTreg),MEM_RESERVE, PAGE_NOACCESS);
- if(v_pINTregs == NULL) {
- ERRORMSG(1,(TEXT("For INTreg: VirtualAlloc failed!rn")));
- return (FALSE);
- }
- else {
- if(!VirtualCopy((PVOID)v_pINTregs,(PVOID)(INT_BASE),sizeof(INTreg),
- PAGE_READWRITE | PAGE_NOCACHE )) {
- ERRORMSG(1,(TEXT("For INTreg: VirtualCopy failed!rn")));
- return (FALSE);
- }
- }
- }
- //
- // If the address space of the client process doesn't yet have the
- // mapping to the pen dma area; map it. If the mapping fails
- // we return FALSE
- //
- if ( v_pDriverGlobals == NULL )
- {
- v_pDriverGlobals =
- (PDRIVER_GLOBALS)
- VirtualAlloc( 0,
- DRIVER_GLOBALS_PHYSICAL_MEMORY_SIZE,
- MEM_RESERVE,
- PAGE_NOACCESS
- );
- if ( v_pDriverGlobals == NULL )
- {
- DEBUGMSG( ZONE_ERROR, (TEXT( "TouchPanelEnable: VirtualAlloc failed!rn")) );
- PddpTouchPanelDeallocateVm();
- return ( FALSE );
- }
- Ret = VirtualCopy( (LPVOID)v_pDriverGlobals,
- (LPVOID)DRIVER_GLOBALS_PHYSICAL_MEMORY_START,
- DRIVER_GLOBALS_PHYSICAL_MEMORY_SIZE,
- PAGE_READWRITE | PAGE_NOCACHE
- );
- if ( Ret == FALSE )
- {
- DEBUGMSG( ZONE_ERROR, (TEXT( "TouchPanelEnable: VirtualCopy failed!rn")) );
- PddpTouchPanelDeallocateVm();
- return ( FALSE );
- }
- }
- // Set up mutex for access to shared registers
- if ((v_hTchAudMutex = CreateMutex(NULL, FALSE, TCHAUD_MUTEX_NAME)) == NULL) {
- DEBUGMSG(ZONE_ERROR, (TEXT("TouchPanelEnable: Error %u in CreateMutexrn"),
- GetLastError()));
- return ( FALSE );
- }
- // Power on touch panel
- TouchPanelPowerOn();
- // Setup pen down interrupts, but leave ints disabled until InterruptEnable().
- TCHAUD_SEM_LOCK();
- PddpSetupPenDownIntr(FALSE);
- TCHAUD_SEM_UNLOCK();
- return( TRUE ); // we always succeed!!!!!!
- }
- // @doc EX_TOUCH_DDSI EXTERNAL DRIVERS DDSI TOUCH_PANEL
- //
- // @func ULONG | DdsiTouchPanelDisable |
- // Powers down the touch panel device.
- //
- // @comm
- // Implemented in the PDD.
- //
- VOID
- DdsiTouchPanelDisable(
- VOID
- )
- {
- //
- // Check pointers in case the enable failed.
- //
- if(v_pADCregs == NULL)
- return ;
- TouchPanelPowerOff(); // Power down the device
- PddpTouchPanelDeallocateVm(); // free up any resources
- }
- //
- // @doc EX_TOUCH_DDSI EXTERNAL DRIVERS DDSI TOUCH_PANEL
- //
- // @func LONG | DdsiTouchPanelAttach |
- // This routine no longer does anything. All functionallity has been moved
- // from here into DdsiTouchPanelEnable to allow this code to be statically
- // linked with GWE rather than existing as a DLL. Technically, when built
- // as a DLL we should keep an attach count and only allow touh.dll to be
- // loaded once. But, since we are loaded at boot time by GWE, there is
- // no real concern about multiple loads (unless gwe has a bug!).
- //
- // @rdesc
- // Always returns 0
- //
- // @comm
- // Implemented in the PDD.
- //
- LONG
- DdsiTouchPanelAttach(
- VOID
- )
- {
- return( 1 );
- }
- //
- // @doc EX_TOUCH_DDSI EXTERNAL DRIVERS DDSI TOUCH_PANEL
- //
- // @func LONG | DdsiTouchPanelDetach |
- // See the descrition for attach. All functionallity has been moved into
- // DdsiTouchPanelDisable.
- //
- // @rdesc
- // The updated global counter. If the initializations failed, the returned
- // count is 0.
- //
- // @comm
- // Implemented in the PDD.
- //
- LONG
- DdsiTouchPanelDetach(
- VOID
- )
- {
- return ( 0 );
- }
- #define COODI_Y
- //
- // @doc EX_TOUCH_DDSI EXTERNAL DRIVERS DDSI TOUCH_PANEL
- //
- // @func void | DdsiTouchPanelGetPoint |
- // Returns the most recently acquired point and its associated tip state
- // information.
- //
- // @parm PDDSI_TOUCHPANEL_TIPSTATE | pTipState |
- // Pointer to where the tip state information will be returned.
- // @parm PLONG | pUnCalX |
- // Pointer to where the x coordinate will be returned.
- // @parm PLONG | pUnCalY |
- // Pointer to where the y coordinate will be returned.
- //
- // @comm
- // Implmented in the PDD.
- //
- #if ( LCD_TYPE == TFT640_480 )
- #define TOUCH_MAX_X 890
- #define TOUCH_MIN_X 125
- #define TOUCH_MAX_Y 860
- #define TOUCH_MIN_Y 140
- #define TOUCH_X 640
- #define TOUCH_Y 480
- #else
- #define TOUCH_MAX_X 900 // 950
- #define TOUCH_MIN_X 100 // 90
- #define TOUCH_MAX_Y 920 // 960 // 910
- #define TOUCH_MIN_Y 100 // 70 //50
- #define TOUCH_X 240
- #define TOUCH_Y 320
- #endif
- #define TOUCH_ERR 50
- static int second = 0;
- VOID Touch_CoordinateConversion(INT *px, INT *py)
- {
- INT TmpX, TmpY;
- INT TmpX0, TmpY0;
- TmpX0 = *px; TmpY0 = *py;
- TmpX = (*px >= TOUCH_MAX_X) ? (TOUCH_MAX_X-1) : *px;
- TmpY = (*py >= TOUCH_MAX_Y) ? (TOUCH_MAX_Y-1) : *py;
- TmpX -= TOUCH_MIN_X;
- TmpY -= TOUCH_MIN_Y;
- TmpX = (TmpX) ? TmpX : 0;
- TmpY = (TmpY) ? TmpY : 0;
- *px = ((TmpX * TOUCH_X) / (TOUCH_MAX_X-TOUCH_MIN_X))*4;
- *py = ((TmpY * TOUCH_Y) / (TOUCH_MAX_Y-TOUCH_MIN_Y))*4;
- return;
- }
- VOID
- DdsiTouchPanelGetPoint(
- TOUCH_PANEL_SAMPLE_FLAGS *pTipStateFlags,
- INT *pUncalX,
- INT *pUncalY
- )
- {
- ULONG status;
- // USHORT ioAdcCntr;
- // USHORT intrMask;
- static int SampleCount = 0;
- static TOUCH_PANEL_SAMPLE_FLAGS PrevStateFlags = TouchSampleIgnore;
- static INT PrevX = 0;
- static INT PrevY = 0;
- TOUCH_PANEL_SAMPLE_FLAGS TmpStateFlags;
- INT TmpX = 0;
- INT TmpY = 0;
- int i;
- //RETAILMSG(1, (TEXT(":::::::::::: DdsiTouchPanelGetPoint routine !!!rn")));
- // Read the status passed back by the HAL
- status = READ_REGISTER_ULONG( &(v_pDriverGlobals->tch.status) );
- if(status == TOUCH_PEN_UP) {
- v_pADCregs->rADCTSC = 0xD3; // Set stylus down interrupt
- *pTipStateFlags = TouchSampleValidFlag;
- *pUncalX = PrevX;
- *pUncalY = PrevY;
- InterruptDone( gIntrTouchChanged );
- RETAILMSG(0, (TEXT("8 - (%d, %d) 0x%Xrn"), *pUncalX, *pUncalY, *pTipStateFlags));
- }
- else if(status == TOUCH_PEN_DOWN){
- *pTipStateFlags = TouchSampleIgnore;
- *pUncalX = PrevX;
- *pUncalY = PrevY;
- Touch_Timer0_Setup();
- InterruptDone( gIntrTouchChanged );
- RETAILMSG(0, (TEXT("9 - (%d, %d) 0x%Xrn"), *pUncalX, *pUncalY, *pTipStateFlags));
- }
- else {
- if( (v_pADCregs->rADCDAT0 & 0x8000) || (v_pADCregs->rADCDAT1 & 0x8000) ){
- v_pADCregs->rADCTSC = 0xD3; // Set stylus down interrupt
- *pTipStateFlags = TouchSampleValidFlag;
- *pUncalX = PrevX;
- *pUncalY = PrevY;
- InterruptDone( gIntrTouchChanged );
- RETAILMSG(0, (TEXT("91 - (%d, %d) 0x%Xrn"), *pUncalX, *pUncalY, *pTipStateFlags));
- }
- else{ // charlie
- // <Auto X-Position and Y-Position Read>
- for (i =0; i < 3; i++) {
- // v_pADCregs->rADCTSC=(0<<8)|(1<<7)|(1<<6)|(0<<5)|(1<<4)|(1<<3)|(1<<2)|(0);
- v_pADCregs->rADCTSC=(1<<3)|(1<<2);
- // Stylus Down,Don't care,Don't care,Don't care,Don't care,XP pullup Dis,Auto,No operation
- v_pADCregs->rADCCON|=0x1; // Start Auto conversion
- while(v_pADCregs->rADCCON & 0x1); //check if Enable_start is low
- while(!(0x8000&v_pADCregs->rADCCON)); // Check ECFLG
- ybuf[i] = 0x3ff - (0x3ff & v_pADCregs->rADCDAT0);
- xbuf[i] = 0x3ff & v_pADCregs->rADCDAT1;
- }
- PddpTouchPanelEvaluateSamples( &TmpStateFlags, &TmpX, &TmpY);
- v_pADCregs->rADCTSC=(1<<8)|(1<<7)|(1<<6)|(0<<5)|(1<<4)|(0<<3)|(0<<2)|(3);
- Touch_CoordinateConversion(&TmpX, &TmpY);
- if (Touch_Pen_filtering(&TmpX, &TmpY)) // Valid touch pen
- {
- //RETAILMSG(1, (TEXT("valid touch penrn")));
- *pTipStateFlags = TouchSampleValidFlag | TouchSampleDownFlag;
- *pTipStateFlags &= ~TouchSampleIgnore;
- }
- else // Invalid touch pen
- {
- //RETAILMSG(1, (TEXT("invalid touch penrn")));
- *pTipStateFlags = TouchSampleValidFlag;
- *pTipStateFlags |= TouchSampleIgnore;
- }
- *pUncalX = PrevX = TmpX;
- *pUncalY = PrevY = TmpY;
- InterruptDone( gIntrTouch );
- RETAILMSG(0, (TEXT("0 - (%d, %d) 0x%Xrn"), *pUncalX, *pUncalY, *pTipStateFlags));
- }
- }
- return;
- }
- #define FILTER_LIMIT 25
- static BOOL
- Touch_Pen_filtering(INT *px, INT *py)
- {
- BOOL RetVal = TRUE;
- // TRUE : Valid pen sample
- // FALSE : Invalid pen sample
- static int count = 0;
- static INT x[2], y[2];
- INT TmpX, TmpY;
- INT dx, dy;
- count++;
- if (count > 2)
- { // apply filtering rule
- count = 2;
- // average between x,y[0] and *px,y
- TmpX = (x[0] + *px) / 2;
- TmpY = (y[0] + *py) / 2;
- // difference between x,y[1] and TmpX,Y
- dx = (x[1] > TmpX) ? (x[1] - TmpX) : (TmpX - x[1]);
- dy = (y[1] > TmpY) ? (y[1] - TmpY) : (TmpY - y[1]);
- if ((dx > FILTER_LIMIT) || (dy > FILTER_LIMIT)) {
- // Invalid pen sample
- *px = x[1];
- *py = y[1]; // previous valid sample
- RetVal = FALSE;
- count = 0;
- }
- else
- {
- // Valid pen sample
- x[0] = x[1]; y[0] = y[1];
- x[1] = *px; y[1] = *py; // reserve pen samples
- RetVal = TRUE;
- //RETAILMSG(1, (TEXT("RetVal = TRUErn")));
- }
- } else { // till 2 samples, no filtering rule
- x[0] = x[1]; y[0] = y[1];
- x[1] = *px; y[1] = *py; // reserve pen samples
- RetVal = FALSE; // <- TRUE jylee 2003.03.04
- }
- //if (RetVal==FALSE) {
- //}
- return RetVal;
- }
- /*++
- @func VOID | DdsiTouchPanelPowerHandler |
- System power state notification.
- @parm BOOL | bOff | TRUE, the system is powering off; FALSE, the system is powering up.
- @comm
- This routine is called in a kernel context and may not make any system
- calls whatsoever. It may read and write its own memory and that's about
- it. This routine is called by the MDD and also serves as an internal
- helper routine for touch enable/disable.
- @devnote This routine will run in kernel context, and may not make
- any system calls. If you can any subroutines inside here, make sure
- that they also follow this restriction.
- --*/
- void
- DdsiTouchPanelPowerHandler(
- BOOL bOff
- )
- {
- // USHORT mask;
- // Set flag so we know to avoid system calls
- bInPowerHandler = TRUE;
- if (bOff) {
- TouchPanelPowerOff();
- }
- else {
- TouchPanelPowerOn();
- PddpSetupPenDownIntr(TRUE);
- }
- bInPowerHandler = FALSE;
- }
- static void
- TouchPanelPowerOff()
- {
- // Powering down, stop DMA and power off touch screen
- RETAILMSG(0,(TEXT("Touch Power Offrn")));
- }
- static void
- TouchPanelPowerOn()
- {
- DWORD tmp = 0;
- v_pIOPregs->rGPGCON &= ~((0x3 << 16));
- v_pIOPregs->rGPGCON |= ((0x2 << 16)); /* External Interrupt #16 Enable */
- v_pIOPregs->rEXTINT2 &= ~(0x7 << 8); // Configure EINT18 as Both Edge Mode
- v_pIOPregs->rEXTINT2 |= (0x7 << 8);
- v_pIOPregs->rEINTPEND = (1 << 16);
- v_pIOPregs->rEINTMASK &= ~(1 << 16);
- RETAILMSG(1,(TEXT("SDMMC config set rGPGCON: %xrn"), v_pIOPregs->rGPGCON));
- RETAILMSG(1,(TEXT("Touch Initrn")));
- //
- // Setup GPIOs for touch
- //
- // Clear GPG15, 14, 13, 12
- v_pIOPregs->rGPGCON &= ~((0x03 << 30)|(0x03 << 28)|(0x03 << 26)|(0x03 << 24));
- // Set GPG15 to use as nYPON, GPG14 to use as YMON, GPG13 to use as nXPON, GPG12 to use as XMON
- v_pIOPregs->rGPGCON |= ((0x01 << 30)|(0x01 << 28)|(0x01 << 26)|(0x01 << 24));
- // Disable full up function
- v_pIOPregs->rGPGUP |= ((0x01 << 15)|(0x01 << 14)|(0x01 << 13)|(0x01 << 12));
- //
- // Setup ADC register
- //
- // Down Int, YMON:0, nYPON:1, XMON:0;nXPON:1, Pullup:1, Auto Conv.,Waiting.
- v_pADCregs->rADCTSC = (0<<8)|(1<<7)|(1<<6)|(0<<5)|(1<<4)|(0<<3)|(0<<2)|(3);
- //v_pADCregs->rADCTSC=(1<<3)|(1<<2);
- v_pADCregs->rADCDLY = ADC_DELAY_TIME;//default value for delay.
- v_pADCregs->rADCCON = (1<<14)|(ADCPRS<<6)|(7<<3); //setup channel, ADCPRS, Touch Input
- /*
- RETAILMSG(1, (TEXT("v_pIOPregs->rGPBCON = 0x%Xrn"), v_pIOPregs->rGPBCON));
- RETAILMSG(1, (TEXT("v_pIOPregs->rGPBDAT = 0x%Xrn"), v_pIOPregs->rGPBDAT));
- RETAILMSG(1, (TEXT("v_pIOPregs->rGPBUP = 0x%Xrn"), v_pIOPregs->rGPBUP));
- RETAILMSG(1, (TEXT("S2440PCLK = %drn"), S2440PCLK));
- RETAILMSG(1, (TEXT("v_pPWMregs->rTCFG0 = 0x%Xrn"), v_pPWMregs->rTCFG0));
- RETAILMSG(1, (TEXT("v_pPWMregs->rTCFG1 = 0x%Xrn"), v_pPWMregs->rTCFG1));
- RETAILMSG(1, (TEXT("v_pPWMregs->rTCON = 0x%Xrn"), v_pPWMregs->rTCON));
- RETAILMSG(1, (TEXT("v_pPWMregs->rTCNTB0 = 0x%Xrn"), v_pPWMregs->rTCNTB0));
- RETAILMSG(1, (TEXT("v_pPWMregs->rTCMPB0 = 0x%Xrn"), v_pPWMregs->rTCMPB0));
- RETAILMSG(1, (TEXT("v_pPWMregs->rTCNTO0 = 0x%Xrn"), v_pPWMregs->rTCNTO0));
- RETAILMSG(1, (TEXT("v_pPWMregs->rTCNTB1 = 0x%Xrn"), v_pPWMregs->rTCNTB1));
- RETAILMSG(1, (TEXT("v_pPWMregs->rTCMPB1 = 0x%Xrn"), v_pPWMregs->rTCMPB1));
- RETAILMSG(1, (TEXT("v_pPWMregs->rTCNTO1 = 0x%Xrn"), v_pPWMregs->rTCNTO1));
- RETAILMSG(1, (TEXT("v_pPWMregs->rTCNTB2 = 0x%Xrn"), v_pPWMregs->rTCNTB2));
- RETAILMSG(1, (TEXT("v_pPWMregs->rTCMPB2 = 0x%Xrn"), v_pPWMregs->rTCMPB2));
- RETAILMSG(1, (TEXT("v_pPWMregs->rTCNTO2 = 0x%Xrn"), v_pPWMregs->rTCNTO2));
- RETAILMSG(1, (TEXT("v_pPWMregs->rTCNTB3 = 0x%Xrn"), v_pPWMregs->rTCNTB3));
- RETAILMSG(1, (TEXT("v_pPWMregs->rTCMPB3 = 0x%Xrn"), v_pPWMregs->rTCMPB3));
- RETAILMSG(1, (TEXT("v_pPWMregs->rTCNTO3 = 0x%Xrn"), v_pPWMregs->rTCNTO3));
- RETAILMSG(1, (TEXT("v_pPWMregs->rTCNTB4 = 0x%Xrn"), v_pPWMregs->rTCNTB4));
- RETAILMSG(1, (TEXT("v_pPWMregs->rTCNTO4 = 0x%Xrn"), v_pPWMregs->rTCNTO4));
- */
- return ;
- }
- static BOOL Touch_Timer0_Setup(void) {
- unsigned int TmpTCON;
- //
- // We use Timer1 of PWM as OS Clock.
- // Disable Timer1 Init..
- v_pINTregs->rINTMSK |= BIT_TIMER1; // Mask timer1 interrupt.
- v_pINTregs->rSRCPND = BIT_TIMER1; // Clear pending bit
- v_pINTregs->rINTPND = BIT_TIMER1;
- //we operate our board with PCLK=203M/4 = 50750000Hz (50.75 Mhz)
- v_pPWMregs->rTCFG0 &= ~(0xff); /* Prescaler 1's Value */
- v_pPWMregs->rTCFG0 |= (PRESCALER); // prescaler value = 24 + 1
- v_pPWMregs->rTCFG1 &= ~(0xf<<4);
- #if( SYS_TIMER_DIVIDER == 2 )
- v_pPWMregs->rTCFG1 |= (0 << 4); /* 1/2 */
- #elif ( SYS_TIMER_DIVIDER == 4 )
- v_pPWMregs->rTCFG1 |= (1 << 4); /* 1/4 */
- #elif ( SYS_TIMER_DIVIDER == 8 )
- v_pPWMregs->rTCFG1 |= (2 << 4); /* 1/8 */
- #elif ( SYS_TIMER_DIVIDER == 16 )
- v_pPWMregs->rTCFG1 |= (3 << 4); /* 1/16 */
- #endif
- // v_pPWMregs->rTCNTB1 = 1000; // about 10 ms(203M/4/2/(255+1))=10ms
- v_pPWMregs->rTCNTB1 = (10 * (S2440PCLK / (PRESCALER+1) / SYS_TIMER_DIVIDER)) / 1000; // 10msec, Charlie
- v_pPWMregs->rTCMPB1 = 0;
- TmpTCON = v_pPWMregs->rTCON; // get TCON value to temp TCON register
- TmpTCON &= ~0xf00; // clear fields of Timer 1
- TmpTCON |= 0x200; // interval mode(auto reload), update TCVNTB4, stop
- v_pPWMregs->rTCON = TmpTCON; // put the value to TCON register
- TmpTCON = v_pPWMregs->rTCON; // get TCON value to temp TCON register
- TmpTCON &= ~0xf00; // clear fields of Timer 1
- TmpTCON |= 0x100; // interval mode, no operation, start for Timer 4
- v_pPWMregs->rTCON = TmpTCON; // put the value to TCON register
- v_pINTregs->rINTMSK &= ~BIT_TIMER1;
- return TRUE;
- }