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++
12600 Discussions

How to access UART that is not STDIN or STDOUT

Altera_Forum
Honored Contributor II
1,913 Views

how do I access / call the uart if it is not SDTIN or STDOUT? my nios has 3 uarts, UART_ONE at 115200, UART_TWO at 57600, and UART_THREE at 38400. in my SOPC, UART_ONE is set to STDIN and STDOUT, and I can connect my pc to the FGPA / Nios and communicate to it using a terminal application on the PC to send and receive characters, using the alt_getchar() , alt_putchar(), and alt_printf() functions, How ever I can not communicate to UART_TWO or UART_THREE using the same functions, HOW do I access a UART that is not STDIN, or STDOUT? I am sending only small messages of about 30 characters or less. I am currently using small library call, because I have limited space in a small FPGA, Cyclone III EP3C5, so I do not have space to use fopen and fclose to access uart as example from manual says.  

int main () 

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 Do I Redirect alt_putchar(), alt_getchar() and alt_printf() functions so I can call UART_TWO, and UART_THREE 

 

I want to have a PC terminal talk to each of the uarts independently to send and receive characters from separate terminal windows (PC port COM3, COM4, COM5), (each uart and pc terminal application instance will act like a simulated field device talking to the FPGA) 

and as I have 3 uarts (3 simulated field devices) theoretically all of them are SDT_IN and STD_OUT 

 

from system.h file uarts are defined as : 

#define ALT_MODULE_CLASS_uart_Com232 altera_avalon_uart 

#define UART_COM232_BASE 0x200020 

#define UART_COM232_BAUD 38400 

#define UART_COM232_NAME "/dev/uart_Com232" 

#define UART_COM232_TYPE "altera_avalon_uart" 

 

/** uart_IR485 configuration**/ 

#define ALT_MODULE_CLASS_uart_IR485 altera_avalon_uart 

#define UART_IR485_BASE 0x200040 

#define UART_IR485_BAUD 38400 

#define UART_IR485_NAME "/dev/uart_IR485" 

#define UART_IR485_TYPE "altera_avalon_uart" 

 

/** uart_debug configuration**/ 

#define ALT_MODULE_CLASS_uart_debug altera_avalon_uart 

#define UART_DEBUG_BASE 0x200060 

#define UART_DEBUG_BAUD 115200 

#define UART_DEBUG_NAME "/dev/uart_debug_115200" 

#define UART_DEBUG_TYPE "altera_avalon_uart"
0 Kudos
5 Replies
Altera_Forum
Honored Contributor II
761 Views

I think that since you don't have room to use fopen or fclose you might have to make your own functions/driver that manipulate the registers in the uarts, that are not tied to stdin or stdout, directly.

0 Kudos
Altera_Forum
Honored Contributor II
761 Views

Yep that's what I have found, because of my limited RAM and storage space, I have to bypass the alt_getchar, alt_putchar, and alt_printf functions, Our system is configured with "enable_reduced_drivers set" and under avalon_uart_driver, "enable_small_driver is set" 

 

so a limited HAL is created and the uart drivers are generated as macros with dedicated device address, so the functions can not be "re-used" 

 

we have to read the uart status registers, and stuff data into RX and TX registers, ourselfs ' basically creating a new driver "
0 Kudos
Altera_Forum
Honored Contributor II
761 Views

I guess the good thing is that you might save some space by not using alt_printf. You might want to opt not using alt_printf etc for stdin or stdout either and maybe use your functions/driver for all and maybe save some space overall.  

 

/Boris
0 Kudos
Altera_Forum
Honored Contributor II
761 Views

For a specific board/product (etc) you don't need the generalisations assumed by the POSIX file access functions. It is almost certainly enough to have a 'write buffer (or string) to UART' function. 

You then need to decide where to buffer data (software or fifo buffer). This rather depends on how much data you might need to buffer - eventually the code will have to spin/sleep or discard anyway. A hardware fifo might be easiest - if you can afford a full memory block. 

I'd also consider whether you need to use interrupts. It may well be possible to add a check of the uart registers to the main schedule/process loop. Not using interrupts will probably generate smaller and faster code.
0 Kudos
Altera_Forum
Honored Contributor II
761 Views

Yep, in the altera manual somewhere, "embedded IP" section, if you select "small drivers, or reduced drivers, etc.." it automatically disables the interrupt functions and creates a polled mode uart driver using the HAL, so we are just running a "check uart" routine in the main process loop, to check uart1, then check uart2, then check uart3, then process our other information, etc,,, the system timer is also running in polled mode, timer expires every Xmsec, and upon expiration, sets a bit, and the fpga in hardware captures this and stores it to a register, so main process loop can check to see if timer expired by reading a register instead of having an interrupt system "our process loop is small and simple" so no need for interrupts, and it takes less code space.

0 Kudos
Reply