1/* Copyright (c) 2002,2004,2005,2009 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   * Redistributions in binary form must reproduce the above copyright
10     notice, this list of conditions and the following disclaimer in
11     the documentation and/or other materials provided with the
12     distribution.
13   * Neither the name of the copyright holders nor the names of
14     contributors may be used to endorse or promote products derived
15     from this software without specific prior written permission.
16
17  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  POSSIBILITY OF SUCH DAMAGE. */
28
29/* $Id: assembler.dox 2305 2013-01-02 17:53:52Z joerg_wunsch $ */
30
31/** \page assembler avr-libc and assembler programs
32
33\section ass_intro Introduction
34
35There might be several reasons to write code for AVR microcontrollers
36using plain assembler source code.  Among them are:
37
38- Code for devices that do not have RAM and are thus not supported
39  by the C compiler.
40- Code for very time-critical applications.
41- Special tweaks that cannot be done in C.
42
43Usually, all but the first could probably be done easily using the
44\ref inline_asm "inline assembler" facility of the compiler.
45
46Although avr-libc is primarily targeted to support programming AVR
47microcontrollers using the C (and C++) language, there's limited
48support for direct assembler usage as well.  The benefits of it are:
49
50- Use of the C preprocessor and thus the ability to use the same
51  symbolic constants that are available to C programs, as well as
52  a flexible macro concept that can use any valid C identifier as
53  a macro (whereas the assembler's macro concept is basically
54  targeted to use a macro in place of an assembler instruction).
55- Use of the runtime framework like automatically assigning
56  interrupt vectors.  For devices that have RAM,
57  \ref sec_dot_init "initializing the RAM variables" can also
58  be utilized.
59
60\section ass_tools Invoking the compiler
61
62For the purpose described in this document, the assembler and linker
63are usually not invoked manually, but rather using the C compiler
64frontend (\c avr-gcc) that in turn will call the assembler and linker
65as required.
66
67This approach has the following advantages:
68
69- There is basically only one program to be called directly,
70  \c avr-gcc, regardless of the actual source language used.
71- The invokation of the C preprocessor will be automatic,
72  and will include the appropriate options to locate required
73  include files in the filesystem.
74- The invokation of the linker will be automatic, and will
75  include the appropriate options to locate additional libraries
76  as well as the application start-up code
77  (<tt>crt</tt><em>XXX</em><tt>.o</tt>) and linker script.
78
79Note that the invokation of the C preprocessor will be automatic when
80the filename provided for the assembler file ends in \c .S (the
81capital letter "s").  This would even apply to operating systems that
82use case-insensitive filesystems since the actual decision is made
83based on the case of the filename suffix given on the command-line,
84not based on the actual filename from the file system.
85
86As an alternative to using \c .S, the suffix \c .sx is recognized for
87this purpose (starting with GCC 4.3.0).  This is primarily meant to be
88compatible with other compiler environments that have been providing
89this variant before in order to cope with operating systems where
90filenames are case-insensitive (and, with some versions of \c make
91that could not distinguish between \c .s and \c .S on such systems).
92
93Alternatively, the language can explicitly be specified using the
94<tt>-x assembler-with-cpp</tt> option.
95
96\section ass_example Example program
97
98The following annotated example features a simple 100 kHz square wave
99generator using an AT90S1200 clocked with a 10.7 MHz crystal.  Pin
100PD6 will be used for the square wave output.
101
102\code
103#include <avr/io.h>		; Note [1]
104
105work	=	16		; Note [2]
106tmp	=	17
107
108inttmp	=	19
109
110intsav	=	0
111
112SQUARE	=	PD6		; Note [3]
113
114				; Note [4]:
115tmconst= 10700000 / 200000	; 100 kHz => 200000 edges/s
116fuzz=	8			; # clocks in ISR until TCNT0 is set
117
118	.section .text
119
120	.global	main				; Note [5]
121main:
122	rcall	ioinit
1231:
124	rjmp	1b				; Note [6]
125
126	.global	TIMER0_OVF_vect			; Note [7]
127TIMER0_OVF_vect:
128	ldi	inttmp, 256 - tmconst + fuzz
129	out	_SFR_IO_ADDR(TCNT0), inttmp	; Note [8]
130
131	in	intsav, _SFR_IO_ADDR(SREG)	; Note [9]
132
133	sbic	_SFR_IO_ADDR(PORTD), SQUARE
134	rjmp	1f
135	sbi	_SFR_IO_ADDR(PORTD), SQUARE
136	rjmp	2f
1371:	cbi	_SFR_IO_ADDR(PORTD), SQUARE
1382:
139
140	out	_SFR_IO_ADDR(SREG), intsav
141	reti
142
143ioinit:
144	sbi	_SFR_IO_ADDR(DDRD), SQUARE
145
146	ldi	work, _BV(TOIE0)
147	out	_SFR_IO_ADDR(TIMSK), work
148
149	ldi	work, _BV(CS00)		; tmr0:	 CK/1
150	out	_SFR_IO_ADDR(TCCR0), work
151
152	ldi	work, 256 - tmconst
153	out	_SFR_IO_ADDR(TCNT0), work
154
155	sei
156
157	ret
158
159	.global __vector_default		; Note [10]
160__vector_default:
161	reti
162
163	.end
164\endcode
165
166\par Note [1]
167
168As in C programs, this includes the central processor-specific file
169containing the IO port definitions for the device.  Note that not all
170include files can be included into assembler sources.
171
172\par Note [2]
173
174Assignment of registers to symbolic names used locally.  Another
175option would be to use a C preprocessor macro instead:
176
177\code #define work 16 \endcode
178
179\par Note [3]
180
181Our bit number for the square wave output.  Note that the right-hand
182side consists of a CPP macro which will be substituted by its value (6
183in this case) before actually being passed to the assembler.
184
185\par Note [4]
186
187The assembler uses integer operations in the host-defined integer size
188(32 bits or longer) when evaluating expressions.  This is in contrast
189to the C compiler that uses the C type \c int by default in order to
190calculate constant integer expressions.
191<br>
192In order to get a 100 kHz output, we need to toggle the PD6 line
193200000 times per second.  Since we use timer 0 without any prescaling
194options in order to get the desired frequency and accuracy, we already
195run into serious timing considerations: while accepting and processing
196the timer overflow interrupt, the timer already continues to count.
197When pre-loading the \c TCCNT0 register, we therefore have to account
198for the number of clock cycles required for interrupt acknowledge and
199for the instructions to reload \c TCCNT0 (4 clock cycles for interrupt
200acknowledge, 2 cycles for the jump from the interrupt vector, 2 cycles
201for the 2 instructions that reload \c TCCNT0).  This is what the
202constant \c fuzz is for.
203
204\par Note [5]
205
206External functions need to be declared to be \c .global.  \c main is
207the application entry point that will be jumped to from the
208ininitalization routine in \c crts1200.o.
209
210\par Note [6]
211
212The main loop is just a single jump back to itself.  Square wave
213generation itself is completely handled by the timer 0 overflow
214interrupt service.  A \c sleep instruction (using idle mode) could be
215used as well, but probably would not conserve much energy anyway since
216the interrupt service is executed quite frequently.
217
218\par Note [7]
219
220Interrupt functions can get the \ref avr_signames "usual names" that
221are also available to C programs.  The linker will then put them into
222the appropriate interrupt vector slots.  Note that they must be
223declared \c .global in order to be acceptable for this purpose.
224This will only work if <tt>&lt;avr/io.h&gt;</tt> has been included.
225Note that the assembler or linker have no chance to check the correct
226spelling of an interrupt function, so it should be double-checked.
227(When analyzing the resulting object file using \c avr-objdump or
228\c avr-nm, a name like <tt>__vector_<em>N</em></tt> should appear,
229with \e N being a small integer number.)
230
231\par Note [8]
232
233As explained in the section about
234\ref avr_sfr_notes "special function registers",
235the actual IO port address should be obtained using the macro
236\c _SFR_IO_ADDR.  (The AT90S1200 does not have RAM thus the memory-mapped
237approach to access the IO registers is not available.  It would be
238slower than using \c in / \c out instructions anyway.)
239<br>
240Since the operation to reload \c TCCNT0 is time-critical, it is even
241performed before saving \c SREG.  Obviously, this requires that the
242instructions involved would not change any of the flag bits in \c SREG.
243
244\anchor ass_isr
245\par Note [9]
246
247Interrupt routines must not clobber the global CPU state.  Thus, it is
248usually necessary to save at least the state of the flag bits in \c SREG.
249(Note that this serves as an example here only since actually, all the
250following instructions would not modify \c SREG either, but that's not
251commonly the case.)
252<br>
253Also, it must be made sure that registers used inside the interrupt
254routine do not conflict with those used outside.  In the case of a
255RAM-less device like the AT90S1200, this can only be done by agreeing
256on a set of registers to be used exclusively inside the interrupt
257routine; there would not be any other chance to "save" a register
258anywhere.
259<br>
260If the interrupt routine is to be linked together with C modules, care
261must be taken to follow the \ref faq_reg_usage "register usage guidelines"
262imposed by the C compiler.  Also, any register modified inside the
263interrupt sevice needs to be saved, usually on the stack.
264
265\par Note [10]
266
267As explained in \ref avr_interrupts "Interrupts", a global "catch-all" interrupt
268handler that gets all unassigned interrupt vectors can be installed
269using the name \c __vector_default.  This must be \c .global, and
270obviously, should end in a \c reti instruction.  (By default, a jump
271to location 0 would be implied instead.)
272
273\section ass_pseudoops Pseudo-ops and operators
274
275The available pseudo-ops in the assembler are described in the GNU
276assembler (gas) manual.  The manual can be found online as part of the
277current binutils release under http://sources.redhat.com/binutils/.
278
279As gas comes from a Unix origin, its pseudo-op and overall assembler
280syntax is slightly different than the one being used by other
281assemblers.  Numeric constants follow the C notation (prefix \c 0x for
282hexadecimal constants), expressions use a C-like syntax.
283
284Some common pseudo-ops include:
285
286- \c .byte allocates single byte constants
287
288- \c .ascii allocates a non-terminated string of characters
289
290
291- \c .asciz allocates a \\0-terminated string of characters (C string)
292
293- \c .data switches to the .data section (initialized RAM variables)
294
295- \c .text switches to the .text section (code and ROM constants)
296
297- \c .set declares a symbol as a constant expression (identical to
298  \c .equ)
299
300- \c .global (or \c .globl) declares a public symbol that is visible
301  to the linker (e. g. function entry point, global variable)
302
303- \c .extern declares a symbol to be externally defined; this is
304  effectively a comment only, as gas treats all undefined symbols
305  it encounters as globally undefined anyway
306
307Note that \c .org is available in gas as well, but is a fairly
308pointless pseudo-op in an assembler environment that uses relocatable
309object files, as it is the linker that determines the final position
310of some object in ROM or RAM.
311
312Along with the architecture-independent standard operators, there are
313some AVR-specific operators available which are unfortunately not yet
314described in the official documentation.  The most notable operators
315are:
316
317- \c lo8 Takes the least significant 8 bits of a 16-bit integer
318
319- \c hi8 Takes the most significant 8 bits of a 16-bit integer
320
321- \c pm Takes a program-memory (ROM) address, and converts it into a
322  RAM address.  This implies a division by 2 as the AVR handles ROM
323  addresses as 16-bit words (e.g. in an \c IJMP or \c ICALL
324  instruction), and can also handle relocatable symbols on the
325  right-hand side.
326
327Example:
328\verbatim
329	ldi	r24, lo8(pm(somefunc))
330	ldi	r25, hi8(pm(somefunc))
331	call	something
332\endverbatim
333
334This passes the address of function \c somefunc as the first parameter
335to function \c something.
336
337*/
338