- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I can use IOWR,IORD and direct address access to operate SDRAM, But
i can not use address to access Uart, for example: 1. use address alt_u8 * UartTxAdr; UartTxAdr = UART0_BASE+1; //that can not send the data * UartTxAdr = 0x30; 2.use IOWR //that can send the data ok IOWR(UART0_BASE,1,0x30); I do not know what different between these two way. in my DMA operate code, from memory to uart, the code is as follow: static volatile int rx_done = 0; alt_u8 buffer[16] __attribute__((section(".sdram"))); static void done (void* handle, void* data) { rx_done++; } // in main function buffer[0]=0x30; //'0' buffer[1]=0x31; //'1' buffer[2]=0x32; //'2' buffer[3]=0x33; //'3' void* tx_data = (void*) &buffer[0]; /* pointer to data to send */ if ((txchan = alt_dma_txchan_open("/dev/dma_0")) == NULL) { IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE, 2); exit (1); } alt_dma_txchan_ioctl(txchan,ALT_DMA_SET_MODE_8,NULL); alt_dma_txchan_ioctl(txchan,ALT_DMA_RX_STREAM_ON,(void*)UART0_BASE+1); if ((rc = alt_dma_txchan_send (txchan,tx_data,4,done,NULL)) < 0) { IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE, 3); exit (1); } while (!rx_done); alt_dma_txchan_close(txchan); the code is execute OK, the rx_done is set, but the data never send out from the uart, maybe it can not use direct address access?? (i think the dma operate is use direct address operate), i add the uart0 in SOPC and set the "include end-of packet register", and connect DMA write-master to usrt0, read-master to sdram by set the small rect with "1", anyone can help me ????Link Copied
5 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi hugeant,
> I do not know what different between these two way. When you use "direct access" you end up using stx/ldx instructions. When you use the IOWR/IORD macros, you get the stxio/ldxio instructions. The "io" instructions bypass the data cache. > but the data never send out from the uart Do you mean you didn't see any data on your terminal? ... or nothing was transmitted at all? Your terminal software simply may not be displaying NULL for example -- but the transmission may actually be occurring. If you're using a data cache, you should flush prior to calling alt_dma_txchan_send. The last time I looked at that code, it didn't flush the cache for you ... so it's your program's responsibility. You might be transmitting all NULL, since your buffer data is still in the cache (it was never written back). Regards, --Scott- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
>When you use "direct access" you end up using stx/ldx instructions. When you use
the IOWR/IORD macros, you get the stxio/ldxio instructions. The "io" instructions bypass the data cache. thanks,Now i understand it , when a do the memory transfer, maybe it first move to data cache, not move to the address i what. >Do you mean you didn't see any data on your terminal? ... or nothing was transmitted at all? Your terminal software simply may not be displaying NULL Yes, nothing was transmitted, I made the terminal program in PC and it can display any data when received. I set the display mode in hex mode.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
/* Here is my test code. To Test DMA from Memory -> UART
some of them cames from this forum. In The Terminal in My PC, I can see the followed data received ========================================= 0x68 0x65 0x6c 0x6c 0x6f 0x20 0x77 0x6f 0x72 0x6c 0x64 0x0a 0x30 0x31 0x32 0x33 ========================================= the first line is the "hello world" then i received 4 data send by IOWR macro after that, nothing received,even NULL. before DMA,i flush all cache,but nothing changed. the Timer is running,that means the dma transmit complete, but i do not know why nothing out from UART. */ # include "system.h"# include <stdio.h># include "altera_avalon_pio_regs.h"# include "altera_avalon_timer_regs.h"# include "sys/alt_dma.h"# include "altera_avalon_dma_regs.h"# include "alt_types.h" volatile alt_u8 count; static volatile int rx_done = 0; alt_u8 buffer[16] __attribute__((section(".onchip_ram"))); static void done (void* handle, void* data) { rx_done++; } void delay(void) { volatile int i; i=0; while (i<400000) i++; } static void handle_Timer0_interrupts(void* context, alt_u32 id) { alt_u8 a; volatile alt_u8 *countptr = (volatile alt_u8 *)context; IOWR_ALTERA_AVALON_TIMER_STATUS(TIMER_0_BASE, 0);//?TO?? a = *countptr; a=a<<1; if (a == 0x10) a=1; *countptr=a; IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE, a); } void startTimer(void) { count=1; alt_irq_register(TIMER_0_IRQ, (void *)&count, handle_Timer0_interrupts); IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE, 0); IOWR_ALTERA_AVALON_TIMER_CONTROL(TIMER_0_BASE, 7); } int main (void) { int rc; alt_dma_txchan txchan; FILE *uart; uart = fopen("/dev/uart0","w"); if(uart==NULL){ }else{ char *str="hello world\n"; fprintf(uart,str); } delay(); buffer[0]=0x30; //'0' buffer[1]=0x31; //'1' buffer[2]=0x32; //'2' buffer[3]=0x33; //'3' IOWR(UART0_BASE,1,buffer[0]); IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE, 1); delay(); IOWR(UART0_BASE,1,buffer[1]); IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE, 2); delay(); IOWR(UART0_BASE,1,buffer[2]); IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE, 4); delay(); IOWR(UART0_BASE,1,buffer[3]); IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE, 8); delay(); void* tx_data = (void*) &buffer[0]; /* pointer to data to send */ IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE, 1); if ((txchan = alt_dma_txchan_open("/dev/dma_0")) == NULL) { IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE, 2); exit (1); } alt_dma_txchan_ioctl(txchan,ALT_DMA_SET_MODE_8,NULL); alt_dma_txchan_ioctl(txchan,ALT_DMA_RX_STREAM_ON,(void*)UART0_BASE+1); alt_dcache_flush_all(); alt_icache_flush_all(); if ((rc = alt_dma_txchan_send (txchan,tx_data,4,done,NULL)) < 0) { IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE, 4); exit (1); } while (!rx_done); alt_dma_txchan_close(txchan); IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE, 15); delay(); // end of DMA stream translate IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE, 0); startTimer(); while (1) {;} if(uart) { fclose(uart); } return 0; }- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Any "I/O variables" should be qualified as volatile
so : volatile alt_u8 * UartTxAdr This prevents the optimiser from tuning the code out (because it will detect that nothing is "reading" the location).- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- originally posted by jasondiplomat@Oct 22 2005, 05:20 AM any "i/o variables" should be qualified as volatile[/b] so : volatile alt_u8 * UartTxAdr This prevents the optimiser from tuning the code out (because it will detect that nothing is "reading" the location). <div align='right'><{post_snapback}> (index.php?act=findpost&pid=10525) --- Quote End --- [/b] --- Quote End --- Thanks for you reply ,JasonDiplomat. you means that the DMA controller also effected by "volatile" ??
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page