- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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 RepublicLink Copied
10 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I used two file pointers : one for Transmit and one for receive
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I would give the alt_stdio functions a try. Read about them in the docs...and there should be some examples as well.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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...- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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 ---- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
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