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