~ubuntu-branches/ubuntu/gutsy/avr-libc/gutsy

« back to all changes in this revision

Viewing changes to include/avr/eeprom.h

  • Committer: Bazaar Package Importer
  • Author(s): Hakan Ardo
  • Date: 2006-05-01 12:03:39 UTC
  • mto: (3.1.1 edgy)
  • mto: This revision was merged to the branch mainline in revision 4.
  • Revision ID: james.westby@ubuntu.com-20060501120339-q93dxulpunby36dj
Tags: upstream-1.4.4
ImportĀ upstreamĀ versionĀ 1.4.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* Copyright (c) 2002, 2003, 2004 Marek Michalkiewicz
 
2
   Copyright (c) 2005, 2006 Bjoern Haase
2
3
   All rights reserved.
3
4
 
4
5
   Redistribution and use in source and binary forms, with or without
28
29
  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
30
  POSSIBILITY OF SUCH DAMAGE. */
30
31
 
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 $ */
32
33
 
33
34
/*
34
35
   eeprom.h
35
36
 
36
37
   Contributors:
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 
 
40
     <LAL@pro.onet.pl>
 
41
     Complete rewrite using the original interface by Bjoern Haase 
 
42
     <bjoern.haase@de.bosch.com>. 
39
43
 */
40
44
 
41
45
#ifndef _EEPROM_H_
45
49
#include <stddef.h>
46
50
#include <inttypes.h>
47
51
 
 
52
 
 
53
#ifdef __AVR_MEGA__
 
54
#define XCALL "call"
 
55
#else
 
56
#define XCALL "rcall"
 
57
#endif
 
58
 
48
59
#include <avr/io.h>
49
 
 
50
 
/** \defgroup avr_eeprom EEPROM handling
 
60
#ifndef __EEPROM_REG_LOCATIONS__
 
61
/** \def __EEPROM_REG_LOCATIONS__
 
62
    \ingroup avr_eeprom
 
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
 
77
#endif
 
78
#define _STR2(EXP) _STR1(EXP)
 
79
#define _STR1(EXP) #EXP
 
80
#define _REG_LOCATION_SUFFIX _STR2(__EEPROM_REG_LOCATIONS__)
 
81
 
 
82
#ifndef CR_TAB
 
83
#define CR_TAB "\n\t"
 
84
#endif
 
85
 
 
86
 
 
87
/** \defgroup avr_eeprom <avr/eeprom.h>: EEPROM handling
51
88
    \code #include <avr/eeprom.h> \endcode
52
89
 
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.
65
102
 
66
 
    \note This library will \e not work with the following devices since these
67
 
    devices have the EEPROM IO ports at different locations:
68
 
 
69
 
    - AT90CAN128
70
 
    - ATmega48
71
 
    - ATmega88
72
 
    - ATmega165
73
 
    - ATmega168
74
 
    - ATmega169
75
 
    - ATmega325
76
 
    - ATmega3250
77
 
    - ATmega645
78
 
    - ATmega6450
 
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 
 
109
     size.
 
110
 
 
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__).
 
114
 
 
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
 
119
     them).
79
120
 
80
121
*/
81
122
 
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."
88
 
#endif
 
123
 
 
124
/* forward declarations of the inline functions so that doxygen does
 
125
   not get confused by the attribute expression.  */
 
126
 
 
127
static inline uint8_t __attribute__ ((always_inline))
 
128
eeprom_read_byte (const uint8_t *addr);
 
129
 
 
130
static inline uint16_t __attribute__ ((always_inline)) 
 
131
eeprom_read_word (const uint16_t *addr);
 
132
 
 
133
static inline void __attribute__ ((always_inline))
 
134
eeprom_read_block (void *pointer_ram,
 
135
                   const void *pointer_eeprom,
 
136
                   size_t size);
 
137
 
 
138
static inline void __attribute__ ((always_inline))
 
139
eeprom_write_byte (uint8_t *addr,uint8_t value);
 
140
 
 
141
static inline void __attribute__ ((always_inline))
 
142
eeprom_write_word (uint16_t *addr,uint16_t value);
 
143
 
 
144
static inline void __attribute__ ((always_inline))
 
145
eeprom_write_block (const void *pointer_ram,
 
146
                    void *pointer_eeprom,
 
147
                    size_t size);
89
148
 
90
149
/** \name avr-libc declarations */
91
150
 
92
151
/*@{*/
93
152
 
 
153
/** \def EEMEM
 
154
    \ingroup avr_eeprom
 
155
    Attribute expression causing a variable to be allocated within the .eeprom
 
156
     section.  */
 
157
#define EEMEM __attribute__((section(".eeprom")))
 
158
 
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. */
97
162
 
98
 
#define eeprom_is_ready() bit_is_clear(EECR, EEWE)
 
