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

📄 pxa-gspi.c

📁 基于wince5.0的GSPI8686 wifi驱动源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	///Note: reg(0x24) = DATA_PORT
	GSPI_STATUS	result;
	int			i;
	///crlo:critical ++
	PSSP_HARDWARE_CONTEXT	pHC = (PSSP_HARDWARE_CONTEXT)hDC;
//GSPIMSG(1, (L"wdat(%xh) \n", nword));
	EnterCriticalSection(&pHC->SSPCritFunc);
	///crlo:critical --
	for (i=0 ; i<GSPI_MAX_REG_RETRY ; i++) {
		///result = ssp_write_data_direct(hDC, datPt, 0x24, size);
		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;
	}
	///crlo:critical ++
	LeaveCriticalSection(&pHC->SSPCritFunc);
	///crlo:critical --
	return result;
}

///===========================================
int pxa_read_intstate(DWORD hDC)
{
	PSSP_HARDWARE_CONTEXT	pHC;
	DWORD			gplr, gedr;
	DWORD			resval;

	if (hDC == 0) {
		resval = 0;
		goto funcfinal;
	}
	pHC = (PSSP_HARDWARE_CONTEXT) hDC;

	gedr = pHC->pGPIORegs->GEDR0;
	gplr = pHC->pGPIORegs->GPLR0;
	GSPIMSG(1, (L"(GPLR0, GEDR): (%08xh, %08xh) \n", gplr, gedr));
	resval = (gplr >> SSP_INTR)&1;
funcfinal:
	return resval;
}
///===========================================

static BOOLEAN dev_ist(PSSP_HARDWARE_CONTEXT pHC, DWORD dwSysIntr)
{
	BOOLEAN		result = TRUE;

    
	if ((pHC->pGPIORegs->GEDR0 & (1 << SSP_INTR)) == 0) {
		GSPIMSG(1, (TEXT("dev_ist(), not our interrupt")));
		goto funcfinal;
	}

	///A patch for the MAINSTONE BSP
	///We use GPIO_22 as our interrupt source. We need to clear the GEDR (GPIO Edge Detect Status Register)
	/// manually. Otherwise, the BSP will think the interrupt has not been served & come to IST continually
	{
		pHC->pGPIORegs->GEDR0 = (1 << SSP_INTR);
		InterruptDone(dwSysIntr);
	}

	//Doing the ISR service routine;
	if (pHC->isrFunc != NULL) {
		pHC->isrFunc(pHC->isrContext);
	}
funcfinal:
	return result;
}



static BOOLEAN dma_ist(LPVOID param, DWORD dwSysIntr)
{
	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("dmaist(): 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;
		InterruptDone(dwSysIntr);
	}

	///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;
}


///
/// 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_GPIOXX_2;
	pHC->DevIntrInfo.pIstFunc = (MYISTFUNC) dev_ist;
	pHC->DevIntrInfo.param = (LPVOID)pHC;
	///Initialize the interrupt, IST 
	setupInterrupt(&pHC->DevIntrInfo);
	///Load the ISR
	//installISR(&pHC->DevIntrInfo);

funcFinal:
	EXITFUNC(result);
	return result;
}


///
/// dma_init: Initialize the DMA
/// Input: 
///		pHC - Hard context
///	Output:
///		None
///	Return:
///		0 - success
///		-1 - fail
///PERF_DMA ++
extern NDIS_HANDLE	g_NdisAdapterHandle;
///PERF_DMA --

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

	BULVERDE_SSP_EXT_REG	*phySSPBase = (BULVERDE_SSP_EXT_REG*)(SSPREG_PHY_BASE);


	if (pHC == NULL) {
		result = -1;
		goto errFuncRet;
	}

	///Allocate the DMA buffers
    Adapter.ObjectSize    = sizeof(DMA_ADAPTER_OBJECT);
    Adapter.InterfaceType = Internal;
    Adapter.BusNumber     = 0;

	///Allocate DMA Descriptor
	pHC->read_desc = (DMADescriptorChannelType *) HalAllocateCommonBuffer(&Adapter, sizeof(DMADescriptorChannelType)*2, &PA, FALSE);
    if (pHC->read_desc) {
        pHC->read_desc_phys_addr = (DMADescriptorChannelType *) PA.LowPart;
    }

	pHC->write_desc = (DMADescriptorChannelType *) HalAllocateCommonBuffer(&Adapter, sizeof(DMADescriptorChannelType)*2, &PA, FALSE);
    if (pHC->write_desc) {
        pHC->write_desc_phys_addr = (DMADescriptorChannelType *) PA.LowPart;
    }

	pHC->rw_desc = (DMADescriptorChannelType *) HalAllocateCommonBuffer(&Adapter, sizeof(DMADescriptorChannelType)*2, &PA, FALSE);
    if (pHC->rw_desc) {
        pHC->rw_desc_phys_addr = (DMADescriptorChannelType *) PA.LowPart;
    }
	///Allocate I/O buffers
	///PERF_DMA ++
	pHC->iodata = (PBYTE) HalAllocateCommonBuffer(&Adapter, PXA_SSP_IODATA_SIZE, &PA, FALSE);
    if (pHC->iodata) {
		pHC->phys_addr = (PBYTE)PA.LowPart;
    }

	/*{
		NDIS_STATUS ndisstatus;
		ndisstatus = NdisMAllocateMapRegisters(g_NdisAdapterHandle, )
		pHC->iodata = (PBYTE) HalAllocateCommonBuffer(&Adapter, PXA_SSP_IODATA_SIZE, &PA, FALSE);
		if (pHC->iodata) {
			pHC->phys_addr = (PBYTE)PA.LowPart;
		}

	}*/
	///PERF_DMA --

	pHC->iorw = (PBYTE) HalAllocateCommonBuffer(&Adapter, PXA_SSP_IODATA_SIZE, &PA, FALSE);
    if (pHC->iorw) {
		pHC->phys_addr_rw = (PBYTE)PA.LowPart;
    }
    
	///==============================================================
	///Initialize the DMA channel parameters
	pHC->DMAParam[RDDMA_PARAM].pDMARegs = pHC->pDMARegs;
	pHC->DMAParam[RDDMA_PARAM].channel = DMA_CH_READ;
	if(!(pHC->DMAParam[RDDMA_PARAM].dmaWaitObj = CreateEvent( NULL, FALSE, FALSE,NULL))) {
        GSPIMSG(ERRMSG, (TEXT("Init rddmaWaitObj, CreateEvent FAILED")));
		result = -1;
        goto errFuncRet;
    }

	pHC->DMAParam[WTDMA_PARAM].pDMARegs = pHC->pDMARegs;
	pHC->DMAParam[WTDMA_PARAM].channel = DMA_CH_RW;
	if(!(pHC->DMAParam[WTDMA_PARAM].dmaWaitObj = CreateEvent( NULL, FALSE, FALSE,NULL))) {
        GSPIMSG(ERRMSG, (TEXT("Init wtdmaWaitObj, CreateEvent FAILED")));
		result = -1;
        goto errFuncRet;
    }

	pHC->pDMARegs->drcmr[DMA_CHMAP_SSP_RX] = pHC->DMAParam[RDDMA_PARAM].channel | DRCMR_MAPVAL;
	pHC->pDMARegs->drcmr[DMA_CHMAP_SSP_TX] = pHC->DMAParam[WTDMA_PARAM].channel | DRCMR_MAPVAL;

	///==============================================================
	/// Request the DMA IRQ

	///
	///Configure the DMA descriptor
	{
		union DMACmdReg CmdBuff;
		volatile DMADescriptorChannelType*	descPt;

	    // set CMD values with bit fields.
		//
		CmdBuff.DcmdReg.len        = 0;		 // length of the memory buffer
		CmdBuff.DcmdReg.width      = 0x2;    // binary 10 (see quick Quick Reference sheet to DMA programming in the cotulla EAS)
		CmdBuff.DcmdReg.size       = 0x1;    // binary 01
		CmdBuff.DcmdReg.endian     = 0;      // little endian
		CmdBuff.DcmdReg.flybyt     = 0;      // Flowthrough
		CmdBuff.DcmdReg.flybys     = 0;      // Flowthrough
		CmdBuff.DcmdReg.endirqen   = 0;      // 1 means Interrupt when decrement length = 0;
		CmdBuff.DcmdReg.startirqen = 0;      // 1 means Interrupt when the desc is loaded
		CmdBuff.DcmdReg.flowtrg    = 0;      // 1 means the target is an external peripheral
		CmdBuff.DcmdReg.flowsrc    = 1;      // 1 means the source is an external peripheral (and needs flow control)
		CmdBuff.DcmdReg.inctrgadd  = 1;      // 1 means increment the target address (since it's memory)
		CmdBuff.DcmdReg.incsrcadd  = 0;      // 1 means increment the source address (since it's a peripheral)

		descPt = pHC->read_desc;
		descPt->ddadr = (UINT32)(pHC->read_desc_phys_addr + 1);
		descPt->dsadr = (UINT32)(&(phySSPBase->base.ssdr));
		descPt->dtadr = (UINT32) (pHC->phys_addr);
		descPt->dcmd  = CmdBuff.DcmdDword;                     // size and cmd values of the RcvA buffer
		///====================================================================
		// set CMD values with bit fields.
		//
		CmdBuff.DcmdReg.len        = 0;		 // length of the memory buffer
		CmdBuff.DcmdReg.width      = 0x2;    // binary 10 (see quick Quick Reference sheet to DMA programming in the cotulla EAS)
		CmdBuff.DcmdReg.size       = 0x1;    // binary 01
		CmdBuff.DcmdReg.endian     = 0;      // little endian
		CmdBuff.DcmdReg.flybyt     = 0;      // Flowthrough
		CmdBuff.DcmdReg.flybys     = 0;      // Flowthrough
		CmdBuff.DcmdReg.endirqen   = 0;      // 1 means Interrupt when decrement length = 0;
		CmdBuff.DcmdReg.startirqen = 0;      // 1 means Interrupt when the desc is loaded
		CmdBuff.DcmdReg.flowtrg    = 1;      // 1 means the target is an external peripheral
		CmdBuff.DcmdReg.flowsrc    = 0;      // 1 means the source is an external peripheral (and needs flow control)
		CmdBuff.DcmdReg.inctrgadd  = 0;      // 1 means increment the target address (since it's memory)
		CmdBuff.DcmdReg.incsrcadd  = 1;      // 1 means increment the source address (since it's a peripheral)

		descPt = pHC->write_desc;
		///descPt->ddadr = (UINT32)(pHC->write_desc_phys_addr + sizeof(DMADescriptorChannelType));
		descPt->ddadr = (UINT32)(pHC->write_desc_phys_addr + 1);
		descPt->dsadr = (UINT32) (pHC->phys_addr);

		///descPt->dtadr = (UINT32)(&(pHC->pSSPRegs->base.ssdr));
		descPt->dtadr = (UINT32)(&(phySSPBase->base.ssdr));
		
		descPt->dcmd  = CmdBuff.DcmdDword;                     // size and cmd values of the RcvA buffer

		///====================================================================
		// set CMD values with bit fields.
		//
		CmdBuff.DcmdReg.len        = 0;		 // length of the memory buffer
		CmdBuff.DcmdReg.width      = 0x2;    // binary 10 (see quick Quick Reference sheet to DMA programming in the cotulla EAS)
		CmdBuff.DcmdReg.size       = 0x1;    // binary 01
		CmdBuff.DcmdReg.endian     = 0;      // little endian
		CmdBuff.DcmdReg.flybyt     = 0;      // Flowthrough
		CmdBuff.DcmdReg.flybys     = 0;      // Flowthrough
		CmdBuff.DcmdReg.endirqen   = 0;      // 1 means Interrupt when decrement length = 0;
		CmdBuff.DcmdReg.startirqen = 0;      // 1 means Interrupt when the desc is loaded
		CmdBuff.DcmdReg.flowtrg    = 1;      // 1 means the target is an external peripheral
		CmdBuff.DcmdReg.flowsrc    = 0;      // 1 means the source is an external peripheral (and needs flow control)
		CmdBuff.DcmdReg.inctrgadd  = 0;      // 1 means increment the target address (since it's memory)
		CmdBuff.DcmdReg.incsrcadd  = 1;      // 1 means increment the source address (since it's a peripheral)

		descPt = pHC->rw_desc;
		descPt->ddadr = (UINT32)(pHC->rw_desc_phys_addr + 1);
		descPt->dsadr = (UINT32) (pHC->phys_addr_rw);
		descPt->dtadr = (UINT32)(&(phySSPBase->base.ssdr));
		descPt->dcmd  = CmdBuff.DcmdDword;                     // size and cmd values of the RcvA buffer

	}
	memset(pHC->iorw, 0xff, sizeof(PXA_SSP_IODATA_SIZE));

	return result;
errFuncRet:
	return result;
}


///
/// ssp_init_hw: Initialize the H/W
/// Input: 
///		pHC - Hard context
///	Output:
///		None
///	Return:
///		None
void ssp_init_hw(PSSP_HARDWARE_CONTEXT	pHC)
{
	PHYSICAL_ADDRESS	Bulverde_GPIO_Base = {BULVERDE_BASE_REG_PA_GPIO};
	PHYSICAL_ADDRESS	Bulverde_SSP_Base = {SSPREG_PHY_BASE};
	PHYSICAL_ADDRESS	Bulverde_CLKMGR_Base = {BULVERDE_BASE_REG_PA_CLKMGR};
	PHYSICAL_ADDRESS	Bulverde_DMA_Base = {BULVERDE_BASE_REG_PA_DMAC};
	PHYSICAL_ADDRESS	Bulverde_PA_OTS_Base = {BULVERDE_BASE_REG_PA_OST};
	PHYSICAL_ADDRESS	Bulverde_ICR_Base = {BULVERDE_BASE_REG_PA_INTC};

	GSPIMSG(ERRMSG, (TEXT("===<NO DMA interrupt>===\n")));
	pHC->pGPIORegs = (BULVERDE_GPIO_REG*)MmMapIoSpace(Bulverde_GPIO_Base, sizeof(BULVERDE_GPIO_REG), FALSE);
	if (!pHC->pGPIORegs) {
		GSPIMSG(ERRMSG, (TEXT("Error in allocating GPIO register\n")));
		goto funcFinal;
	}
	
	pHC->pSSPRegs = (BULVERDE_SSP_EXT_REG*)MmMapIoSpace(Bulverde_SSP_Base, sizeof(BULVERDE_SSP_EXT_REG), FALSE);
	if (!pHC->pSSPRegs) {
		GSPIMSG(ERRMSG, (TEXT("Error in allocating SSP register\n")));
		goto funcFinal;
	}
	
	pHC->pCLKRegs = (BULVERDE_CLKMGR_REG*)MmMapIoSpace(Bulverde_CLKMGR_Base, sizeof(BULVERDE_CLKMGR_REG), FALSE);
	if (!pHC->pCLKRegs) {
		GSPIMSG(ERRMSG, (TEXT("Error in allocating CLK register\n")));
		goto funcFinal;
	}

	pHC->pDMARegs = (BULVERDE_DMA_REG*)MmMapIoSpace(Bulverde_DMA_Base, sizeof(BULVERDE_DMA_REG), FALSE);
	if (!pHC->pDMARegs) {
		GSPIMSG(ERRMSG, (TEXT("Error in allocating DMA register\n")));
		goto funcFinal;
	}

	pHC->pOSTRegs = (BULVERDE_OST_REG*)MmMapIoSpace(Bulverde_PA_OTS_Base, sizeof(BULVERDE_OST_REG), FALSE);
	if (!pHC->pOSTRegs) {
		GSPIMSG(ERRMSG, (TEXT("Error in allocating OST register\n")));
		goto funcFinal;
	}


	///
	///Configure the GPIO 
	///
	set_GPIO_mode(pHC->pGPIORegs, SSP_SCLK|SSPSCLK_ATTR);				///SCLK
	set_GPIO_mode(pHC->pGPIORegs, SSP_SFRM|SSPSFRM_ATTR);				///SFRM
	set_GPIO_mode(pHC->pGPIORegs, SSP_TX|SSPTX_ATTR);					///TX
	set_GPIO_mode(pHC->pGPIORegs, SSP_RX|SSPRX_ATTR);					///RX
	set_GPIO_signal(pHC->pGPIORegs, SSP_SFRM, SIG_UP); 
     
     
	pHC->pSSPRegs->base.sscr0 = 0;
	pHC->pSSPRegs->base.sscr1 = 0;

	///udelay(pHC->pOSTRegs, 100);
	NdisMSleep(10);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -