📄 pci.c
字号:
MCD_SINGLE_DMA | MCD_INTERRUPT | MCD_TT_FLAGS_SP, 0 | MCD_NO_CSUM | MCD_NO_BYTE_SWAP); if(result != MCD_OK) { /* There was a problem */ printf("error: MCD_startDma\n" ); } /* now increment the src */ dmatx_task.src_indx = dmatx_task.src_indx + tsize; } else printf("dma packet screw-up"); }/*** ===================================================================** Function : pci_fifo_tx_handler**** Description : PCI TX FIFO interrupt handler.** This function looks at a global structure to** determine if it needs to restart a PCI FIFO packet** to finish sending data, or to stop sending data.**** Parameters : none**** Return Value: none** ** ===================================================================*/void pci_fifo_tx_handler(void){ uint32 tsize; dmatx_task.pkt_done++; /* Clear the NT bit in the PCITSR */ MCF_PCI_PCITSR |= MCF_PCI_PCITSR_NT; /* Write Packet Size value to begin the transfer if length is < max packet size*/ if(dmatx_task.fifo_indx >= dmatx_task.length) /* was that the end of the last packet */ { /* I'm done with the FIFO */ /* Disable Normal Termination interrupt */ MCF_PCI_PCITER &= ~(MCF_PCI_PCITER_NE); printf("\ndmatx done: 0x%08X bytes written\n",dmatx_task.fifo_indx); } else if((dmatx_task.length-dmatx_task.fifo_indx) <= PCI_MAX_PKT_SIZE) { /* pre increment pointers */ tsize = dmatx_task.length-dmatx_task.fifo_indx; dmatx_task.pkt_start++; dmatx_task.fifo_indx = dmatx_task.fifo_indx + tsize; MCF_PCI_PCITPSR = MCF_PCI_PCITPSR_PKTSIZE(tsize); /* size of length*/ } else if((dmatx_task.length-dmatx_task.fifo_indx) > PCI_MAX_PKT_SIZE) { /* pre increment pointers */ tsize = PCI_MAX_PKT_SIZE; dmatx_task.pkt_start++; dmatx_task.fifo_indx = dmatx_task.fifo_indx + tsize; MCF_PCI_PCITPSR = MCF_PCI_PCITPSR_PKTSIZE(tsize); /* size of length*/ } else printf("FIFO intterrupt screw-up"); }/*** ===================================================================** Function : pci_start_dma_rx**** Description : Read data from PCI memory space and write to ** ColdFire memory space using the DMA and interrupts**** Parameters** ---------- ** -source : Pointer to source address in PCI memory space.** Must be longword aligned.** -destination: Pointer to destination address in ColdFire memory space.** Must be longword aligned.** -length : Length in Bytes to receive, must be in longword ** increments**** Return Value: none** ** ===================================================================*/void pci_start_dma_rx(uint8* source, uint8* destination, uint32 length) { int result,i; uint32 tsize; /* Set-up RX FIFO's */ /* Hold Rx controller at reset */ MCF_PCI_PCIRER |= MCF_PCI_PCIRER_RC; /* Set PCI Command, Max_Retries, and Max_Beats */ /* MCF_PCI_PCIRTCR = MCF_PCI_PCIRTCR_PCICMD(0x7); same as default out of reset */ /* Set Mode, Continuous or Non-continuous */ MCF_PCI_PCIRER |= MCF_PCI_PCIRER_CM; /* Enable Normal Termination interrupt */ MCF_PCI_PCIRER |= MCF_PCI_PCIRER_NE; /* Reset FIFO */ MCF_PCI_PCIRER |= MCF_PCI_PCIRER_RF; for(i=0;i<100;i++); /* wait */ MCF_PCI_PCIRER &= ~(0|MCF_PCI_PCIRER_RF); /* Set the FIFO Alarm and Granularity Fields */ MCF_PCI_PCIRFCR |= MCF_PCI_PCIRFCR_GR(4); /* high water mark = 128 bytes -(4*4) = 16 bytes left in the FIFO, this is when the request to the DMA is deasserted*/ MCF_PCI_PCIRFAR = MCF_PCI_PCIRFAR_ALARM(32); /* low water mark = 16 bytes, this is when the request to the DMA is asserted to take data from the FIFO and put it in memory */ /* Set Master Enable Bit and some error stuff*/ MCF_PCI_PCIRER |= MCF_PCI_PCIRER_FE | MCF_PCI_PCIRER_IAE | MCF_PCI_PCIRER_TAE | MCF_PCI_PCIRER_ME; /* Configure PCI source */ MCF_PCI_PCIRSAR = (uint32)source; /* Set the Reset Controller bit Low */ MCF_PCI_PCIRER &= ~(MCF_PCI_PCIRER_RC); /* Clear the NT bit in the PCIRSR */ MCF_PCI_PCIRSR |= MCF_PCI_PCIRSR_NT; dmarx_task.pkt_start = 0; dmarx_task.pkt_done = 0; dmarx_task.dma_start = 0; dmarx_task.dma_done = 0; dmarx_task.dma_indx = 0; dmarx_task.fifo_indx = 0; dmarx_task.length = length; dmarx_task.src_indx = source; dmarx_task.dst_indx = destination; /* Write Packet Size value to begin the transfer if length is < max packet size*/ if((dmarx_task.length-dmarx_task.dma_indx) <= PCI_MAX_PKT_SIZE) { /* pre increment pointers */ tsize = dmarx_task.length-dmarx_task.dma_indx; dmarx_task.pkt_start++; dmarx_task.dma_start++; dmarx_task.dma_indx = dmarx_task.dma_indx + tsize; dmarx_task.fifo_indx = dmarx_task.fifo_indx + tsize; MCF_PCI_PCIRPSR = MCF_PCI_PCIRPSR_PKTSIZE(tsize); /* size of length*/ /* Pop FIFO */ /* kick off DMA */ result = MCD_startDma(dma_get_channel(DMA_PCI_RX), /* channel */ (s8*)(MBAR_ADDRESS+0x84C0), /* source buffer address */ 0, /* source increment */ (s8*)dmarx_task.dst_indx, /* destination buffer address */ 4, /* destination increment */ tsize, /* number of bytes to transfer */ 4, /* width of transfers */ dma_get_initiator(DMA_PCI_RX), /* initiator to use PCI Tx*/ 5, /* priority */ 0 | MCD_SINGLE_DMA | MCD_INTERRUPT | MCD_TT_FLAGS_SP, 0 | MCD_NO_CSUM | MCD_NO_BYTE_SWAP); if(result != MCD_OK) { /* There was a problem */ printf("error: MCD_startDma\n" ); } /* now increment the dst */ dmarx_task.dst_indx = dmarx_task.dst_indx + tsize; } else if((dmarx_task.length-dmarx_task.dma_indx) > PCI_MAX_PKT_SIZE) { /* pre increment pointers */ tsize = PCI_MAX_PKT_SIZE; dmarx_task.pkt_start++; dmarx_task.dma_start++; dmarx_task.dma_indx = dmarx_task.dma_indx + tsize; dmarx_task.fifo_indx = dmarx_task.fifo_indx + tsize; MCF_PCI_PCIRPSR = MCF_PCI_PCIRPSR_PKTSIZE(PCI_MAX_PKT_SIZE); /* size of length*/ /* Pop FIFO */ /* kick off DMA */ result = MCD_startDma(dma_get_channel(DMA_PCI_RX), /* channel */ (s8*)(MBAR_ADDRESS+0x84C0), /* source buffer address */ 0, /* source increment */ (s8*)dmarx_task.dst_indx, /* destination buffer address */ 4, /* destination increment */ tsize, /* number of bytes to transfer */ 4, /* width of transfers */ dma_get_initiator(DMA_PCI_RX), /* initiator to use PCI Tx*/ 5, /* priority */ 0 | MCD_SINGLE_DMA | MCD_INTERRUPT | MCD_TT_FLAGS_SP, 0 | MCD_NO_CSUM | MCD_NO_BYTE_SWAP); if(result != MCD_OK) { /* There was a problem */ printf("error: MCD_startDma\n" ); } /* now increment the src */ dmarx_task.dst_indx = dmarx_task.dst_indx + tsize; } else printf("packet screw-up");}/*** ===================================================================** Function : pci_dma_rx_handler**** Description : DMA interrupt handler for the Receive DMA task.** This function looks at a global structure to** determine if it needs to restart a DMA task to ** finish receiveing data from the PCI Rx FIFO, or if ** it's done.**** Parameters : none**** Return Value: none** ** ===================================================================*/void pci_dma_rx_handler(void){ int result,i; uint32 tsize; /* un-stuff the FIFO */ /* but remember... the PCI FIFO could still be going */ /* up the number of dma tasks completed */ dmarx_task.dma_done++; if(dmarx_task.dma_indx >= dmarx_task.length) /* is this the last one? */ { /* I'm done with Poping data off the FIFO */ printf("\ndmarx done: 0x%08X bytes read\n",dmarx_task.dma_indx); } else if((dmarx_task.length-dmarx_task.dma_indx) <= PCI_MAX_PKT_SIZE) { /* pre increment pointers */ tsize = dmarx_task.length-dmarx_task.dma_indx; dmarx_task.dma_start++; dmarx_task.dma_indx = dmarx_task.dma_indx + tsize; /* Pop FIFO */ /* kick off DMA */ result = MCD_startDma(dma_get_channel(DMA_PCI_RX), /* channel */ (s8*)(MBAR_ADDRESS+0x84C0), /* source buffer address */ 0, /* source increment */ (s8*)dmarx_task.dst_indx, /* destination buffer address */ 4, /* destination increment */ tsize, /* number of bytes to transfer */ 4, /* width of transfers */ dma_get_initiator(DMA_PCI_RX), /* initiator to use PCI Rx*/ 5, /* priority */ 0 | MCD_SINGLE_DMA | MCD_INTERRUPT | MCD_TT_FLAGS_SP, 0 | MCD_NO_CSUM | MCD_NO_BYTE_SWAP); if(result != MCD_OK) { /* There was a problem */ printf("error: MCD_startDma\n" ); } /* now increment the dst_indx */ dmarx_task.dst_indx = dmarx_task.dst_indx + tsize; } else if((dmarx_task.length-dmarx_task.dma_indx) > PCI_MAX_PKT_SIZE) { /* pre increment pointers */ tsize = PCI_MAX_PKT_SIZE; dmarx_task.dma_start++; dmarx_task.dma_indx = dmarx_task.dma_indx + tsize; /* Pop FIFO */ /* kick off DMA */ result = MCD_startDma(dma_get_channel(DMA_PCI_RX), /* channel */ (s8*)(MBAR_ADDRESS+0x84C0), /* source buffer address */ 0, /* source increment */ (s8*)dmarx_task.dst_indx, /* destination buffer address */ 4, /* destination increment */ tsize, /* number of bytes to transfer */ 4, /* width of transfers */ dma_get_initiator(DMA_PCI_RX), /* initiator to use PCI Rx*/ 5, /* priority */ 0 | MCD_SINGLE_DMA | MCD_INTERRUPT | MCD_TT_FLAGS_SP, 0 | MCD_NO_CSUM | MCD_NO_BYTE_SWAP); if(result != MCD_OK) { /* There was a problem */ printf("error: MCD_startDma\n" ); } /* now increment the dst_indx */ dmarx_task.dst_indx = dmarx_task.dst_indx + tsize; } else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -