Quantcast
Channel: Altera Forums
Viewing all articles
Browse latest Browse all 19390

Scatter-Gather DMA Controller

$
0
0
Hello everyone,

To get familiar with the Avalon Streaming Interface, I am trying to use the SGDMA IP to produce an Avalon stream from the extern DDR3 memory and to write this stream back to the memory. Therefore I used this example from http://www.alterawiki.com/wiki/SGDMA.

The code is working fine until it comes to the while-loop were the code is waiting for the interrupt. I used the debugger to check the registers and settings of the SGDMA device and of the descriptors which looked fine to me.

I used the Qsys editor to generate the hardware components (I attached a screenshot of the configuration). Furthermore, I amusing the DE5-Net developer board with Quartus 17.


Has anyone a suggestion what I am doing wrong? If you need more information please let meknow.

Thanks,
Jan

Code:

#include "terasic_includes.h"
#include "mem_verify.h"




#define STATUS_BIT_DONE    0x01
#define STATUS_BIT_FAIL    0x02
#define STATUS_BIT_SUCCESS    0x04




/* These will gate the data checking near the end of main */
volatile alt_u8 tx_done = 0;
volatile alt_u8 rx_done = 0;


void transmit_callback_function(void * context){
  tx_done++;  /* main will be polling for this value being 1 */
}


void receive_callback_function(void * context){
  rx_done++;  /* main will be polling for this value being 1 */
}


int main()
{
    alt_u32 *transmit_ptr;
    alt_u8 temp_transmit;




    //Let's try to initialize the SGDMA block
    printf("Initialization of the SGDMA...\n");


    /* Open a SG-DMA for MM-->ST and ST-->MM (two SG-DMAs are present) */
    alt_sgdma_dev * transmit_DMA = alt_avalon_sgdma_open(SGDMA_NAME);
    alt_sgdma_dev * receive_DMA = alt_avalon_sgdma_open(SGDMA_0_NAME);


    /* Needs one allocated descriptor at the end to mark the tail of the list.
    * Copies are made so that they can be put back on the heap when we are done.
    * The copies are a superset of the other pointers so by freeing them at the
    * end we'll be freeing transmit_descriptors and receive_descriptors as well. */
    alt_sgdma_descriptor *transmit_descriptors, *transmit_descriptors_copy;
    alt_sgdma_descriptor *receive_descriptors, *receive_descriptors_copy;


    alt_u32 return_code;


    /**************************************************************
    * Making sure the SG-DMAs were opened correctly            *
    ************************************************************/
    if(transmit_DMA == NULL){
      printf("Could not open the transmit SG-DMA\n");
      return 1;
    }
    if(receive_DMA == NULL){
      printf("Could not open the receive SG-DMA\n");
      return 1;
    }




    /**************************************************************
    * Allocating descriptor table space from main memory.      *
    * Pointers are passed by reference since they will be      *
    * modified by this function.                              *
    ************************************************************/
    printf("Allocating the descriptor memory..\n");
    return_code = descriptor_allocation(&transmit_descriptors,
                                &transmit_descriptors_copy,
                                &receive_descriptors,
                                &receive_descriptors_copy,
                                NUMBER_OF_BUFFERS);


    if(return_code == 1){
        printf("Allocating the descriptor memory failed... exiting\n");
        return 1;
    }


    /**************************************************************
    * Allocating data buffers and populating them with data    *
    ************************************************************/
    printf("Allocating the data buffers and creating the data...\n");
    return_code = create_test_data(transmit_descriptors,
                                receive_descriptors,
                                NUMBER_OF_BUFFERS,
                                BUFFER_LENGTH);
    if(return_code == 1){
        printf("Allocating the data buffers failed... exiting\n");
        return 1;
    }


    transmit_ptr = transmit_descriptors[0].read_addr;
    temp_transmit = IORD_8DIRECT((alt_u32)transmit_ptr, 0);
    printf("Written data: %u \n", (unsigned int) temp_transmit);


    transmit_ptr = transmit_descriptors[2].read_addr;
    temp_transmit = IORD_8DIRECT((alt_u32)transmit_ptr, 2);
    printf("Written data: %u \n", (unsigned int) temp_transmit);


    printf("Transmit_descriptor_ptr: %p \n", &transmit_descriptors[31]);


    /**************************************************************/




    /**************************************************************
    * Register the ISRs that will get called when each (full)  *
    * transfer completes                                      *
    ************************************************************/
    printf("Setting the callback functions...\n");
    alt_avalon_sgdma_register_callback(transmit_DMA,
                                &transmit_callback_function,
                                (ALTERA_AVALON_SGDMA_CONTROL_IE_GLOBAL_MSK | ALTERA_AVALON_SGDMA_CONTROL_IE_CHAIN_COMPLETED_MSK),
                                NULL);
    alt_avalon_sgdma_register_callback(receive_DMA,
                                &receive_callback_function,
                                (ALTERA_AVALON_SGDMA_CONTROL_IE_GLOBAL_MSK | ALTERA_AVALON_SGDMA_CONTROL_IE_CHAIN_COMPLETED_MSK),
                                NULL);
    /**************************************************************/


    printf("Starting up the SGDMA transfer\n");


    /* Prime the SGDMA engines with the descriptor lists (first one, it's a linked list) */
    if(alt_avalon_sgdma_do_async_transfer(transmit_DMA, &transmit_descriptors[0]) != 0){
        printf("Writing the head of the transmit descriptor list to the DMA failed\n");
        return 1;
    }


    if(alt_avalon_sgdma_do_async_transfer(receive_DMA, &receive_descriptors[0]) != 0){
        printf("Writing the head of the receive descriptor list to the DMA failed\n");
        return 1;
    }


    while(tx_done == 0) {}
    printf("The transmit SGDMA has completed\n");


    while(rx_done == 0) {}
    printf("The receive SGDMA has completed\n");


    verify_stream_data(transmit_descriptors, receive_descriptors, NUMBER_OF_BUFFERS);


    /**************************************************************
    * Stop the SGDMAs and free up the descriptor memory        *
    ************************************************************/
    alt_avalon_sgdma_stop(transmit_DMA);
    alt_avalon_sgdma_stop(receive_DMA);


    free(transmit_descriptors_copy);
    free(receive_descriptors_copy);
    /**************************************************************/


    return 0;
}



Attached Images

Viewing all articles
Browse latest Browse all 19390

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>