Just in case I am using the SGDMA block incorrectly, here is my code that sets up a dma transfer:
void process_dma_transfer( uint16 descriptor_index,
alt_u32* source_ptr,
alt_u32* destination_ptr,
bool fixed_read,
bool fixed_write,
bool interrupt_protect )
{
uint8 result;
alt_avalon_sgdma_construct_mem_to_mem_desc( &desc, // Pointer to descriptor being constructed
&desc, // Pointer to next descriptor
source_ptr, // Source address
destination_ptr, // Destination address
USB_MESSAGE_LEN, // Bytes to send (512)
(int) fixed_read, // fixed read?
(int) fixed_write ); // fixed write?
// this bit must be set before each transfer
desc.control = desc.control | OWNED_BY_HW_BIT;
if (interrupt_protect == TRUE)
{
// disable interrupt during dma transfer because alt_avalon_sgdma_do_sync_transfer()
// isn't thread-safe and it gets called inside the ISR
disable_fx2_data_ready_interrupt();
}
result = (uint8)alt_avalon_sgdma_do_sync_transfer(DMA, &desc);
if (interrupt_protect == TRUE)
{
// re-enable interrupt after dma transfer
enable_fx2_data_ready_interrupt();
}
}