163
#if defined(__DOXYGEN__)
 
164
# define eeprom_is_ready()
 
165
#elif defined(EEWE)
 
166
# define eeprom_is_ready() bit_is_clear(EECR, EEWE)
 
167
#elif defined(EEPE)
 
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)
 
171
#else
 
172
# error "No write enable bit known for this device's EEPROM."
 
173
#endif
99
174
 
100
175
/** \def eeprom_busy_wait
101
176
    \ingroup avr_eeprom
106
181
 
107
182
#define eeprom_busy_wait() do {} while (!eeprom_is_ready())
108
183
 
109
 
#ifdef __cplusplus
110
 
extern "C" {
111
 
#endif
112
184
 
113
185
/** \ingroup avr_eeprom
114
186
    Read one byte from EEPROM address \c addr. */
115
187
 
116
 
extern uint8_t eeprom_read_byte (const uint8_t *addr);
 
188
uint8_t 
 
189
eeprom_read_byte (const uint8_t *addr) 
 
190
{
 
191
  uint8_t result;
 
192
  asm volatile
 
193
      ( XCALL " __eeprom_read_byte_" _REG_LOCATION_SUFFIX CR_TAB
 
194
        "mov %1,__tmp_reg__"
 
195
       : "+x" (addr),
 
196
         "=r" (result)
 
197
       : );
 
198
  return result;
 
199
}
117
200
 
118
201
/** \ingroup avr_eeprom
119
202
    Read one 16-bit word (little endian) from EEPROM address \c addr. */
120
 
 
121
 
extern uint16_t eeprom_read_word (const uint16_t *addr);
122
 
 
123
 
/** \ingroup avr_eeprom
124
 
    Read a block of \c n bytes from EEPROM address \c addr to
125
 
    \c buf. */
126
 
 
127
 
extern void eeprom_read_block (void *buf, const void *addr, size_t n);
128
 
 
129
 
/** \ingroup avr_eeprom
130
 
    Write a byte \c val to EEPROM address \c addr. */
131
 
 
132
 
extern void eeprom_write_byte (uint8_t *addr, uint8_t val);
133
 
 
134
 
/** \ingroup avr_eeprom
135
 
    Write a word \c val to EEPROM address \c addr. */
136
 
 
137
 
extern void eeprom_write_word (uint16_t *addr, uint16_t val);
138
 
 
139
 
/** \ingroup avr_eeprom
140
 
    Write a block of \c n bytes to EEPROM address \c addr from
141
 
    \c buf. */
142
 
 
143
 
extern void eeprom_write_block (const void *buf, void *addr, size_t n);
144
 
 
145
 
#ifdef __cplusplus
146
 
}
 
203
uint16_t
 
204
eeprom_read_word (const uint16_t *addr)
 
205
{
 
206
  uint16_t result;
 
207
 
 
208
  asm ( 
 
209
        XCALL " __eeprom_read_word_" _REG_LOCATION_SUFFIX CR_TAB
 
210
       : "+x" (addr),
 
211
         "=z" (result)
 
212
       : );
 
213
  return result;
 
214
}
 
215
 
 
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
 
220
    loop is expanded. */
 
221
 
 
222
void 
 
223
eeprom_read_block (void *pointer_ram,
 
224
                   const void *pointer_eeprom,
 
225
                   size_t n)
 
226
{
 
227
  if (!__builtin_constant_p (n)
 
228
      || n > 256)
 
229
    {
 
230
      /* make sure size is a 16 bit variable.  */
 
231
      uint16_t size = n; 
 
232
 
 
233
      asm volatile ( 
 
234
            ".%=_start:" CR_TAB
 
235
            "sbiw %2,1" CR_TAB
 
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
 
240
            ".%=_finished:" 
 
241
          : "=x" (pointer_eeprom),
 
242
            "=z" (pointer_ram),
 
243
            "+w" (size)
 
244
           : "x" (pointer_eeprom), 
 
245
             "z" (pointer_ram)
 
246
           : "memory");
 
247
    }
 
248
  else
 
249
    {
 
250
      if (n != 0)
 
251
        {
 
252
          if (n == 256)
 
253
            {
 
254
              asm volatile (
 
255
                  XCALL " __eeprom_read_block_" _REG_LOCATION_SUFFIX 
 
256
                : "+x" (pointer_eeprom),
 
257
                  "=z" (pointer_ram)
 
258
                : "z"  (pointer_ram)
 
259
                : "memory");
 
260
            }
 
261
          else
 
262
            {
 
263
              /* Needed in order to truncate to 8 bit.  */
 
264
              uint8_t len;
 
265
              len = (uint8_t) n; 
 
266
 
 
267
              asm volatile (
 
268
                  "mov __zero_reg__,%2"      CR_TAB
 
269
                   XCALL " __eeprom_read_block_" _REG_LOCATION_SUFFIX 
 
270
                : "+x" (pointer_eeprom),
 
271
                  "=z" (pointer_ram)
 
272
                : "r"  (len),
 
273
                  "z"  (pointer_ram)
 
274
                : "memory");
 
275
            }
 
276
        }
 
277
    }
 
278
}
 
