AVR Libc Home Page AVRs 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$ */
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__ __volatile__ \
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_tiny__(addr) \
423 (__extension__({ \
424  uint16_t __addr16 = (uint16_t)(addr) + __AVR_TINY_PM_BASE_ADDRESS__; \
425  uint8_t __result; \
426  __asm__ \
427  ( \
428  "ld %0, z" "\n\t" \
429  : "=r" (__result) \
430  : "z" (__addr16) \
431  ); \
432  __result; \
433 }))
434 
435 #define __LPM_enhanced__(addr) \
436 (__extension__({ \
437  uint16_t __addr16 = (uint16_t)(addr); \
438  uint8_t __result; \
439  __asm__ __volatile__ \
440  ( \
441  "lpm %0, Z" "\n\t" \
442  : "=r" (__result) \
443  : "z" (__addr16) \
444  ); \
445  __result; \
446 }))
447 
448 #define __LPM_word_classic__(addr) \
449 (__extension__({ \
450  uint16_t __addr16 = (uint16_t)(addr); \
451  uint16_t __result; \
452  __asm__ __volatile__ \
453  ( \
454  "lpm" "\n\t" \
455  "mov %A0, r0" "\n\t" \
456  "adiw r30, 1" "\n\t" \
457  "lpm" "\n\t" \
458  "mov %B0, r0" "\n\t" \
459  : "=r" (__result), "=z" (__addr16) \
460  : "1" (__addr16) \
461  : "r0" \
462  ); \
463  __result; \
464 }))
465 
466 #define __LPM_word_tiny__(addr) \
467 (__extension__({ \
468  uint16_t __addr16 = (uint16_t)(addr) + __AVR_TINY_PM_BASE_ADDRESS__; \
469  uint16_t __result; \
470  __asm__ \
471  ( \
472  "ld %A0, z+" "\n\t" \
473  "ld %B0, z" "\n\t" \
474  : "=r" (__result), "=z" (__addr16) \
475  : "1" (__addr16) \
476  ); \
477  __result; \
478 }))
479 
480 #define __LPM_word_enhanced__(addr) \
481 (__extension__({ \
482  uint16_t __addr16 = (uint16_t)(addr); \
483  uint16_t __result; \
484  __asm__ __volatile__ \
485  ( \
486  "lpm %A0, Z+" "\n\t" \
487  "lpm %B0, Z" "\n\t" \
488  : "=r" (__result), "=z" (__addr16) \
489  : "1" (__addr16) \
490  ); \
491  __result; \
492 }))
493 
494 #define __LPM_dword_classic__(addr) \
495 (__extension__({ \
496  uint16_t __addr16 = (uint16_t)(addr); \
497  uint32_t __result; \
498  __asm__ __volatile__ \
499  ( \
500  "lpm" "\n\t" \
501  "mov %A0, r0" "\n\t" \
502  "adiw r30, 1" "\n\t" \
503  "lpm" "\n\t" \
504  "mov %B0, r0" "\n\t" \
505  "adiw r30, 1" "\n\t" \
506  "lpm" "\n\t" \
507  "mov %C0, r0" "\n\t" \
508  "adiw r30, 1" "\n\t" \
509  "lpm" "\n\t" \
510  "mov %D0, r0" "\n\t" \
511  : "=r" (__result), "=z" (__addr16) \
512  : "1" (__addr16) \
513  : "r0" \
514  ); \
515  __result; \
516 }))
517 
518 #define __LPM_dword_tiny__(addr) \
519 (__extension__({ \
520  uint16_t __addr16 = (uint16_t)(addr) + __AVR_TINY_PM_BASE_ADDRESS__; \
521  uint32_t __result; \
522  __asm__ \
523  ( \
524  "ld %A0, z+" "\n\t" \
525  "ld %B0, z+" "\n\t" \
526  "ld %C0, z+" "\n\t" \
527  "ld %D0, z" "\n\t" \
528  : "=r" (__result), "=z" (__addr16) \
529  : "1" (__addr16) \
530  ); \
531  __result; \
532 }))
533 
534 #define __LPM_dword_enhanced__(addr) \
535 (__extension__({ \
536  uint16_t __addr16 = (uint16_t)(addr); \
537  uint32_t __result; \
538  __asm__ __volatile__ \
539  ( \
540  "lpm %A0, Z+" "\n\t" \
541  "lpm %B0, Z+" "\n\t" \
542  "lpm %C0, Z+" "\n\t" \
543  "lpm %D0, Z" "\n\t" \
544  : "=r" (__result), "=z" (__addr16) \
545  : "1" (__addr16) \
546  ); \
547  __result; \
548 }))
549 
550 #define __LPM_float_classic__(addr) \
551 (__extension__({ \
552  uint16_t __addr16 = (uint16_t)(addr); \
553  float __result; \
554  __asm__ __volatile__ \
555  ( \
556  "lpm" "\n\t" \
557  "mov %A0, r0" "\n\t" \
558  "adiw r30, 1" "\n\t" \
559  "lpm" "\n\t" \
560  "mov %B0, r0" "\n\t" \
561  "adiw r30, 1" "\n\t" \
562  "lpm" "\n\t" \
563  "mov %C0, r0" "\n\t" \
564  "adiw r30, 1" "\n\t" \
565  "lpm" "\n\t" \
566  "mov %D0, r0" "\n\t" \
567  : "=r" (__result), "=z" (__addr16) \
568  : "1" (__addr16) \
569  : "r0" \
570  ); \
571  __result; \
572 }))
573 
574 #define __LPM_float_tiny__(addr) \
575 (__extension__({ \
576  uint16_t __addr16 = (uint16_t)(addr) + __AVR_TINY_PM_BASE_ADDRESS__; \
577  float __result; \
578  __asm__ \
579  ( \
580  "ld %A0, z+" "\n\t" \
581  "ld %B0, z+" "\n\t" \
582  "ld %C0, z+" "\n\t" \
583  "ld %D0, z" "\n\t" \
584  : "=r" (__result), "=z" (__addr16) \
585  : "1" (__addr16) \
586  ); \
587  __result; \
588 }))
589 
590 #define __LPM_float_enhanced__(addr) \
591 (__extension__({ \
592  uint16_t __addr16 = (uint16_t)(addr); \
593  float __result; \
594  __asm__ __volatile__ \
595  ( \
596  "lpm %A0, Z+" "\n\t" \
597  "lpm %B0, Z+" "\n\t" \
598  "lpm %C0, Z+" "\n\t" \
599  "lpm %D0, Z" "\n\t" \
600  : "=r" (__result), "=z" (__addr16) \
601  : "1" (__addr16) \
602  ); \
603  __result; \
604 }))
605 
606 #if defined (__AVR_HAVE_LPMX__)
607 #define __LPM(addr) __LPM_enhanced__(addr)
608 #define __LPM_word(addr) __LPM_word_enhanced__(addr)
609 #define __LPM_dword(addr) __LPM_dword_enhanced__(addr)
610 #define __LPM_float(addr) __LPM_float_enhanced__(addr)
611 /*
612 Macro to read data from program memory for avr tiny parts(tiny 4/5/9/10/20/40).
613 why:
614 - LPM instruction is not available in AVR_TINY instruction set.
615 - Programs are executed starting from address 0x0000 in program memory.
616 But it must be addressed starting from 0x4000 when accessed via data memory.
617 Reference: TINY device (ATTiny 4,5,9,10,20 and 40) datasheets
618 Bug: avrtc-536
619 */
620 #elif defined (__AVR_TINY__)
621 #define __LPM(addr) __LPM_tiny__(addr)
622 #define __LPM_word(addr) __LPM_word_tiny__(addr)
623 #define __LPM_dword(addr) __LPM_dword_tiny__(addr)
624 #define __LPM_float(addr) __LPM_float_tiny__(addr)
625 #else
626 #define __LPM(addr) __LPM_classic__(addr)
627 #define __LPM_word(addr) __LPM_word_classic__(addr)
628 #define __LPM_dword(addr) __LPM_dword_classic__(addr)
629 #define __LPM_float(addr) __LPM_float_classic__(addr)
630 #endif
631 
632 /** \ingroup avr_pgmspace
633  \def pgm_read_byte_near(address_short)
634  Read a byte from the program space with a 16-bit (near) address.
635  \note The address is a byte address.
636  The address is in the program space. */
637 
638 #define pgm_read_byte_near(address_short) __LPM((uint16_t)(address_short))
639 
640 /** \ingroup avr_pgmspace
641  \def pgm_read_word_near(address_short)
642  Read a word from the program space with a 16-bit (near) address.
643  \note The address is a byte address.
644  The address is in the program space. */
645 
646 #define pgm_read_word_near(address_short) __LPM_word((uint16_t)(address_short))
647 
648 /** \ingroup avr_pgmspace
649  \def pgm_read_dword_near(address_short)
650  Read a double word from the program space with a 16-bit (near) address.
651  \note The address is a byte address.
652  The address is in the program space. */
653 
654 #define pgm_read_dword_near(address_short) \
655  __LPM_dword((uint16_t)(address_short))
656 
657 /** \ingroup avr_pgmspace
658  \def pgm_read_float_near(address_short)
659  Read a float from the program space with a 16-bit (near) address.
660  \note The address is a byte address.
661  The address is in the program space. */
662 
663 #define pgm_read_float_near(address_short) \
664  __LPM_float((uint16_t)(address_short))
665 
666 /** \ingroup avr_pgmspace
667  \def pgm_read_ptr_near(address_short)
668  Read a pointer from the program space with a 16-bit (near) address.
669  \note The address is a byte address.
670  The address is in the program space. */
671 
672 #define pgm_read_ptr_near(address_short) \
673  (void*)__LPM_word((uint16_t)(address_short))
674 
675 #if defined(RAMPZ) || defined(__DOXYGEN__)
676 
677 /* Only for devices with more than 64K of program memory.
678  RAMPZ must be defined (see iom103.h, iom128.h).
679 */
680 
681 /* The classic functions are needed for ATmega103. */
682 
683 #define __ELPM_classic__(addr) \
684 (__extension__({ \
685  uint32_t __addr32 = (uint32_t)(addr); \
686  uint8_t __result; \
687  __asm__ __volatile__ \
688  ( \
689  "out %2, %C1" "\n\t" \
690  "mov r31, %B1" "\n\t" \
691  "mov r30, %A1" "\n\t" \
692  "elpm" "\n\t" \
693  "mov %0, r0" "\n\t" \
694  : "=r" (__result) \
695  : "r" (__addr32), \
696  "I" (_SFR_IO_ADDR(RAMPZ)) \
697  : "r0", "r30", "r31" \
698  ); \
699  __result; \
700 }))
701 
702 #define __ELPM_enhanced__(addr) \
703 (__extension__({ \
704  uint32_t __addr32 = (uint32_t)(addr); \
705  uint8_t __result; \
706  __asm__ __volatile__ \
707  ( \
708  "out %2, %C1" "\n\t" \
709  "movw r30, %1" "\n\t" \
710  "elpm %0, Z+" "\n\t" \
711  : "=r" (__result) \
712  : "r" (__addr32), \
713  "I" (_SFR_IO_ADDR(RAMPZ)) \
714  : "r30", "r31" \
715  ); \
716  __result; \
717 }))
718 
719 #define __ELPM_xmega__(addr) \
720 (__extension__({ \
721  uint32_t __addr32 = (uint32_t)(addr); \
722  uint8_t __result; \
723  __asm__ __volatile__ \
724  ( \
725  "in __tmp_reg__, %2" "\n\t" \
726  "out %2, %C1" "\n\t" \
727  "movw r30, %1" "\n\t" \
728  "elpm %0, Z+" "\n\t" \
729  "out %2, __tmp_reg__" \
730  : "=r" (__result) \
731  : "r" (__addr32), \
732  "I" (_SFR_IO_ADDR(RAMPZ)) \
733  : "r30", "r31" \
734  ); \
735  __result; \
736 }))
737 
738 #define __ELPM_word_classic__(addr) \
739 (__extension__({ \
740  uint32_t __addr32 = (uint32_t)(addr); \
741  uint16_t __result; \
742  __asm__ __volatile__ \
743  ( \
744  "out %2, %C1" "\n\t" \
745  "mov r31, %B1" "\n\t" \
746  "mov r30, %A1" "\n\t" \
747  "elpm" "\n\t" \
748  "mov %A0, r0" "\n\t" \
749  "in r0, %2" "\n\t" \
750  "adiw r30, 1" "\n\t" \
751  "adc r0, __zero_reg__" "\n\t" \
752  "out %2, r0" "\n\t" \
753  "elpm" "\n\t" \
754  "mov %B0, r0" "\n\t" \
755  : "=r" (__result) \
756  : "r" (__addr32), \
757  "I" (_SFR_IO_ADDR(RAMPZ)) \
758  : "r0", "r30", "r31" \
759  ); \
760  __result; \
761 }))
762 
763 #define __ELPM_word_enhanced__(addr) \
764 (__extension__({ \
765  uint32_t __addr32 = (uint32_t)(addr); \
766  uint16_t __result; \
767  __asm__ __volatile__ \
768  ( \
769  "out %2, %C1" "\n\t" \
770  "movw r30, %1" "\n\t" \
771  "elpm %A0, Z+" "\n\t" \
772  "elpm %B0, Z" "\n\t" \
773  : "=r" (__result) \
774  : "r" (__addr32), \
775  "I" (_SFR_IO_ADDR(RAMPZ)) \
776  : "r30", "r31" \
777  ); \
778  __result; \
779 }))
780 
781 #define __ELPM_word_xmega__(addr) \
782 (__extension__({ \
783  uint32_t __addr32 = (uint32_t)(addr); \
784  uint16_t __result; \
785  __asm__ __volatile__ \
786  ( \
787  "in __tmp_reg__, %2" "\n\t" \
788  "out %2, %C1" "\n\t" \
789  "movw r30, %1" "\n\t" \
790  "elpm %A0, Z+" "\n\t" \
791  "elpm %B0, Z" "\n\t" \
792  "out %2, __tmp_reg__" \
793  : "=r" (__result) \
794  : "r" (__addr32), \
795  "I" (_SFR_IO_ADDR(RAMPZ)) \
796  : "r30", "r31" \
797  ); \
798  __result; \
799 }))
800 
801 #define __ELPM_dword_classic__(addr) \
802 (__extension__({ \
803  uint32_t __addr32 = (uint32_t)(addr); \
804  uint32_t __result; \
805  __asm__ __volatile__ \
806  ( \
807  "out %2, %C1" "\n\t" \
808  "mov r31, %B1" "\n\t" \
809  "mov r30, %A1" "\n\t" \
810  "elpm" "\n\t" \
811  "mov %A0, r0" "\n\t" \
812  "in r0, %2" "\n\t" \
813  "adiw r30, 1" "\n\t" \
814  "adc r0, __zero_reg__" "\n\t" \
815  "out %2, r0" "\n\t" \
816  "elpm" "\n\t" \
817  "mov %B0, r0" "\n\t" \
818  "in r0, %2" "\n\t" \
819  "adiw r30, 1" "\n\t" \
820  "adc r0, __zero_reg__" "\n\t" \
821  "out %2, r0" "\n\t" \
822  "elpm" "\n\t" \
823  "mov %C0, r0" "\n\t" \
824  "in r0, %2" "\n\t" \
825  "adiw r30, 1" "\n\t" \
826  "adc r0, __zero_reg__" "\n\t" \
827  "out %2, r0" "\n\t" \
828  "elpm" "\n\t" \
829  "mov %D0, r0" "\n\t" \
830  : "=r" (__result) \
831  : "r" (__addr32), \
832  "I" (_SFR_IO_ADDR(RAMPZ)) \
833  : "r0", "r30", "r31" \
834  ); \
835  __result; \
836 }))
837 
838 #define __ELPM_dword_enhanced__(addr) \
839 (__extension__({ \
840  uint32_t __addr32 = (uint32_t)(addr); \
841  uint32_t __result; \
842  __asm__ __volatile__ \
843  ( \
844  "out %2, %C1" "\n\t" \
845  "movw r30, %1" "\n\t" \
846  "elpm %A0, Z+" "\n\t" \
847  "elpm %B0, Z+" "\n\t" \
848  "elpm %C0, Z+" "\n\t" \
849  "elpm %D0, Z" "\n\t" \
850  : "=r" (__result) \
851  : "r" (__addr32), \
852  "I" (_SFR_IO_ADDR(RAMPZ)) \
853  : "r30", "r31" \
854  ); \
855  __result; \
856 }))
857 
858 #define __ELPM_dword_xmega__(addr) \
859 (__extension__({ \
860  uint32_t __addr32 = (uint32_t)(addr); \
861  uint32_t __result; \
862  __asm__ __volatile__ \
863  ( \
864  "in __tmp_reg__, %2" "\n\t" \
865  "out %2, %C1" "\n\t" \
866  "movw r30, %1" "\n\t" \
867  "elpm %A0, Z+" "\n\t" \
868  "elpm %B0, Z+" "\n\t" \
869  "elpm %C0, Z+" "\n\t" \
870  "elpm %D0, Z" "\n\t" \
871  "out %2, __tmp_reg__" \
872  : "=r" (__result) \
873  : "r" (__addr32), \
874  "I" (_SFR_IO_ADDR(RAMPZ)) \
875  : "r30", "r31" \
876  ); \
877  __result; \
878 }))
879 
880 #define __ELPM_float_classic__(addr) \
881 (__extension__({ \
882  uint32_t __addr32 = (uint32_t)(addr); \
883  float __result; \
884  __asm__ __volatile__ \
885  ( \
886  "out %2, %C1" "\n\t" \
887  "mov r31, %B1" "\n\t" \
888  "mov r30, %A1" "\n\t" \
889  "elpm" "\n\t" \
890  "mov %A0, r0" "\n\t" \
891  "in r0, %2" "\n\t" \
892  "adiw r30, 1" "\n\t" \
893  "adc r0, __zero_reg__" "\n\t" \
894  "out %2, r0" "\n\t" \
895  "elpm" "\n\t" \
896  "mov %B0, r0" "\n\t" \
897  "in r0, %2" "\n\t" \
898  "adiw r30, 1" "\n\t" \
899  "adc r0, __zero_reg__" "\n\t" \
900  "out %2, r0" "\n\t" \
901  "elpm" "\n\t" \
902  "mov %C0, r0" "\n\t" \
903  "in r0, %2" "\n\t" \
904  "adiw r30, 1" "\n\t" \
905  "adc r0, __zero_reg__" "\n\t" \
906  "out %2, r0" "\n\t" \
907  "elpm" "\n\t" \
908  "mov %D0, r0" "\n\t" \
909  : "=r" (__result) \
910  : "r" (__addr32), \
911  "I" (_SFR_IO_ADDR(RAMPZ)) \
912  : "r0", "r30", "r31" \
913  ); \
914  __result; \
915 }))
916 
917 #define __ELPM_float_enhanced__(addr) \
918 (__extension__({ \
919  uint32_t __addr32 = (uint32_t)(addr); \
920  float __result; \
921  __asm__ __volatile__ \
922  ( \
923  "out %2, %C1" "\n\t" \
924  "movw r30, %1" "\n\t" \
925  "elpm %A0, Z+" "\n\t" \
926  "elpm %B0, Z+" "\n\t" \
927  "elpm %C0, Z+" "\n\t" \
928  "elpm %D0, Z" "\n\t" \
929  : "=r" (__result) \
930  : "r" (__addr32), \
931  "I" (_SFR_IO_ADDR(RAMPZ)) \
932  : "r30", "r31" \
933  ); \
934  __result; \
935 }))
936 
937 #define __ELPM_float_xmega__(addr) \
938 (__extension__({ \
939  uint32_t __addr32 = (uint32_t)(addr); \
940  float __result; \
941  __asm__ __volatile__ \
942  ( \
943  "in __tmp_reg__, %2" "\n\t" \
944  "out %2, %C1" "\n\t" \
945  "movw r30, %1" "\n\t" \
946  "elpm %A0, Z+" "\n\t" \
947  "elpm %B0, Z+" "\n\t" \
948  "elpm %C0, Z+" "\n\t" \
949  "elpm %D0, Z" "\n\t" \
950  "out %2, __tmp_reg__" \
951  : "=r" (__result) \
952  : "r" (__addr32), \
953  "I" (_SFR_IO_ADDR(RAMPZ)) \
954  : "r30", "r31" \
955  ); \
956  __result; \
957 }))
958 
959 /*
960 Check for architectures that implement RAMPD (avrxmega3, avrxmega5,
961 avrxmega7) as they need to save/restore RAMPZ for ELPM macros so it does
962 not interfere with data accesses.
963 */
964 #if defined (__AVR_HAVE_RAMPD__)
965 
966 #define __ELPM(addr) __ELPM_xmega__(addr)
967 #define __ELPM_word(addr) __ELPM_word_xmega__(addr)
968 #define __ELPM_dword(addr) __ELPM_dword_xmega__(addr)
969 #define __ELPM_float(addr) __ELPM_float_xmega__(addr)
970 
971 #else
972 
973 #if defined (__AVR_HAVE_LPMX__)
974 
975 #define __ELPM(addr) __ELPM_enhanced__(addr)
976 #define __ELPM_word(addr) __ELPM_word_enhanced__(addr)
977 #define __ELPM_dword(addr) __ELPM_dword_enhanced__(addr)
978 #define __ELPM_float(addr) __ELPM_float_enhanced__(addr)
979 
980 #else
981 
982 #define __ELPM(addr) __ELPM_classic__(addr)
983 #define __ELPM_word(addr) __ELPM_word_classic__(addr)
984 #define __ELPM_dword(addr) __ELPM_dword_classic__(addr)
985 #define __ELPM_float(addr) __ELPM_float_classic__(addr)
986 
987 #endif /* __AVR_HAVE_LPMX__ */
988 
989 #endif /* __AVR_HAVE_RAMPD__ */
990 
991 
992 /** \ingroup avr_pgmspace
993  \def pgm_read_byte_far(address_long)
994  Read a byte from the program space with a 32-bit (far) address.
995 
996  \note The address is a byte address.
997  The address is in the program space. */
998 
999 #define pgm_read_byte_far(address_long) __ELPM((uint32_t)(address_long))
1000 
1001 /** \ingroup avr_pgmspace
1002  \def pgm_read_word_far(address_long)
1003  Read a word from the program space with a 32-bit (far) address.
1004 
1005  \note The address is a byte address.
1006  The address is in the program space. */
1007 
1008 #define pgm_read_word_far(address_long) __ELPM_word((uint32_t)(address_long))
1009 
1010 /** \ingroup avr_pgmspace
1011  \def pgm_read_dword_far(address_long)
1012  Read a double word from the program space with a 32-bit (far) address.
1013 
1014  \note The address is a byte address.
1015  The address is in the program space. */
1016 
1017 #define pgm_read_dword_far(address_long) __ELPM_dword((uint32_t)(address_long))
1018 
1019 /** \ingroup avr_pgmspace
1020  \def pgm_read_float_far(address_long)
1021  Read a float from the program space with a 32-bit (far) address.
1022 
1023  \note The address is a byte address.
1024  The address is in the program space. */
1025 
1026 #define pgm_read_float_far(address_long) __ELPM_float((uint32_t)(address_long))
1027 
1028 /** \ingroup avr_pgmspace
1029  \def pgm_read_ptr_far(address_long)
1030  Read a pointer from the program space with a 32-bit (far) address.
1031 
1032  \note The address is a byte address.
1033  The address is in the program space. */
1034 
1035 #define pgm_read_ptr_far(address_long) (void*)__ELPM_word((uint32_t)(address_long))
1036 
1037 #endif /* RAMPZ or __DOXYGEN__ */
1038 
1039 /** \ingroup avr_pgmspace
1040  \def pgm_read_byte(address_short)
1041  Read a byte from the program space with a 16-bit (near) address.
1042 
1043  \note The address is a byte address.
1044  The address is in the program space. */
1045 
1046 #define pgm_read_byte(address_short) pgm_read_byte_near(address_short)
1047 
1048 /** \ingroup avr_pgmspace
1049  \def pgm_read_word(address_short)
1050  Read a word from the program space with a 16-bit (near) address.
1051 
1052  \note The address is a byte address.
1053  The address is in the program space. */
1054 
1055 #define pgm_read_word(address_short) pgm_read_word_near(address_short)
1056 
1057 /** \ingroup avr_pgmspace
1058  \def pgm_read_dword(address_short)
1059  Read a double word from the program space with a 16-bit (near) address.
1060 
1061  \note The address is a byte address.
1062  The address is in the program space. */
1063 
1064 #define pgm_read_dword(address_short) pgm_read_dword_near(address_short)
1065 
1066 /** \ingroup avr_pgmspace
1067  \def pgm_read_float(address_short)
1068  Read a float from the program space with a 16-bit (near) address.
1069 
1070  \note The address is a byte address.
1071  The address is in the program space. */
1072 
1073 #define pgm_read_float(address_short) pgm_read_float_near(address_short)
1074 
1075 /** \ingroup avr_pgmspace
1076  \def pgm_read_ptr(address_short)
1077  Read a pointer from the program space with a 16-bit (near) address.
1078 
1079  \note The address is a byte address.
1080  The address is in the program space. */
1081 
1082 #define pgm_read_ptr(address_short) pgm_read_ptr_near(address_short)
1083 
1084 /* pgm_get_far_address() macro
1085 
1086  This macro facilitates the obtention of a 32 bit "far" pointer (only 24 bits
1087  used) to data even passed the 64KB limit for the 16 bit ordinary pointer. It
1088  is similar to the '&' operator, with some limitations.
1089 
1090  Comments:
1091 
1092  - The overhead is minimal and it's mainly due to the 32 bit size operation.
1093 
1094  - 24 bit sizes guarantees the code compatibility for use in future devices.
1095 
1096  - hh8() is an undocumented feature but seems to give the third significant byte
1097  of a 32 bit data and accepts symbols, complementing the functionality of hi8()
1098  and lo8(). There is not an equivalent assembler function to get the high
1099  significant byte.
1100 
1101  - 'var' has to be resolved at linking time as an existing symbol, i.e, a simple
1102  type variable name, an array name (not an indexed element of the array, if the
1103  index is a constant the compiler does not complain but fails to get the address
1104  if optimization is enabled), a struct name or a struct field name, a function
1105  identifier, a linker defined identifier,...
1106 
1107  - The returned value is the identifier's VMA (virtual memory address) determined
1108  by the linker and falls in the corresponding memory region. The AVR Harvard
1109  architecture requires non overlapping VMA areas for the multiple address spaces
1110  in the processor: Flash ROM, RAM, and EEPROM. Typical offset for this are
1111  0x00000000, 0x00800xx0, and 0x00810000 respectively, derived from the linker
1112  script used and linker options. The value returned can be seen then as a
1113  universal pointer.
1114 
1115 */
1116 
1117 #define pgm_get_far_address(var) \
1118 ({ \
1119  uint_farptr_t tmp; \
1120  \
1121  __asm__ __volatile__( \
1122  \
1123  "ldi %A0, lo8(%1)" "\n\t" \
1124  "ldi %B0, hi8(%1)" "\n\t" \
1125  "ldi %C0, hh8(%1)" "\n\t" \
1126  "clr %D0" "\n\t" \
1127  : \
1128  "=d" (tmp) \
1129  : \
1130  "p" (&(var)) \
1131  ); \
1132  tmp; \
1133 })
1134 
1135 
1136 
1137 extern const void * memchr_P(const void *, int __val, size_t __len) __ATTR_CONST__;
1138 extern int memcmp_P(const void *, const void *, size_t) __ATTR_PURE__;
1139 extern void *memccpy_P(void *, const void *, int __val, size_t);
1140 extern void *memcpy_P(void *, const void *, size_t);
1141 extern void *memmem_P(const void *, size_t, const void *, size_t) __ATTR_PURE__;
1142 extern const void * memrchr_P(const void *, int __val, size_t __len) __ATTR_CONST__;
1143 extern char *strcat_P(char *, const char *);
1144 extern const char * strchr_P(const char *, int __val) __ATTR_CONST__;
1145 extern const char * strchrnul_P(const char *, int __val) __ATTR_CONST__;
1146 extern int strcmp_P(const char *, const char *) __ATTR_PURE__;
1147 extern char *strcpy_P(char *, const char *);
1148 extern int strcasecmp_P(const char *, const char *) __ATTR_PURE__;
1149 extern char *strcasestr_P(const char *, const char *) __ATTR_PURE__;
1150 extern size_t strcspn_P(const char *__s, const char * __reject) __ATTR_PURE__;
1151 extern size_t strlcat_P (char *, const char *, size_t );
1152 extern size_t strlcpy_P (char *, const char *, size_t );
1153 extern size_t __strlen_P(const char *) __ATTR_CONST__; /* program memory can't change */
1154 extern size_t strnlen_P(const char *, size_t) __ATTR_CONST__; /* program memory can't change */
1155 extern int strncmp_P(const char *, const char *, size_t) __ATTR_PURE__;
1156 extern int strncasecmp_P(const char *, const char *, size_t) __ATTR_PURE__;
1157 extern char *strncat_P(char *, const char *, size_t);
1158 extern char *strncpy_P(char *, const char *, size_t);
1159 extern char *strpbrk_P(const char *__s, const char * __accept) __ATTR_PURE__;
1160 extern const char * strrchr_P(const char *, int __val) __ATTR_CONST__;
1161 extern char *strsep_P(char **__sp, const char * __delim);
1162 extern size_t strspn_P(const char *__s, const char * __accept) __ATTR_PURE__;
1163 extern char *strstr_P(const char *, const char *) __ATTR_PURE__;
1164 extern char *strtok_P(char *__s, const char * __delim);
1165 extern char *strtok_rP(char *__s, const char * __delim, char **__last);
1166 
1167 extern size_t strlen_PF (uint_farptr_t src) __ATTR_CONST__; /* program memory can't change */
1168 extern size_t strnlen_PF (uint_farptr_t src, size_t len) __ATTR_CONST__; /* program memory can't change */
1169 extern void *memcpy_PF (void *dest, uint_farptr_t src, size_t len);
1170 extern char *strcpy_PF (char *dest, uint_farptr_t src);
1171 extern char *strncpy_PF (char *dest, uint_farptr_t src, size_t len);
1172 extern char *strcat_PF (char *dest, uint_farptr_t src);
1173 extern size_t strlcat_PF (char *dst, uint_farptr_t src, size_t siz);
1174 extern char *strncat_PF (char *dest, uint_farptr_t src, size_t len);
1175 extern int strcmp_PF (const char *s1, uint_farptr_t s2) __ATTR_PURE__;
1176 extern int strncmp_PF (const char *s1, uint_farptr_t s2, size_t n) __ATTR_PURE__;
1177 extern int strcasecmp_PF (const char *s1, uint_farptr_t s2) __ATTR_PURE__;
1178 extern int strncasecmp_PF (const char *s1, uint_farptr_t s2, size_t n) __ATTR_PURE__;
1179 extern char *strstr_PF (const char *s1, uint_farptr_t s2);
1180 extern size_t strlcpy_PF (char *dst, uint_farptr_t src, size_t siz);
1181 extern int memcmp_PF(const void *, uint_farptr_t, size_t) __ATTR_PURE__;
1182 
1183 
1184 __attribute__((__always_inline__)) static __inline__ size_t strlen_P(const char * s);
1185 static __inline__ size_t strlen_P(const char *s) {
1186  return __builtin_constant_p(__builtin_strlen(s))
1187  ? __builtin_strlen(s) : __strlen_P(s);
1188 }
1189 
1190 
1191 
1192 #ifdef __cplusplus
1193 }
1194 #endif
1195 
1196 #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
signed int int16_t
Definition: stdint.h:84
signed char int8_t
Definition: stdint.h:74
#define PROGMEM
Definition: pgmspace.h:109
signed long int int32_t
Definition: stdint.h:94
int8_t PROGMEM prog_int8_t
Definition: pgmspace.h:194
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 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
unsigned int uint16_t
Definition: stdint.h:89
uint8_t PROGMEM prog_uint8_t
Definition: pgmspace.h:212
int16_t PROGMEM prog_int16_t
Definition: pgmspace.h:230

Automatically generated by Doxygen 1.8.11 on Tue Dec 24 2019.