Forum Discussion
111 Replies
- Altera_Forum
Honored Contributor
currently, this is my code:
--- Quote Start --- # include "io.h"# include <stdio.h># include <unistd.h># include <sys/alt_dma.h># include "altera_avalon_dma_regs.h"# include "altera_avalon_pio_regs.h"# include "alt_types.h"# include "system.h" //#include "sys/alt_timestamp.h" int main() { int i; unsigned int dst = SDRAM_BASE + 0x200000; for(i=0; i<128; i++) { IOWR_32DIRECT(PERIPHERAL_0_BASE, 0, i); //printf("%d\n", IORD_32DIRECT(PERIPHERAL_0_BASE, 0)); } IOWR_ALTERA_AVALON_DMA_STATUS(DMA_BASE, 0x00); printf("%d\n", IORD_ALTERA_AVALON_DMA_STATUS(DMA_BASE)); IOWR_32DIRECT(PERIPHERAL_0_BASE, 0, i); IOWR_ALTERA_AVALON_DMA_RADDRESS(DMA_BASE, PERIPHERAL_0_BASE); IOWR_ALTERA_AVALON_DMA_WADDRESS(DMA_BASE,dst); IOWR_ALTERA_AVALON_DMA_LENGTH(DMA_BASE,100); IOWR_ALTERA_AVALON_DMA_CONTROL(DMA_BASE,0x19C); usleep(200000); for(i=0; i<128; i++) { printf("%d\n", IORD_32DIRECT(dst, i)); } return 0; } --- Quote End --- i dont know if the arrangement of my code is correct. update: i just manage to get the result for this: printf("%d\n", IORD_ALTERA_AVALON_DMA_STATUS(DMA_BASE)); which is 0 - Altera_Forum
Honored Contributor
That's strange, because either done or busy should be set.
What values do you read from the other registers? Try setting the control register first to 0x194, then read it back, and at last 0x19c to add the Run bit. I'm not certain the DMA will start if the control reg is set to run from Zero. Are you sure, you want to enable the interrupt? Maybe it's neccessary to first issue a softreset. Edit: Now I see you read the status right after you reset it. Try reading it later on, to see what happened to the DMA.... - Altera_Forum
Honored Contributor
I think now my DMA is working... But it seems like it cannot write into the memory.. my code:
--- Quote Start --- #include "io.h"# include <stdio.h># include <unistd.h># include <sys/alt_dma.h># include "altera_avalon_dma_regs.h"# include "altera_avalon_pio_regs.h"# include "alt_types.h"# include "system.h" int main() { int i; for(i=0; i<100; i++) { IOWR(PERIPHERAL_0_BASE, 0, i); } IOWR_ALTERA_AVALON_DMA_STATUS(DMA_BASE, 0x00); IOWR_ALTERA_AVALON_DMA_RADDRESS(DMA_BASE, PERIPHERAL_0_BASE); IOWR_ALTERA_AVALON_DMA_WADDRESS(DMA_BASE, EXT_SRAM_BASE); IOWR_ALTERA_AVALON_DMA_LENGTH(DMA_BASE, 200); IOWR_ALTERA_AVALON_DMA_CONTROL(DMA_BASE, 0x1102); IOWR_ALTERA_AVALON_DMA_CONTROL(DMA_BASE, 0x10A); printf("done\n"); for(i=0; i<100; i++) { printf("%d\n", IORD(EXT_SRAM_BASE, i)); } return 0; } --- Quote End --- i disable the interrupt and add in the softreset initially... update: result is: done 0 -1 -1 -1 -1 then all are -1.... - Altera_Forum
Honored Contributor
i'm not sure if it is ok to configure the DMA when issuing a reset.
Doesn't the DMA reset the registers then? Resetting the DMA should be the very first thing to do.... - Altera_Forum
Honored Contributor
is it reset the DMA first only then write 0x00 into the dma status? result i got:
result is: done 0 -1 -1 -1 -1 then all are -1.... - Altera_Forum
Honored Contributor
--- Quote Start --- #include "io.h"# include <stdio.h># include <unistd.h># include <sys/alt_dma.h># include "altera_avalon_dma_regs.h"# include "altera_avalon_pio_regs.h"# include "alt_types.h"# include "system.h" int main() { int i; for(i=0; i<100; i++) { IOWR(PERIPHERAL_0_BASE, 0, i); } IOWR_ALTERA_AVALON_DMA_CONTROL(DMA_BASE, 0x1000); IOWR_ALTERA_AVALON_DMA_STATUS(DMA_BASE, 0x00); IOWR_ALTERA_AVALON_DMA_RADDRESS(DMA_BASE, PERIPHERAL_0_BASE); IOWR_ALTERA_AVALON_DMA_WADDRESS(DMA_BASE, EXT_SRAM_BASE); IOWR_ALTERA_AVALON_DMA_LENGTH(DMA_BASE, 200); IOWR_ALTERA_AVALON_DMA_CONTROL(DMA_BASE, 0x102); IOWR_ALTERA_AVALON_DMA_CONTROL(DMA_BASE, 0x10A); printf("done\n"); for(i=0; i<100; i++) { printf("%d\n", IORD(EXT_SRAM_BASE, i)); } return 0; } --- Quote End --- result: --- Quote Start --- done 131072 393220 655368 917516 1179664 1441812 1703960.... --- Quote End --- until finish, all are random numbers - Altera_Forum
Honored Contributor
maybe is it because i dont disable the dma in BSP setting? because i cant find it in Nios II IDE 9.0
- Altera_Forum
Honored Contributor
That might be a reason. The NIOS manual is clear in this case:
--- Quote Start --- If ... the HAL driver is active for the same device, your driver will conflict and fail to operate. --- Quote End --- As I already said, check the DMA register contents, whether the HAl driver interferes with your settings. Do it at least before issuing the run bit. - Altera_Forum
Honored Contributor
Yes, I just read all the registers and the values are all correct. before i print out the result, the DONE is already '1' and status is '10001' in binary, suppose finish running. But still, in the dst, cant get the result. my new code is as below, DMA transfer data from SDRAM to peripheral, then second DMA_0 transfer from peripheral to EXT_SRAM.
--- Quote Start --- # include "io.h"# include <stdio.h># include <unistd.h># include <sys/alt_dma.h># include "altera_avalon_dma_regs.h"# include "altera_avalon_pio_regs.h"# include "alt_types.h"# include "system.h" int main() { int i; unsigned int src = SDRAM_BASE + 0x200000; unsigned int dst = EXT_SRAM_BASE; for(i=0; i<100; i++) { IOWR(src, i, 1); printf("initial: %d\n", IORD(src, i)); } IOWR_ALTERA_AVALON_DMA_CONTROL(DMA_BASE, 0x1000); printf("ctrl1: %d\n", IORD_ALTERA_AVALON_DMA_CONTROL(DMA_BASE)); IOWR_ALTERA_AVALON_DMA_CONTROL(DMA_0_BASE, 0x1000); printf("ctrl2: %d\n", IORD_ALTERA_AVALON_DMA_CONTROL(DMA_0_BASE)); IOWR_ALTERA_AVALON_DMA_STATUS(DMA_BASE, 0x00); printf("stat1: %d\n", IORD_ALTERA_AVALON_DMA_STATUS(DMA_BASE)); IOWR_ALTERA_AVALON_DMA_STATUS(DMA_0_BASE, 0x00); printf("stat2: %d\n", IORD_ALTERA_AVALON_DMA_STATUS(DMA_0_BASE)); IOWR_ALTERA_AVALON_DMA_RADDRESS(DMA_BASE, src); printf("rdadd1: %d\n", IORD_ALTERA_AVALON_DMA_RADDRESS(DMA_BASE)); IOWR_ALTERA_AVALON_DMA_WADDRESS(DMA_BASE, PERIPHERAL_0_BASE); printf("wradd1: %d\n", IORD_ALTERA_AVALON_DMA_WADDRESS(DMA_BASE)); IOWR_ALTERA_AVALON_DMA_RADDRESS(DMA_0_BASE, PERIPHERAL_0_BASE); printf("rdadd2: %d\n", IORD_ALTERA_AVALON_DMA_RADDRESS(DMA_0_BASE)); IOWR_ALTERA_AVALON_DMA_WADDRESS(DMA_0_BASE, dst); printf("wradd2: %d\n", IORD_ALTERA_AVALON_DMA_WADDRESS(DMA_0_BASE)); IOWR_ALTERA_AVALON_DMA_LENGTH(DMA_BASE, 200); printf("len1: %d\n", IORD_ALTERA_AVALON_DMA_LENGTH(DMA_BASE)); IOWR_ALTERA_AVALON_DMA_LENGTH(DMA_0_BASE, 200); printf("len2: %d\n", IORD_ALTERA_AVALON_DMA_LENGTH(DMA_0_BASE)); IOWR_ALTERA_AVALON_DMA_CONTROL(DMA_BASE, 0x282); printf("crtl1: %d\n", IORD_ALTERA_AVALON_DMA_CONTROL(DMA_BASE)); IOWR_ALTERA_AVALON_DMA_CONTROL(DMA_0_BASE, 0x182); printf("ctrl2: %d\n", IORD_ALTERA_AVALON_DMA_CONTROL(DMA_0_BASE)); IOWR_ALTERA_AVALON_DMA_CONTROL(DMA_BASE, 0x28A); printf("run1: %d\n", IORD_ALTERA_AVALON_DMA_CONTROL(DMA_BASE)); IOWR_ALTERA_AVALON_DMA_CONTROL(DMA_0_BASE, 0x18A); printf("run2: %d\n", IORD_ALTERA_AVALON_DMA_CONTROL(DMA_0_BASE)); printf("status: %d\t%d\n", IORD_ALTERA_AVALON_DMA_STATUS(DMA_BASE), IORD_ALTERA_AVALON_DMA_STATUS(DMA_0_BASE)); for(i=0;i<100;i++) { printf("waiting\n"); } printf("status: %d\t%d\n", IORD_ALTERA_AVALON_DMA_STATUS(DMA_BASE), IORD_ALTERA_AVALON_DMA_STATUS(DMA_0_BASE)); printf("done\n"); for(i=0; i<100; i++) { printf("end: %d\n", IORD(dst, i)); } return 0; } --- Quote End --- pls help me to check the flow of my code. i am not sure if i arrange the calling function in such way is correct or not. i am afraid, maybe sometimes the data hasnt arrive and DMA also start fetching the data. pls help me to check. thanks! - Altera_Forum
Honored Contributor
my registers: all in decimals
--- Quote Start --- ctrl1: 4096 ctrl2: 4096 stat1: 0 stat2: 0 rdadd1: 10485760 wradd1: 17838208 rdradd2: 17838208 wradd2: 17301504 len1: 200 len2: 200 crtl1: 642 ctrl2: 386 run1: 650 run2: 394 status: 17 17 --- Quote End ---