1/* Copyright (c) 2005,2007 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: largedemo.dox 1190 2007-01-19 22:17:10Z joerg_wunsch $ */
32
33/** \defgroup largedemo A more sophisticated project
34    \ingroup demos
35
36This project extends the basic idea of the
37\ref demo_project "simple project" to control a LED with a PWM
38output, but adds methods to adjust the LED brightness.
39It employs a lot of the basic concepts of avr-libc to achieve
40that goal.
41
42Understanding this project assumes the simple project has been
43understood in full, as well as being acquainted with the basic
44hardware concepts of an AVR microcontroller.
45
46\section largedemo_hw Hardware setup
47
48The demo is set up in a way so it can be run on the ATmega16 that
49ships with the STK500 development kit.  The only external part needed
50is a potentiometer attached to the ADC.  It is connected to a 10-pin
51ribbon cable for port A, both ends of the potentiometer to pins 9
52(GND) and 10 (VCC), and the wiper to pin 1 (port A0).
53A bypass capacitor from pin 1 to pin 9 (like 47 nF) is recommendable.
54
55\image html largedemo-setup.jpg "Setup of the STK500"
56\image latex largedemo-setup.eps "Setup of the STK500" width=12cm
57
58The coloured patch cables are used to provide various
59interconnections.  As there are only four of them in the STK500, there
60are two options to connect them for this demo.  The second option for
61the yellow-green cable is shown in parenthesis in the table.
62Alternatively, the "squid" cable from the JTAG ICE kit can be used if
63available.
64
65<table>
66 <tr><td><b>Port</b></td><td><b>Header</b></td><td><b>Color</b></td><td><b>Function</b></td><td><b>Connect to</b></td></tr>
67 <tr><td>D0</td> <td>1</td> <td>brown</td>  <td>RxD</td>           <td>RXD of the RS-232 header</td></tr>
68 <tr><td>D1</td> <td>2</td> <td>grey</td>   <td>TxD</td>           <td>TXD of the RS-232 header</td></tr>
69 <tr><td>D2</td> <td>3</td> <td>black</td>  <td>button "down"</td> <td>SW0 (pin 1 switches header)</td></tr>
70 <tr><td>D3</td> <td>4</td> <td>red</td>    <td>button "up"</td>   <td>SW1 (pin 2 switches header)</td></tr>
71 <tr><td>D4</td> <td>5</td> <td>green</td>  <td>button "ADC"</td>  <td>SW2 (pin 3 switches header)</td></tr>
72 <tr><td>D5</td> <td>6</td> <td>blue</td>   <td>LED</td>           <td>LED0 (pin 1 LEDs header)</td></tr>
73 <tr><td>D6</td> <td>7</td> <td>(green)</td><td>clock out</td>     <td>LED1 (pin 2 LEDs header)</td></tr>
74 <tr><td>D7</td> <td>8</td> <td>white</td>  <td>1-second flash</td><td>LED2 (pin 3 LEDs header)</td></tr>
75 <tr><td>GND</td><td>9</td> <td></td>   <td>unused</td></tr>
76 <tr><td>VCC</td><td>10</td><td></td> <td>unused</td></tr>
77</table>
78
79\image html largedemo-wiring.jpg "Wiring of the STK500"
80\image latex largedemo-wiring.eps "Wiring of the STK500" width=12cm
81
82The following picture shows the alternate wiring where LED1 is
83connected but SW2 is not:
84
85\image html largedemo-wiring2.jpg "Wiring option #2 of the STK500"
86\image latex largedemo-wiring2.eps "Wiring option #2 of the STK500" width=12cm
87
88As an alternative, this demo can also be run on the popular ATmega8
89controller, or its successor ATmega88 as well as the ATmega48 and
90ATmega168 variants of the latter.  These controllers do not have a
91port named "A", so their ADC inputs are located on port C instead,
92thus the potentiometer needs to be attached to port C.  Likewise, the
93OC1A output is not on port D pin 5 but on port B pin 1 (PB1).  Thus,
94the above cabling scheme needs to be changed so that PB1 connects to
95the LED0 pin.  (PD6 remains unconnected.)  When using the STK500, use
96one of the jumper cables for this connection.  All other port D pins
97should be connected the same way as described for the ATmega16 above.
98
99When not using an STK500 starter kit, attach the LEDs through some
100resistor to Vcc (low-active LEDs), and attach pushbuttons from the
101respective input pins to GND.  The internal pull-up resistors are
102enabled for the pushbutton pins, so no external resistors are needed.
103
104Finally, the demo has been ported to the ATtiny2313 as well.  As this
105AVR does not offer an ADC, everything related to handling the ADC is
106disabled in the code for that MCU type.  Also, port D of this
107controller type only features 6 pins, so the 1-second flash LED had to
108be moved from PD6 to PD4.  (PD4 is used as the ADC control button on
109the other MCU types, but that is not needed here.)  OC1A is located at
110PB3 on this device.
111
112The \c MCU_TARGET macro in the Makefile needs to be adjusted
113appropriately for the alternative controller types.
114
115The flash ROM and RAM consumption of this demo are way below the
116resources of even an ATmega48, and still well within the capabilities
117of an ATtiny2313.
118The major advantage of experimenting
119with the ATmega16 (in addition that it ships together with an STK500
120anyway) is that it can be debugged online via JTAG.
121Likewise, the ATmega48/88/168 and ATtiny2313 devices can be debugged
122through debugWire, using the Atmel JTAG ICE mkII or the low-cost
123AVR Dragon.
124
125Note that in the explanation below, all port/pin names are applicable
126to the ATmega16 setup.
127
128\section largedemo_overview Functional overview
129
130PD6 will be toggled with each internal clock tick (approx. 10
131ms).  PD7 will flash once per second.
132
133PD0 and PD1 are configured as UART IO, and can be used to connect the
134demo kit to a PC (9600 Bd, 8N1 frame format).  The demo application
135talks to the serial port, and it can be controlled from the serial
136port.
137
138PD2 through PD4 are configured as inputs, and control the
139application unless control has been taken over by the serial
140port.  Shorting PD2 to GND will decrease the current PWM value,
141shorting PD3 to GND will increase it.
142
143While PD4 is shorted to GND, one ADC conversion for channel 0 (ADC
144input is on PA0) will be triggered each internal clock tick, and
145the resulting value will be used as the PWM value.  So the
146brightness of the LED follows the analog input value on PC0.  VAREF
147on the STK500 should be set to the same value as VCC.
148
149When running in serial control mode, the function of the
150watchdog timer can be demonstrated by typing an `r'.  This will
151make the demo application run in a tight loop without retriggering
152the watchdog  so after some seconds, the watchdog will reset the
153MCU.  This situation can be figured out on startup by reading the
154MCUCSR register.
155
156The current value of the PWM is backed up in an EEPROM cell after
157about 3 seconds of idle time after the last change.  If that EEPROM
158cell contains a reasonable (i. e. non-erased) value at startup, it is
159taken as the initial value for the PWM.  This virtually preserves the
160last value across power cycles.  By not updating the EEPROM
161immmediately but only after a timeout, EEPROM wear is reduced
162considerably compared to immediately writing the value at each change.
163
164\section largedemo_code A code walkthrough
165
166This section explains the ideas behind individual parts of the code.
167The \ref largedemo_src "source code" has been divided into numbered
168parts, and the following subsections explain each of these parts.
169
170\subsection largedemo_code_p1 Part 1: Macro definitions
171
172A number of preprocessor macros are defined to improve readability
173and/or portability of the application.
174
175The first macros describe the IO pins our LEDs and pushbuttons are
176connected to.  This provides some kind of mini-HAL (hardware
177abstraction layer) so should some of the connections be changed, they
178don't need to be changed inside the code but only on top.  Note that
179the location of the PWM output itself is mandated by the hardware, so
180it cannot be easily changed.  As the ATmega48/88/168 controllers
181belong to a more recent generation of AVRs, a number of register and
182bit names have been changed there, so they are mapped back to their
183ATmega8/16 equivalents to keep the actual program code portable.
184
185The name \c F_CPU is the conventional name to describe the CPU clock
186frequency of the controller.  This demo project just uses the internal
187calibrated 1 MHz RC oscillator that is enabled by default.  Note that
188when using the <tt>&lt;util/delay.h&gt;</tt> functions, \c F_CPU needs
189to be defined before including that file.
190
191The remaining macros have their own comments in the source code.  The
192macro \c TMR1_SCALE shows how to use the preprocessor and the
193compiler's constant expression computation to calculate the value of
194timer 1's post-scaler in a way so it only depends on \c F_CPU and the
195desired software clock frequency.  While the formula looks a bit
196complicated, using a macro offers the advantage that the application
197will automatically scale to new target softclock or master CPU
198frequencies without having to manually re-calculate hardcoded
199constants.
200
201\subsection largedemo_code_p2 Part 2: Variable definitions
202
203The \c intflags structure demonstrates a way to allocate bit variables
204in memory.  Each of the interrupt service routines just sets one bit
205within that structure, and the application's main loop then monitors
206the bits in order to act appropriately.
207
208Like all variables that are used to communicate values between an
209interrupt service routine and the main application, it is declared
210\ref faq_volatile "volatile".
211
212The variable \c ee_pwm is not a variable in the classical C sense that
213could be used as an lvalue or within an expression to obtain its
214value.  Instead, the
215
216\code __attribute__((section(".eeprom"))) \endcode
217
218marks it as belonging to the \ref sec_dot_eeprom "EEPROM section".
219This section is merely used as a placeholder so the compiler can
220arrange for each individual variable's location in EEPROM.  The
221compiler will also keep track of initial values assigned, and usually
222the Makefile is arranged to extract these initial values into a
223separate load file (\c largedemo_eeprom.* in this case) that can be
224used to initialize the EEPROM.
225
226The actual EEPROM IO must be performed manually.
227
228Similarly, the variable \c mcucsr is kept in the
229\ref sec_dot_noinit ".noinit" section in order to prevent it from
230being cleared upon application startup.
231
232\subsection largedemo_code_p3 Part 3: Interrupt service routines
233
234The ISR to handle timer 1's overflow interrupt arranges for the
235software clock.  While timer 1 runs the PWM, it calls its overflow
236handler rather frequently, so the \c TMR1_SCALE value is used as a
237postscaler to reduce the internal software clock frequency further.
238If the software clock triggers, it sets the \c tmr_int bitfield,
239and defers all further tasks to the main loop.
240
241The ADC ISR just fetches the value from the ADC conversion, disables
242the ADC interrupt again, and announces the presence of the new value
243in the \c adc_int bitfield.  The interrupt is kept disabled while not
244needed, because the ADC will also be triggered by executing the SLEEP
245instruction in idle mode (which is the default sleep mode).  Another
246option would be to turn off the ADC completely here, but that
247increases the ADC's startup time (not that it would matter much for
248this application).
249
250\subsection largedemo_code_p4 Part 4: Auxiliary functions
251
252The function \c handle_mcucsr() uses two \c __attribute__ declarators
253to achieve specific goals.  First, it will instruct the compiler to
254place the generated code into the \ref sec_dot_init ".init3" section
255of the output.  Thus, it will become part of the application
256initialization sequence.  This is done in order to fetch (and clear)
257the reason of the last hardware reset from \c MCUCSR as early as
258possible.  There is a short period of time where the next reset could
259already trigger before the current reason has been evaluated.  This
260also explains why the variable \c mcucsr that mirrors the register's
261value needs to be placed into the .noinit section, because otherwise
262the default initialization (which happens after .init3) would blank
263the value again.
264
265As the initialization code is not called using CALL/RET instructions
266but rather concatenated together, the compiler needs to be instructed
267to omit the entire function prologue and epilogue.  This is performed
268by the \e naked attribute.  So while syntactically, \c handle_mcucsr()
269is a function to the compiler, the compiler will just emit the
270instructions for it without setting up any stack frame, and not even a RET instruction
271at the end.
272
273Function \c ioinit() centralizes all hardware setup.  The very last
274part of that function demonstrates the use of the EEPROM variable \c
275ee_pwm to obtain an EEPROM address that can in turn be applied as an
276argument to \c eeprom_read_word().
277
278The following functions handle UART character and string output.
279(UART input is handled by an ISR.)  There are two string output
280functions, \c printstr() and \c printstr_p().  The latter function
281fetches the string from \ref avr_pgmspace "program memory".  Both
282functions translate a newline character into a carriage return/newline
283sequence, so a simple \c \\n can be used in the source
284code.
285
286The function \c set_pwm() propagates the new PWM value to the PWM,
287performing range checking.  When the value has been changed, the new
288percentage will be announced on the serial link.  The current value is
289mirrored in the variable \c pwm so others can use it in calculations.
290In order to allow for a simple calculation of a percentage value
291without requiring floating-point mathematics, the maximal value of the
292PWM is restricted to 1000 rather than 1023, so a simple division by 10
293can be used.  Due to the nature of the human eye, the difference in
294LED brightness between 1000 and 1023 is not noticable anyway.
295
296\subsection largedemo_code_p5 Part 5: main()
297
298At the start of \c main(), a variable \c mode is declared to keep the
299current mode of operation.  An enumeration is used to improve the
300readability.  By default, the compiler would allocate a variable of
301type \e int for an enumeration.  The \e packed attribute declarator
302instructs the compiler to use the smallest possible integer type
303(which would be an 8-bit type here).
304
305After some initialization actions, the application's main loop
306follows.  In an embedded application, this is normally an infinite
307loop as there is nothing an application could "exit" into anyway.
308
309At the beginning of the loop, the watchdog timer will be retriggered.
310If that timer is not triggered for about 2 seconds, it will issue a
311hardware reset.  Care needs to be taken that no code path blocks
312longer than this, or it needs to frequently perform watchdog resets of
313its own.  An example of such a code path would be the string IO
314functions: for an overly large string to print (about 2000 characters
315at 9600 Bd), they might block for too long.
316
317The loop itself then acts on the interrupt indication bitfields as
318appropriate, and will eventually put the CPU on sleep at its end to
319conserve power.
320
321The first interrupt bit that is handled is the (software) timer, at a
322frequency of approximately 100 Hz.  The \c CLOCKOUT pin will be
323toggled here, so e. g. an oscilloscope can be used on that pin to
324measure the accuracy of our software clock.  Then, the LED flasher for
325LED2 ("We are alive"-LED) is built.  It will flash that LED for about
32650 ms, and pause it for another 950 ms.  Various actions depending on
327the operation mode follow.  Finally, the 3-second backup timer is
328implemented that will write the PWM value back to EEPROM once it is
329not changing anymore.
330
331The ADC interrupt will just adjust the PWM value only.
332
333Finally, the UART Rx interrupt will dispatch on the last character
334received from the UART.
335
336All the string literals that are used as informational messages within
337\c main() are placed in \ref avr_pgmspace "program memory" so no SRAM
338needs to be allocated for them.  This is done by using the PSTR macro,
339and passing the string to \c printstr_p().
340
341\section largedemo_src The source code
342
343\htmlonly
344Source file: <a href="../examples/largedemo/largedemo.c">largedemo.c</a>
345\endhtmlonly
346
347\latexonly
348The source code is installed under
349
350\texttt{\$prefix/share/doc/avr-libc/examples/largedemo/largedemo.c},
351
352where \texttt{\$prefix} is a configuration option.  For Unix
353systems, it is usually set to either \texttt{/usr} or
354\texttt{/usr/local}.
355\endlatexonly
356
357*/
358