~ubuntu-branches/ubuntu/wily/avr-libc/wily-proposed

« back to all changes in this revision

Viewing changes to doc/examples/stdiodemo/stdiodemo.dox

  • Committer: Bazaar Package Importer
  • Author(s): Hakan Ardo
  • Date: 2006-11-15 21:12:47 UTC
  • mfrom: (3.1.2 feisty)
  • Revision ID: james.westby@ubuntu.com-20061115211247-b7qhgnb6o49v5zsg
Tags: 1:1.4.5-2
* Convertion to debheler fixed (closes: #398220)
* Reference to /usr/share/common-licenses in copyright file

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (c) 2005,2006 Joerg Wunsch
 
2
   All rights reserved.
 
3
 
 
4
   Redistribution and use in source and binary forms, with or without
 
5
   modification, are permitted provided that the following conditions are met:
 
6
 
 
7
   * Redistributions of source code must retain the above copyright
 
8
     notice, this list of conditions and the following disclaimer.
 
9
 
 
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
 
13
     distribution.
 
14
 
 
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.
 
18
 
 
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. */
 
30
 
 
31
/* $Id*/
 
32
 
 
33
/** \defgroup stdiodemo Using the standard IO facilities
 
34
    \ingroup demos
 
35
 
 
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.
 
42
 
 
43
This demo is meant to supplement the \ref avr_stdio "documentation",
 
44
not to replace it.
 
45
 
 
46
\section stdiodemo_hw Hardware setup
 
47
 
 
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),
 
53
respectively.
 
54
 
 
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:
 
59
 
 
60
<table>
 
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>
 
72
</table>
 
73
 
 
74
\image html stdiodemo-setup.jpg "Wiring of the STK500"
 
75
\image latex stdiodemo-setup.eps "Wiring of the STK500" width=12cm
 
76
 
 
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.
 
84
 
 
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
 
89
UART connection.
 
90
 
 
91
\section stdiodemo_overview Functional overview
 
92
 
 
93
The project consists of the following files:
 
94
 
 
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
 
103
 
 
104
\section stdiodemo_code A code walkthrough
 
105
 
 
106
\subsection stdiodemo_main stdiodemo.c
 
107
 
 
108
As usual, include files go first.  While conventionally, system header
 
109
files (those in angular brackets \c &lt; ... \c &gt;) 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>&lt;utils/delay.h&gt;</tt>.
 
114
 
 
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.
 
122
 
 
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
 
132
be given as \c NULL.
 
133
 
 
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.
 
138
 
 
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>&lt;util/delay.h&gt;</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.
 
147
 
 
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.
 
151
 
 
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
 
158
diagnostic messages.
 
159
 
 
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.
 
163
 
 
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.
 
167
 
 
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.
 
174
 
 
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.
 
186
 
 
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.
 
192
 
 
193
There are three "commands" recognized, each determined
 
194
by the first letter of the line entered (converted to lower case):
 
195
 
 
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.
 
202
 
 
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).
 
206
 
 
207
 
 
208
\subsection stdiodemo_defines defines.h
 
209
 
 
210
This file just contains a few peripheral definitions.
 
211
 
 
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.
 
214
 
 
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
 
217
supported.
 
218
 
 
219
The remaining macros customize the IO port and pins used for the
 
220
HD44780 LCD driver.
 
221
 
 
222
\subsection stdiodemo_hd44780_h hd44780.h
 
223
 
 
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.
 
229
 
 
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.
 
234
 
 
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.
 
238
 
 
239
\subsection stdiodemo_hd44780_c hd44780.c
 
240
 
 
241
This is the implementation of the low-level HD44780 LCD controller
 
242
driver.
 
243
 
 
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.
 
248
 
 
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.
 
257
 
 
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.
 
262
 
 
263
Building upon these, the public functions \c hd44780_outbyte() and
 
264
\c hd44780_inbyte() transfer one byte to/from the controller.
 
265
 
 
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.
 
271
 
 
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).
 
281
 
 
282
\subsection stdiodemo_lcd_h lcd.h
 
283
 
 
284
This function declares the public interface of the higher-level
 
285
(character IO) LCD driver.
 
286
 
 
287
\subsection stdiodemo_lcd_c lcd.c
 
288
 
 
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.
 
297
 
 
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.
 
309
 
 
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.
 
313
 
 
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).
 
318
 
 
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.
 
325
 
 
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.
 
333
 
 
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().
 
345
 
 
346
 
 
347
\subsection stdiodemo_uart_h uart.h
 
348
 
 
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.
 
352
 
 
353
As the RS-232 input is line-buffered in this example, the macro
 
354
\c RX_BUFSIZE determines the size of that buffer.
 
355
 
 
356
 
 
357
\subsection stdiodemo_uart_c uart.c
 
358
 
 
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>).
 
365
 
 
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
 
370
implemented are:
 
371
 
 
372
- \c \\b (back space) or \c \\177 (delete) deletes the previous
 
373
character
 
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
 
378
buffer (refresh)
 
379
- \c \\t (tabulator) will be replaced by a single space
 
380
 
 
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.
 
388
 
 
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.
 
395
 
 
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.
 
400
 
 
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.
 
409
 
 
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
 
419
again.)
 
420
 
 
421
 
 
422
\section stdiodemo_src The source code
 
423
 
 
424
\htmlonly
 
425
<ul>
 
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>
 
434
</li>
 
435
\endhtmlonly
 
436
 
 
437
\latexonly
 
438
The source code is installed under
 
439
 
 
440
\texttt{\$prefix/share/doc/avr-libc/examples/stdiodemo/},
 
441
 
 
442
where \texttt{\$prefix} is a configuration option.  For Unix
 
443
systems, it is usually set to either \texttt{/usr} or
 
444
\texttt{/usr/local}.
 
445
\endlatexonly
 
446
 
 
447
*/