2002-08-21 Theodore A. Roth * doc/api/sfr.dox: Grammar cleanups. * include/avr/sfr_defs.h: Make Marek's notes into dox. Added compiler note to _BV(). Added note about switched arg order for outb()/outw(). Documented deprecated macros. Index: doc/api/sfr.dox =================================================================== RCS file: /cvsroot/avr-libc/avr-libc/doc/api/sfr.dox,v retrieving revision 1.1 diff -u -r1.1 sfr.dox --- doc/api/sfr.dox 21 Aug 2002 19:16:56 -0000 1.1 +++ doc/api/sfr.dox 22 Aug 2002 06:20:07 -0000 @@ -27,7 +27,7 @@ /** \defgroup avr_sfr Special function registers -When working with microcontrollers, a lot of the task usually consists +When working with microcontrollers, many of the tasks usually consist of controlling the peripherals that are connected to the device, respectively programming the subsystems that are contained in the controller (which by itself communicate with the circuitry connected @@ -35,7 +35,7 @@ The AVR series of microcontrollers offers two different paradigms to perform this task. There's a separate IO address space available (as -it's e. g. known from some high-level CISC CPUs) that can be addressed +it's known on some high-level CISC CPUs) that can be addressed with specific IO instructions that are applicable to some or all of the IO address space (\c in, \c out, \c sbi etc.). The entire IO address space is also made available as memory-mapped IO, @@ -65,9 +65,9 @@ \endcode The compiler's choice of which method to use when actually accessing -the IO port is completely independent of the programmer's way to write -the code. So even if the programmer uses the memory-mapped paradigm -and writes +the IO port is completely independent of the way the programmer chooses +to write the code. So even if the programmer uses the memory-mapped +paradigm and writes \code PORTA |= 0x40; @@ -80,7 +80,7 @@ The advantage of using the memory-mapped paradigm in C programs is that it makes the programs more portable to other C compilers for the -AVR platform. Some people might also feel this to be better readable. +AVR platform. Some people might also feel that this is more readable. For example, the following two statements would be equivalent: \code @@ -88,7 +88,7 @@ DDRD &= ~LCDBITS; \endcode -The generated code is identical for both. Whitout optimization, the +The generated code is identical for both. Without optimization, the compiler strictly generates code following the memory-mapped paradigm, while with optimization turned on, code is generated using the (faster and smaller) \c in/out MCU instructions. Index: include/avr/sfr_defs.h =================================================================== RCS file: /cvsroot/avr-libc/avr-libc/include/avr/sfr_defs.h,v retrieving revision 1.2 diff -u -r1.2 sfr_defs.h --- include/avr/sfr_defs.h 21 Aug 2002 19:16:56 -0000 1.2 +++ include/avr/sfr_defs.h 22 Aug 2002 06:20:08 -0000 @@ -28,72 +28,87 @@ #ifndef _AVR_SFR_DEFS_H_ #define _AVR_SFR_DEFS_H_ 1 -/* - This file is included by all of the files, which use macros - defined here to make the special function register definitions look like - C variables or simple constants, depending on the _SFR_ASM_COMPAT define. - Some examples from to show how to define such macros: +/** \defgroup avr_sfr_notes Additional notes from + \ingroup avr_sfr + + The \c file is included by all of the \c + files, which use macros defined here to make the special function register + definitions look like C variables or simple constants, depending on the + _SFR_ASM_COMPAT define. Some examples from \c to + show how to define such macros: +\code #define PORTA _SFR_IO8(0x1b) #define TCNT1 _SFR_IO16(0x2c) #define PORTF _SFR_MEM8(0x61) #define TCNT3 _SFR_MEM16(0x88) +\endcode - If _SFR_ASM_COMPAT is not defined, C programs can use names like PORTA - directly in C expressions (also on the left side of assignment operators) - and GCC will do the right thing (use short I/O instructions if possible). - The __SFR_OFFSET definition is not used in any way in this case. + If \c _SFR_ASM_COMPAT is not defined, C programs can use names like + PORTA directly in C expressions (also on the left side of + assignment operators) and GCC will do the right thing (use short I/O + instructions if possible). The \c __SFR_OFFSET definition is not used in + any way in this case. - Define _SFR_ASM_COMPAT as 1 to make these names work as simple constants + Define \c _SFR_ASM_COMPAT as 1 to make these names work as simple constants (addresses of the I/O registers). This is necessary when included in - preprocessed assembler (*.S) source files, so it is done automatically - if __ASSEMBLER__ is defined. By default, all addresses are defined as - if they were memory addresses (used in lds/sts instructions). To use - these addresses in in/out instructions, you must subtract 0x20 from them. + preprocessed assembler (*.S) source files, so it is done automatically if + \c __ASSEMBLER__ is defined. By default, all addresses are defined as if + they were memory addresses (used in \c lds/sts instructions). To use these + addresses in \c in/out instructions, you must subtract 0x20 from them. For more backwards compatibility, insert the following at the start of your old assembler source file: +\code #define __SFR_OFFSET 0 +\endcode - This automatically subtracts 0x20 from I/O space addresses, but it's - a hack, so it is recommended to change your source: wrap such addresses - in macros defined here, as shown below. After this is done, the - __SFR_OFFSET definition is no longer necessary and can be removed. + This automatically subtracts 0x20 from I/O space addresses, but it's a + hack, so it is recommended to change your source: wrap such addresses in + macros defined here, as shown below. After this is done, the + __SFR_OFFSET definition is no longer necessary and can be removed. Real example - this code could be used in a boot loader that is portable - between devices with SPMCR at different addresses. + between devices with \c SPMCR at different addresses. - : #define SPMCR _SFR_IO8(0x37) - : #define SPMCR _SFR_MEM8(0x68) +\verbatim +: #define SPMCR _SFR_IO8(0x37) +: #define SPMCR _SFR_MEM8(0x68) +\endverbatim +\code #if _SFR_IO_REG_P(SPMCR) out _SFR_IO_ADDR(SPMCR), r24 #else sts _SFR_MEM_ADDR(SPMCR), r24 #endif +\endcode - You can use the in/out/cbi/sbi/sbic/sbis instructions, without the - _SFR_IO_REG_P test, if you know that the register is in the I/O space - (as with SREG, for example). If it isn't, the assembler will complain - (I/O address out of range 0...0x3f), so this should be fairly safe. - - If you do not define __SFR_OFFSET (so it will be 0x20 by default), all - special register addresses are defined as memory addresses (so SREG is - 0x5f), and (if code size and speed are not important, and you don't - like the ugly #if above) you can always use lds/sts to access them. - But, this will not work if __SFR_OFFSET != 0x20, so use a different - macro (defined only if __SFR_OFFSET == 0x20) for safety: + You can use the \c in/out/cbi/sbi/sbic/sbis instructions, without the + _SFR_IO_REG_P test, if you know that the register is in the I/O + space (as with \c SREG, for example). If it isn't, the assembler will + complain (I/O address out of range 0...0x3f), so this should be fairly + safe. + + If you do not define \c __SFR_OFFSET (so it will be 0x20 by default), all + special register addresses are defined as memory addresses (so \c SREG is + 0x5f), and (if code size and speed are not important, and you don't like + the ugly \#if above) you can always use \c lds/sts to access them. + But, this will not work if __SFR_OFFSET != 0x20, so use a + different macro (defined only if __SFR_OFFSET == 0x20) for safety: +\code sts _SFR_ADDR(SPMCR), r24 +\endcode + + In C programs, all 3 combinations of \c _SFR_ASM_COMPAT and + __SFR_OFFSET are supported - the \c _SFR_ADDR(SPMCR) macro can be + used to get the address of the \c SPMCR register (0x57 or 0x68 depending on + device). - In C programs, all 3 combinations of _SFR_ASM_COMPAT and __SFR_OFFSET - are supported - the _SFR_ADDR(SPMCR) macro can be used to get the - address of the SPMCR register (0x57 or 0x68 depending on device). - - The old inp/outp macros are still supported, but not recommended - to use in new code. The order of outp() arguments is confusing. - */ + The old inp()/outp() macros are still supported, but not recommended + to use in new code. The order of outp() arguments is confusing. */ #ifdef __ASSEMBLER__ #define _SFR_ASM_COMPAT 1 @@ -156,7 +171,11 @@ \code #include \endcode - Converts a bit number into a byte value. */ + Converts a bit number into a byte value. + + \note The bit shift is performed by the compiler which then inserts the + result into the code. Thus, there is no run-time overhead when using + _BV(). */ #define _BV(bit) (1 << (bit)) @@ -200,7 +219,10 @@ \code #include \endcode - Write \c val to IO register \c sfr. */ + Write \c val to IO register \c sfr. + + \note The order of the arguments was switched in older versions of + avr-libc (versions <= 20020203). */ #define outb(sfr, val) (_SFR_BYTE(sfr) = (val)) @@ -212,8 +234,11 @@ Write the 16-bit value \c val to IO register pair \c sfr. Care will be taken to write the lower register first. When used to update 16-bit registers where the timing is critical and the - operation can be interrupted, the programmer is responsible to - disable interrupts before accessing the register pair. */ + operation can be interrupted, the programmer is the responsible for + disabling interrupts before accessing the register pair. + + \note The order of the arguments was switched in older versions of + avr-libc (versions <= 20020203). */ #define outw(sfr, val) (_SFR_WORD(sfr) = (val)) @@ -283,8 +308,31 @@ #endif /* !__ASSEMBLER__ */ /* Backwards compatibility, do not use in new programs. */ + +/** \name Deprecated Macros */ +/address@hidden/ + +/** \def outp + \ingroup avr_sfr + \deprecated + Backwards compatibility, do not use in new programs. */ + #define outp(val, sfr) outb(sfr, val) + +/** \def inp + \ingroup avr_sfr + \deprecated + Backwards compatibility, do not use in new programs. */ + #define inp(sfr) inb(sfr) + +/** \def BV + \ingroup avr_sfr + \deprecated + Backwards compatibility, do not use in new programs. */ + #define BV(bit) _BV(bit) + +/address@hidden/ #endif /* _SFR_DEFS_H_ */