279
 
 
280
/** \ingroup avr_eeprom
 
281
    Write a byte \c value to EEPROM address \c addr. */
 
282
 
 
283
void 
 
284
eeprom_write_byte (uint8_t *addr,uint8_t value)
 
285
{
 
286
  asm volatile (
 
287
         "mov __tmp_reg__,%1"      CR_TAB
 
288
         XCALL " __eeprom_write_byte_" _REG_LOCATION_SUFFIX
 
289
       : "+x" (addr)
 
290
       : "r"  (value)
 
291
       : "memory"
 
292
      );
 
293
}
 
294
 
 
295
/** \ingroup avr_eeprom
 
296
    Write a word \c value to EEPROM address \c addr. */
 
297
 
 
298
void 
 
299
eeprom_write_word (uint16_t *addr,uint16_t value)
 
300
{
 
301
  asm volatile (
 
302
#if __AVR_HAVE_MOVW__
 
303
         "movw __tmp_reg__,%A1" CR_TAB
 
304
#else
 
305
         "mov __tmp_reg__,%A1"      CR_TAB
 
306
         "mov __zero_reg__,%B1"     CR_TAB
147
307
#endif
 
308
          XCALL " __eeprom_write_word_" _REG_LOCATION_SUFFIX CR_TAB
 
309
       : "+x" (addr)
 
310
       : "r"  (value)
 
311
       : "memory"
 
312
      );
 
313
}
 
314
 
 
315
/** \ingroup avr_eeprom
 
316
    Write a block of \c n bytes to EEPROM address \c pointer_eeprom from
 
317
    \c pointer_ram. */
 
318
 
 
319
void 
 
320
eeprom_write_block (const void *pointer_ram,
 
321
                    void *pointer_eeprom,
 
322
                    size_t n)
 
323
{
 
324
  if (!__builtin_constant_p (n)
 
325
      || n > 256)
 
326
    {
 
327
      /* make sure size is a 16 bit variable.  */
 
328
      uint16_t size = n; 
 
329
 
 
330
      asm volatile ( 
 
331
            ".%=_start:" CR_TAB
 
332
            "sbiw %2,1" CR_TAB
 
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
 
337
            ".%=_finished:" 
 
338
          : "=x" (pointer_eeprom),
 
339
            "=z" (pointer_ram),
 
340
            "+w" (size)
 
341
           : "x" (pointer_eeprom), 
 
342
             "z" (pointer_ram)
 
343
           : "memory");
 
344
    }
 
345
  else
 
346
    {
 
347
      /* Do nothing for compile time constant transfer size n == 0.  */
 
348
      if (n != 0)
 
349
        {
 
350
          if (n == 256)
 
351
            {
 
352
              asm volatile (
 
353
                 XCALL " __eeprom_write_block_" _REG_LOCATION_SUFFIX
 
354
               : "+x" (pointer_eeprom),
 
355
                 "=z" (pointer_ram)
 
356
               : "z"  (pointer_ram)
 
357
               : "memory" );
 
358
            }
 
359
          else
 
360
            {
 
361
              uint8_t len;
 
362
              len = (uint8_t) n;
 
363
 
 
364
              asm volatile (
 
365
                 "mov __zero_reg__,%2" CR_TAB
 
366
                 XCALL " __eeprom_write_block_" _REG_LOCATION_SUFFIX
 
367
               : "+x" (pointer_eeprom),
 
368
                 "=z" (pointer_ram)
 
369
               : "r"  (len),
 
370
                 "z"  (pointer_ram)
 
371
               : "memory" );
 
372
            }
 
373
 
 
374
        }
 
375
    }
 
376
}
148
377
 
149
378
/*@}*/
150
379
 
154
383
 
155
384
/** \def _EEPUT
156
385
    \ingroup avr_eeprom
157
 
    Write a byte to EEPROM. */
 
386
    Write a byte to EEPROM. Compatibility define for IAR C. */
158
387
 
159
388
#define _EEPUT(addr, val) eeprom_write_byte ((uint8_t *)(addr), (uint8_t)(val))
160
389
 
161
390
/** \def _EEGET
162
391
    \ingroup avr_eeprom
163
 
    Read a byte from EEPROM. */
 
392
    Read a byte from EEPROM. Compatibility define for IAR C. */
164
393
 
165
394
#define _EEGET(var, addr) (var) = eeprom_read_byte ((uint8_t *)(addr))
166
395