Nios® V/II Embedded Design Suite (EDS)
Support for Embedded Development Tools, Processors (SoCs and Nios® V/II processor), Embedded Development Suites (EDSs), Boot and Configuration, Operating Systems, C and C++

IOWR and direct adress access

Altera_Forum
Honored Contributor II
1,983 Views

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 ????
0 Kudos
5 Replies
Altera_Forum
Honored Contributor II
767 Views

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&#39;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&#39;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&#39;t flush the cache for you ... so it&#39;s your 

program&#39;s responsibility. You might be transmitting all NULL, since your buffer data 

is still in the cache (it was never written back). 

 

Regards, 

--Scott
0 Kudos
Altera_Forum
Honored Contributor II
767 Views

>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&#39;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.
0 Kudos
Altera_Forum
Honored Contributor II
767 Views

/* 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; //&#39;0&#39; 

buffer[1]=0x31; //&#39;1&#39; 

buffer[2]=0x32; //&#39;2&#39; 

buffer[3]=0x33; //&#39;3&#39;  

 

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; 

}
0 Kudos
Altera_Forum
Honored Contributor II
767 Views

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).
0 Kudos
Altera_Forum
Honored Contributor II
767 Views

 

--- 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" ??
0 Kudos
Reply