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
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;
}