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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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_ */
uint32_t PROGMEM prog_uint32_t
Definition: pgmspace.h:284
signed long long int int64_t
Definition: stdint.h:106
char * strtok_P(char *s, PGM_P delim)
Parses the string into tokens.
Definition: strtok_P.c:60
int32_t PROGMEM prog_int32_t
Definition: pgmspace.h:266
uint64_t PROGMEM prog_uint64_t
Definition: pgmspace.h:326
unsigned char PROGMEM prog_uchar
Definition: pgmspace.h:176
void PROGMEM prog_void
Definition: pgmspace.h:140
int64_t PROGMEM prog_int64_t
Definition: pgmspace.h:305
void * memcpy_PF(void *dest, uint_farptr_t src, size_t len)
Copy a memory block from flash to SRAM.
signed int int16_t
Definition: stdint.h:84
signed char int8_t
Definition: stdint.h:74
char * strcpy_PF(char *dest, uint_farptr_t src)
Duplicate a string.
char * strcat_PF(char *dest, uint_farptr_t src)
Concatenates two strings.
#define PROGMEM
Definition: pgmspace.h:109
size_t strlcat_PF(char *dst, uint_farptr_t src, size_t siz)
Concatenate two strings.
char * strncat_PF(char *dest, uint_farptr_t src, size_t len)
Concatenate two strings.
signed long int int32_t
Definition: stdint.h:94
char * strstr_PF(const char *s1, uint_farptr_t s2)
Locate a substring.
size_t strlcpy_PF(char *dst, uint_farptr_t src, size_t siz)
Copy a string from progmem to RAM.
int8_t PROGMEM prog_int8_t
Definition: pgmspace.h:194
int memcmp_PF(const void *, uint_farptr_t, size_t) __ATTR_PURE__
Compare memory areas.
int strcmp_PF(const char *s1, uint_farptr_t s2) __ATTR_PURE__
Compares two strings.
unsigned char uint8_t
Definition: stdint.h:79
uint32_t uint_farptr_t
Definition: inttypes.h:81
unsigned long int uint32_t
Definition: stdint.h:99
char * strncpy_PF(char *dest, uint_farptr_t src, size_t len)
Duplicate a string until a limited length.
char PROGMEM prog_char
Definition: pgmspace.h:158
uint16_t PROGMEM prog_uint16_t
Definition: pgmspace.h:248
unsigned long long int uint64_t
Definition: stdint.h:113
int strncmp_PF(const char *s1, uint_farptr_t s2, size_t n) __ATTR_PURE__
Compare two strings with limited length.
size_t strlen_PF(uint_farptr_t src)
Obtain the length of a string.
unsigned int uint16_t
Definition: stdint.h:89
uint8_t PROGMEM prog_uint8_t
Definition: pgmspace.h:212
size_t strnlen_PF(uint_farptr_t src, size_t len)
Determine the length of a fixed-size string.
int strcasecmp_PF(const char *s1, uint_farptr_t s2) __ATTR_PURE__
Compare two strings ignoring case.
int strncasecmp_PF(const char *s1, uint_farptr_t s2, size_t n) __ATTR_PURE__
Compare two strings ignoring case.
int16_t PROGMEM prog_int16_t
Definition: pgmspace.h:230

Automatically generated by Doxygen 1.8.7 on Tue Jul 8 2014. Dash Docset conversion by Matt Kane