Hi BadOmen (and others),
Do you have any experience with the modular SGDMA? Because I now have the following code. (Pretty much directly taken from the example.)
And I have a question as seen in the next post.
// flag used to determine when all the transfers have completed
volatileint sgdma_interrupt_fired = 0;
staticvoid sgdma_complete_isr (void *context, alt_u32 id)
{
sgdma_interrupt_fired = 1;
clear_irq (MODULAR_SGDMA_ONCHIP_CSR_BASE);
}
void modular_sgdma_transfer()
{
sgdma_standard_descriptor a_descriptor;
sgdma_standard_descriptor * a_descriptor_ptr = &a_descriptor; // using this instead of 'a_descriptor' throughout the code
unsignedlong length;
unsignedlong read_address;
unsignedlong write_address;
unsignedlong control_bits;
unsigned long transfer_time, test_throughput, I, number_of_transfers;
alt_irq_register (MODULAR_SGDMA_ONCHIP_CSR_IRQ, NULL, sgdma_complete_isr); // register the ISR
enable_global_interrupt_mask(MODULAR_SGDMA_ONCHIP_CSR_BASE); // turn on the global interrupt mask in the SGDMA
memset((void*)SRIO_ONCHIP_TX_DATA_BASE,0x00, SRIO_ONCHIP_TX_DATA_SPAN);
memset((void*)SRIO_ONCHIP_RX_DATA_BASE,0x00, SRIO_ONCHIP_RX_DATA_SPAN);
printf("Content of TX before DMA operation\n");
read_address = SRIO_ONCHIP_TX_DATA_BASE;
write_address = SRIO_ONCHIP_RX_DATA_BASE;
length = MAXIMUM_BUFFER_SIZE; // 16384
number_of_transfers=100;
alt_timestamp_start();
control_bits = 0; // go bit is handled
construct_standard_mm_to_mm_descriptor (a_descriptor_ptr, (alt_u32 *)read_address, (alt_u32 *)write_address, length, control_bits);
for(i = 0; i < number_of_transfers; i++)
{
//See next post for code
}
//Write the last descriptor (is last transfer)
control_bits = DESCRIPTOR_CONTROL_TRANSFER_COMPLETE_IRQ_MASK; // go bit is handled 'construct_standard_mm_to_mm_descriptor'
construct_standard_mm_to_mm_descriptor (a_descriptor_ptr, (alt_u32 *)read_address, (alt_u32 *)write_address, length, control_bits);
while ((read_csr_status(MODULAR_SGDMA_ONCHIP_CSR_BASE) & CSR_DESCRIPTOR_BUFFER_FULL_MASK) != 0) {} // spin until there is room for another descriptor to be written to the SGDMA
write_standard_descriptor (MODULAR_SGDMA_ONCHIP_CSR_BASE, MODULAR_SGDMA_ONCHIP_DESCRIPTOR_SLAVE_BASE, a_descriptor_ptr) ;
while (sgdma_interrupt_fired == 0) {} // keep spinning until the interrupt fires when the last word is written to the destination location by the SGDMA
transfer_time = alt_timestamp(); // number of clock ticks from the time that descriptors where formed and sent to the SGDMA to the time of the last memory write occuring
mem_compare( (void*) SRIO_ONCHIP_TX_DATA_BASE, (void*) SRIO_ONCHIP_RX_DATA_BASE, MAXIMUM_BUFFER_SIZE);
sgdma_interrupt_fired = 0; // set back to 0 to perform another test
// / = total test time in seconds
//throughput = / = ( * ) / <--- this would be bytes per second so divide by 1024*1024 to get MB/s
length = length*128;
test_throughput = (unsignedlong)((((double)(number_of_transfers*length)) * ((double)alt_timestamp_freq())) / ((double)transfer_time * 1024 * 1024) );
printf("Test completed with a throughput of %ldMB/s.\n", test_throughput);
}