📄 tsc_ssp.c
字号:
// Developped for TI's TSC2301
//
// Copyright (c) 2002, 2003, Texas Instruments
/* ----
Module Name:
TSC_ssp.c
Abstract:
This module contains the functions to communicate with the TSC2200/2301
device through the ssp functionality of the Cotulla Platform
Functions:
Revision History:
Bob Green (Embedded Express for Texas' Intruments) FEB 2002
--*/
#include <windows.h>
#include <types.h>
#include <memory.h>
#include <nkintr.h>
#include <oalintr.h>
//#include <reg.h>
#include <xsc1.h>
#include <xsc1bd.h>
#include <drv_glob.h>
//#include <macros.h>
#include <tsc_ssp.h>
#ifdef __cplusplus
extern "C"{
#endif
PVOID VirtualAllocCopy(unsigned size,char *str,PVOID pVirtualAddress);
void msWait(unsigned msVal);
void usWait(unsigned usVal);
#ifdef __cplusplus
}
#endif
// Functions to handle the mutex we use to ensure the two drivers don't collide.
BOOL ReleaseOurMutex(HANDLE hOurMutex);
BOOL GrabOurMutex(HANDLE hOurMutex);
void DeleteOurMutex(HANDLE hOurMutex);
HANDLE CreateOurMutex(void);
// Defines for SSP Configuration
// Bg 19JUN02 - modifying these defines from the SA1110 version
// defines for SSP Control Register 0 (SSCR0)
#define SSE_DISABLE 0x00
#define SSE_ENABLE 0x80
#define ECS_INTERNAL 0x00
#define ESC_EXTERNAL 0x40
#define FRF_MICROWIRE 0x20
#define FRF_TI 0x10
#define FRF_MOTOROLA 0x00
#define DSS_16_BIT 0x0F
#define SCR_1800_KHZ 0x0000 // Really 1.8432 Mbps
#define SCR_900KHZ 0x0100 // Really 921.6 KHz
#define SCR_600_KHZ 0x0200 // 614.4
#define SCR_300_KHZ 0x0400 // 368.64
#define SCR_200_KHZ 0x0800 // 204.8
#define SCR_100_KHZ 0x1100 // 102.4
#define SCR_50_KHZ 0x2300 // 51.2
#define SCR_7_KHZ 0xFF00 // 7.2
// defines for SSP Control Register 1 (SSCR1)
#define RIE_DISABLE 0x00
#define RIE_ENABLE 0x01
#define TIE_DISABLE 0x00
#define TIE_ENABLE 0x02
#define LBM_DISABLE 0x00
#define LBM_ENABLE 0x40
#define SPO_IDLE_LOW 0x00
#define SPO_IDLE_HIGH 0x80
#define SPH_FULL_DELAY 0x00
#define SPH_HALF_DELAY 0x10
#define MWDS_8_BIT 0x00
#define MWDS_16_BIT 0x20
#define TFT_ZERO 0x0000
#define TFT_SEVEN 0x01C0
#define RFT_SEVEN 0x1C00
#define RFT_FIFTEEN 0x3C00
// defines for SSP Status Register (SSSR)
#define TNF_FULL 0x00
#define TNF_NOT_FULL 0x02
#define RNE_EMPTY 0x00
#define RNE_NOT_EMPTY 0x40
#define BSY_IDLE 0x00
#define BSY_BUSY 0x80
#define TFS_NORMAL 0x00
#define TFS_IRQ_THROWN 0x10
#define RFS_NORMAL 0x00
#define RFS_IRQ_THROWN 0x20
#define ROR_NORMAL 0x00
#define ROR__OVERRUN 0x40
#define SPR_SHARE_COM4 0
#define SPR_USE_GPIO 1
#define GAFR_NORMAL 0
#define GAFR_ALTERNATE 1
#define GPDR_INPUT 0
#define GPDR_OUTPUT 1
#define MUTEX_NAME (TEXT("TSC2200MUTEX"))
// Module level variables
//volatile struct ppcreg *v_pPPCReg = NULL; // from the ADS7846 driver version
PSSP_REGS v_pSSPreg = (PSSP_REGS) SSP_BASE_U_VIRTUAL; // from the ADS7846 driver version
PGPIO_REGS v_pTSC_GPIOReg = (PGPIO_REGS)GPIO_BASE_U_VIRTUAL;
volatile HANDLE hMutex = NULL; // our handle to the named mutex used to prevent collision on the SPI communications
HANDLE CreateOurMutex(void)
{
HANDLE hRetMutex;
hRetMutex = CreateMutex(NULL, FALSE, MUTEX_NAME);
return hRetMutex;
}
void DeleteOurMutex(HANDLE hOurMutex)
{
if (hOurMutex)
CloseHandle(hOurMutex);
}
BOOL GrabOurMutex(HANDLE hOurMutex)
{
BOOL bRet = FALSE;
DWORD dwWaitRet;
if (hOurMutex)
{
dwWaitRet = WaitForSingleObject(hOurMutex, 1000);
//RETAILMSG(1, (TEXT("GrabOurMutex: %08X"), dwWaitRet));
if ( dwWaitRet != WAIT_TIMEOUT )
{
bRet = TRUE;
}
} else
{
RETAILMSG(1, (TEXT("GrabOurMutex - hOurMutex is NULL")));
}
return bRet;
}
BOOL ReleaseOurMutex(HANDLE hOurMutex)
{
BOOL bRet = FALSE;
if (hOurMutex)
bRet = ReleaseMutex(hOurMutex);
return bRet;
}
void setupSSP()
{
// volatile struct icreg *v_pICReg = (volatile struct icreg *)IC_BASE_VIRTUAL;
//PGPIO_REGS v_pTSC_GPIOReg = (PGPIO_REGS)GPIO_BASE_U_VIRTUAL;
HANDLE hTempMutex;
hTempMutex = CreateOurMutex();
// Bg 19FEB02 - changing to using named mutex for protection
if (hTempMutex)
{
if (GrabOurMutex(hTempMutex))
{
// Program PPC Pin Assignment Register (PPAR)
// IOW_REG_FIELD (struct pparBits, &v_pPPCReg->ppar, spr, SPR_USE_GPIO); // SSP pin reassignment
// Program GPIO alternate function register (GAFR0_U)
v_pTSC_GPIOReg->GAFR1_x |= GPIO_23_AF2_SCLK;
// v_pTSC_GPIOReg->GAFR1_x |= GPIO_24_AF2_SFRM;
v_pTSC_GPIOReg->GAFR1_x |= GPIO_25_AF2_TXD;
v_pTSC_GPIOReg->GAFR1_x |= GPIO_26_AF1_RXD;
// Bg 16AUG02 trying to see if we can control SFRM pin ourselves
// Program GPIO pin direction register (GPDR)
v_pTSC_GPIOReg->GPDR_x |= GPIO_23;
v_pTSC_GPIOReg->GPDR_x |= GPIO_24;
v_pTSC_GPIOReg->GPDR_x |= GPIO_25;
v_pTSC_GPIOReg->GPDR_x &= ~GPIO_26;
// Bg 16AUG02 trying to see if we can control SFRM pin ourselves
v_pTSC_GPIOReg->GPSR_x |= GPIO_24; // initially it needs to be high.
// Synchronous serial port enable (SET LAST!)
v_pSSPreg->sscr1 = (RIE_DISABLE | TIE_DISABLE | LBM_DISABLE | SPO_IDLE_LOW | SPH_HALF_DELAY | MWDS_16_BIT | TFT_ZERO | RFT_SEVEN);
v_pSSPreg->sscr0 = (DSS_16_BIT | FRF_MOTOROLA | ECS_INTERNAL | SSE_ENABLE | SCR_600_KHZ);
// Bg 19FEB02
ReleaseOurMutex(hTempMutex);
} else // GrabOurMutex
{
RETAILMSG(1, (TEXT("setupSSP - Failed to grab our mutex\r\n")));
}
} else // CreateOurMutex
{
RETAILMSG(1, (TEXT("setupSSP - Failed to grab our mutex\r\n")));
}
//RETAILMSG(1, (TEXT("setupSSP - 7\r\n")));
}
//copied directly from the ADS7825 version driver
void SetupSSPRegisters(void)
{
// check to ensure we don't do this more than once per thread
// but we don't use the start mutex, because each thread need a copy.
//RETAILMSG(1, (TEXT("SetupSSPRegisters - 1\r\n")));
if (v_pSSPreg == NULL)
{
//RETAILMSG(1, (TEXT("SetupSSPRegisters - 2\r\n")));
v_pSSPreg = (PSSP_REGS) VirtualAllocCopy(sizeof(SSP_REGS),
(char *)TEXT("TouchPanelEnable: SSP_BASE_VIRTUAL"), (PVOID)SSP_BASE_U_VIRTUAL);
//RETAILMSG(1, (TEXT("SetupSSPRegisters - 3\r\n")));
// if (v_pSSPreg)
// {
// if (v_pPPCReg == NULL)
// {
// v_pPPCReg = (volatile struct ppcreg *) VirtualAllocCopy(sizeof(struct ppcreg),
// (char *)TEXT("TouchPanelEnable: PPC_BASE_VIRTUAL"), (PVOID)PPC_BASE_VIRTUAL);
// }
// }
}
//RETAILMSG(1, (TEXT("SetupSSPRegisters - 4\r\n")));
}
void DisableSSP(void)
{
HANDLE hTempMutex;
hTempMutex = CreateOurMutex();
if (hTempMutex)
{
if (GrabOurMutex(hTempMutex))
{
// disable SPP operation using the SSCR/SSE register
v_pSSPreg->sscr0 &= ~SSE_ENABLE;
ReleaseOurMutex(hTempMutex);
} else // GrabOurMutex
{
RETAILMSG(1, (TEXT("DisableSSP - Failed to grab our mutex\r\n")));
}
}
}
void EnableSSP(void)
{
HANDLE hTempMutex;
hTempMutex = CreateOurMutex();
if (hTempMutex)
{
if (GrabOurMutex(hTempMutex))
{
// enable SPP operation using the SSCR/SSE register
v_pSSPreg->sscr0 |= SSE_ENABLE;
ReleaseOurMutex(hTempMutex);
} else // GrabOurMutex
{
RETAILMSG(1, (TEXT("EnableSSP - Failed to grab our mutex\r\n")));
}
}
}
// This should be the first function any driver calls...
void InitSSP(void)
{
//RETAILMSG(1, (TEXT("InitSSP\r\n")));
// setup the structures and pointers to the SSP registers
// SetupSSPRegisters();
// configure the SSP registers
setupSSP();
#ifdef XXX
// setup DMA buffer
dma_buf = (PUCHAR)VirtualAlloc(0, DMA_BUFFER_SIZE, MEM_RESERVE, PAGE_NOACCESS);
if (dma_buf)
{
VirtualCopy((LPVOID) dma_page[0],
(LPVOID)DMA_BUFFER_VIRTUAL, //this will clobber DMA, itshould be DMA_RCV_A_BUFFER_BASE_VIRTUAL,
DMA_BUFFER_SIZE,
PAGE_READWRITE | PAGE_NOCACHE);
} else
{
RETAILMSG( 1, (TEXT("dma_buf Allocation Failed")));
ERRMSG("dma_buf Allocation Failed");
}
#endif
//RETAILMSG(1, (TEXT("InitSSP - exiting\r\n")));
}
/////////////////////////////////////////////////////
/////////////////////////////////////////////////////
///// Start of functions for SPI Transactions /////
/////////////////////////////////////////////////////
/////////////////////////////////////////////////////
void TwoWordSPITransaction(unsigned __int16 *iWord1, unsigned __int16 *iWord2)
{
unsigned __int16 iData;
unsigned __int16 iTempData;
unsigned __int16 iStatus = 0;
BOOL bRecv = FALSE;
HANDLE hTempMutex;
hTempMutex = CreateOurMutex();
if (hTempMutex)
{
if (GrabOurMutex(hTempMutex))
{
//RETAILMSG(1, (TEXT("TwoWordSPITransaction - Sending(%X, %X)\r\n"), *iWord1, *iWord2));
// 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;
// Bg 16AUG02
// wait until SSP is no longer busy.
usWait(1);
while (v_pSSPreg->ssr & 0x00000010)
usWait(1);
// usWait(3);
iData = *iWord2;
v_pSSPreg->ssdr = iData; // dummy write
// Bg 16AUG02
// wait until SSP is no longer busy.
usWait(1);
while (v_pSSPreg->ssr & 0x00000010)
usWait(1);
// need to wait for SSP tp finish clocking in
//usWait(60);
iStatus = v_pSSPreg->ssr;
bRecv = (iStatus & 0x0008);
while (bRecv)
{
iTempData = v_pSSPreg->ssdr;
*iWord1 = *iWord2;
*iWord2 = iTempData;
//RETAILMSG(1, (TEXT("TwoWordSPITransaction -- 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("TwoWordSPITransaction - Failed to grab our mutex\r\n")));
}
} else
{
RETAILMSG(1, (TEXT("TwoWordSPITransaction - Failed to create our mutex\r\n")));
}
}
void ThreeWordSPITransaction(unsigned __int16 *iWord1, unsigned __int16 *iWord2, unsigned __int16 *iWord3)
{
unsigned __int16 iData;
unsigned __int16 iTempData;
unsigned __int16 iStatus = 0;
BOOL bRecv = FALSE;
HANDLE hTempMutex;
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;
usWait(2);
// Bg 16AUG02
// wait until SSP is no longer busy.
while (v_pSSPreg->ssr & 0x00000010)
usWait(2);
//usWait(2);
iData = *iWord2;
v_pSSPreg->ssdr = iData; // next word
// Bg 16AUG02
// wait until SSP is no longer busy.
usWait(2);
while (v_pSSPreg->ssr & 0x00000010)
usWait(2);
//usWait(2);
iData = *iWord3;
v_pSSPreg->ssdr = iData; // next word
// Bg 16AUG02
// wait until SSP is no longer busy.
usWait(2);
while (v_pSSPreg->ssr & 0x00000010)
usWait(2);
// need to wait for SSP tp finish clocking in
// ::TODO need to replace this usWait with a loop checking of the PSI busy bit int the status reg.
// usWait(90);
// 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 = iTempData;
//RETAILMSG(1, (TEXT("ThreeWordSPITransaction -- 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("TwoWordSPITransaction - Failed to grab our mutex\r\n")));
}
} else // CreateOurMutex
{
RETAILMSG(1, (TEXT("TwoWordSPITransaction - Failed to create our mutex\r\n")));
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -