www.pudn.com > DMBDRV.rar > PxaDMA.c
#include#include #include "SianoDMA.h" #include "PxaDMA.h" #if (_WINCEOSVER==502) #include #include "xllp_dmac.h" #include "xllp_defs.h" #include "dmawince.h" #else #include "xllp_dmac.h" #include "xllp_defs.h" #endif #include "memmap.h" static const DWORD userBurstSizeToDmaConfig[] = {0x1, 0x2, 0x3}; static const DWORD userBusWidthToDmaConfig[] = {0x1, 0x2, 0x3}; extern PVOID VirtualAllocCopy(unsigned size,char *str,PVOID pVirtualAddress); extern XLLP_STATUS_T XllpDmacInit(); extern XLLP_STATUS_T XllpDmacAllocChannel( P_XLLP_DMAC_CHANNEL_T pChannel, XLLP_DMAC_CHANNEL_PRIORITY_T aChannelPriority ); extern void XllpDmacFreeChannel( XLLP_DMAC_CHANNEL_T aChannel, XLLP_DMAC_DRCMR_T aDeviceDrcmr ); BOOL PhyDmaSetUp(DMA_DRV_PARAMS_ST* dev) { void* ptr; PHYSICAL_ADDRESS phyAddr; //volatile P_XLLP_DMAC_T pDmacHandle = NULL; DMA_ADAPTER_OBJECT adapter; if(XllpDmacInit()==0) { RETAILMSG(1, (TEXT("PhyDmaSetUp, VirtualAllocCopy(): GdeDmacInit Failed\r\n"))); } XllpDmacAllocChannel((XLLP_DMAC_CHANNEL_T*)&dev->channel,XLLP_DMAC_CHANNEL_PRIORITY_HIGH); phyAddr.LowPart = DMAC_BASE_PHYSICAL; phyAddr.HighPart = 0; // ptr = MmMapIoSpace(phyAddr, sizeof(DMAC_REGISTERS), FALSE); // RETAILMSG(1, (TEXT("PhyDmaSetUp, MmMapIoSpace ptr: 0x%x\r\n"),ptr)); ptr= (DMAC_REGISTERS *)VirtualAllocCopy(sizeof(DMAC_REGISTERS),"dma registers",(PVOID)(DMAC_BASE_U_VIRTUAL)); adapter.ObjectSize = sizeof(DMA_ADAPTER_OBJECT); adapter.InterfaceType = Internal; adapter.BusNumber = 0; dev->desc = HalAllocateCommonBuffer( &adapter, sizeof(DMAC_FRAME_DESCRIPTOR_ST), &dev->descPhyAddr, FALSE); dev->pDmacAddr = ptr; return TRUE; } VOID PhyDmaRemoveChannel(DMA_DRV_PARAMS_ST* dev) { DMA_ADAPTER_OBJECT adapter; adapter.ObjectSize = sizeof(DMA_ADAPTER_OBJECT); adapter.InterfaceType = Internal; adapter.BusNumber = 0; //Interrupt has ended, free the descriptors memory allocated on channel config. HalFreeCommonBuffer( &adapter, sizeof(DMAC_FRAME_DESCRIPTOR_ST), dev->descPhyAddr, dev->desc, FALSE); XllpDmacFreeChannel(dev->channel, XLLP_DMAC_MEM2MEM_MOVE); MmUnmapIoSpace(dev->pDmacAddr, sizeof(DMAC_REGISTERS)); } BOOL PhyDmaSendDescriptor(DMA_DRV_PARAMS_ST* dev,DMA_DB_NODE_ST* transaction) { volatile DMAC_REGISTERS_P pDmacAddr; DWORD tmp; DMAC_FRAME_DESCRIPTOR_ST* desc; DMA_DESCRIPTOR_ST* dbDesc = transaction->desc; ResetEvent(dev->dmaIntEvent); pDmacAddr = dev->pDmacAddr; desc = dev->desc; desc->ddadr = 1; desc->dsadr = dbDesc->srcPhyAddr; desc->dtadr = dbDesc->dstPhyAddr; desc->dcmd = dbDesc->len; tmp = userBurstSizeToDmaConfig[dev->burstSize]; desc->dcmd |= (tmp<<16); // BURST tmp = userBusWidthToDmaConfig[dev->busWidth]; desc->dcmd |= (tmp<<14); // TRANSFER WIDTH if (dbDesc->flags & DMA_INC_SRC_ADDR) desc->dcmd |= DMAC_DCMD_INCSRCADDR; if (dbDesc->flags & DMA_INC_DST_ADDR) desc->dcmd |= DMAC_DCMD_INCTRGADDR; if (dbDesc->flags & DMA_USE_DST_FLOW_CONTROL) desc->dcmd |= DMAC_DCMD_FLOWTRG; if (dbDesc->flags & DMA_USE_SRC_FLOW_CONTROL) desc->dcmd |= DMAC_DCMD_FLOWSRC; desc->dcmd |= DMAC_DCMD_ENDIRQEN; // Enable end interrupt for last descriptor. if (dev->useHWFlowCtrl == TRUE) {//Request to Channel Map for DREQ pDmacAddr->drcmr1[dev->dmaReq] = DMAC_DRCRM_MAP_CHANNEL + dev->channel; } //Clear all existing interrupts and set mode to no descriptor fetch pDmacAddr->dcsr[dev->channel] = DMAC_DCSR_CLEAR_ALL_INTERRUPTS; // DALGN - DMA ALIGNMENT REG. if ((dbDesc[0].srcPhyAddr & 0x7) || (dbDesc[0].dstPhyAddr & 7)) pDmacAddr->dalgn |= 1< channel; else pDmacAddr->dalgn &= ~(1< channel); //Set DMA first descriptor pDmacAddr->ddg[dev->channel].ddadr = dev->descPhyAddr.LowPart; // Start Running pDmacAddr->dcsr[dev->channel] = DMAC_DCSR_RUN;// | DMAC_DCSR_EORIRQEN; return TRUE; } DWORD PhyDmaIntHandler(DMA_DRV_PARAMS_ST* dev, DMA_DB_NODE_ST* transaction) { DWORD stReg; stReg = GetEventData(dev->dmaIntEvent); //RETAILMSG(1, (TEXT("DMB dma int.\r\n"))); //Check that status returned from DMA controllers is good. if (stReg & DMAC_DCSR_ENDINTR || stReg & DMAC_DCSR_EORINT) return DMA_STATUS_OK; else return DMA_STATUS_ERR; }