Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Valued Contributor III
4,128 Views

RX and TX UART with NIOS2/e

Hello all, 

i am beginner in NIOS2 programming and I try to use UART_0 in my system, where i have 22kB RAM on chip. 

So I have used the hello_world_small template. I tryed to blink with led, setting pio ports and sending with printf("hello world.\n") text to jtag uart and read the jtag uart characters. (alt_getchar). 

 

But i am not able to read and send the chars to uart_0, because i am not able to use fopen or open in this small model: 

 

---------------- like this ---------------------- 

char* msg = "Detected the character 't'.\n"; 

FILE* fp; 

char prompt = 0; 

fp = fopen ("/dev/uart1", "r+"); //Open file for reading and writing 

if (fp) 

while (prompt != 'v')  

{ // Loop until we receive a 'v'. 

prompt = getc(fp); // Get a character from the UART. 

if (prompt == 't') 

{ // Print a message if character is 't'. 

fwrite (msg, strlen (msg), 1, fp); 

fprintf(fp, "Closing the UART file.\n"); 

fclose (fp); 

return 0; 

 

How can I read UART_0 and write to UART_0 ? 

I tryed to find some examples on alterawiki, but without succesfull. 

 

Thank you very much. 

 

Jan Naceradsky, Czech Republic
0 Kudos
10 Replies
Highlighted
Valued Contributor III
108 Views

Personally I'd look at the register definition for the UART and write a function to add bytes to the fifo. 

You then have to make a concious decision about what to do when the tx fifo is full. 

Either: 

- spin waiting for space. 

- tell caller how many bytes were written (who might ignore the error). 

You might decide it is worth adding a software fifo, but a large hardware fifo has much the same effect. 

If you do use a software fifo, you don't necessarily need to use interupts - provided the software can poll the hardware often enough. 

 

The same is true of receive - make the hardware fifo big enough. 

I don't know if the uart can share an internal memory block between its rx and tx sides. 

It also ought to be possibly to design a multi-port uart that uses a single memory block.
0 Kudos
Highlighted
Valued Contributor III
108 Views

I used two file pointers : one for Transmit and one for receive

0 Kudos
Highlighted
Valued Contributor III
108 Views

I would give the alt_stdio functions a try. Read about them in the docs...and there should be some examples as well.

0 Kudos
Highlighted
Valued Contributor III
108 Views

Yes, i can use the functions: 

alt_printf()  

alt_putchar()  

alt_putstr()  

alt_getchar() 

 

they work with stdin,stdout, but how can i change this standard i/o from jtag uart to uart_0 ?  

And in additionally, when i tryed getchar function, it waits for RETURN. How can i make this, when i need to read the binary message from uart ? 

 

Thank you very much. 

 

Jan
0 Kudos
Highlighted
Valued Contributor III
108 Views

Hi all,  

I finally found some examples and make program, which work - it sends 4 bytes via uart0 and receives max.16 bytes via uart0. It works in hello world small template and when i compile, it take only 1852bytes (i run this on DE0_NANO development board). 

-------------------------------------------------- 

# include <stdio.h> 

# include <unistd.h> 

# include <fcntl.h> 

# include "sys/alt_stdio.h" 

# include "system.h" 

# include "altera_avalon_pio_regs.h" 

# include "altera_avalon_uart_regs.h" 

# include "altera_avalon_uart.h" 

 

// global variables 

int count = 0,ch,n,status,led=0xff; 

int rx_cnt,rx_buf[16]; 

 

int main() 

alt_printf("1.Hello from Nios II!\n"); 

 

while(1) 

{ // printf("Hello from Nios II!\n"); 

IOWR_ALTERA_AVALON_PIO_DATA(DATA_BUS_BASE, count ); 

IOWR_ALTERA_AVALON_PIO_DATA(LED_BASE, count); 

count++; 

 

// send 4 bytes via UART0 (with waiting 100us) 

IOWR_ALTERA_AVALON_UART_TXDATA(UART_0_BASE,0xFF); 

usleep(100); 

IOWR_ALTERA_AVALON_UART_TXDATA(UART_0_BASE,0xAA); 

usleep(100); 

IOWR_ALTERA_AVALON_UART_TXDATA(UART_0_BASE,count/256); 

usleep(100); 

IOWR_ALTERA_AVALON_UART_TXDATA(UART_0_BASE,count%256); 

usleep(100); 

 

// read bytes from UART and wait 20ms 

rx_cnt=0; 

for(n=0;n<1000;n++) 

{ usleep(20); 

ch = IORD_ALTERA_AVALON_UART_STATUS(UART_0_BASE); 

// if received some byte, read it 

if ((ch&0x80)==0x80) 

{ ch = IORD_ALTERA_AVALON_UART_RXDATA(UART_0_BASE); 

rx_buf[rx_cnt]= ch; 

rx_cnt++; 

 

// print the bytes to terminal 

if (rx_cnt>0) 

{ alt_printf("rx_data:"); 

for(n=0;n<rx_cnt;n++) 

{ alt_printf("%x ",rx_buf[n]); 

alt_printf("\n"); 

 

return 0; 

------------------------ 

 

Jan Naceradsky, Czech Republic
0 Kudos
Highlighted
Valued Contributor III
108 Views

Altera doesn't advice to employ IOWR_ALTERA_AVALON_UART_TXDATA and others "direct" functions. 

They prefer user to use API. It is explained in Altera UART core .pdf
0 Kudos
Highlighted
Valued Contributor III
108 Views

Yes, and their APIs suck - especially if you want small code and/or high performance. 

But I would write small wrapper functions. 

 

Oh - put code fragments inside 'code' tags...
0 Kudos
Highlighted
Valued Contributor III
108 Views

Hi! May I know what do you receive on your HyperTerminal? I keep receiving a 7 look alike thing at hyperterminal and when I copy and paste it in here , it become a ª. 

How may I solve it? 

And at the Nios II Console, Random number are coming out. 

 

Example I type in... 

3 and the result is 33 

a and the result is 61 

s and the result is 73 

 

May I know where ran wrong? I am suppose to test by sending something to uart and read from it then display it on Nios II console. 

 

Can anyone tell me what does the 0xFF,0xAA, count/256 and count%256 are for? 

 

Sorry for all these questions...  

 

 

--- Quote Start ---  

Hi all,  

I finally found some examples and make program, which work - it sends 4 bytes via uart0 and receives max.16 bytes via uart0. It works in hello world small template and when i compile, it take only 1852bytes (i run this on DE0_NANO development board). 

--------------------------------------------------# include <stdio.h># include <unistd.h># include <fcntl.h># include "sys/alt_stdio.h"# include "system.h"# include "altera_avalon_pio_regs.h"# include "altera_avalon_uart_regs.h"# include "altera_avalon_uart.h" 

 

// global variables 

int count = 0,ch,n,status,led=0xff; 

int rx_cnt,rx_buf[16]; 

 

int main() 

alt_printf("1.Hello from Nios II!\n"); 

 

while(1) 

{ // printf("Hello from Nios II!\n"); 

IOWR_ALTERA_AVALON_PIO_DATA(DATA_BUS_BASE, count ); 

IOWR_ALTERA_AVALON_PIO_DATA(LED_BASE, count); 

count++; 

 

// send 4 bytes via UART0 (with waiting 100us) 

IOWR_ALTERA_AVALON_UART_TXDATA(UART_0_BASE,0xFF); 

usleep(100); 

IOWR_ALTERA_AVALON_UART_TXDATA(UART_0_BASE,0xAA); 

usleep(100); 

IOWR_ALTERA_AVALON_UART_TXDATA(UART_0_BASE,count/256); 

usleep(100); 

IOWR_ALTERA_AVALON_UART_TXDATA(UART_0_BASE,count%256); 

usleep(100); 

 

// read bytes from UART and wait 20ms 

rx_cnt=0; 

for(n=0;n<1000;n++) 

{ usleep(20); 

ch = IORD_ALTERA_AVALON_UART_STATUS(UART_0_BASE); 

// if received some byte, read it 

if ((ch&0x80)==0x80) 

{ ch = IORD_ALTERA_AVALON_UART_RXDATA(UART_0_BASE); 

rx_buf[rx_cnt]= ch; 

rx_cnt++; 

 

// print the bytes to terminal 

if (rx_cnt>0) 

{ alt_printf("rx_data:"); 

for(n=0;n<rx_cnt;n++) 

{ alt_printf("%x ",rx_buf[n]); 

alt_printf("\n"); 

 

return 0; 

------------------------ 

 

Jan Naceradsky, Czech Republic 

--- Quote End ---  

0 Kudos
Highlighted
Valued Contributor III
108 Views

 

--- Quote Start ---  

Hi! May I know what do you receive on your HyperTerminal? I keep receiving a 7 look alike thing at hyperterminal and when I copy and paste it in here , it become a ª. 

How may I solve it? 

And at the Nios II Console, Random number are coming out. 

 

Example I type in... 

3 and the result is 33 

a and the result is 61 

s and the result is 73 

 

May I know where ran wrong? I am suppose to test by sending something to uart and read from it then display it on Nios II console. 

 

Can anyone tell me what does the 0xFF,0xAA, count/256 and count%256 are for? 

 

Sorry for all these questions... 

--- Quote End ---  

 

 

Surely in the meanwhile you have found the answers but if not: 

 

"example i type in... 

3 and the result is 33 

a and the result is 61..

these are the exadecimal ascii codes of the keys you are pressing, simply search for ASCII Table and you can know why. 

 

"can anyone tell me what does the 0xff,0xaa, count/256 and count%256 are for?

I think naceradsky added it only for testing purpose, just to show what is happening! 

 

UART rs232 used as stdio: 

Regarding other "very old" questions posted in the forum related to programs that have to continue "working" without waiting for user inputs (i.e.:keystroke via UART terminal) I have found my own little solution. 

I'm not a software developer and I'm not able to use "high level" functions, but I noticed that when tyr to use functions that involve stdin & stdout like "printf" or "scanf" this functions (obviously) accesses and alter the UART registers. So if we want to access UART using those registers we don't have to use stdio functions. 

 

I have first tryed using o_nonblock (niosII 9.1 sp2) but for me it doesn't work well, so I wrote an horrible code probably, but for my tests is working fine, this is an extraction from my altered version of Altara's "board_diag", i'll post it if any beginner would like to take a look! 

 

! This is not a full code! 

 

* static void TestSW_INPUT(void) 

* function that reads swithces status on DE1 board 

* write switches value on red led and have a free running counter 1 to F 

* and display count on green led and on terminal rs232 

* It exits when the user types a 'q'. 

*/ 

 

 

static void TestSW_INPUT(void) 

 

 

alt_u16 sw_input; 

alt_u16 count = 0x0000; 

char char_count[81]; 

int num_char_count; 

char stop ='0';// ...can also use a boolean flag ... 

//static char entry[4];//used for previous tests 

alt_u16 UartSts; 

alt_u16 CntrOrig; 

alt_u16 rrdy = 0x0000; 

alt_u16 tmt = 0x0000;//transmitter empty 

 

 

 

 

//fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK);//sets uart in non blocking mode 

printf( "\r\n press 'q' to EXIT \n\r"); 

printf( "\r\n or change switches to show their value \n\r"); 

//usleep(10000); 

CntrOrig=IORD_ALTERA_AVALON_UART_CONTROL(UART_BASE);//save original uart control reg 

 

 

 

 

while (count < 0x0f && stop != 'q' ) 

/*while (tmt != 0x0020)//wait for any tx 

UartSts = IORD_ALTERA_AVALON_UART_STATUS(UART_BASE);//read UART status reg 

tmt = UartSts & 0x0020;//test tmt 

}*/ //previous tests!! 

IOWR_ALTERA_AVALON_UART_CONTROL(UART_BASE,0x00);//erase masks if any! 

/* Read HW switches status */ 

sw_input = IORD_ALTERA_AVALON_PIO_DATA(SW_INPUT_BASE); 

IOWR_ALTERA_AVALON_PIO_DATA(LED_R_BASE, sw_input); 

IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE, count); 

//usleep(1000000); 

UartSts = IORD_ALTERA_AVALON_UART_STATUS(UART_BASE);//read UART status reg 

rrdy = UartSts & 0x0080;//test RRDY 

if (rrdy == 0x80) 

stop=IORD_ALTERA_AVALON_UART_RXDATA(UART_BASE); 

count++; 

usleep(100000);//delay to avaluate funcionality 

num_char_count = sprintf(char_count, "count value is: %x \n",count); 

for (int i=0; i<=num_char_count;i++) 

IOWR_ALTERA_AVALON_UART_TXDATA(UART_BASE,char_count[i]); 

usleep(1000); 

IOWR_ALTERA_AVALON_UART_TXDATA(UART_BASE,0x0D);//CR 

//fcntl(STDIN_FILENO, F_SETFL, EWOULDBLOCK);////set back uart in blocking mode? 

//sscanf( entry, "%c\n", &stop );//need to empty entry? 

IOWR_ALTERA_AVALON_UART_CONTROL(UART_BASE,CntrOrig);//set back original uart_control value 

printf(".....Exiting TestSW_INPUT.\n\r"); 

 

note that I have use STDIO function "printf" but outside the direct acces of UART functionality.
0 Kudos
Highlighted
Valued Contributor III
108 Views

Don't use hyperterm - it is horrid beyond belief. 

Something like putty is much better and will actually show you what the serail port is doing.
0 Kudos