📄 tsc_ssp.c
字号:
void TSC2301WriteAudioGPIOReg(unsigned __int16 newValue)
{
unsigned __int16 iData = 0, iData2 =0;
//RETAILMSG(1, (TEXT("TSC2301WriteAudioGPIOReg(%X);\r\n"), newValue));
iData = (TSC_CMD_WRITE | TSC_AUDIO_GPIO);
iData2 = newValue;
TwoWordSPITransaction(&iData, &iData2);
}
// Bg 18JUL02
unsigned __int16 TSC2301ReadAudioGPIOReg(void)
{
unsigned __int16 iData = 0, iData2 =0;
iData = (TSC_CMD_READ | TSC_AUDIO_GPIO);
iData2 = 0x0000;
TwoWordSPITransaction(&iData, &iData2);
//RETAILMSG(1, (TEXT("TSC2301ReadAudioGPIOReg() = %X;\r\n"), iData2));
return iData2;
}
// Bg 12AUG02
void TSC2301GenericWriteReg(unsigned __int16 targetReg, unsigned __int16 newValue)
{
unsigned __int16 iData = 0, iData2 =0;
//RETAILMSG(1, (TEXT("TSC2301WriteAudioGPIOReg(%X);\r\n"), newValue));
iData = targetReg;
iData2 = newValue;
TwoWordSPITransaction(&iData, &iData2);
}
// Bg 12AUG02
unsigned __int16 TSC2301GenericReadReg(unsigned __int16 sourceReg)
{
unsigned __int16 iData = 0, iData2 =0;
iData = sourceReg;
iData2 = 0x0000;
TwoWordSPITransaction(&iData, &iData2);
return iData2;
}
void TSC2200ReadX(unsigned __int16 *pXdata)
{
BOOL bRetVal = FALSE;
unsigned __int16 iData = 0, iData2 = 0, iData3 = 0;
unsigned __int16 iXdata = 0;
unsigned __int16 iYdata = 0;
//iData = 0x8000; // read page 0 addr 0 (X Reg)
iData = (TSC_CMD_READ | TSC_CMD_X);
TwoWordSPITransaction(&iData, &iData2);
*pXdata = iData2;
bRetVal = TRUE;
}
// Bg 12SEP02 - this special function is intended only for use when setting up the touch ADC reg.
void TwoTwoWordSPITransactions(unsigned __int16 *iWord1, unsigned __int16 *iWord2, unsigned __int16 *iWord3, unsigned __int16 *iWord4)
{
unsigned __int16 iData;
unsigned __int16 iTempData;
unsigned __int16 iStatus = 0;
BOOL bRecv = FALSE;
HANDLE hTempMutex;
//RETAILMSG(1, (TEXT("TwoTwoWordSPITransactions(%X, %X, %X, %X)"), *iWord1, *iWord2, *iWord3, *iWord4));
hTempMutex = CreateOurMutex();
if (hTempMutex)
{
if (GrabOurMutex(hTempMutex))
{
// Bg 16AUG02 trying to see if we can control SFRM pin ourselves
v_pTSC_GPIOReg->GPCR_x |= GPIO_24; // need to drop SFRM to signal start of frame.
v_pSSPreg->ssdr = *iWord1; // SEND out word 1
usWait(2);
// Bg 16AUG02
// wait until SSP is no longer busy.
while (v_pSSPreg->ssr & 0x00000010)
usWait(2);
iData = *iWord2;
v_pSSPreg->ssdr = iData; // SEND out word 2
// Bg 16AUG02
// wait until SSP is no longer busy.
usWait(2);
while (v_pSSPreg->ssr & 0x00000010)
usWait(2);
// here we need to raise and drop SFRM so that TSC2301 will interpret the next word and an new command
v_pTSC_GPIOReg->GPSR_x |= GPIO_24; // raise SFRM
usWait(1);
v_pTSC_GPIOReg->GPCR_x |= GPIO_24; // drop SFRM
iData = *iWord3;
v_pSSPreg->ssdr = iData; // SEND out word 3
// Bg 16AUG02
// wait until SSP is no longer busy.
usWait(2);
while (v_pSSPreg->ssr & 0x00000010)
usWait(2);
iData = *iWord4;
v_pSSPreg->ssdr = iData; // SEND out word 4
// Bg 16AUG02
// wait until SSP is no longer busy.
usWait(2);
while (v_pSSPreg->ssr & 0x00000010)
usWait(2);
// use the bRecv bit in the status reg to tell us when we've read everything in the FIFO.
iStatus = v_pSSPreg->ssr;
bRecv = (iStatus & 0x0008);
while (bRecv)
{
// grab an entry from the receive FIFO
iTempData = v_pSSPreg->ssdr;
// this little round robin below is just an easy way of making sure
// that if the SPI recieve FIFO is not empty, we still on return the
// three last words corresponding to the three words we sent
*iWord1 = *iWord2;
*iWord2 = *iWord3;
*iWord3 = *iWord4;
*iWord4 = iTempData;
//RETAILMSG(1, (TEXT("TwoTwoWordSPITransactions -- iTempData:%X\r\n"), iTempData));
usWait(20);
iStatus = v_pSSPreg->ssr;
bRecv = (iStatus & 0x0008);
}
// Bg 16AUG02 trying to see if we can control SFRM pin ourselves
v_pTSC_GPIOReg->GPSR_x |= GPIO_24; // need to raise SFRM when we are done.
ReleaseOurMutex(hTempMutex);
} else // GrabOurMutex
{
RETAILMSG(1, (TEXT("TwoTwoWordSPITransactions - Failed to grab our mutex\r\n")));
}
} else // CreateOurMutex
{
RETAILMSG(1, (TEXT("TwoTwoWordSPITransactions - Failed to create our mutex\r\n")));
}
}
// Bg 12SEP02 - new function to handling setting up the touch ADC control register.
// Due to a bug in chip itself, we have to first ensure the chip's
// internal clock running by performing a host-controlling touch conversion.
//
// Only call this function during driver initiation.
void TSC2301SetupADCReg(unsigned __int16 newValue)
{
// so, we need to first write a host-controlled X scan,
// and while the chip is still working on that (ie. the clock is still running)
// we need to write the real value we really want to the ADC reg.
unsigned __int16 iData1;
unsigned __int16 iData2;
unsigned __int16 iData3;
unsigned __int16 iData4;
BOOL bDAV = TRUE;
//RETAILMSG(1, (TEXT("TSC2301SetupADCReg(%X - %X)"), newValue, ADC_SETUP_VALUE_2));
iData1 = (TSC_CMD_WRITE | TSC_CMD_ADC); // 0x0800 - Write to ADC control Register
iData2 = ADC_SETUP_VALUE_2;
iData3 = (TSC_CMD_WRITE | TSC_CMD_ADC); // 0x0800 - Write to ADC control Register
iData4 = newValue;
TwoTwoWordSPITransactions(&iData1, &iData2, &iData3, &iData4);
// now we need to make sure that we read the X value that we have requested so that DAVB doesn't get stuck
msWait(30);
TSC2200ReadX(&iData1); // we don't really care what the result really is.
//RETAILMSG(1, (TEXT("TSC2301SetupADCReg done")));
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////
// The following functions are used to help share DAV among the various drivers and applications
///////////////////////////////////////////////////////////////////////////////////////////////////////////
// Applications or drivers wishing to read data other than touch XYor Z, can use the TSC2301ReadData or
// the TSC2301ReadPortScan functions. These two functions will coordinate with the touch screen,
// issue the request, wait for DAV to signal and return the new data.
// CreateDAVMutex, DeleteDAVMutex, GrabDAVMutex, ReleaseDAVMutex, CreateDataEvent, DeleteDataEvent,
// GrabDataEvent, and ReleaseDataEvent are all internal functions used to share DAV access.
//
// Is_DAV_Open is called by DdsiTouchPanelGetPoint in the touch driver to know whether or not
// DAV is already in use and therefore the Data available is not touch data, but some other data.
///////////////////////////////////////////////////////////////////////////////////////////////////////////
#define DAV_MUTEX_NAME (TEXT("TSC_DAV_MUTEX"))
#define DATA_EVENT_NAME (TEXT("TSC_DATA_MUTEX"))
volatile HANDLE hDAVMutex = NULL; // named mutex used to help share DAV between touch and battery, aux, etc.
volatile HANDLE hDATAEvent = NULL; // named mutex used to help share DAV between touch and battery, aux, etc.
volatile BOOL bDAVFree = TRUE;
volatile static BOOL bDAVFlag = FALSE;
HANDLE CreateDAVMutex(void)
{
HANDLE hTempMutex;
hTempMutex = CreateMutex(NULL, FALSE, DAV_MUTEX_NAME);
return hTempMutex;
}
void DeleteDAVMutex(HANDLE hTempMutex)
{
if (hTempMutex)
CloseHandle(hTempMutex);
}
BOOL GrabDAVMutex(HANDLE hTempMutex, BOOL bWait)
{
BOOL bRet = FALSE;
int iTimeout = 1000;
if (hTempMutex)
{
if (bWait)
iTimeout = 1000;
else
iTimeout = 0;
if ( WaitForSingleObject(hTempMutex, iTimeout) != WAIT_TIMEOUT )
{
bRet = TRUE;
}
}
return bRet;
}
BOOL ReleaseDAVMutex(HANDLE hTempMutex)
{
BOOL bRet = FALSE;
if (hTempMutex)
bRet = ReleaseMutex(hTempMutex);
return bRet;
}
HANDLE CreateDataEvent(void)
{
HANDLE hTempEvent;
hTempEvent = CreateEvent(NULL, FALSE, FALSE, DATA_EVENT_NAME);
return hTempEvent;
}
void DeleteDataEvent(HANDLE hTempEvent)
{
if (hTempEvent)
CloseHandle(hTempEvent);
}
BOOL GrabDataEvent(HANDLE hTempEvent, BOOL bWait)
{
BOOL bRet = FALSE;
int iTimeout = 1000;
if (hTempEvent)
{
if (bWait)
iTimeout = 1000;
else
iTimeout = 0;
if ( WaitForSingleObject(hTempEvent, iTimeout) != WAIT_TIMEOUT )
{
bRet = TRUE;
}
}
return bRet;
}
BOOL ReleaseDataEvent(HANDLE hTempEvent)
{
BOOL bRet = FALSE;
if (hTempEvent)
bRet = ReleaseMutex(hTempEvent);
return bRet;
}
BOOL TSC2301ReadData(unsigned __int16 iSetupValue, unsigned __int16 iReadValue, unsigned __int16 *pDataVal)
{
BOOL bRetVal = FALSE;
BOOL bDone = FALSE;
HANDLE hTempMutex;
HANDLE hDataEvent;
//RETAILMSG(1,(TEXT("TSC2301ReadData")));
hTempMutex = CreateDAVMutex();
if (hTempMutex)
{
//RETAILMSG(1,(TEXT("TSC2301ReadData - after creating DAV mutex")));
if (GrabDAVMutex(hTempMutex, FALSE))
{
//RETAILMSG(1,(TEXT("TSC2301ReadData - grabbed the DAVMutex")));
TSC2200WriteADCReg(iSetupValue);
hDataEvent = CreateDataEvent();
if (hDataEvent)
{
//RETAILMSG(1,(TEXT("TSC2301ReadData - about to GrabDataEvent")));
// wait until the other process (through the function below sets the hDataEvent, signally that DAV has dropped
if (GrabDataEvent(hDataEvent, TRUE))
{
// once we get here, DAV has gone low and we can read the data
//RETAILMSG(1,(TEXT("TSC2301ReadData - about to TSC2301GenericReadReg")));
*pDataVal = TSC2301GenericReadReg(iReadValue);
DeleteDataEvent(hDataEvent);
TSC2200StartConversions(); // reset so that touch screen continues to work
} else
{
//RETAILMSG(1,(TEXT("TSC2301ReadData - GrabDataEvent returned false!!!!")));
}
}
ReleaseDAVMutex(hTempMutex);
bRetVal = TRUE;
} else
{
bRetVal = FALSE;
}
DeleteDAVMutex(hTempMutex);
}
return bRetVal;
}
BOOL TSC2301ReadPortScan(unsigned __int16 *pBat1Val, unsigned __int16 *pBat2Val, unsigned __int16 *pAux1Val, unsigned __int16 *pAux2Val)
{
BOOL bRetVal = FALSE;
BOOL bDone = FALSE;
HANDLE hTempMutex;
HANDLE hDataEvent;
//RETAILMSG(1,(TEXT("TSC2301ReadData")));
hTempMutex = CreateDAVMutex();
if (hTempMutex)
{
//RETAILMSG(1,(TEXT("TSC2301ReadData - after creating DAV mutex")));
if (GrabDAVMutex(hTempMutex, FALSE))
{
//RETAILMSG(1,(TEXT("TSC2301ReadData - grabbed the DAVMutex")));
TSC2200WriteADCReg(SETUP_PORT_SCAN_VALUE);
hDataEvent = CreateDataEvent();
if (hDataEvent)
{
//RETAILMSG(1,(TEXT("TSC2301ReadData - about to GrabDataEvent")));
// wait until the other process (through the function below sets the hDataEvent, signally that DAV has dropped
if (GrabDataEvent(hDataEvent, TRUE))
{
// once we get here, DAV has gone low and we can read the data
//RETAILMSG(1,(TEXT("TSC2301ReadData - about to TSC2301GenericReadReg")));
*pBat1Val = TSC2301GenericReadReg(READ_BATT1_VALUE);
*pBat2Val = TSC2301GenericReadReg(READ_BATT2_VALUE);
*pAux1Val = TSC2301GenericReadReg(READ_AUX1_VALUE);
*pAux2Val = TSC2301GenericReadReg(READ_AUX2_VALUE);
DeleteDataEvent(hDataEvent);
TSC2200StartConversions(); // reset so that touch screen continues to work
} else
{
//RETAILMSG(1,(TEXT("TSC2301ReadData - GrabDataEvent returned false!!!!")));
}
}
ReleaseDAVMutex(hTempMutex);
bRetVal = TRUE;
} else
{
bRetVal = FALSE;
}
DeleteDAVMutex(hTempMutex);
}
return bRetVal;
}
/////////////////////////////////////////////////////////////////////
//
BOOL Is_DAV_Open(void)
{
BOOL bRetVal = FALSE;
HANDLE hDataEvent;
HANDLE hTempMutex;
hTempMutex = CreateDAVMutex();
if (hTempMutex)
{
//RETAILMSG(1,(TEXT("Is_DAV_Open - about to GrabDAVMutex")));
if (GrabDAVMutex(hTempMutex, FALSE))
{
//RETAILMSG(1,(TEXT("Is_DAV_Open - gRabbed DAV mutex - releasing it and returning")));
ReleaseDAVMutex(hTempMutex);
bRetVal = TRUE;
} else
{
//RETAILMSG(1,(TEXT("Is_DAV_Open - Couldn't GrabDAVMutex")));
hDataEvent = CreateDataEvent();
//RETAILMSG(1,(TEXT("Is_DAV_Open - CreateDataEvent")));
if (hDataEvent)
{
//RETAILMSG(1,(TEXT("Is_DAV_Open - about to set hDataEvent")));
SetEvent(hDataEvent);
//RETAILMSG(1,(TEXT("Is_DAV_Open - signaled hDataEvent now returning")));
Sleep(100);
}
}
DeleteDataEvent(hDataEvent);
}
return bRetVal;
}
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -