Altera_Forum
Honored Contributor
15 years agoSGDMA Core loop problem - setting CHAIN_COMPLETED
Hello.
OK, I have cut my project back so it consists of just the NIOS, SGDMA, SDRAM controller, and an onchip memory component. If I set up the SGDMA to transfer a set of bytes between two locations on the on-chip memory it works fine. If I change it to use the SDRAM by shifting locations my test code uses, it fails. The content of the registers appear just as they do when working with the on chip memory, with the exception of the actual_bytes_transferred value of the first descriptor, which always shows the bytes_to_transfer value shifted left by 16 bits (I've tried four different values now it always does this). EDIT: OK, last edit hopefully, I have found that it I store the descriptors on the ONCHIPMEMORY the SGDMA can make transfers between locations on the SDRAM. I saw no mention in the documentation about why this may be necessary, is this normal? Here is the code:#include <stdio.h># include <stdlib.h># include <string.h># include <sys/alt_cache.h># include <malloc.h># include "altera_avalon_sgdma.h"# include "altera_avalon_sgdma_regs.h"
int main()
{
printf("Hello from Nios II!\n");
alt_sgdma_dev* device = alt_avalon_sgdma_open(SGDMA_1_NAME);
alt_sgdma_descriptor* descriptor_one = (alt_sgdma_descriptor*)0x8004000; //onchip memory base (code, etc still runs from sdram)
//alt_sgdma_descriptor* descriptor_one = (alt_sgdma_descriptor*)0x06000000; //should be safe area of sdram
alt_sgdma_descriptor* descriptor_two = (alt_sgdma_descriptor*)descriptor_one + sizeof(alt_sgdma_descriptor);
int datalen = 512;
void* source = descriptor_two + sizeof(alt_sgdma_descriptor);
void* dest = source + datalen;
memset(source, 0xf0f0f0f0, datalen);
memset(dest, 0, datalen);
alt_avalon_sgdma_construct_mem_to_mem_desc(
descriptor_one, // descriptor
descriptor_two, // next descriptor
source, // read buffer location
dest, // write buffer location
(alt_u16) datalen, // length of the buffer
0, // reads are not from a fixed location
0); // writes are not from a fixed location
int status = alt_avalon_sgdma_do_async_transfer(device, descriptor_one);
while(1)
{
printf("%c",getchar()); //break here to check out memory content
}
return 0;
}