Forum Discussion
Altera_Forum
Honored Contributor
12 years agoOk nailed this one ... as I suspected the DMA controller was hung with some bus width mismatch.
Everything worked fine when I added two icotl()'s to move from a default transfer of 32 bits to 64. I checked the DMA status vie the PCIe link , vie the Lauterbach on the host system. I must admit that is kind of convoluted but seemed easiest. The DMA was working via scripts running on the host system via scripts so possibly the transfer count of 10 in the HAL calls was an issue as well. Here is a question though that I can't answer, observe that the test of rx_done will report polling of that flag if it is not zero. I extended the transfer count from a small count to 256 and 1024. At no time do I get a polling message. I can max out the transfer count, and if I don't get a polling message, I suspect the DMA operation is somehow usurping the NIOS II execution, or the DMA has a very high priority on the Avalon MM fabric. Any comments there . The NIOS II is the /e which is without any caches , bells or whistles. I am implementing a consumer / producer data transfer ... if the DMA engine moves the data buffer to the host system, I am wondering the latency to get the rx_done flag back from the DMA interrupt. Is there any way to reduce it ? Any ideas on the "thin" Linux device driver, I need to provide that for the system running on the host with Linux. I'm thinking at a minimum, the device driver has to open , close the FPGA PCIe device and an some ioctl() calls to post the head of a descriptor linked list resident in system memory, request destination buffers on the FPGA side and some flag / status bit management routined. As a new user I am 100% impressed with the ALTERA offering and still need to get the included simulator up. Thanks in advance . Bob. // check attributes rxchan_depth = alt_dma_rxchan_depth( rxchan ); printf ( "rxchan_depth = %i \n" , rxchan_depth ); txchan_depth = alt_dma_rxchan_depth( rxchan ); printf ( "txchan_depth = %i \n" , txchan_depth ); val = alt_dma_rxchan_ioctl( rxchan, ALT_DMA_GET_MODE, 0 ); printf ( "rxchan mode = %x \n" , val ); val = alt_dma_txchan_ioctl( txchan, ALT_DMA_GET_MODE, 0 ); printf ( "txchan mode = %x \n" , val ); val = alt_dma_rxchan_ioctl( rxchan, ALT_DMA_SET_MODE_64, 0 ); //************************* ADDED ******************************************* val = alt_dma_txchan_ioctl( txchan, ALT_DMA_SET_MODE_64, 0 ); //************************* ADDED ******************************************** /* Post the transmit request */ if ((rc = alt_dma_txchan_send (txchan,tx_data,1024,NULL,NULL)) < 0) { printf ("Failed to post transmit request, reason = %i\n", rc); exit (1); } /* Post the receive request */ if ((rc = alt_dma_rxchan_prepare (rxchan,rx_buffer,1024,done,NULL)) <0 ) { printf ("Failed to post read request, reason = %i\n", rc); exit (1); } else { // printf ("Passed post read request\n"); } /* wait for transfer to complete */ while (!rx_done) { printf ("Waiting on rx_done, rx_done = %i\n", rx_done); } printf ("Transfer successful!\n");