1
/* Copyright (c) 2005,2006 Joerg Wunsch
4
Redistribution and use in source and binary forms, with or without
5
modification, are permitted provided that the following conditions are met:
7
* Redistributions of source code must retain the above copyright
8
notice, this list of conditions and the following disclaimer.
10
* Redistributions in binary form must reproduce the above copyright
11
notice, this list of conditions and the following disclaimer in
12
the documentation and/or other materials provided with the
15
* Neither the name of the copyright holders nor the names of
16
contributors may be used to endorse or promote products derived
17
from this software without specific prior written permission.
19
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
POSSIBILITY OF SUCH DAMAGE. */
33
/** \defgroup stdiodemo Using the standard IO facilities
36
This project illustrates how to use the standard IO facilities (stdio)
37
provided by this library. It assumes a basic knowledge of how the
38
stdio subsystem is used in standard C applications, and concentrates
39
on the differences in this library's implementation that mainly result
40
from the differences of the microcontroller environment, compared to a
41
hosted environment of a standard computer.
43
This demo is meant to supplement the \ref avr_stdio "documentation",
46
\section stdiodemo_hw Hardware setup
48
The demo is set up in a way so it can be run on the ATmega16 that
49
ships with the STK500 development kit. The UART port needs to be
50
connected to the RS-232 "spare" port by a jumper cable
51
that connects PD0 to RxD and PD1 to TxD. The RS-232 channel is set up
52
as standard input (\c stdin) and standard output (\c stdout),
55
In order to have a different device available for a standard error
56
channel (\c stderr), an industry-standard LCD display with an
57
HD44780-compatible LCD controller has been chosen. This display needs
58
to be connected to port A of the STK500 in the following way:
61
<tr><td><b>Port</b></td><td><b>Header</b></td><td><b>Function</b></td></tr>
62
<tr><td>A0</td> <td>1</td> <td>LCD D4</td></tr>
63
<tr><td>A1</td> <td>2</td> <td>LCD D5</td></tr>
64
<tr><td>A2</td> <td>3</td> <td>LCD D6</td></tr>
65
<tr><td>A3</td> <td>4</td> <td>LCD D7</td></tr>
66
<tr><td>A4</td> <td>5</td> <td>LCD R/~W</td></tr>
67
<tr><td>A5</td> <td>6</td> <td>LCD E</td></tr>
68
<tr><td>A6</td> <td>7</td> <td>LCD RS</td></tr>
69
<tr><td>A7</td> <td>8</td> <td>unused</td></tr>
70
<tr><td>GND</td><td>9</td> <td>GND</td></tr>
71
<tr><td>VCC</td><td>10</td><td>Vcc</td></tr>
74
\image html stdiodemo-setup.jpg "Wiring of the STK500"
75
\image latex stdiodemo-setup.eps "Wiring of the STK500" width=12cm
77
The LCD controller is used in 4-bit mode, including polling the
78
"busy" flag so the R/~W line from the LCD controller needs
79
to be connected. Note that the LCD controller has yet another supply
80
pin that is used to adjust the LCD's contrast (V5). Typically, that
81
pin connects to a potentiometer between Vcc and GND. Often, it might
82
work to just connect that pin to GND, while leaving it unconnected
83
usually yields an unreadable display.
85
Port A has been chosen as 7 pins on a single port are needed to
86
connect the LCD, yet all other ports are already partially in use:
87
port B has the pins for in-system programming (ISP), port C has the
88
ports for JTAG (can be used for debugging), and port D is used for the
91
\section stdiodemo_overview Functional overview
93
The project consists of the following files:
95
- \c stdiodemo.c This is the main example file.
96
- \c defines.h Contains some global defines, like the LCD wiring
97
- \c hd44780.c Implementation of an HD44780 LCD display driver
98
- \c hd44780.h Interface declarations for the HD44780 driver
99
- \c lcd.c Implementation of LCD character IO on top of the HD44780 driver
100
- \c lcd.h Interface declarations for the LCD driver
101
- \c uart.c Implementation of a character IO driver for the internal UART
102
- \c uart.h Interface declarations for the UART driver
104
\section stdiodemo_code A code walkthrough
106
\subsection stdiodemo_main stdiodemo.c
108
As usual, include files go first. While conventionally, system header
109
files (those in angular brackets \c < ... \c >) go before
110
application-specific header files (in double quotes), \c defines.h
111
comes as the first header file here. The main reason is that this
112
file defines the value of \c F_CPU which needs to be known before
113
including <tt><utils/delay.h></tt>.
115
The function \c ioinit() summarizes all hardware initialization tasks.
116
As this function is declared to be module-internal only (\c static),
117
the compiler will notice its simplicity, and with a reasonable
118
optimization level in effect, it will inline that function. That
119
needs to be kept in mind when debugging, because the inlining might
120
cause the debugger to "jump around wildly" at a first
121
glance when single-stepping.
123
The definitions of \c uart_str and \c lcd_str set up two stdio
124
streams. The initialization is done using the \c FDEV_SETUP_STREAM()
125
initializer template macro, so a static object can be constructed that
126
can be used for IO purposes. This initializer macro takes three
127
arguments, two function macros to connect the corresponding output and
128
input functions, respectively, the third one describes the intent of
129
the stream (read, write, or both). Those functions that are not
130
required by the specified intent (like the input function for
131
\c lcd_str which is specified to only perform output operations) can
134
The stream \c uart_str corresponds to input and output operations
135
performed over the RS-232 connection to a terminal (e.g. from/to a PC
136
running a terminal program), while the \c lcd_str stream provides a
137
method to display character data on the LCD text display.
139
The function \c delay_1s() suspends program execution for
140
approximately one second. This is done using the \c _delay_ms()
141
function from <tt><util/delay.h></tt> which in turn needs the \c
142
F_CPU macro in order to adjust the cycle counts. As the \c _delay_ms()
143
function has a limited range of allowable argument values (depending on
144
\c F_CPU), a value of 10 ms has been chosen as the base delay which
145
would be safe for CPU frequencies of up to about 26 MHz. This function
146
is then called 100 times to accomodate for the actual one-second delay.
148
In a practical application, long delays like this one were better be
149
handled by a hardware timer, so the main CPU would be free for other
150
tasks while waiting, or could be put on sleep.
152
At the beginning of \c main(), after initializing the peripheral devices,
153
the default stdio streams \c stdin, \c stdout, and \c stderr are set
154
up by using the existing static \c FILE stream objects. While this is
155
not mandatory, the availability of \c stdin and \c stdout allows to
156
use the shorthand functions (e.g. \c printf() instead of \c fprintf()),
157
and \c stderr can mnemonically be referred to when sending out
160
Just for demonstration purposes, \c stdin and \c stdout are connected
161
to a stream that will perform UART IO, while \c stderr is arranged to
162
output its data to the LCD text display.
164
Finally, a main loop follows that accepts simple
165
"commands" entered via the RS-232 connection, and performs
166
a few simple actions based on the commands.
168
First, a prompt is sent out using \c printf_P() (which takes a
169
\ref avr_pgmspace "program space string"). The string is read into
170
an internal buffer as one line of input, using \c fgets(). While it
171
would be also possible to use \c gets() (which implicitly reads from
172
\c stdin), \c gets() has no control that the user's input does not
173
overflow the input buffer provided so it should never be used at all.
175
If \c fgets() fails to read anything, the main loop is left. Of
176
course, normally the main loop of a microcontroller application is
177
supposed to never finish, but again, for demonstrational purposes,
178
this explains the error handling of stdio. \c fgets() will return
179
NULL in case of an input error or end-of-file condition on input.
180
Both these conditions are in the domain of the function that is used
181
to establish the stream, \c uart_putchar() in this case. In short,
182
this function returns EOF in case of a serial line "break"
183
condition (extended start condition) has been recognized on the serial
184
line. Common PC terminal programs allow to assert this condition as
185
some kind of out-of-band signalling on an RS-232 connection.
187
When leaving the main loop, a goodbye message is sent to standard
188
error output (i.e. to the LCD), followed by three dots in one-second
189
spacing, followed by a sequence that will clear the LCD. Finally,
190
\c main() will be terminated, and the library will add an infinite
191
loop, so only a CPU reset will be able to restart the application.
193
There are three "commands" recognized, each determined
194
by the first letter of the line entered (converted to lower case):
196
- The 'q' (quit) command has the same effect of
197
leaving the main loop.
198
- The 'l' (LCD) command takes its second argument,
199
and sends it to the LCD.
200
- The 'u' (UART) command takes its second argument,
201
and sends it back to the UART connection.
203
Command recognition is done using \c sscanf() where the first format
204
in the format string just skips over the command itself (as the
205
assignment suppression modifier \c * is given).
208
\subsection stdiodemo_defines defines.h
210
This file just contains a few peripheral definitions.
212
The \c F_CPU macro defines the CPU clock frequency, to be used in
213
delay loops, as well as in the UART baud rate calculation.
215
The macro \c UART_BAUD defines the RS-232 baud rate. Depending on the
216
actual CPU frequency, only a limited range of baud rates can be
219
The remaining macros customize the IO port and pins used for the
222
\subsection stdiodemo_hd44780_h hd44780.h
224
This file describes the public interface of the low-level LCD driver
225
that interfaces to the HD44780 LCD controller. Public functions are
226
available to initialize the controller into 4-bit mode, to wait for
227
the controller's busy bit to be clear, and to read or write one byte
228
from or to the controller.
230
As there are two different forms of controller IO, one to send a
231
command or receive the controller status (RS signal clear), and one to
232
send or receive data to/from the controller's SRAM (RS asserted),
233
macros are provided that build on the mentioned function primitives.
235
Finally, macros are provided for all the controller commands to allow
236
them to be used symbolically. The HD44780 datasheet explains these
237
basic functions of the controller in more detail.
239
\subsection stdiodemo_hd44780_c hd44780.c
241
This is the implementation of the low-level HD44780 LCD controller
244
On top, a few preprocessor glueing tricks are used to establish
245
symbolic access to the hardware port pins the LCD controller is
246
attached to, based on the application's definitions made in
247
\ref stdiodemo_defines.
249
The \c hd44780_pulse_e() function asserts a short pulse to the
250
controller's E (enable) pin.
251
Since reading back the data asserted by the LCD controller needs
252
to be performed while E is active, this function reads and returns
253
the input data if the parameter \c readback is true.
254
When called with a compile-time constant parameter that is false,
255
the compiler will completely eliminate the unused readback operation,
256
as well as the return value as part of its optimizations.
258
As the controller is used in 4-bit interface mode, all byte IO to/from
259
the controller needs to be handled as two nibble IOs. The functions
260
\c hd44780_outnibble() and \c hd44780_innibble() implement this. They
261
do not belong to the public interface, so they are declared static.
263
Building upon these, the public functions \c hd44780_outbyte() and
264
\c hd44780_inbyte() transfer one byte to/from the controller.
266
The function \c hd44780_wait_ready() waits for the controller to
267
become ready, by continuously polling the controller's status (which
268
is read by performing a byte read with the RS signal cleard), and
269
examining the BUSY flag within the status byte. This function needs
270
to be called before performing any controller IO.
272
Finally, \c hd44780_init() initializes the LCD controller into 4-bit
273
mode, based on the initialization sequence mandated by the datasheet.
274
As the BUSY flag cannot be examined yet at this point, this is the
275
only part of this code where timed delays are used.
276
While the controller can perform a power-on reset when certain
277
constraints on the power supply rise time are met, always calling the
278
software initialization routine at startup ensures the controller will
279
be in a known state. This function also puts the interface into 4-bit
280
mode (which would not be done automatically after a power-on reset).
282
\subsection stdiodemo_lcd_h lcd.h
284
This function declares the public interface of the higher-level
285
(character IO) LCD driver.
287
\subsection stdiodemo_lcd_c lcd.c
289
The implementation of the higher-level LCD driver. This driver builds
290
on top of the HD44780 low-level LCD controller driver, and offers a
291
character IO interface suitable for direct use by the standard IO
292
facilities. Where the low-level HD44780 driver deals with setting up
293
controller SRAM addresses, writing data to the controller's SRAM, and
294
controlling display functions like clearing the display, or moving the
295
cursor, this high-level driver allows to just write a character to the
296
LCD, in the assumption this will somehow show up on the display.
298
Control characters can be handled at this level, and used to perform
299
specific actions on the LCD. Currently, there is only one control
300
character that is being dealt with: a newline character (\c \\n) is
301
taken as an indication to clear the display and set the cursor into
302
its initial position upon reception of the next character, so a
303
"new line" of text can be displayed. Therefore, a
304
received newline character is remembered until more characters have
305
been sent by the application, and will only then cause the display to
306
be cleared before continuing. This provides a convenient abstraction
307
where full lines of text can be sent to the driver, and will remain
308
visible at the LCD until the next line is to be displayed.
310
Further control characters could be implemented, e. g. using a set of
311
escape sequences. That way, it would be possible to implement
312
self-scrolling display lines etc.
314
The public function \c lcd_init() first calls the initialization entry
315
point of the lower-level HD44780 driver, and then sets up the LCD in a
316
way we'd like to (display cleared, non-blinking cursor enabled, SRAM
317
addresses are increasing so characters will be written left to right).
319
The public function \c lcd_putchar() takes arguments that make it
320
suitable for being passed as a \c put() function pointer to the stdio
321
stream initialization functions and macros (\c fdevopen(),
322
\c FDEV_SETUP_STREAM() etc.). Thus, it takes two arguments, the
323
character to display itself, and a reference to the underlying stream
324
object, and it is expected to return 0 upon success.
326
This function remembers the last unprocessed newline character seen in
327
the function-local static variable \c nl_seen. If a newline character
328
is encountered, it will simply set this variable to a true value, and
329
return to the caller. As soon as the first non-newline character is
330
to be displayed with \c nl_seen still true, the LCD controller is told
331
to clear the display, put the cursor home, and restart at SRAM address
332
0. All other characters are sent to the display.
334
The single static function-internal variable \c nl_seen works for this
335
purpose. If multiple LCDs should be controlled using the same set of
336
driver functions, that would not work anymore, as a way is needed to
337
distinguish between the various displays. This is where the second
338
parameter can be used, the reference to the stream itself: instead of
339
keeping the state inside a private variable of the function, it can be
340
kept inside a private object that is attached to the stream itself. A
341
reference to that private object can be attached to the stream
342
(e.g. inside the function \c lcd_init() that then also needs to be
343
passed a reference to the stream) using \c fdev_set_udata(), and can
344
be accessed inside \c lcd_putchar() using fdev_get_udata().
347
\subsection stdiodemo_uart_h uart.h
349
Public interface definition for the RS-232 UART driver, much like in
350
\ref stdiodemo_lcd_h "lcd.h" except there is now also a character
351
input function available.
353
As the RS-232 input is line-buffered in this example, the macro
354
\c RX_BUFSIZE determines the size of that buffer.
357
\subsection stdiodemo_uart_c uart.c
359
This implements an stdio-compatible RS-232 driver using an AVR's
360
standard UART (or USART in asynchronous operation mode). Both,
361
character output as well as character input operations are
362
implemented. Character output takes care of converting the internal
363
newline \c \\n into its external representation carriage return/line
364
feed (<tt>\\r\\n</tt>).
366
Character input is organized as a line-buffered operation that allows
367
to minimally edit the current line until it is "sent" to the
368
application when either a carriage return (\c \\r) or newline (\c \\n)
369
character is received from the terminal. The line editing functions
372
- \c \\b (back space) or \c \\177 (delete) deletes the previous
374
- ^u (control-U, ASCII NAK) deletes the entire input buffer
375
- ^w (control-W, ASCII ETB) deletes the previous input word,
376
delimited by white space
377
- ^r (control-R, ASCII DC2) sends a \c \\r, then reprints the
379
- \c \\t (tabulator) will be replaced by a single space
381
The function \c uart_init() takes care of all hardware initialization
382
that is required to put the UART into a mode with 8 data bits, no
383
parity, one stop bit (commonly referred to as 8N1) at the baud rate
384
configured in \ref stdiodemo_defines_h "defines.h". At low CPU clock
385
frequencies, the \c U2X bit in the UART is set, reducing the
386
oversampling from 16x to 8x, which allows for a 9600 Bd rate to be
387
achieved with tolerable error using the default 1 MHz RC oscillator.
389
The public function \c uart_putchar() again has suitable arguments for
390
direct use by the stdio stream interface. It performs the \c \\n into
391
\c \\r\\n translation by recursively calling itself when it sees a \c \\n
392
character. Just for demonstration purposes, the \c \\a (audible bell,
393
ASCII BEL) character is implemented by sending a string to \c stderr,
394
so it will be displayed on the LCD.
396
The public function \c uart_getchar() implements the line editor. If
397
there are characters available in the line buffer (variable \c rxp is
398
not \c NULL), the next character will be returned from the buffer
399
without any UART interaction.
401
If there are no characters inside the line buffer, the input loop will
402
be entered. Characters will be read from the UART, and processed
403
accordingly. If the UART signalled a framing error (\c FE bit set),
404
typically caused by the terminal sending a <em>line break</em>
405
condition (start condition held much longer than one character period),
406
the function will return an end-of-file condition using \c _FDEV_EOF.
407
If there was a data overrun condition on input (\c DOR bit set),
408
an error condition will be returned as \c _FDEV_ERR.
410
Line editing characters are handled inside the loop, potentially
411
modifying the buffer status. If characters are attempted to be
412
entered beyond the size of the line buffer, their reception is
413
refused, and a \c \\a character is sent to the terminal. If a \c \\r
414
or \c \\n character is seen, the variable \c rxp (receive pointer) is
415
set to the beginning of the buffer, the loop is left, and the first
416
character of the buffer will be returned to the application. (If no
417
other characters have been entered, this will just be the newline
418
character, and the buffer is marked as being exhausted immediately
422
\section stdiodemo_src The source code
426
<li><a href="../examples/stdiodemo/stdiodemo.c">stdiodemo.c</a></li>
427
<li><a href="../examples/stdiodemo/defines.h">defines.h</a></li>
428
<li><a href="../examples/stdiodemo/hd44780.h">hd44780.h</a></li>
429
<li><a href="../examples/stdiodemo/hd44780.c">hd44780.c</a></li>
430
<li><a href="../examples/stdiodemo/lcd.h">lcd.h</a></li>
431
<li><a href="../examples/stdiodemo/lcd.c">lcd.c</a></li>
432
<li><a href="../examples/stdiodemo/uart.h">uart.h</a></li>
433
<li><a href="../examples/stdiodemo/uart.c">uart.c</a></li>
438
The source code is installed under
440
\texttt{\$prefix/share/doc/avr-libc/examples/stdiodemo/},
442
where \texttt{\$prefix} is a configuration option. For Unix
443
systems, it is usually set to either \texttt{/usr} or