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