28
29
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
30
POSSIBILITY OF SUCH DAMAGE. */
31
/* $Id: eeprom.h,v 1.11.2.1 2005/01/13 10:58:01 joerg_wunsch Exp $ */
32
/* $Id: eeprom.h,v 1.17.2.1 2006/02/26 21:51:04 aesok Exp $ */
37
38
Created by Marek Michalkiewicz <marekm@linux.org.pl>
38
eeprom_write_word and eeprom_write_block added by Artur Lipowski <LAL@pro.onet.pl>
39
eeprom_write_word and eeprom_write_block added by Artur Lipowski
41
Complete rewrite using the original interface by Bjoern Haase
42
<bjoern.haase@de.bosch.com>.
45
49
#include <stddef.h>
46
50
#include <inttypes.h>
48
59
#include <avr/io.h>
50
/** \defgroup avr_eeprom EEPROM handling
60
#ifndef __EEPROM_REG_LOCATIONS__
61
/** \def __EEPROM_REG_LOCATIONS__
63
In order to be able to work without a requiring a multilib
64
approach for dealing with controllers having the EEPROM registers
65
at different positions in memory space, the eeprom functions evaluate
66
__EEPROM_REG_LOCATIONS__: It is assumed to be defined by
67
the device io header and contains 6 uppercase hex digits encoding the
68
addresses of EECR,EEDR and EEAR.
69
First two letters: EECR address.
70
Second two letters: EEDR address.
71
Last two letters: EEAR address.
72
The default 1C1D1E corresponds to the
73
register location that is valid for most controllers. The value
74
of this define symbol is used for appending it to the base name of the
75
assembler functions. */
76
#define __EEPROM_REG_LOCATIONS__ 1C1D1E
78
#define _STR2(EXP) _STR1(EXP)
79
#define _STR1(EXP) #EXP
80
#define _REG_LOCATION_SUFFIX _STR2(__EEPROM_REG_LOCATIONS__)
87
/** \defgroup avr_eeprom <avr/eeprom.h>: EEPROM handling
51
88
\code #include <avr/eeprom.h> \endcode
53
90
This header file declares the interface to some simple library
63
100
should first poll the EEPROM e. g. using eeprom_is_ready() before
64
101
attempting any actual I/O.
66
\note This library will \e not work with the following devices since these
67
devices have the EEPROM IO ports at different locations:
103
\note This header file declares inline functions that call the
104
assembler subroutines directly. This prevents that the compiler
105
generates push/pops for the call-clobbered registers. This way
106
also a specific calling convention could be used for the eeprom
107
routines e.g. by passing values in __tmp_reg__, eeprom addresses in
108
X and memory addresses in Z registers. Method is optimized for code
111
\note Presently supported are two locations of the EEPROM register
112
set: 0x1F,0x20,0x21 and 0x1C,0x1D,0x1E
113
(see ::__EEPROM_REG_LOCATIONS__).
115
\note As these functions modify IO registers, they are known to be
116
non-reentrant. If any of these functions are used from both,
117
standard and interrupt context, the applications must ensure
118
proper protection (e.g. by disabling interrupts before accessing
82
#if defined(__AVR_AT90CAN128__) || defined(__AVR_ATmega48__) ||\
83
defined(__AVR_ATmega88__) || defined(__AVR_ATmega165__) ||\
84
defined(__AVR_ATmega168__) || defined(__AVR_ATmega169__) ||\
85
defined(__AVR_ATmega325__) || defined(__AVR_ATmega3250__) ||\
86
defined(__AVR_ATmega645__) || defined(__AVR_ATmega6450__)
87
# warning "The functions from <avr/eeprom.h> are not supported on this MCU."
124
/* forward declarations of the inline functions so that doxygen does
125
not get confused by the attribute expression. */
127
static inline uint8_t __attribute__ ((always_inline))
128
eeprom_read_byte (const uint8_t *addr);
130
static inline uint16_t __attribute__ ((always_inline))
131
eeprom_read_word (const uint16_t *addr);
133
static inline void __attribute__ ((always_inline))
134
eeprom_read_block (void *pointer_ram,
135
const void *pointer_eeprom,
138
static inline void __attribute__ ((always_inline))
139
eeprom_write_byte (uint8_t *addr,uint8_t value);
141
static inline void __attribute__ ((always_inline))
142
eeprom_write_word (uint16_t *addr,uint16_t value);
144
static inline void __attribute__ ((always_inline))
145
eeprom_write_block (const void *pointer_ram,
146
void *pointer_eeprom,
90
149
/** \name avr-libc declarations */
155
Attribute expression causing a variable to be allocated within the .eeprom
157
#define EEMEM __attribute__((section(".eeprom")))
94
159
/** \def eeprom_is_ready
95
160
\ingroup avr_eeprom
96
161
\returns 1 if EEPROM is ready for a new read/write operation, 0 if not. */
98
#define eeprom_is_ready() bit_is_clear(EECR, EEWE)
163
#if defined(__DOXYGEN__)
164
# define eeprom_is_ready()
166
# define eeprom_is_ready() bit_is_clear(EECR, EEWE)
168
# define eeprom_is_ready() bit_is_clear(EECR, EEPE)
169
#elif defined(DEECR) && defined(EEL)
170
# define eeprom_is_ready() bit_is_clear(DEECR, EEL)
172
# error "No write enable bit known for this device's EEPROM."
100
175
/** \def eeprom_busy_wait
101
176
\ingroup avr_eeprom
107
182
#define eeprom_busy_wait() do {} while (!eeprom_is_ready())
113
185
/** \ingroup avr_eeprom
114
186
Read one byte from EEPROM address \c addr. */
116
extern uint8_t eeprom_read_byte (const uint8_t *addr);
189
eeprom_read_byte (const uint8_t *addr)
193
( XCALL " __eeprom_read_byte_" _REG_LOCATION_SUFFIX CR_TAB
118
201
/** \ingroup avr_eeprom
119
202
Read one 16-bit word (little endian) from EEPROM address \c addr. */
121
extern uint16_t eeprom_read_word (const uint16_t *addr);
123
/** \ingroup avr_eeprom
124
Read a block of \c n bytes from EEPROM address \c addr to
127
extern void eeprom_read_block (void *buf, const void *addr, size_t n);
129
/** \ingroup avr_eeprom
130
Write a byte \c val to EEPROM address \c addr. */
132
extern void eeprom_write_byte (uint8_t *addr, uint8_t val);
134
/** \ingroup avr_eeprom
135
Write a word \c val to EEPROM address \c addr. */
137
extern void eeprom_write_word (uint16_t *addr, uint16_t val);
139
/** \ingroup avr_eeprom
140
Write a block of \c n bytes to EEPROM address \c addr from
143
extern void eeprom_write_block (const void *buf, void *addr, size_t n);
204
eeprom_read_word (const uint16_t *addr)
209
XCALL " __eeprom_read_word_" _REG_LOCATION_SUFFIX CR_TAB
216
/** \ingroup avr_eeprom
217
Read a block of \c n bytes from EEPROM address \c pointer_eeprom to
218
\c pointer_ram. For constant n <= 256 bytes a library function is used.
219
For block sizes unknown at compile time or block sizes > 256 an inline
223
eeprom_read_block (void *pointer_ram,
224
const void *pointer_eeprom,
227
if (!__builtin_constant_p (n)
230
/* make sure size is a 16 bit variable. */
236
"brlt .%=_finished" CR_TAB
237
XCALL " __eeprom_read_byte_" _REG_LOCATION_SUFFIX CR_TAB
238
"st z+,__tmp_reg__" CR_TAB
239
"rjmp .%=_start" CR_TAB
241
: "=x" (pointer_eeprom),
244
: "x" (pointer_eeprom),
255
XCALL " __eeprom_read_block_" _REG_LOCATION_SUFFIX
256
: "+x" (pointer_eeprom),
263
/* Needed in order to truncate to 8 bit. */
268
"mov __zero_reg__,%2" CR_TAB
269
XCALL " __eeprom_read_block_" _REG_LOCATION_SUFFIX
270
: "+x" (pointer_eeprom),
280
/** \ingroup avr_eeprom
281
Write a byte \c value to EEPROM address \c addr. */
284
eeprom_write_byte (uint8_t *addr,uint8_t value)
287
"mov __tmp_reg__,%1" CR_TAB
288
XCALL " __eeprom_write_byte_" _REG_LOCATION_SUFFIX
295
/** \ingroup avr_eeprom
296
Write a word \c value to EEPROM address \c addr. */
299
eeprom_write_word (uint16_t *addr,uint16_t value)
302
#if __AVR_HAVE_MOVW__
303
"movw __tmp_reg__,%A1" CR_TAB
305
"mov __tmp_reg__,%A1" CR_TAB
306
"mov __zero_reg__,%B1" CR_TAB
308
XCALL " __eeprom_write_word_" _REG_LOCATION_SUFFIX CR_TAB
315
/** \ingroup avr_eeprom
316
Write a block of \c n bytes to EEPROM address \c pointer_eeprom from
320
eeprom_write_block (const void *pointer_ram,
321
void *pointer_eeprom,
324
if (!__builtin_constant_p (n)
327
/* make sure size is a 16 bit variable. */
333
"brlt .%=_finished" CR_TAB
334
"ld __tmp_reg__,z+" CR_TAB
335
XCALL " __eeprom_write_byte_" _REG_LOCATION_SUFFIX CR_TAB
336
"rjmp .%=_start" CR_TAB
338
: "=x" (pointer_eeprom),
341
: "x" (pointer_eeprom),
347
/* Do nothing for compile time constant transfer size n == 0. */
353
XCALL " __eeprom_write_block_" _REG_LOCATION_SUFFIX
354
: "+x" (pointer_eeprom),
365
"mov __zero_reg__,%2" CR_TAB
366
XCALL " __eeprom_write_block_" _REG_LOCATION_SUFFIX
367
: "+x" (pointer_eeprom),