Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
15 years ago

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

4 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I don't see anything wrong with your code, except maybe the "should be safe area of sdram" which could be a bad assumption ;)

    You should use a malloc call or a static table just to be sure that you don't overwrite any part of the memory.

    Try also to use the constants defined in system.h instead of the static addresses, it makes things easier if SOPC builder changes the addresses of all the components.

    Did you check all the connections in SOPC builder? The read and write masters must be connected to both the onchip RAM and the SRAM. The same applies to the descriptor master if you want to put the descriptors in different places.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi Daixiwen, thanks for taking a look.

    Dont worry that was just for the test code ;)

    In the SOPC project all SGDMA masters are connected to both the SDRAM and the on-chip memory.

    In my main project (working on a video pipeline) I've added a few KB of on-chip memory for the descriptrors and it appears to be working (that is if I drive frames with solid colours I can see the appropriate signals on my scope).

    I am happy with this solution as if anything it improves performance by reducing access to the on-chip memory, but still I would like to know for future reference why I can't store the descriptors on the SDRAM.

    Is it possible this was just a quirk of that particular project, that it wasn't building properly?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I've had descriptors in SDRAM in the past and don't understand why it isn't working... the next step would be to put SignalTap probes all around the SGDMA core and look at what it is doing...

    Are you sure that the transfer isn't done? If the CPU has a data cache, the contents of both the descriptor and the memory buffers could be hidden by the cache if you don't invalidate it (or go around it when looking at the memory contents).
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Yes, I am using the NIOS /e so its not caching. I check the descriptors and the actual source & destination memory after each supposed transfer and every time its the same: the descriptor shows the 'actual bytes transferred' as the byes to transfer but right shifted 16 bits, and no change to the destination memory.

    I can only think its a fault with the project as I can perform transfers with the descriptors elsewhere and execute code of the SDRAM, so it can't be a board problem, and the 'actual bytes transferred' field I cant think of any explanation for.

    Ill get my LCD working and then as you say go back with SignalTap and see if I can't work out where its getting hung up.