📄 gspx-pxa.c
字号:
/// Output:
/// none
/// Return:
/// 0 - success
/// -1 - failure
GSPI_STATUS ssp_read_data(PVOID hDC, WORD* datPt, WORD reg, WORD nword)
{
GSPI_STATUS result;
int i;
for (i=0 ; i<GSPI_MAX_REG_RETRY ; i++) {
result = ssp_read_data_direct(hDC, datPt, reg, nword, g_spi_dummy_clk_data);
if (result == GSPI_SUCCESS) {
break;
}
}
if (i == GSPI_MAX_REG_RETRY) {
GSPIMSG(ERRMSG, (L"%s, Read data(%xh) timeout \n", TEXT(__FUNCTION__), nword));
result = GSPI_TIMEOUT;
}
return result;
}
///
/// ssp_write_data: Write the data from SSP interface
/// Input:
/// hDC - the context returned from SSP_Init
/// datPt - data buffer
/// size - size of the data buffer
/// Output:
/// datPt - returned data buffer
/// size - size of the returned data buffer
/// Return:
/// 0 - success
/// -1 - failure
GSPI_STATUS ssp_write_data(PVOID hDC, WORD* datPt, WORD reg, WORD nword)
{
///Note: reg(0x24) = DATA_PORT
GSPI_STATUS result;
int i;
for (i=0 ; i<GSPI_MAX_REG_RETRY ; i++) {
result = ssp_write_data_direct(hDC, datPt, reg, nword);
if (result == GSPI_SUCCESS) {
break;
}
}
if (i == GSPI_MAX_REG_RETRY) {
GSPIMSG(ERRMSG, (L"%s, Read data(%xh) timeout \n", TEXT(__FUNCTION__), nword));
result = GSPI_TIMEOUT;
}
return result;
}
///===========================================
static BOOLEAN dev_ist(PSSP_HARDWARE_CONTEXT pHC)
{
#if (USE_DEVIRQ == 0)
if (pHC->DriverShutdown == TRUE) {
return FALSE;
}
#endif ///USE_DEVIRQ
//###xlin BSP clear it already
// {
// pHC->pGPIORegs->GEDR0 = (1 << SSP_INTR);
// }
//Doing the ISR service routine;
if (pHC->isrFunc != NULL) {
pHC->isrFunc(pHC->isrContext);
}
return TRUE;
}
static BOOLEAN dma_ist(LPVOID param)
{
BOOLEAN result = FALSE;
MYDMAPARAM *pDmaParam = (MYDMAPARAM *)param;
volatile DWORD dcsr;
///GSPIMSG(1, (TEXT("Enter %s"), TEXT(__FUNCTION__)));
dcsr = pDmaParam->pDMARegs->dcsr[pDmaParam->channel];
///GSPIMSG(1, (TEXT("ch:%d dcsr= %xh"), pDmaParam->channel, dcsr));
//dcsr &= ~DCSR_STOPIRQEN;
//dcsr |= DCSR_ENDINTR;
///pDmaParam->pDMARegs->dcsr[pDmaParam->channel] = dcsr;
GSPIMSG(DMA_MSG, (TEXT("Write dcsr= %xh"), dcsr));
///if ((dcsr & DCSR_RUN) && (dcsr & DCSR_STOPSTATE)) {
if (dcsr & (DCSR_BUSERR|DCSR_ENDINTR)) {
dcsr &= ~DCSR_STOPIRQEN;
dcsr |= DCSR_ENDINTR;
pDmaParam->pDMARegs->dcsr[pDmaParam->channel] = dcsr;
dcsr = pDmaParam->pDMARegs->dcsr[pDmaParam->channel];
GSPIMSG(DMA_MSG, (TEXT("=>after clr: ch:%d dcsr= %xh"), pDmaParam->channel, dcsr));
SetEvent(pDmaParam->dmaWaitObj);
result = TRUE;
}
///Bus Error
if (dcsr & DCSR_BUSERR) {
///dcsr |= DCSR_BUSERR;
GSPIMSG(ERRMSG, (TEXT("%s => DMA Bus Error"), TEXT(__FUNCTION__)));
goto funcFinal;
}
///Data transfer completed
if (dcsr & DCSR_ENDINTR) {
GSPIMSG(PROGFLOW, (TEXT("%s => DMA Complete"), TEXT(__FUNCTION__)));
goto funcFinal;
}
funcFinal:
return result;
}
#if 0
#define CONTROLLER_DMA_ISR_DLL_TEXT _T("DMAIsrDll")
#define CONTROLLER_DMA_ISR_HANDLER_TEXT _T("DMAIsrHandler")
#define CONTROLLER_DMA_IRQ_TEXT _T("DMAIRQ")
#define CONTROLLER_DMA_SYSINT_TEXT _T("DMASysIntr")
#define CONTROLLER_DMA_CHANNEL_TEXT _T("DMAChannel")
#define CONTROLLER_DMA_IST_PRI_TEXT _T("DMAISTPriority")
#define CONTROLLER_DMA_BUFFER_SIZE_TEXT _T("DMABufferSize")
void LoadRegistrySettings(HKEY hKeyDevice, PSSP_HARDWARE_CONTEXT pController)
{
DWORD dwRegVal;
DWORD dwDataSize;
DWORD dwType;
// Get the DMA Information
dwDataSize = sizeof(DWORD);
if( ERROR_SUCCESS == RegQueryValueEx( hKeyDevice, CONTROLLER_DMA_CHANNEL_TEXT,
NULL, &dwType, (LPBYTE)&dwRegVal, &dwDataSize ) &&
REG_DWORD == dwType )
{
if( dwRegVal > 31 )
{
pController->dwDmaChannel = 0xffffffff;
return FALSE;
}
pController->dwDmaChannel = dwRegVal;
// get the DMA IRQ
dwDataSize = sizeof(DWORD);
if( ERROR_SUCCESS == RegQueryValueEx( hKeyDevice, CONTROLLER_DMA_IRQ_TEXT,
NULL, &dwType, (LPBYTE)&dwRegVal, &dwDataSize ) &&
REG_DWORD == dwType )
{
pController->dwDmaIRQ = dwRegVal;
}
else
{
pController->dwDmaIRQ = IRQ_DMAC;
}
// get the DMA buffer size
dwDataSize = sizeof(DWORD);
if( ERROR_SUCCESS == RegQueryValueEx( hKeyDevice, CONTROLLER_DMA_BUFFER_SIZE_TEXT,
NULL, &dwType, (LPBYTE)&dwRegVal, &dwDataSize ) &&
REG_DWORD == dwType )
{
pController->dwDmaBufferSize = dwRegVal;
}
else
{
pController->dwDmaBufferSize = 0;
}
// get the DMA SysInt
dwDataSize = sizeof(DWORD);
if( ERROR_SUCCESS == RegQueryValueEx( hKeyDevice, CONTROLLER_DMA_SYSINT_TEXT,
NULL, &dwType, (LPBYTE)&dwRegVal, &dwDataSize ) &&
REG_DWORD == dwType )
{
pController->dwDmaSysIntr = dwRegVal;
}
else
{
pController->dwDmaSysIntr = SYSINTR_UNDEFINED;
}
dwDataSize = sizeof(pController->wszDmaIsrDll);
if( ERROR_SUCCESS == RegQueryValueEx( hKeyDevice, CONTROLLER_DMA_ISR_DLL_TEXT,
NULL, &dwType, (LPBYTE)pController->wszDmaIsrDll, &dwDataSize ) &&
REG_SZ == dwType )
{
}
else
{
pController->wszDmaIsrDll[0] = 0;
}
dwDataSize = sizeof(pController->wszDmaIsrHandler);
if( ERROR_SUCCESS == RegQueryValueEx( hKeyDevice, CONTROLLER_DMA_ISR_HANDLER_TEXT,
NULL, &dwType, (LPBYTE)pController->wszDmaIsrHandler, &dwDataSize ) &&
REG_SZ == dwType )
{
}
else
{
pController->wszDmaIsrHandler[0] = 0;
}
dwDataSize = sizeof(DWORD);
if( ERROR_SUCCESS == RegQueryValueEx( hKeyDevice, CONTROLLER_DMA_IST_PRI_TEXT,
NULL, &dwType, (LPBYTE)&dwRegVal, &dwDataSize ) &&
REG_DWORD == dwType )
{
pController->DmaIstThreadPriority = dwRegVal;
}
else
{
pController->DmaIstThreadPriority = SDH_DMA_CONTROLLER_PRIORITY;
}
}
else
{
pController->dwDmaChannel = 0xffffffff;
pController->wszDmaIsrDll[0] = 0;
pController->wszDmaIsrHandler[0] = 0;
}
return;
}
#endif ///0
#if (USE_DEVIRQ == 0)
///crlo: A problem while using a polling mode:
///Description: there is a delay if no interrupt.
/// However, NdisMSleep has overhead that 1ns is still too big
///=> the performance of 1 tx thread in Chariot could be very bad
/// Note: If putting more threads, we may not see this problem
/// because there may always be interrupts
static ULONG dev_isrpoll_func(PSSP_HARDWARE_CONTEXT pHC)
{
DWORD dwStatus;
MYINTRINFO* pMyIntrInfo = &pHC->DevIntrInfo;
const DWORD EDGEREG = (0x00000001 << SSP_INTR);
DWORD intrval;
///Wait until we get the 1st edge detection.
while (((pHC->pGPIORegs->GEDR0 & EDGEREG) == 0) &&
(pMyIntrInfo->quitIST == FALSE)) {
dwStatus = WaitForSingleObject(pMyIntrInfo->hIntrEvent, 1);
}
while (pMyIntrInfo->quitIST == FALSE) {
intrval = pHC->pGPIORegs->GPLR0 & EDGEREG;
if (intrval == 0) {
pMyIntrInfo->pIstFunc(pMyIntrInfo->param);
} else {
Sleep(0);
}
}
SetEvent(pMyIntrInfo->waitobj);
return TRUE;
}
#endif ///USE_DEVIRQ
///
/// intr_init: Initialize the Interrupt
/// Input:
/// pHC - Hard context
/// Output:
/// None
/// Return:
/// 0 - success
/// -1 - fail
static int intr_init(PSSP_HARDWARE_CONTEXT pHC)
{
int result = 0;
///DWORD threadID; // thread ID
ENTERFUNC();
if (pHC == NULL) {
result = -1;
goto funcFinal;
}
set_GPIO_mode(pHC->pGPIORegs, SSP_INTR|SSPIRQ_ATTR); ///INTR
set_GPIO_IRQ_edge(pHC->pGPIORegs, SSP_INTR, SIG_FALLING);
///Initialize the device interrupt info
pHC->DevIntrInfo.irq = IRQ_GPIO17_EXPBD;
pHC->DevIntrInfo.dwSysIntr = SYSINTR_UNDEFINED;
pHC->DevIntrInfo.pIstFunc = (MYISTFUNC) dev_ist;
pHC->DevIntrInfo.param = (LPVOID)pHC;
#if (USE_DEVIRQ == 1)
///Initialize the interrupt, IST
setupInterrupt(&pHC->DevIntrInfo);
///Load the ISR
//installISR(&pHC->DevIntrInfo);
#else
{
MYINTRINFO* pMyIntrInfo = &pHC->DevIntrInfo;
DWORD threadID;
if(!(pMyIntrInfo->hIntrEvent = CreateEvent( NULL, FALSE, FALSE, NULL))) {
GSPIMSG(ERRMSG, (TEXT("CreateEvent(DevIntrInfo.hIntrEvent) FAILED!\n")));
goto funcFinal;
}
pMyIntrInfo->hISTHandle = CreateThread((LPSECURITY_ATTRIBUTES)NULL,
0,
dev_isrpoll_func,
pHC,
0,
&threadID);
if (pMyIntrInfo->hISTHandle == NULL) {
GSPIMSG(ERRMSG, (TEXT("hSSPInterThread Create FAILED!\n")));
goto funcFinal;
}
CeSetThreadPriority(pMyIntrInfo->hISTHandle, DEFAULT_IST_PRIORITY);
}
#endif ///USE_DEVIRQ
funcFinal:
EXITFUNC(result);
return result;
}
VOID intr_deinit(PSSP_HARDWARE_CONTEXT pDC)
{
PSSP_HARDWARE_CONTEXT pHC = (PSSP_HARDWARE_CONTEXT)pDC;
MYINTRINFO* pMyIntrInfo = &pHC->DevIntrInfo;
#if (USE_DMA == 1) && (USE_DMAIRQ == 1)
int i;
#endif
pHC->DriverShutdown = TRUE;
clrInterrupt(pMyIntrInfo);
CloseHandle(pMyIntrInfo->hIntrEvent);
#if (USE_DMA == 1) && (USE_DMAIRQ == 1)
if(NULL != pHC->hBusAcceHND)
{
CloseBusAccessHandle(pHC->hBusAcceHND);
pHC->hBusAcceHND = NULL;
}
for (i=0 ; i<MAXDMA_PARAM ; i++)
{
clrInterrupt(&pHC->DMAIntrInfo[i]);
}
#endif /// (USE_DMA == 1) && (USE_DMAIRQ == 1)
//put the devcice into power down mode
gspx_power_down(pHC);
///Delete the synchronization semphore
if (pHC->waitqueue)
{
CloseHandle(pHC->waitqueue);
pHC->waitqueue = NULL;
}
return;
}
///
/// dma_init: Initialize the DMA
/// Input:
/// pHC - Hard context
/// Output:
/// None
/// Return:
/// 0 - success
/// -1 - fail
static int dma_init(PSSP_HARDWARE_CONTEXT pHC)
{
int result=0;
DMA_ADAPTER_OBJECT Adapter;
PHYSICAL_ADDRESS PA;
PHYSICAL_ADDRESS DCSRAddr[] = { {DMA_DCSR(DMA_CH_READ), 0},
{DMA_DCSR(DMA_CH_RW), 0}};
DWORD inIoSpace=0; ///I/O Space
///DWORD threadID; // thread ID
#if (USE_DMA == 1)
BULVERDE_SSP_EXT_REG *phySSPBase = (BULVERDE_SSP_EXT_REG*)(SSPREG_PHY_BASE);
#endif ///USE_DMA
if (pHC == NULL) {
result = -1;
goto errFuncRet;
}
///Allocate the DMA buffers
Adapter.ObjectSize = sizeof(DMA_ADAPTER_OBJECT);
Adapter.InterfaceType = Internal;
Adapter.BusNumber = 0;
#if (USE_DMA == 1)
///Allocate DMA Descriptor
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -