00001 00049 #include <cfg/crt.h> /* Floating point configuration. */ 00050 00051 #include <string.h> 00052 #include <stdio.h> 00053 #include <io.h> 00054 00055 #include <dev/board.h> 00056 #include <sys/timer.h> 00057 00058 static char *banner = "\nNut/OS UART Sample\n"; 00059 static prog_char presskey_P[] = "Press any key..."; 00060 static prog_char pgm_ptr[] = "\nHello stranger!\n"; 00061 00062 static char inbuf[128]; 00063 00064 /* 00065 * UART sample. 00066 * 00067 * Some functions do not work with ICCAVR. 00068 */ 00069 int main(void) 00070 { 00071 int got; 00072 char *cp; 00073 uint32_t baud = 115200; 00074 FILE *uart; 00075 #ifdef STDIO_FLOATING_POINT 00076 float dval = 0.0; 00077 #endif 00078 00079 /* 00080 * Each device must be registered. We do this by referencing the 00081 * device structure of the driver. The advantage is, that only 00082 * those device drivers are included in our flash code, which we 00083 * really need. 00084 * 00085 * The uart0 device is the first one on the ATmega chip. So it 00086 * has no configurable base address or interrupt and we set both 00087 * parameters to zero. 00088 */ 00089 NutRegisterDevice(&DEV_CONSOLE, 0, 0); 00090 00091 /* 00092 * Now, as the device is registered, we can open it. The fopen() 00093 * function returns a pointer to a FILE structure, which we use 00094 * for subsequent reading and writing. 00095 */ 00096 uart = fopen(DEV_CONSOLE_NAME, "r+"); 00097 00098 /* 00099 * Before doing the first read or write, we set the baudrate. 00100 * This low level function doesn't know about FILE structures 00101 * and we use _fileno() to get the low level file descriptor 00102 * of the stream. 00103 * 00104 * The short sleep allows the UART to settle after the baudrate 00105 * change. 00106 */ 00107 _ioctl(_fileno(uart), UART_SETSPEED, &baud); 00108 00109 /* 00110 * Stream devices can use low level read and write functions. 00111 * Writing program space data is supported too. 00112 */ 00113 _write(_fileno(uart), banner, strlen(banner)); 00114 { 00115 _write_P(_fileno(uart), presskey_P, sizeof(presskey_P)); 00116 } 00117 00118 /* 00119 * Stream devices do buffered I/O. That means, nothing will be 00120 * passed to the hardware device until either the output buffer 00121 * is full or we do a flush. With stream I/O we typically use 00122 * fflush(), but low level writing a null pointer will also flush 00123 * the output buffer. 00124 */ 00125 _write(_fileno(uart), 0, 0); 00126 00127 /* 00128 * The low level function read() will grab all available bytes 00129 * from the input buffer. If the buffer is empty, the call will 00130 * block until something is available for reading. 00131 */ 00132 got = _read(_fileno(uart), inbuf, sizeof(inbuf)); 00133 _write(_fileno(uart), inbuf, got); 00134 00135 /* 00136 * Nut/OS never expects a thread to return. So we enter an 00137 * endless loop here. 00138 */ 00139 for (;;) { 00140 /* 00141 * A bit more advanced input routine is able to read a string 00142 * up to and including the first newline character or until a 00143 * specified maximum number of characters, whichever comes first. 00144 */ 00145 fputs("\nEnter your name: ", uart); 00146 fflush(uart); 00147 fgets(inbuf, sizeof(inbuf), uart); 00148 00149 /* 00150 * Chop off trailing linefeed. 00151 */ 00152 cp = strchr(inbuf, '\n'); 00153 if (cp) 00154 *cp = 0; 00155 00156 /* 00157 * Streams support formatted output as well as printing strings 00158 * from program space. 00159 */ 00160 if (inbuf[0]) 00161 fprintf(uart, "\nHello %s!\n", inbuf); 00162 else { 00163 fputs_P(pgm_ptr, uart); 00164 } 00165 00166 /* 00167 * Just to demonstrate formatted floating point output. 00168 * In order to use this, we need to link the application 00169 * with nutcrtf instead of nutcrt for pure integer. 00170 */ 00171 #ifdef STDIO_FLOATING_POINT 00172 dval += 1.0125; 00173 fprintf(uart, "FP %f\n", dval); 00174 #endif 00175 } 00176 return 0; 00177 }