- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
hi all
I have try the altera memory test project with Nios II IDE.. but always display "-Testing memory using DMA"... http://forum.niosforum.com/work2/style_emoticons/<#EMO_DIR#>/sad.gif the dma might be already open.. and didn`t display "Memory at 0x%X Okay"....... so...I found the code at nios forum...it should be work but it always display"wait for transfer to complete"...why? look like the same problem with memory test !? I use Quartus II 5.1 SP2 & Nios II IDE 5.1 SP1 the exception address is sram_0 at SOPC Builder the program memory & .rodata & .rwdata & heap memory & stack memory are sdram_0 and I sure I have connect the DMA read & write master with sdram_0 & avalon tristate bridge in the SOPC builder this is the code...please help me thanks.... # include <stdio.h># include "system.h"# include "sys/alt_dma.h"# include "alt_types.h" /* Create the transmit channel */ static volatile int rx_done = 0; /* ready handler*/ static void done (void* handle, void* data) { rx_done++; } int main (int argc, char* argv[], char* envp[]) { int rc; alt_u8 Inbuf[1024], Outbuf[1024]; alt_dma_txchan txchan; alt_dma_rxchan rxchan; void* tx_data = (void*) &Inbuf[0]; /* pointer to data to send */ void* rx_buffer = (void*) &Outbuf[0]; /* pointer to rx buffer */ if ((txchan = alt_dma_txchan_open("/dev/avalon_dma")) == NULL) { printf ("Failed to open transmit channel\n"); exit (1); } /* Create the receive channel */ if ((rxchan = alt_dma_rxchan_open("/dev/avalon_dma")) == NULL) { printf ("Failed to open receive channel\n"); exit (1); } /* Post the transmit request */ if ((rc = alt_dma_txchan_send (txchan,tx_data,1024,NULL,NULL)) < 0) { printf ("Failed to post transmit request, reason = %i\n", rc); exit (1); } /* Post the receive request */ if ((rc = alt_dma_rxchan_prepare (rxchan,rx_buffer,1024,done,NULL)) < 0) { printf ("Failed to post read request, reason = %i\n", rc); exit (1); } /* wait for transfer to complete */ printf ("wait for transfer to complete\n"); while (!rx_done); printf("Transfer successful!\n"); return 0; }Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
im also having the same kind of problem..
the memory test program example (provided in nios eds) stuck at "-testing memory using dma".unfortunately i didnt see anybody reply to your thread.. and i know this is an old thread, but have you found the solution to it? Im stuck with it like two weeks now finding the solution. please guide me through this if you or somebody else has already solved it. I dont believe its a physical hardware problem of the memory chip since the bits testing of the sdram does work.. Only the dma didnt work. Seems like it never got the "rx_done" into '1' since the transfer does not complete. I wonder why.. here is the screen shot of my sopc: https://www.alteraforum.com/forum/attachment.php?attachmentid=2382 i tried to attach my full system but its too big. sorry BTW im using Altera 8.0 version software.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I don't see anything wrong with the hardware configuration... Does your design meet timing requirements?
You could use some signaltap probes on the avalon master busses from the DMA to check if it is doing anything or not.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I manage to get DMA transfer complete. but rewrite the code, and it only copy from a single address to buffer.(more like a streaming).
I read from the documentation that this method is supposed to be for peripheral to memory copy..however i give the input to it my 2nd SDRAM base address - which i name it mem_sdram (im using de2-70). So im assuming that it supposed to be copying only the first data to buffer which i declare earlier. However after the transfer finish..i check the value inside buffer.Its not the same as in mem_sdram. here is the output:
Testing DMA!
readaddress =4000000, length =0, status =0, control =1f9
dma transfer: 1ms
Transaction complete
0:3
1:0
2:0
3:0
it shows there '3' and followed by 0.Im expecting the buffer to be filled with '78'. because at the first 32bits of mem_sdram i have already write it with this command : iowr_32direct(mem_sdram_base,0,0x12345678); Here is my code: # define DEPTH 4
# include <stdio.h># include <stddef.h># include <stdlib.h># include "string.h"# include "system.h"
# include "sys/alt_dma.h"# include "altera_avalon_dma_regs.h"# include "altera_avalon_dma.h"
# include "sys/alt_cache.h"# include "sys/alt_alarm.h"# include "alt_types.h"
volatile int dma_complete = 0;
void dma_done (void * handle, void * data)
{
dma_complete = 1;
}
void check(void)
{
alt_u32 control, status, readaddress, length;
readaddress = IORD_ALTERA_AVALON_DMA_RADDRESS(DMA_BASE);
printf ("readaddress =%x, ", readaddress);
length = IORD_ALTERA_AVALON_DMA_LENGTH (DMA_BASE);
printf ("length =%x, ", length);
status = IORD_ALTERA_AVALON_DMA_STATUS (DMA_BASE);
printf ("status =%x, ", status);
control = IORD_ALTERA_AVALON_DMA_CONTROL (DMA_BASE);
printf ("control =%x \n", control);
}
int main()
{
printf("Testing DMA!\n");
alt_u8 buffer;
//memset(buffer, 0x55, 2024);
alt_dcache_flush_all();
alt_dma_rxchan_dev * rx;
alt_u32 start,end;
IOWR_32DIRECT(MEM_SDRAM_BASE,0,0x12345678);
start = alt_nticks();
if ((rx = alt_dma_rxchan_open ("/dev/dma")) == NULL)
{
printf ("Error: failed to open device");
exit(1);
}
else
{
alt_dma_rxchan_ioctl(rx, ALT_DMA_SET_MODE_8, NULL);
alt_dma_rxchan_ioctl(rx, ALT_DMA_TX_ONLY_OFF, NULL);
alt_dma_rxchan_ioctl(rx, ALT_DMA_RX_ONLY_ON, (void *)MEM_SDRAM_BASE);
check();
}
int ret;
if ((ret = alt_dma_rxchan_prepare (rx,(void *) buffer, DEPTH , dma_done, NULL)) <0)
{
printf ("Error: failed to post receive request\n");
exit (1);
}
while (!dma_complete);
end = alt_nticks();
printf("dma transfer: %dms\n",(end-start));
/*start = alt_nticks();
memcpy(buffer,(void *)MEM_SDRAM_BASE,DEPTH);
end = alt_nticks();
printf("memcpy transfer: %dms\n",(end-start));*/
printf ("Transaction complete \n");
alt_dma_rxchan_close(rx);
for(int x=0;x<DEPTH;x++)
{
printf("%d:%x\n",x,buffer);
}
printf("---using IORD---\n");
for(int x=0;x<DEPTH;x++)
{
printf("%d:%x\n",x,IORD_8DIRECT(MEM_SDRAM_BASE,0));
}
return 0;
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You could have a cache problem. The CPU could be reading its data cache instead of the buffer in memory.
Try to create a second pointer:alt_u8 *uncached_buffer = alt_remap_uncached(buffer,DEPTH);
and when you print the contents of the buffer, read the data with uncached_buffer[x], and see if you have different results.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- You could have a cache problem. The CPU could be reading its data cache instead of the buffer in memory. Try to create a second pointer:
alt_u8 *uncached_buffer = alt_remap_uncached(buffer,DEPTH);
and when you print the contents of the buffer, read the data with uncached_buffer[x], and see if you have different results. --- Quote End --- alt_u8 *uncached_buffer = alt_remap_uncached(buffer,depth); gave compile error : invalid conversion from `volatile void*' to `alt_8*' so i change it to volatile void * uncached_buffer = alt_remap_uncached(buffer,depth);
but now the "uncached_buffer" variable cannot be read.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Sorry, try this:alt_u8 *uncached_buffer = (alt_u8 *)alt_remap_uncached(buffer,DEPTH);
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- Sorry, try this:
alt_u8 *uncached_buffer = (alt_u8 *)alt_remap_uncached(buffer,DEPTH);
--- Quote End --- cool.. it works like a charm .. thank you Daixiwen here is the code (in case somebody else having the same problem): # define DEPTH 100
# include <stdio.h># include <stddef.h># include <stdlib.h># include "string.h"# include "system.h"
# include "sys/alt_dma.h"# include "altera_avalon_dma_regs.h"# include "altera_avalon_dma.h"
# include "sys/alt_cache.h"# include "sys/alt_alarm.h"# include "alt_types.h"
volatile int dma_complete = 0;
void dma_done (void * handle, void * data)
{
dma_complete = 1;
}
void check(void)
{
alt_u32 control, status, readaddress, length;
readaddress = IORD_ALTERA_AVALON_DMA_RADDRESS(DMA_BASE);
printf ("readaddress =%x, ", readaddress);
length = IORD_ALTERA_AVALON_DMA_LENGTH (DMA_BASE);
printf ("length =%x, ", length);
status = IORD_ALTERA_AVALON_DMA_STATUS (DMA_BASE);
printf ("status =%x, ", status);
control = IORD_ALTERA_AVALON_DMA_CONTROL (DMA_BASE);
printf ("control =%x \n", control);
}
int main()
{
printf("Testing DMA!\n");
alt_u8 buffer;
alt_u8 * ubuffer = (alt_u8 *)alt_remap_uncached(buffer,DEPTH);
memset(ubuffer, 0x55, DEPTH * 2);
//alt_dcache_flush_all();
alt_dma_rxchan_dev * rx;
alt_u32 start,end;
IOWR_32DIRECT(MEM_SDRAM_BASE,0,0x12345678);
start = alt_nticks();
if ((rx = alt_dma_rxchan_open ("/dev/dma")) == NULL)
{
printf ("Error: failed to open device");
exit(1);
}
else
{
alt_dma_rxchan_ioctl(rx, ALT_DMA_SET_MODE_8, NULL);
alt_dma_rxchan_ioctl(rx, ALT_DMA_TX_ONLY_OFF, NULL);
alt_dma_rxchan_ioctl(rx, ALT_DMA_RX_ONLY_ON, (void *)MEM_SDRAM_BASE);
check();
}
int ret;
if ((ret = alt_dma_rxchan_prepare (rx,(void *) ubuffer, DEPTH, dma_done, NULL)) <0)
{
printf ("Error: failed to post receive request\n");
exit (1);
}
while (!dma_complete);
end = alt_nticks();
printf("dma transfer: %dms\n",(end-start));
/*start = alt_nticks();
memcpy(buffer,(void *)MEM_SDRAM_BASE,DEPTH);
end = alt_nticks();
printf("memcpy transfer: %dms\n",(end-start));*/
printf ("Transaction complete \n");
alt_dma_rxchan_close(rx);
for(int x=0;x<DEPTH;x++)
{
printf("%d:%x\n",x,ubuffer);
}
printf("---using IORD---\n");
for(int x=0;x<DEPTH;x++)
{
printf("%d:%x\n",x,IORD_8DIRECT(MEM_SDRAM_BASE,0));
}
return 0;
}
i found that this line , memset(ubuffer, 0x55, depth * 2); is somehow also affect the output.. -if i comment this line the output is not correct. //seems like we have to initialize the ubuffer first -if i change it to memset(ubuffer, 0x0, depth * 2);, the output is incorrect -if i change it to memset(ubuffer, 0x0, depth); -- somehow the length which must be set has to be double the size of the buffer we need. :p so many mystery that i still dont understand about this dma controller provided by altera in sopc.. rite now im back to trying the transfer from memory to memory with dma controller provided with sopc. memcpy works best without bug for me. somehow the disadvantage is that i have to wait until memcpy operation finish b4 i can do other operation. With dma controller, i can tell it to copy a certain block of memory and do other operation. if the copy operation is done (can check it with flag) i can continue what i want todo with the copied data.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
There could still be a cache problem, because with your memcpy statement, you are using the cached address, and as a result the NIOS CPU may not immediately write the cache contents to the buffer area. After that you read and display the uncached values, so they could be different than what was written by memcpy.
I wouldn't recommend to keep the memset with DEPTH*2. You are writing on the stack in a space that was probably allocated for something else, and it could trigger all kind of unexplainable bugs in your code.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
....continue from previous post ...
this is an example of a larger chunk transfer using dma from ssram_0 to buffer (allocated in sdram_0)
/*
* NIOSimg.cpp
*
* Created on: Apr 26, 2010
* Author: suki
*/
# include <stdio.h># include <stdlib.h># include <stddef.h># include <string.h>
# include <system.h># include <io.h>
# include <alt_types.h># include "sys/alt_dma.h"# include "sys/alt_cache.h"# include "sys/alt_alarm.h"# include "alt_types.h"
# define DEPTH 0x4b000
static volatile int txrx_done = 0;
//callback function when DMA transfer done
static void txrxDone(void * handle, void * data)
{
txrx_done = 1;
}
void initMEM(int base_addr,int len)
{
for (int i=0;i<len;i++)
{
IOWR_8DIRECT(base_addr,i,i);
}
}
int main()
{
printf("testing memory to memory DMA transfer operation of 0x%x bytes\n",DEPTH);
alt_8 buffer;
//memset((void *)SSRAM_0_BASE,0x7a,0x10);//this write base on byte
initMEM(SDRAM_1_BASE,DEPTH);
//memset((void *)(SDRAM_1_BASE+0x10),0x33,0x10);
memset(buffer,0x33,DEPTH);
int rc; //request
alt_dma_txchan txchan;
alt_dma_rxchan rxchan;
void* tx_data = (void*)SDRAM_1_BASE; /* pointer to data to send */
void* rx_buffer = (void*)&buffer; /* pointer to rx buffer */
/* Create the transmit channel */
if ((txchan = alt_dma_txchan_open("/dev/dma_0")) == NULL)
{
printf ("Failed to open transmit channel\n");
exit (1);
}
/* Create the receive channel */
if ((rxchan = alt_dma_rxchan_open("/dev/dma_0")) == NULL)
{
printf ("Failed to open receive channel\n");
exit (1);
}
/* Post the transmit request */
if ((rc = alt_dma_txchan_send (txchan,
tx_data,
DEPTH,
NULL,
NULL)) < 0)
{
printf ("Failed to post transmit request, reason = %i\n", rc);
//exit (1);
}
/* Post the receive request */
if ((rc = alt_dma_rxchan_prepare (rxchan,
rx_buffer,
DEPTH,
txrxDone,
NULL)) < 0)
{
printf ("Failed to post read request, reason = %i\n", rc);
//exit (1);
}
printf("DMA transfer running. . .");
/* wait for transfer to complete */
while (!txrx_done);
printf ("Transfer finish!\n");
printf("Verifying transfered data using memcmp. . .");
if (!(memcmp((void*)SDRAM_1_BASE,(void*)&buffer,DEPTH)))
printf("Verification succesful!\n");
else
printf("Verification failed\n");
// printf("content of buffer\n");
// for (int i=0;i<sizeof(buffer)/2;i++)
// printf("%d: %x\n",i,buffer); // this output width ,base on what we declare
/*printf("content of ssram_0\n");
for (int i=0;i<sizeof(buffer);i=i+2)
{
printf("%d: %x\n",i/2,IORD_16DIRECT(SSRAM_0_BASE,i));
}
printf("content of sdram_1\n");
for (int i=0;i<sizeof(buffer);i=i+2)
{
printf("%d: %x\n",i/2,IORD_16DIRECT(SDRAM_1_BASE,i));
}
memcpy((void*)SDRAM_1_BASE,(void *)SSRAM_0_BASE,20);
printf("content of sdram_1: after memcpy operation\n");
for (int i=0;i<sizeof(buffer);i=i+2)
{
printf("%d: %x\n",i/2,IORD_16DIRECT(SDRAM_1_BASE,i));
}*/
return 0;
}
The output:
testing memory to memory DMA transfer operation of 0x4b000 bytes
DMA transfer running. . .Transfer finish!
Verifying transfered data using memcmp. . .Verification succesful!
cheers, sukiminna.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
HELLO, thanks for the info. but i am using altera de2 board with one sdram (8Mb)and one sram (512kb). is the same code can be used? by the way, may i know how to configure sram module in sopc? like the setting..? thanks.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
thank you so much for the code.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello aprado, do you know how to configure DMA using VHDL in Quartus before we can run the code in NiosII? thanks!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello, using the Quartus you can instantiate it inside SOPC builder and set all the parameters you need
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
thanks. may i know how? if possible, can you pls provide a simple example? thanks!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Look at the first post of this thread, it is very detailed.
click on the icon in the left side of the ? at quartus to open sopc builder- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
i had done the sopc part. but i am stuck with the vhdl code in Quartus II. i thought we have to write the VHDL in Quartus II in order to be compatible with the sopc. only then, we can run the C code in nios2 ide. am i right? pls advise if i am wrong.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- i had done the sopc part. but i am stuck with the vhdl code in Quartus II. i thought we have to write the VHDL in Quartus II in order to be compatible with the sopc. only then, we can run the C code in nios2 ide. am i right? pls advise if i am wrong. --- Quote End --- SOPC Builder will generate the VHDL for the entire system which you then compile using Quartus II (as apposed to writing the logic manually). Once you have a programming file created by Quartus II you download the file to the FPGA and then you can communicate with the Nios II processor inside your SOPC Builder system.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi BadOmen, thanks for the reply! really? this is nice! i always thought i have to write the code manually. May I know how to generate the VHDL for the entire system? Thanks!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I recommend reading this tutorial, it'll explain all the steps:
http://www.altera.com/literature/tt/tt_nios2_hardware_tutorial.pdf http://www.altera.com/literature/tt/niosii_hw_dev_tutorial.zip- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
why my system stuck at:
--- Quote Start --- while (!txrx_done); printf ("Transfer successful!\n"); --- Quote End ---
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page