AVR Libc Home Page |  | AVR Libc Development Pages
Main Page | User Manual | Library Reference | FAQ | Alphabetical Index | Example Projects

pgmspace.h
Go to the documentation of this file.
1 /* Copyright (c) 2002-2007 Marek Michalkiewicz
2 Copyright (c) 2006, Carlos Lamas
3 Copyright (c) 2009-2010, Jan Waclawek
4 All rights reserved.
5
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions are met:
8
9 * Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11 * Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in
13 the documentation and/or other materials provided with the
14 distribution.
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: pgmspace.h 2270 2011-12-29 08:42:00Z joerg_wunsch $ */
32
33 /*
34 pgmspace.h
35
36 Contributors:
37 Created by Marek Michalkiewicz <marekm@linux.org.pl>
38 Eric B. Weddington <eric@ecentral.com>
39 Wolfgang Haidinger <wh@vmars.tuwien.ac.at> (pgm_read_dword())
40 Ivanov Anton <anton@arc.com.ru> (pgm_read_float())
41 */
42
43 /** \file */
44 /** \defgroup avr_pgmspace <avr/pgmspace.h>: Program Space Utilities
45 \code
46 #include <avr/io.h>
47 #include <avr/pgmspace.h>
48 \endcode
49
50 The functions in this module provide interfaces for a program to access
51 data stored in program space (flash memory) of the device. In order to
52 use these functions, the target device must support either the \c LPM or
53 \c ELPM instructions.
54
55 \note These functions are an attempt to provide some compatibility with
56 header files that come with IAR C, to make porting applications between
57 different compilers easier. This is not 100% compatibility though (GCC
58 does not have full support for multiple address spaces yet).
59
60 \note If you are working with strings which are completely based in ram,
61 use the standard string functions described in \ref avr_string.
62
63 \note If possible, put your constant tables in the lower 64 KB and use
64 pgm_read_byte_near() or pgm_read_word_near() instead of
65 pgm_read_byte_far() or pgm_read_word_far() since it is more efficient that
66 way, and you can still use the upper 64K for executable code.
67 All functions that are suffixed with a \c _P \e require their
68 arguments to be in the lower 64 KB of the flash ROM, as they do
69 not use ELPM instructions. This is normally not a big concern as
70 the linker setup arranges any program space constants declared
71 using the macros from this header file so they are placed right after
72 the interrupt vectors, and in front of any executable code. However,
73 it can become a problem if there are too many of these constants, or
74 for bootloaders on devices with more than 64 KB of ROM.
75 <em>All these functions will not work in that situation.</em>
76
77 \note For <b>Xmega</b> devices, make sure the NVM controller
78 command register (\c NVM.CMD or \c NVM_CMD) is set to 0x00 (NOP)
79 before using any of these functions.
80 */
81
82 #ifndef __PGMSPACE_H_
83 #define __PGMSPACE_H_ 1
84
85 #define __need_size_t
86 #include <inttypes.h>
87 #include <stddef.h>
88 #include <avr/io.h>
89
90 #ifndef __ATTR_CONST__
91 #define __ATTR_CONST__ __attribute__((__const__))
92 #endif
93
94 #ifndef __ATTR_PROGMEM__
95 #define __ATTR_PROGMEM__ __attribute__((__progmem__))
96 #endif
97
98 #ifndef __ATTR_PURE__
99 #define __ATTR_PURE__ __attribute__((__pure__))
100 #endif
101
102 /**
103 \ingroup avr_pgmspace
104 \def PROGMEM
105
106 Attribute to use in order to declare an object being located in
107 flash ROM.
108 */
109 #define PROGMEM __ATTR_PROGMEM__
110
111 #ifdef __cplusplus
112 extern "C" {
113 #endif
114
115 #if defined(__DOXYGEN__)
116 /*
117 * Doxygen doesn't grok the appended attribute syntax of
118 * GCC, and confuses the typedefs with function decls, so
119 * supply a doxygen-friendly view.
120 */
121
122 /**
123 \ingroup avr_pgmspace
124 \typedef prog_void
125 \note DEPRECATED
126
127 This typedef is now deprecated because the usage of the __progmem__
128 attribute on a type is not supported in GCC. However, the use of the
129 __progmem__ attribute on a variable declaration is supported, and this is
130 now the recommended usage.
131
132 The typedef is only visible if the macro __PROG_TYPES_COMPAT__
133 has been defined before including <avr/pgmspace.h> (either by a
134 #define directive, or by a -D compiler option.)
135
136 Type of a "void" object located in flash ROM. Does not make much
137 sense by itself, but can be used to declare a "void *" object in
138 flash ROM.
139 */
140 typedef void PROGMEM prog_void;
141
142 /**
143 \ingroup avr_pgmspace
144 \typedef prog_char
145 \note DEPRECATED
146
147 This typedef is now deprecated because the usage of the __progmem__
148 attribute on a type is not supported in GCC. However, the use of the
149 __progmem__ attribute on a variable declaration is supported, and this is
150 now the recommended usage.
151
152 The typedef is only visible if the macro __PROG_TYPES_COMPAT__
153 has been defined before including <avr/pgmspace.h> (either by a
154 #define directive, or by a -D compiler option.)
155
156 Type of a "char" object located in flash ROM.
157 */
158 typedef char PROGMEM prog_char;
159
160 /**
161 \ingroup avr_pgmspace
162 \typedef prog_uchar
163 \note DEPRECATED
164
165 This typedef is now deprecated because the usage of the __progmem__
166 attribute on a type is not supported in GCC. However, the use of the
167 __progmem__ attribute on a variable declaration is supported, and this is
168 now the recommended usage.
169
170 The typedef is only visible if the macro __PROG_TYPES_COMPAT__
171 has been defined before including <avr/pgmspace.h> (either by a
172 #define directive, or by a -D compiler option.)
173
174 Type of an "unsigned char" object located in flash ROM.
175 */
176 typedef unsigned char PROGMEM prog_uchar;
177
178 /**
179 \ingroup avr_pgmspace
180 \typedef prog_int8_t
181 \note DEPRECATED
182
183 This typedef is now deprecated because the usage of the __progmem__
184 attribute on a type is not supported in GCC. However, the use of the
185 __progmem__ attribute on a variable declaration is supported, and this is
186 now the recommended usage.
187
188 The typedef is only visible if the macro __PROG_TYPES_COMPAT__
189 has been defined before including <avr/pgmspace.h> (either by a
190 #define directive, or by a -D compiler option.)
191
192 Type of an "int8_t" object located in flash ROM.
193 */
194 typedef int8_t PROGMEM prog_int8_t;
195
196 /**
197 \ingroup avr_pgmspace
198 \typedef prog_uint8_t
199 \note DEPRECATED
200
201 This typedef is now deprecated because the usage of the __progmem__
202 attribute on a type is not supported in GCC. However, the use of the
203 __progmem__ attribute on a variable declaration is supported, and this is
204 now the recommended usage.
205
206 The typedef is only visible if the macro __PROG_TYPES_COMPAT__
207 has been defined before including <avr/pgmspace.h> (either by a
208 #define directive, or by a -D compiler option.)
209
210 Type of an "uint8_t" object located in flash ROM.
211 */
212 typedef uint8_t PROGMEM prog_uint8_t;
213
214 /**
215 \ingroup avr_pgmspace
216 \typedef prog_int16_t
217 \note DEPRECATED
218
219 This typedef is now deprecated because the usage of the __progmem__
220 attribute on a type is not supported in GCC. However, the use of the
221 __progmem__ attribute on a variable declaration is supported, and this is
222 now the recommended usage.
223
224 The typedef is only visible if the macro __PROG_TYPES_COMPAT__
225 has been defined before including <avr/pgmspace.h> (either by a
226 #define directive, or by a -D compiler option.)
227
228 Type of an "int16_t" object located in flash ROM.
229 */
230 typedef int16_t PROGMEM prog_int16_t;
231
232 /**
233 \ingroup avr_pgmspace
234 \typedef prog_uint16_t
235 \note DEPRECATED
236
237 This typedef is now deprecated because the usage of the __progmem__
238 attribute on a type is not supported in GCC. However, the use of the
239 __progmem__ attribute on a variable declaration is supported, and this is
240 now the recommended usage.
241
242 The typedef is only visible if the macro __PROG_TYPES_COMPAT__
243 has been defined before including <avr/pgmspace.h> (either by a
244 #define directive, or by a -D compiler option.)
245
246 Type of an "uint16_t" object located in flash ROM.
247 */
248 typedef uint16_t PROGMEM prog_uint16_t;
249
250 /**
251 \ingroup avr_pgmspace
252 \typedef prog_int32_t
253 \note DEPRECATED
254
255 This typedef is now deprecated because the usage of the __progmem__
256 attribute on a type is not supported in GCC. However, the use of the
257 __progmem__ attribute on a variable declaration is supported, and this is
258 now the recommended usage.
259
260 The typedef is only visible if the macro __PROG_TYPES_COMPAT__
261 has been defined before including <avr/pgmspace.h> (either by a
262 #define directive, or by a -D compiler option.)
263
264 Type of an "int32_t" object located in flash ROM.
265 */
266 typedef int32_t PROGMEM prog_int32_t;
267
268 /**
269 \ingroup avr_pgmspace
270 \typedef prog_uint32_t
271 \note DEPRECATED
272
273 This typedef is now deprecated because the usage of the __progmem__
274 attribute on a type is not supported in GCC. However, the use of the
275 __progmem__ attribute on a variable declaration is supported, and this is
276 now the recommended usage.
277
278 The typedef is only visible if the macro __PROG_TYPES_COMPAT__
279 has been defined before including <avr/pgmspace.h> (either by a
280 #define directive, or by a -D compiler option.)
281
282 Type of an "uint32_t" object located in flash ROM.
283 */
284 typedef uint32_t PROGMEM prog_uint32_t;
285
286 /**
287 \ingroup avr_pgmspace
288 \typedef prog_int64_t
289 \note DEPRECATED
290
291 This typedef is now deprecated because the usage of the __progmem__
292 attribute on a type is not supported in GCC. However, the use of the
293 __progmem__ attribute on a variable declaration is supported, and this is
294 now the recommended usage.
295
296 The typedef is only visible if the macro __PROG_TYPES_COMPAT__
297 has been defined before including <avr/pgmspace.h> (either by a
298 #define directive, or by a -D compiler option.)
299
300 Type of an "int64_t" object located in flash ROM.
301
302 \note This type is not available when the compiler
303 option -mint8 is in effect.
304 */
305 typedef int64_t PROGMEM prog_int64_t;
306
307 /**
308 \ingroup avr_pgmspace
309 \typedef prog_uint64_t
310 \note DEPRECATED
311
312 This typedef is now deprecated because the usage of the __progmem__
313 attribute on a type is not supported in GCC. However, the use of the
314 __progmem__ attribute on a variable declaration is supported, and this is
315 now the recommended usage.
316
317 The typedef is only visible if the macro __PROG_TYPES_COMPAT__
318 has been defined before including <avr/pgmspace.h> (either by a
319 #define directive, or by a -D compiler option.)
320
321 Type of an "uint64_t" object located in flash ROM.
322
323 \note This type is not available when the compiler
324 option -mint8 is in effect.
325 */
326 typedef uint64_t PROGMEM prog_uint64_t;
327
328 /** \ingroup avr_pgmspace
329 \def PGM_P
330
331 Used to declare a variable that is a pointer to a string in program
332 space. */
333
334 #ifndef PGM_P
335 #define PGM_P const char *
336 #endif
337
338 /** \ingroup avr_pgmspace
339 \def PGM_VOID_P
340
341 Used to declare a generic pointer to an object in program space. */
342
343 #ifndef PGM_VOID_P
344 #define PGM_VOID_P const void *
345 #endif
346
347 #elif defined(__PROG_TYPES_COMPAT__) /* !DOXYGEN */
348
349 typedef void prog_void __attribute__((__progmem__,deprecated("prog_void type is deprecated.")));
350 typedef char prog_char __attribute__((__progmem__,deprecated("prog_char type is deprecated.")));
351 typedef unsigned char prog_uchar __attribute__((__progmem__,deprecated("prog_uchar type is deprecated.")));
352 typedef int8_t prog_int8_t __attribute__((__progmem__,deprecated("prog_int8_t type is deprecated.")));
353 typedef uint8_t prog_uint8_t __attribute__((__progmem__,deprecated("prog_uint8_t type is deprecated.")));
354 typedef int16_t prog_int16_t __attribute__((__progmem__,deprecated("prog_int16_t type is deprecated.")));
355 typedef uint16_t prog_uint16_t __attribute__((__progmem__,deprecated("prog_uint16_t type is deprecated.")));
356 typedef int32_t prog_int32_t __attribute__((__progmem__,deprecated("prog_int32_t type is deprecated.")));
357 typedef uint32_t prog_uint32_t __attribute__((__progmem__,deprecated("prog_uint32_t type is deprecated.")));
358 #if !__USING_MINT8
359 typedef int64_t prog_int64_t __attribute__((__progmem__,deprecated("prog_int64_t type is deprecated.")));
360 typedef uint64_t prog_uint64_t __attribute__((__progmem__,deprecated("prog_uint64_t type is deprecated.")));
361 #endif
362
363 #ifndef PGM_P
364 #define PGM_P const prog_char *
365 #endif
366
367 #ifndef PGM_VOID_P
368 #define PGM_VOID_P const prog_void *
369 #endif
370
371 #else /* !defined(__DOXYGEN__), !defined(__PROG_TYPES_COMPAT__) */
372
373 #ifndef PGM_P
374 #define PGM_P const char *
375 #endif
376
377 #ifndef PGM_VOID_P
378 #define PGM_VOID_P const void *
379 #endif
380 #endif /* defined(__DOXYGEN__), defined(__PROG_TYPES_COMPAT__) */
381
382 /* Although in C, we can get away with just using __c, it does not work in
383 C++. We need to use &__c[0] to avoid the compiler puking. Dave Hylands
384 explaned it thusly,
385
386 Let's suppose that we use PSTR("Test"). In this case, the type returned
387 by __c is a prog_char[5] and not a prog_char *. While these are
388 compatible, they aren't the same thing (especially in C++). The type
389 returned by &__c[0] is a prog_char *, which explains why it works
390 fine. */
391
392 #if defined(__DOXYGEN__)
393 /*
394 * The #define below is just a dummy that serves documentation
395 * purposes only.
396 */
397 /** \ingroup avr_pgmspace
398 \def PSTR(s)
399
400 Used to declare a static pointer to a string in program space. */
401 # define PSTR(s) ((const PROGMEM char *)(s))
402 #else /* !DOXYGEN */
403 /* The real thing. */
404 # define PSTR(s) (__extension__({static const char __c[] PROGMEM = (s); &__c[0];}))
405 #endif /* DOXYGEN */
406
407 #define __LPM_classic__(addr) \
408 (__extension__({ \
409 uint16_t __addr16 = (uint16_t)(addr); \
410 uint8_t __result; \
411 __asm__ \
412 ( \
413 "lpm" "\n\t" \
414 "mov %0, r0" "\n\t" \
415 : "=r" (__result) \
416 : "z" (__addr16) \
417 : "r0" \
418 ); \
419 __result; \
420 }))
421
422 #define __LPM_enhanced__(addr) \
423 (__extension__({ \
424 uint16_t __addr16 = (uint16_t)(addr); \
425 uint8_t __result; \
426 __asm__ \
427 ( \
428 "lpm %0, Z" "\n\t" \
429 : "=r" (__result) \
430 : "z" (__addr16) \
431 ); \
432 __result; \
433 }))
434
435 #define __LPM_word_classic__(addr) \
436 (__extension__({ \
437 uint16_t __addr16 = (uint16_t)(addr); \
438 uint16_t __result; \
439 __asm__ \
440 ( \
441 "lpm" "\n\t" \
442 "mov %A0, r0" "\n\t" \
443 "adiw r30, 1" "\n\t" \
444 "lpm" "\n\t" \
445 "mov %B0, r0" "\n\t" \
446 : "=r" (__result), "=z" (__addr16) \
447 : "1" (__addr16) \
448 : "r0" \
449 ); \
450 __result; \
451 }))
452
453 #define __LPM_word_enhanced__(addr) \
454 (__extension__({ \
455 uint16_t __addr16 = (uint16_t)(addr); \
456 uint16_t __result; \
457 __asm__ \
458 ( \
459 "lpm %A0, Z+" "\n\t" \
460 "lpm %B0, Z" "\n\t" \
461 : "=r" (__result), "=z" (__addr16) \
462 : "1" (__addr16) \
463 ); \
464 __result; \
465 }))
466
467 #define __LPM_dword_classic__(addr) \
468 (__extension__({ \
469 uint16_t __addr16 = (uint16_t)(addr); \
470 uint32_t __result; \
471 __asm__ \
472 ( \
473 "lpm" "\n\t" \
474 "mov %A0, r0" "\n\t" \
475 "adiw r30, 1" "\n\t" \
476 "lpm" "\n\t" \
477 "mov %B0, r0" "\n\t" \
478 "adiw r30, 1" "\n\t" \
479 "lpm" "\n\t" \
480 "mov %C0, r0" "\n\t" \
481 "adiw r30, 1" "\n\t" \
482 "lpm" "\n\t" \
483 "mov %D0, r0" "\n\t" \
484 : "=r" (__result), "=z" (__addr16) \
485 : "1" (__addr16) \
486 : "r0" \
487 ); \
488 __result; \
489 }))
490
491 #define __LPM_dword_enhanced__(addr) \
492 (__extension__({ \
493 uint16_t __addr16 = (uint16_t)(addr); \
494 uint32_t __result; \
495 __asm__ \
496 ( \
497 "lpm %A0, Z+" "\n\t" \
498 "lpm %B0, Z+" "\n\t" \
499 "lpm %C0, Z+" "\n\t" \
500 "lpm %D0, Z" "\n\t" \
501 : "=r" (__result), "=z" (__addr16) \
502 : "1" (__addr16) \
503 ); \
504 __result; \
505 }))
506
507 #define __LPM_float_classic__(addr) \
508 (__extension__({ \
509 uint16_t __addr16 = (uint16_t)(addr); \
510 float __result; \
511 __asm__ \
512 ( \
513 "lpm" "\n\t" \
514 "mov %A0, r0" "\n\t" \
515 "adiw r30, 1" "\n\t" \
516 "lpm" "\n\t" \
517 "mov %B0, r0" "\n\t" \
518 "adiw r30, 1" "\n\t" \
519 "lpm" "\n\t" \
520 "mov %C0, r0" "\n\t" \
521 "adiw r30, 1" "\n\t" \
522 "lpm" "\n\t" \
523 "mov %D0, r0" "\n\t" \
524 : "=r" (__result), "=z" (__addr16) \
525 : "1" (__addr16) \
526 : "r0" \
527 ); \
528 __result; \
529 }))
530
531 #define __LPM_float_enhanced__(addr) \
532 (__extension__({ \
533 uint16_t __addr16 = (uint16_t)(addr); \
534 float __result; \
535 __asm__ \
536 ( \
537 "lpm %A0, Z+" "\n\t" \
538 "lpm %B0, Z+" "\n\t" \
539 "lpm %C0, Z+" "\n\t" \
540 "lpm %D0, Z" "\n\t" \
541 : "=r" (__result), "=z" (__addr16) \
542 : "1" (__addr16) \
543 ); \
544 __result; \
545 }))
546
547 #if defined (__AVR_HAVE_LPMX__)
548 #define __LPM(addr) __LPM_enhanced__(addr)
549 #define __LPM_word(addr) __LPM_word_enhanced__(addr)
550 #define __LPM_dword(addr) __LPM_dword_enhanced__(addr)
551 #define __LPM_float(addr) __LPM_float_enhanced__(addr)
552 #else
553 #define __LPM(addr) __LPM_classic__(addr)
554 #define __LPM_word(addr) __LPM_word_classic__(addr)
555 #define __LPM_dword(addr) __LPM_dword_classic__(addr)
556 #define __LPM_float(addr) __LPM_float_classic__(addr)
557 #endif
558
559 /** \ingroup avr_pgmspace
560 \def pgm_read_byte_near(address_short)
561 Read a byte from the program space with a 16-bit (near) address.
562 \note The address is a byte address.
563 The address is in the program space. */
564
565 #define pgm_read_byte_near(address_short) __LPM((uint16_t)(address_short))
566
567 /** \ingroup avr_pgmspace
568 \def pgm_read_word_near(address_short)
569 Read a word from the program space with a 16-bit (near) address.
570 \note The address is a byte address.
571 The address is in the program space. */
572
573 #define pgm_read_word_near(address_short) __LPM_word((uint16_t)(address_short))
574
575 /** \ingroup avr_pgmspace
576 \def pgm_read_dword_near(address_short)
577 Read a double word from the program space with a 16-bit (near) address.
578 \note The address is a byte address.
579 The address is in the program space. */
580
581 #define pgm_read_dword_near(address_short) \
582 __LPM_dword((uint16_t)(address_short))
583
584 /** \ingroup avr_pgmspace
585 \def pgm_read_float_near(address_short)
586 Read a float from the program space with a 16-bit (near) address.
587 \note The address is a byte address.
588 The address is in the program space. */
589
590 #define pgm_read_float_near(address_short) \
591 __LPM_float((uint16_t)(address_short))
592
593 #if defined(RAMPZ) || defined(__DOXYGEN__)
594
595 /* Only for devices with more than 64K of program memory.
596 RAMPZ must be defined (see iom103.h, iom128.h).
597 */
598
599 /* The classic functions are needed for ATmega103. */
600
601 #define __ELPM_classic__(addr) \
602 (__extension__({ \
603 uint32_t __addr32 = (uint32_t)(addr); \
604 uint8_t __result; \
605 __asm__ \
606 ( \
607 "out %2, %C1" "\n\t" \
608 "mov r31, %B1" "\n\t" \
609 "mov r30, %A1" "\n\t" \
610 "elpm" "\n\t" \
611 "mov %0, r0" "\n\t" \
612 : "=r" (__result) \
613 : "r" (__addr32), \
614 "I" (_SFR_IO_ADDR(RAMPZ)) \
615 : "r0", "r30", "r31" \
616 ); \
617 __result; \
618 }))
619
620 #define __ELPM_enhanced__(addr) \
621 (__extension__({ \
622 uint32_t __addr32 = (uint32_t)(addr); \
623 uint8_t __result; \
624 __asm__ \
625 ( \
626 "out %2, %C1" "\n\t" \
627 "movw r30, %1" "\n\t" \
628 "elpm %0, Z+" "\n\t" \
629 : "=r" (__result) \
630 : "r" (__addr32), \
631 "I" (_SFR_IO_ADDR(RAMPZ)) \
632 : "r30", "r31" \
633 ); \
634 __result; \
635 }))
636
637 #define __ELPM_xmega__(addr) \
638 (__extension__({ \
639 uint32_t __addr32 = (uint32_t)(addr); \
640 uint8_t __result; \
641 __asm__ \
642 ( \
643 "in __tmp_reg__, %2" "\n\t" \
644 "out %2, %C1" "\n\t" \
645 "movw r30, %1" "\n\t" \
646 "elpm %0, Z+" "\n\t" \
647 "out %2, __tmp_reg__" \
648 : "=r" (__result) \
649 : "r" (__addr32), \
650 "I" (_SFR_IO_ADDR(RAMPZ)) \
651 : "r30", "r31" \
652 ); \
653 __result; \
654 }))
655
656 #define __ELPM_word_classic__(addr) \
657 (__extension__({ \
658 uint32_t __addr32 = (uint32_t)(addr); \
659 uint16_t __result; \
660 __asm__ \
661 ( \
662 "out %2, %C1" "\n\t" \
663 "mov r31, %B1" "\n\t" \
664 "mov r30, %A1" "\n\t" \
665 "elpm" "\n\t" \
666 "mov %A0, r0" "\n\t" \
667 "in r0, %2" "\n\t" \
668 "adiw r30, 1" "\n\t" \
669 "adc r0, __zero_reg__" "\n\t" \
670 "out %2, r0" "\n\t" \
671 "elpm" "\n\t" \
672 "mov %B0, r0" "\n\t" \
673 : "=r" (__result) \
674 : "r" (__addr32), \
675 "I" (_SFR_IO_ADDR(RAMPZ)) \
676 : "r0", "r30", "r31" \
677 ); \
678 __result; \
679 }))
680
681 #define __ELPM_word_enhanced__(addr) \
682 (__extension__({ \
683 uint32_t __addr32 = (uint32_t)(addr); \
684 uint16_t __result; \
685 __asm__ \
686 ( \
687 "out %2, %C1" "\n\t" \
688 "movw r30, %1" "\n\t" \
689 "elpm %A0, Z+" "\n\t" \
690 "elpm %B0, Z" "\n\t" \
691 : "=r" (__result) \
692 : "r" (__addr32), \
693 "I" (_SFR_IO_ADDR(RAMPZ)) \
694 : "r30", "r31" \
695 ); \
696 __result; \
697 }))
698
699 #define __ELPM_word_xmega__(addr) \
700 (__extension__({ \
701 uint32_t __addr32 = (uint32_t)(addr); \
702 uint16_t __result; \
703 __asm__ \
704 ( \
705 "in __tmp_reg__, %2" "\n\t" \
706 "out %2, %C1" "\n\t" \
707 "movw r30, %1" "\n\t" \
708 "elpm %A0, Z+" "\n\t" \
709 "elpm %B0, Z" "\n\t" \
710 "out %2, __tmp_reg__" \
711 : "=r" (__result) \
712 : "r" (__addr32), \
713 "I" (_SFR_IO_ADDR(RAMPZ)) \
714 : "r30", "r31" \
715 ); \
716 __result; \
717 }))
718
719 #define __ELPM_dword_classic__(addr) \
720 (__extension__({ \
721 uint32_t __addr32 = (uint32_t)(addr); \
722 uint32_t __result; \
723 __asm__ \
724 ( \
725 "out %2, %C1" "\n\t" \
726 "mov r31, %B1" "\n\t" \
727 "mov r30, %A1" "\n\t" \
728 "elpm" "\n\t" \
729 "mov %A0, r0" "\n\t" \
730 "in r0, %2" "\n\t" \
731 "adiw r30, 1" "\n\t" \
732 "adc r0, __zero_reg__" "\n\t" \
733 "out %2, r0" "\n\t" \
734 "elpm" "\n\t" \
735 "mov %B0, r0" "\n\t" \
736 "in r0, %2" "\n\t" \
737 "adiw r30, 1" "\n\t" \
738 "adc r0, __zero_reg__" "\n\t" \
739 "out %2, r0" "\n\t" \
740 "elpm" "\n\t" \
741 "mov %C0, r0" "\n\t" \
742 "in r0, %2" "\n\t" \
743 "adiw r30, 1" "\n\t" \
744 "adc r0, __zero_reg__" "\n\t" \
745 "out %2, r0" "\n\t" \
746 "elpm" "\n\t" \
747 "mov %D0, r0" "\n\t" \
748 : "=r" (__result) \
749 : "r" (__addr32), \
750 "I" (_SFR_IO_ADDR(RAMPZ)) \
751 : "r0", "r30", "r31" \
752 ); \
753 __result; \
754 }))
755
756 #define __ELPM_dword_enhanced__(addr) \
757 (__extension__({ \
758 uint32_t __addr32 = (uint32_t)(addr); \
759 uint32_t __result; \
760 __asm__ \
761 ( \
762 "out %2, %C1" "\n\t" \
763 "movw r30, %1" "\n\t" \
764 "elpm %A0, Z+" "\n\t" \
765 "elpm %B0, Z+" "\n\t" \
766 "elpm %C0, Z+" "\n\t" \
767 "elpm %D0, Z" "\n\t" \
768 : "=r" (__result) \
769 : "r" (__addr32), \
770 "I" (_SFR_IO_ADDR(RAMPZ)) \
771 : "r30", "r31" \
772 ); \
773 __result; \
774 }))
775
776 #define __ELPM_dword_xmega__(addr) \
777 (__extension__({ \
778 uint32_t __addr32 = (uint32_t)(addr); \
779 uint32_t __result; \
780 __asm__ \
781 ( \
782 "in __tmp_reg__, %2" "\n\t" \
783 "out %2, %C1" "\n\t" \
784 "movw r30, %1" "\n\t" \
785 "elpm %A0, Z+" "\n\t" \
786 "elpm %B0, Z+" "\n\t" \
787 "elpm %C0, Z+" "\n\t" \
788 "elpm %D0, Z" "\n\t" \
789 "out %2, __tmp_reg__" \
790 : "=r" (__result) \
791 : "r" (__addr32), \
792 "I" (_SFR_IO_ADDR(RAMPZ)) \
793 : "r30", "r31" \
794 ); \
795 __result; \
796 }))
797
798 #define __ELPM_float_classic__(addr) \
799 (__extension__({ \
800 uint32_t __addr32 = (uint32_t)(addr); \
801 float __result; \
802 __asm__ \
803 ( \
804 "out %2, %C1" "\n\t" \
805 "mov r31, %B1" "\n\t" \
806 "mov r30, %A1" "\n\t" \
807 "elpm" "\n\t" \
808 "mov %A0, r0" "\n\t" \
809 "in r0, %2" "\n\t" \
810 "adiw r30, 1" "\n\t" \
811 "adc r0, __zero_reg__" "\n\t" \
812 "out %2, r0" "\n\t" \
813 "elpm" "\n\t" \
814 "mov %B0, r0" "\n\t" \
815 "in r0, %2" "\n\t" \
816 "adiw r30, 1" "\n\t" \
817 "adc r0, __zero_reg__" "\n\t" \
818 "out %2, r0" "\n\t" \
819 "elpm" "\n\t" \
820 "mov %C0, r0" "\n\t" \
821 "in r0, %2" "\n\t" \
822 "adiw r30, 1" "\n\t" \
823 "adc r0, __zero_reg__" "\n\t" \
824 "out %2, r0" "\n\t" \
825 "elpm" "\n\t" \
826 "mov %D0, r0" "\n\t" \
827 : "=r" (__result) \
828 : "r" (__addr32), \
829 "I" (_SFR_IO_ADDR(RAMPZ)) \
830 : "r0", "r30", "r31" \
831 ); \
832 __result; \
833 }))
834
835 #define __ELPM_float_enhanced__(addr) \
836 (__extension__({ \
837 uint32_t __addr32 = (uint32_t)(addr); \
838 float __result; \
839 __asm__ \
840 ( \
841 "out %2, %C1" "\n\t" \
842 "movw r30, %1" "\n\t" \
843 "elpm %A0, Z+" "\n\t" \
844 "elpm %B0, Z+" "\n\t" \
845 "elpm %C0, Z+" "\n\t" \
846 "elpm %D0, Z" "\n\t" \
847 : "=r" (__result) \
848 : "r" (__addr32), \
849 "I" (_SFR_IO_ADDR(RAMPZ)) \
850 : "r30", "r31" \
851 ); \
852 __result; \
853 }))
854
855 #define __ELPM_float_xmega__(addr) \
856 (__extension__({ \
857 uint32_t __addr32 = (uint32_t)(addr); \
858 float __result; \
859 __asm__ \
860 ( \
861 "in __tmp_reg__, %2" "\n\t" \
862 "out %2, %C1" "\n\t" \
863 "movw r30, %1" "\n\t" \
864 "elpm %A0, Z+" "\n\t" \
865 "elpm %B0, Z+" "\n\t" \
866 "elpm %C0, Z+" "\n\t" \
867 "elpm %D0, Z" "\n\t" \
868 "out %2, __tmp_reg__" \
869 : "=r" (__result) \
870 : "r" (__addr32), \
871 "I" (_SFR_IO_ADDR(RAMPZ)) \
872 : "r30", "r31" \
873 ); \
874 __result; \
875 }))
876
877 /*
878 Check for architectures that implement RAMPD (avrxmega3, avrxmega5,
879 avrxmega7) as they need to save/restore RAMPZ for ELPM macros so it does
880 not interfere with data accesses.
881 */
882 #if defined (__AVR_HAVE_RAMPD__)
883
884 #define __ELPM(addr) __ELPM_xmega__(addr)
885 #define __ELPM_word(addr) __ELPM_word_xmega__(addr)
886 #define __ELPM_dword(addr) __ELPM_dword_xmega__(addr)
887 #define __ELPM_float(addr) __ELPM_float_xmega__(addr)
888
889 #else
890
891 #if defined (__AVR_HAVE_LPMX__)
892
893 #define __ELPM(addr) __ELPM_enhanced__(addr)
894 #define __ELPM_word(addr) __ELPM_word_enhanced__(addr)
895 #define __ELPM_dword(addr) __ELPM_dword_enhanced__(addr)
896 #define __ELPM_float(addr) __ELPM_float_enhanced__(addr)
897
898 #else
899
900 #define __ELPM(addr) __ELPM_classic__(addr)
901 #define __ELPM_word(addr) __ELPM_word_classic__(addr)
902 #define __ELPM_dword(addr) __ELPM_dword_classic__(addr)
903 #define __ELPM_float(addr) __ELPM_float_classic__(addr)
904
905 #endif /* __AVR_HAVE_LPMX__ */
906
907 #endif /* __AVR_HAVE_RAMPD__ */
908
909
910 /** \ingroup avr_pgmspace
911 \def pgm_read_byte_far(address_long)
912 Read a byte from the program space with a 32-bit (far) address.
913
914 \note The address is a byte address.
915 The address is in the program space. */
916
917 #define pgm_read_byte_far(address_long) __ELPM((uint32_t)(address_long))
918
919 /** \ingroup avr_pgmspace
920 \def pgm_read_word_far(address_long)
921 Read a word from the program space with a 32-bit (far) address.
922
923 \note The address is a byte address.
924 The address is in the program space. */
925
926 #define pgm_read_word_far(address_long) __ELPM_word((uint32_t)(address_long))
927
928 /** \ingroup avr_pgmspace
929 \def pgm_read_dword_far(address_long)
930 Read a double word from the program space with a 32-bit (far) address.
931
932 \note The address is a byte address.
933 The address is in the program space. */
934
935 #define pgm_read_dword_far(address_long) __ELPM_dword((uint32_t)(address_long))
936
937 /** \ingroup avr_pgmspace
938 \def pgm_read_float_far(address_long)
939 Read a float from the program space with a 32-bit (far) address.
940
941 \note The address is a byte address.
942 The address is in the program space. */
943
944 #define pgm_read_float_far(address_long) __ELPM_float((uint32_t)(address_long))
945
946 #endif /* RAMPZ or __DOXYGEN__ */
947
948 /** \ingroup avr_pgmspace
949 \def pgm_read_byte(address_short)
950 Read a byte from the program space with a 16-bit (near) address.
951
952 \note The address is a byte address.
953 The address is in the program space. */
954
955 #define pgm_read_byte(address_short) pgm_read_byte_near(address_short)
956
957 /** \ingroup avr_pgmspace
958 \def pgm_read_word(address_short)
959 Read a word from the program space with a 16-bit (near) address.
960
961 \note The address is a byte address.
962 The address is in the program space. */
963
964 #define pgm_read_word(address_short) pgm_read_word_near(address_short)
965
966 /** \ingroup avr_pgmspace
967 \def pgm_read_dword(address_short)
968 Read a double word from the program space with a 16-bit (near) address.
969
970 \note The address is a byte address.
971 The address is in the program space. */
972
973 #define pgm_read_dword(address_short) pgm_read_dword_near(address_short)
974
975 /** \ingroup avr_pgmspace
976 \def pgm_read_float(address_short)
977 Read a float from the program space with a 16-bit (near) address.
978
979 \note The address is a byte address.
980 The address is in the program space. */
981
982 #define pgm_read_float(address_short) pgm_read_float_near(address_short)
983
984 /* pgm_get_far_address() macro
985
986 This macro facilitates the obtention of a 32 bit "far" pointer (only 24 bits
987 used) to data even passed the 64KB limit for the 16 bit ordinary pointer. It
988 is similar to the '&' operator, with some limitations.
989
990 Comments:
991
992 - The overhead is minimal and it's mainly due to the 32 bit size operation.
993
994 - 24 bit sizes guarantees the code compatibility for use in future devices.
995
996 - hh8() is an undocumented feature but seems to give the third significant byte
997 of a 32 bit data and accepts symbols, complementing the functionality of hi8()
998 and lo8(). There is not an equivalent assembler function to get the high
999 significant byte.
1000
1001 - 'var' has to be resolved at linking time as an existing symbol, i.e, a simple
1002 type variable name, an array name (not an indexed element of the array, if the
1003 index is a constant the compiler does not complain but fails to get the address
1004 if optimization is enabled), a struct name or a struct field name, a function
1005 identifier, a linker defined identifier,...
1006
1007 - The returned value is the identifier's VMA (virtual memory address) determined
1008 by the linker and falls in the corresponding memory region. The AVR Harvard
1009 architecture requires non overlapping VMA areas for the multiple address spaces
1010 in the processor: Flash ROM, RAM, and EEPROM. Typical offset for this are
1011 0x00000000, 0x00800xx0, and 0x00810000 respectively, derived from the linker
1012 script used and linker options. The value returned can be seen then as a
1013 universal pointer.
1014
1015 */
1016
1017 #define pgm_get_far_address(var) \
1018 ({ \
1019 uint_farptr_t tmp; \
1020 \
1021 __asm__ __volatile__( \
1022 \
1023 "ldi %A0, lo8(%1)" "\n\t" \
1024 "ldi %B0, hi8(%1)" "\n\t" \
1025 "ldi %C0, hh8(%1)" "\n\t" \
1026 "clr %D0" "\n\t" \
1027 : \
1028 "=d" (tmp) \
1029 : \
1030 "p" (&(var)) \
1031 ); \
1032 tmp; \
1033 })
1034
1035
1036
1037 extern const void * memchr_P(const void *, int __val, size_t __len) __ATTR_CONST__;
1038 extern int memcmp_P(const void *, const void *, size_t) __ATTR_PURE__;
1039 extern void *memccpy_P(void *, const void *, int __val, size_t);
1040 extern void *memcpy_P(void *, const void *, size_t);
1041 extern void *memmem_P(const void *, size_t, const void *, size_t) __ATTR_PURE__;
1042 extern const void * memrchr_P(const void *, int __val, size_t __len) __ATTR_CONST__;
1043 extern char *strcat_P(char *, const char *);
1044 extern const char * strchr_P(const char *, int __val) __ATTR_CONST__;
1045 extern const char * strchrnul_P(const char *, int __val) __ATTR_CONST__;
1046 extern int strcmp_P(const char *, const char *) __ATTR_PURE__;
1047 extern char *strcpy_P(char *, const char *);
1048 extern int strcasecmp_P(const char *, const char *) __ATTR_PURE__;
1049 extern char *strcasestr_P(const char *, const char *) __ATTR_PURE__;
1050 extern size_t strcspn_P(const char *__s, const char * __reject) __ATTR_PURE__;
1051 extern size_t strlcat_P (char *, const char *, size_t );
1052 extern size_t strlcpy_P (char *, const char *, size_t );
1053 extern size_t __strlen_P(const char *) __ATTR_CONST__; /* program memory can't change */
1054 extern size_t strnlen_P(const char *, size_t) __ATTR_CONST__; /* program memory can't change */
1055 extern int strncmp_P(const char *, const char *, size_t) __ATTR_PURE__;
1056 extern int strncasecmp_P(const char *, const char *, size_t) __ATTR_PURE__;
1057 extern char *strncat_P(char *, const char *, size_t);
1058 extern char *strncpy_P(char *, const char *, size_t);
1059 extern char *strpbrk_P(const char *__s, const char * __accept) __ATTR_PURE__;
1060 extern const char * strrchr_P(const char *, int __val) __ATTR_CONST__;
1061 extern char *strsep_P(char **__sp, const char * __delim);
1062 extern size_t strspn_P(const char *__s, const char * __accept) __ATTR_PURE__;
1063 extern char *strstr_P(const char *, const char *) __ATTR_PURE__;
1064 extern char *strtok_P(char *__s, const char * __delim);
1065 extern char *strtok_rP(char *__s, const char * __delim, char **__last);
1066
1067 extern size_t strlen_PF (uint_farptr_t src) __ATTR_CONST__; /* program memory can't change */
1068 extern size_t strnlen_PF (uint_farptr_t src, size_t len) __ATTR_CONST__; /* program memory can't change */
1069 extern void *memcpy_PF (void *dest, uint_farptr_t src, size_t len);
1070 extern char *strcpy_PF (char *dest, uint_farptr_t src);
1071 extern char *strncpy_PF (char *dest, uint_farptr_t src, size_t len);
1072 extern char *strcat_PF (char *dest, uint_farptr_t src);
1073 extern size_t strlcat_PF (char *dst, uint_farptr_t src, size_t siz);
1074 extern char *strncat_PF (char *dest, uint_farptr_t src, size_t len);
1075 extern int strcmp_PF (const char *s1, uint_farptr_t s2) __ATTR_PURE__;
1076 extern int strncmp_PF (const char *s1, uint_farptr_t s2, size_t n) __ATTR_PURE__;
1077 extern int strcasecmp_PF (const char *s1, uint_farptr_t s2) __ATTR_PURE__;
1078 extern int strncasecmp_PF (const char *s1, uint_farptr_t s2, size_t n) __ATTR_PURE__;
1079 extern char *strstr_PF (const char *s1, uint_farptr_t s2);
1080 extern size_t strlcpy_PF (char *dst, uint_farptr_t src, size_t siz);
1081 extern int memcmp_PF(const void *, uint_farptr_t, size_t) __ATTR_PURE__;
1082
1083
1084 __attribute__((__always_inline__)) static inline size_t strlen_P(const char * s);
1085 static inline size_t strlen_P(const char *s) {
1086 return __builtin_constant_p(__builtin_strlen(s))
1087 ? __builtin_strlen(s) : __strlen_P(s);
1088 }
1089
1090
1091
1092 #ifdef __cplusplus
1093 }
1094 #endif
1095
1096 #endif /* __PGMSPACE_H_ */

Automatically generated by Doxygen 1.8.3.1 on Sat Jun 22 2013.