📄 pci.c
字号:
if(result != MCD_OK) { /* There was a problem */ printf("error: MCD_startDma\n" ); } /* DMA is Done */ index = index + (length-index); } else if((length-index) > PCI_MAX_PKT_SIZE) { /* Make sure I've completed the packet from before (if there was one) by checking the NT bit in the PCITSR */ while(pkt_start > pkt_done) { if(MCF_PCI_PCITSR&MCF_PCI_PCITSR_NT) { /* increment the packets done */ pkt_done++; /* Clear the NT bit in the PCITSR */ MCF_PCI_PCITSR |= MCF_PCI_PCITSR_NT; } } MCF_PCI_PCITPSR = MCF_PCI_PCITPSR_PKTSIZE(PCI_MAX_PKT_SIZE); /* size of length*/ pkt_start++; /* Stuff FIFO */ /* kick off DMA */ result = MCD_startDma(dma_get_channel(DMA_PCI_TX), /* channel */ (s8*)source, /* source buffer address */ 4, /* source increment */ (s8*)(MBAR_ADDRESS+0x8440), /* destination buffer address */ 0, /* destination increment */ PCI_MAX_PKT_SIZE, /* number of bytes to transfer */ 4, /* width of transfers */ dma_get_initiator(DMA_PCI_TX), /* initiator to use PCI Tx*/ 5, /* priority */ 0 | MCD_SINGLE_DMA, 0 | MCD_NO_CSUM | MCD_NO_BYTE_SWAP); if(result != MCD_OK) { /* There was a problem */ printf("error: MCD_startDma\n" ); } source = source + PCI_MAX_PKT_SIZE; index = index + PCI_MAX_PKT_SIZE; } else printf("packet screw-up"); } }/*** ===================================================================** Function : pci_start_dma_tx**** Description : Transmit data from CF memory to PCI memory space ** using the DMA and interrupts**** Parameters** ---------- ** -source : Pointer to source address in ColdFire memory space.** Must be longword aligned.** -destination: Pointer to destination address in PCI memory space.** Must be longword aligned.** -length : Length in Bytes to tansmit, must be in longword ** increments**** Return Value: none** ** ===================================================================*/void pci_start_dma_tx(uint8* source, uint8* destination, uint32 length){ int result,i; uint32 tsize; /* Set-up TX FIFO's */ /* Hold Tx controller at reset */ MCF_PCI_PCITER |= MCF_PCI_PCITER_RC; /* Set PCI Command, Max_Retries, and Max_Beats */ /* MCF_PCI_PCITTCR = MCF_PCI_PCITTCR_PCICMD(0x7); same as default out of reset */ /* Set Mode, Continuous or Non-continuous */ MCF_PCI_PCITER |= MCF_PCI_PCITER_CM; /* Enable Normal Termination interrupt */ MCF_PCI_PCITER |= MCF_PCI_PCITER_NE; /* Reset FIFO */ MCF_PCI_PCITER |= MCF_PCI_PCITER_RF; for(i=0;i<100;i++); /* wait */ MCF_PCI_PCITER &= ~(0|MCF_PCI_PCITER_RF); /* Set the FIFO Alarm and Granularity Fields */ MCF_PCI_PCITFCR |= MCF_PCI_PCITFCR_GR(4); /* high water mark = 128 bytes -(4*4) = 16 bytes free in the FIFO */ MCF_PCI_PCITFAR |= MCF_PCI_PCITFAR_ALARM(32); /* low water mark = 16 bytes */ /* Set Master Enable Bit and some error stuff*/ MCF_PCI_PCITER |= MCF_PCI_PCITER_IAE | MCF_PCI_PCITER_TAE | MCF_PCI_PCITER_ME; /* Configure PCI destination */ MCF_PCI_PCITSAR = (uint32)destination; /* Set the Reset Controller bit Low */ MCF_PCI_PCITER &= ~(MCF_PCI_PCITER_RC); /* Clear the NT bit in the PCITSR */ MCF_PCI_PCITSR |= MCF_PCI_PCITSR_NT; dmatx_task.pkt_start = 0; dmatx_task.pkt_done = 0; dmatx_task.dma_start = 0; dmatx_task.dma_done = 0; dmatx_task.dma_indx = 0; dmatx_task.fifo_indx = 0; dmatx_task.length = length; dmatx_task.src_indx = source; dmatx_task.dst_indx = destination; /* Write Packet Size value to begin the transfer if length is < max packet size*/ if((dmatx_task.length-dmatx_task.dma_indx) <= PCI_MAX_PKT_SIZE) { /* pre increment pointers */ tsize = dmatx_task.length-dmatx_task.dma_indx; dmatx_task.pkt_start++; dmatx_task.dma_start++; dmatx_task.dma_indx = dmatx_task.dma_indx + tsize; dmatx_task.fifo_indx = dmatx_task.fifo_indx + tsize; /* size of length*/ MCF_PCI_PCITPSR = MCF_PCI_PCITPSR_PKTSIZE(tsize); /* Stuff FIFO */ /* kick off DMA */ result = MCD_startDma(dma_get_channel(DMA_PCI_TX), /* channel */ (s8*)dmatx_task.src_indx, /* source buffer address */ 4, /* source increment */ (s8*)(MBAR_ADDRESS+0x8440), /* destination buffer address */ 0, /* destination increment */ tsize, /* number of bytes to transfer */ 4, /* width of transfers */ dma_get_initiator(DMA_PCI_TX), /* 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 */ dmatx_task.src_indx = dmatx_task.src_indx + tsize; } else if((dmatx_task.length-dmatx_task.dma_indx) > PCI_MAX_PKT_SIZE) { /* pre increment pointers */ tsize = PCI_MAX_PKT_SIZE; dmatx_task.pkt_start++; dmatx_task.dma_start++; dmatx_task.dma_indx = dmatx_task.dma_indx + tsize; dmatx_task.fifo_indx = dmatx_task.fifo_indx + tsize; /* size of length*/ MCF_PCI_PCITPSR = MCF_PCI_PCITPSR_PKTSIZE(PCI_MAX_PKT_SIZE); /* Stuff FIFO */ /* kick off DMA */ result = MCD_startDma(dma_get_channel(DMA_PCI_TX), /* channel */ (s8*)dmatx_task.src_indx, /* source buffer address */ 4, /* source increment */ (s8*)(MBAR_ADDRESS+0x8440), /* destination buffer address */ 0, /* destination increment */ tsize, /* number of bytes to transfer */ 4, /* width of transfers */ dma_get_initiator(DMA_PCI_TX), /* 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 */ dmatx_task.src_indx = dmatx_task.src_indx + tsize; } else printf("packet screw-up");}/*** ===================================================================** Function : pci_dma_interrupt_handler**** Description : My global DMA interrupt handler. This function calls** the appropriate DMA handled based on which Channel ** triggered the interrupt**** Parameters : none**** Return Value: none** ** ===================================================================*/extern volatile uint8 dma_iflag[16];__interrupt__void pci_dma_interrupt_handler (void) { uint32 i, interrupts; /* * Determine which interrupt(s) triggered by AND'ing the * pending interrupts with those that aren't masked. */ interrupts = MCF_DMA_DIPR & ~MCF_DMA_DIMR; /* Make sure we are here for a reason */ ASSERT(interrupts != 0); /* Clear the interrupt in the pending register */ MCF_DMA_DIPR = interrupts; for (i=0; i<16; ++i, interrupts>>=1) { if (interrupts & 0x1) { dma_iflag[i] = 1; if (i == dma_get_channel(DMA_PCI_TX)) pci_dma_tx_handler(); else if (i == dma_get_channel(DMA_PCI_RX)) pci_dma_rx_handler(); } }}/*** ===================================================================** Function : pci_dma_tx_handler**** Description : DMA interrupt handler for the Transmit DMA task.** This function looks at a global structure to** determine if it needs to restart a DMA task to ** finish sending data to PCI Tx FIFO, or if it's done.**** Parameters : none**** Return Value: none** ** ===================================================================*/void pci_dma_tx_handler(void){ int result,i; uint32 tsize; /* re-stuff the FIFO */ /* but remember... the PCI FIFO is still going */ /* up the number of dma tasks completed */ dmatx_task.dma_done++; if(dmatx_task.dma_indx >= dmatx_task.length) /* is this the last one? */ { /* I'm done with the DMA stuffing of the FIFO */ /* do nothing */ } else if((dmatx_task.length-dmatx_task.dma_indx) <= PCI_MAX_PKT_SIZE) { /* pre increment pointers */ tsize = dmatx_task.length-dmatx_task.dma_indx; dmatx_task.dma_start++; dmatx_task.dma_indx = dmatx_task.dma_indx + tsize; /* Stuff FIFO */ /* kick off DMA */ result = MCD_startDma(dma_get_channel(DMA_PCI_TX), /* channel */ (s8*)dmatx_task.src_indx, /* source buffer address */ 4, /* source increment */ (s8*)(MBAR_ADDRESS+0x8440), /* destination buffer address */ 0, /* destination increment */ tsize, /* number of bytes to transfer */ 4, /* width of transfers */ dma_get_initiator(DMA_PCI_TX), /* 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 */ dmatx_task.src_indx = dmatx_task.src_indx + tsize; } else if((dmatx_task.length-dmatx_task.dma_indx) > PCI_MAX_PKT_SIZE) { /* pre increment pointers */ tsize = PCI_MAX_PKT_SIZE; dmatx_task.dma_start++; dmatx_task.dma_indx = dmatx_task.dma_indx + tsize; /* Stuff FIFO */ /* kick off DMA */ result = MCD_startDma(dma_get_channel(DMA_PCI_TX), /* channel */ (s8*)dmatx_task.src_indx, /* source buffer address */ 4, /* source increment */ (s8*)(MBAR_ADDRESS+0x8440), /* destination buffer address */ 0, /* destination increment */ tsize, /* number of bytes to transfer */ 4, /* width of transfers */ dma_get_initiator(DMA_PCI_TX), /* initiator to use PCI Tx*/ 5, /* priority */ 0 |
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -