⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gspx-pxa.c

📁 Wince BSP 下的Wifi 驱动 基于PXA270 CPU
💻 C
📖 第 1 页 / 共 5 页
字号:
///	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 + -