pgmspace.h Source File

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_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__ \
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__ \
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__ \
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__ \
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__ \
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__ \
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__ \
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 #if defined(RAMPZ) || defined(__DOXYGEN__)
667
668 /* Only for devices with more than 64K of program memory.
669 RAMPZ must be defined (see iom103.h, iom128.h).
670 */
671
672 /* The classic functions are needed for ATmega103. */
673
674 #define __ELPM_classic__(addr) \
675 (__extension__({ \
676 uint32_t __addr32 = (uint32_t)(addr); \
677 uint8_t __result; \
678 __asm__ \
679 ( \
680 "out %2, %C1" "\n\t" \
681 "mov r31, %B1" "\n\t" \
682 "mov r30, %A1" "\n\t" \
683 "elpm" "\n\t" \
684 "mov %0, r0" "\n\t" \
685 : "=r" (__result) \
686 : "r" (__addr32), \
687 "I" (_SFR_IO_ADDR(RAMPZ)) \
688 : "r0", "r30", "r31" \
689 ); \
690 __result; \
691 }))
692
693 #define __ELPM_enhanced__(addr) \
694 (__extension__({ \
695 uint32_t __addr32 = (uint32_t)(addr); \
696 uint8_t __result; \
697 __asm__ \
698 ( \
699 "out %2, %C1" "\n\t" \
700 "movw r30, %1" "\n\t" \
701 "elpm %0, Z+" "\n\t" \
702 : "=r" (__result) \
703 : "r" (__addr32), \
704 "I" (_SFR_IO_ADDR(RAMPZ)) \
705 : "r30", "r31" \
706 ); \
707 __result; \
708 }))
709
710 #define __ELPM_xmega__(addr) \
711 (__extension__({ \
712 uint32_t __addr32 = (uint32_t)(addr); \
713 uint8_t __result; \
714 __asm__ \
715 ( \
716 "in __tmp_reg__, %2" "\n\t" \
717 "out %2, %C1" "\n\t" \
718 "movw r30, %1" "\n\t" \
719 "elpm %0, Z+" "\n\t" \
720 "out %2, __tmp_reg__" \
721 : "=r" (__result) \
722 : "r" (__addr32), \
723 "I" (_SFR_IO_ADDR(RAMPZ)) \
724 : "r30", "r31" \
725 ); \
726 __result; \
727 }))
728
729 #define __ELPM_word_classic__(addr) \
730 (__extension__({ \
731 uint32_t __addr32 = (uint32_t)(addr); \
732 uint16_t __result; \
733 __asm__ \
734 ( \
735 "out %2, %C1" "\n\t" \
736 "mov r31, %B1" "\n\t" \
737 "mov r30, %A1" "\n\t" \
738 "elpm" "\n\t" \
739 "mov %A0, r0" "\n\t" \
740 "in r0, %2" "\n\t" \
741 "adiw r30, 1" "\n\t" \
742 "adc r0, __zero_reg__" "\n\t" \
743 "out %2, r0" "\n\t" \
744 "elpm" "\n\t" \
745 "mov %B0, r0" "\n\t" \
746 : "=r" (__result) \
747 : "r" (__addr32), \
748 "I" (_SFR_IO_ADDR(RAMPZ)) \
749 : "r0", "r30", "r31" \
750 ); \
751 __result; \
752 }))
753
754 #define __ELPM_word_enhanced__(addr) \
755 (__extension__({ \
756 uint32_t __addr32 = (uint32_t)(addr); \
757 uint16_t __result; \
758 __asm__ \
759 ( \
760 "out %2, %C1" "\n\t" \
761 "movw r30, %1" "\n\t" \
762 "elpm %A0, Z+" "\n\t" \
763 "elpm %B0, Z" "\n\t" \
764 : "=r" (__result) \
765 : "r" (__addr32), \
766 "I" (_SFR_IO_ADDR(RAMPZ)) \
767 : "r30", "r31" \
768 ); \
769 __result; \
770 }))
771
772 #define __ELPM_word_xmega__(addr) \
773 (__extension__({ \
774 uint32_t __addr32 = (uint32_t)(addr); \
775 uint16_t __result; \
776 __asm__ \
777 ( \
778 "in __tmp_reg__, %2" "\n\t" \
779 "out %2, %C1" "\n\t" \
780 "movw r30, %1" "\n\t" \
781 "elpm %A0, Z+" "\n\t" \
782 "elpm %B0, Z" "\n\t" \
783 "out %2, __tmp_reg__" \
784 : "=r" (__result) \
785 : "r" (__addr32), \
786 "I" (_SFR_IO_ADDR(RAMPZ)) \
787 : "r30", "r31" \
788 ); \
789 __result; \
790 }))
791
792 #define __ELPM_dword_classic__(addr) \
793 (__extension__({ \
794 uint32_t __addr32 = (uint32_t)(addr); \
795 uint32_t __result; \
796 __asm__ \
797 ( \
798 "out %2, %C1" "\n\t" \
799 "mov r31, %B1" "\n\t" \
800 "mov r30, %A1" "\n\t" \
801 "elpm" "\n\t" \
802 "mov %A0, r0" "\n\t" \
803 "in r0, %2" "\n\t" \
804 "adiw r30, 1" "\n\t" \
805 "adc r0, __zero_reg__" "\n\t" \
806 "out %2, r0" "\n\t" \
807 "elpm" "\n\t" \
808 "mov %B0, 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 %C0, 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 %D0, r0" "\n\t" \
821 : "=r" (__result) \
822 : "r" (__addr32), \
823 "I" (_SFR_IO_ADDR(RAMPZ)) \
824 : "r0", "r30", "r31" \
825 ); \
826 __result; \
827 }))
828
829 #define __ELPM_dword_enhanced__(addr) \
830 (__extension__({ \
831 uint32_t __addr32 = (uint32_t)(addr); \
832 uint32_t __result; \
833 __asm__ \
834 ( \
835 "out %2, %C1" "\n\t" \
836 "movw r30, %1" "\n\t" \
837 "elpm %A0, Z+" "\n\t" \
838 "elpm %B0, Z+" "\n\t" \
839 "elpm %C0, Z+" "\n\t" \
840 "elpm %D0, Z" "\n\t" \
841 : "=r" (__result) \
842 : "r" (__addr32), \
843 "I" (_SFR_IO_ADDR(RAMPZ)) \
844 : "r30", "r31" \
845 ); \
846 __result; \
847 }))
848
849 #define __ELPM_dword_xmega__(addr) \
850 (__extension__({ \
851 uint32_t __addr32 = (uint32_t)(addr); \
852 uint32_t __result; \
853 __asm__ \
854 ( \
855 "in __tmp_reg__, %2" "\n\t" \
856 "out %2, %C1" "\n\t" \
857 "movw r30, %1" "\n\t" \
858 "elpm %A0, Z+" "\n\t" \
859 "elpm %B0, Z+" "\n\t" \
860 "elpm %C0, Z+" "\n\t" \
861 "elpm %D0, Z" "\n\t" \
862 "out %2, __tmp_reg__" \
863 : "=r" (__result) \
864 : "r" (__addr32), \
865 "I" (_SFR_IO_ADDR(RAMPZ)) \
866 : "r30", "r31" \
867 ); \
868 __result; \
869 }))
870
871 #define __ELPM_float_classic__(addr) \
872 (__extension__({ \
873 uint32_t __addr32 = (uint32_t)(addr); \
874 float __result; \
875 __asm__ \
876 ( \
877 "out %2, %C1" "\n\t" \
878 "mov r31, %B1" "\n\t" \
879 "mov r30, %A1" "\n\t" \
880 "elpm" "\n\t" \
881 "mov %A0, r0" "\n\t" \
882 "in r0, %2" "\n\t" \
883 "adiw r30, 1" "\n\t" \
884 "adc r0, __zero_reg__" "\n\t" \
885 "out %2, r0" "\n\t" \
886 "elpm" "\n\t" \
887 "mov %B0, r0" "\n\t" \
888 "in r0, %2" "\n\t" \
889 "adiw r30, 1" "\n\t" \
890 "adc r0, __zero_reg__" "\n\t" \
891 "out %2, r0" "\n\t" \
892 "elpm" "\n\t" \
893 "mov %C0, r0" "\n\t" \
894 "in r0, %2" "\n\t" \
895 "adiw r30, 1" "\n\t" \
896 "adc r0, __zero_reg__" "\n\t" \
897 "out %2, r0" "\n\t" \
898 "elpm" "\n\t" \
899 "mov %D0, r0" "\n\t" \
900 : "=r" (__result) \
901 : "r" (__addr32), \
902 "I" (_SFR_IO_ADDR(RAMPZ)) \
903 : "r0", "r30", "r31" \
904 ); \
905 __result; \
906 }))
907
908 #define __ELPM_float_enhanced__(addr) \
909 (__extension__({ \
910 uint32_t __addr32 = (uint32_t)(addr); \
911 float __result; \
912 __asm__ \
913 ( \
914 "out %2, %C1" "\n\t" \
915 "movw r30, %1" "\n\t" \
916 "elpm %A0, Z+" "\n\t" \
917 "elpm %B0, Z+" "\n\t" \
918 "elpm %C0, Z+" "\n\t" \
919 "elpm %D0, Z" "\n\t" \
920 : "=r" (__result) \
921 : "r" (__addr32), \
922 "I" (_SFR_IO_ADDR(RAMPZ)) \
923 : "r30", "r31" \
924 ); \
925 __result; \
926 }))
927
928 #define __ELPM_float_xmega__(addr) \
929 (__extension__({ \
930 uint32_t __addr32 = (uint32_t)(addr); \
931 float __result; \
932 __asm__ \
933 ( \
934 "in __tmp_reg__, %2" "\n\t" \
935 "out %2, %C1" "\n\t" \
936 "movw r30, %1" "\n\t" \
937 "elpm %A0, Z+" "\n\t" \
938 "elpm %B0, Z+" "\n\t" \
939 "elpm %C0, Z+" "\n\t" \
940 "elpm %D0, Z" "\n\t" \
941 "out %2, __tmp_reg__" \
942 : "=r" (__result) \
943 : "r" (__addr32), \
944 "I" (_SFR_IO_ADDR(RAMPZ)) \
945 : "r30", "r31" \
946 ); \
947 __result; \
948 }))
949
950 /*
951 Check for architectures that implement RAMPD (avrxmega3, avrxmega5,
952 avrxmega7) as they need to save/restore RAMPZ for ELPM macros so it does
953 not interfere with data accesses.
954 */
955 #if defined (__AVR_HAVE_RAMPD__)
956
957 #define __ELPM(addr) __ELPM_xmega__(addr)
958 #define __ELPM_word(addr) __ELPM_word_xmega__(addr)
959 #define __ELPM_dword(addr) __ELPM_dword_xmega__(addr)
960 #define __ELPM_float(addr) __ELPM_float_xmega__(addr)
961
962 #else
963
964 #if defined (__AVR_HAVE_LPMX__)
965
966 #define __ELPM(addr) __ELPM_enhanced__(addr)
967 #define __ELPM_word(addr) __ELPM_word_enhanced__(addr)
968 #define __ELPM_dword(addr) __ELPM_dword_enhanced__(addr)
969 #define __ELPM_float(addr) __ELPM_float_enhanced__(addr)
970
971 #else
972
973 #define __ELPM(addr) __ELPM_classic__(addr)
974 #define __ELPM_word(addr) __ELPM_word_classic__(addr)
975 #define __ELPM_dword(addr) __ELPM_dword_classic__(addr)
976 #define __ELPM_float(addr) __ELPM_float_classic__(addr)
977
978 #endif /* __AVR_HAVE_LPMX__ */
979
980 #endif /* __AVR_HAVE_RAMPD__ */
981
982
983 /** \ingroup avr_pgmspace
984 \def pgm_read_byte_far(address_long)
985 Read a byte from the program space with a 32-bit (far) address.
986
987 \note The address is a byte address.
988 The address is in the program space. */
989
990 #define pgm_read_byte_far(address_long) __ELPM((uint32_t)(address_long))
991
992 /** \ingroup avr_pgmspace
993 \def pgm_read_word_far(address_long)
994 Read a word 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_word_far(address_long) __ELPM_word((uint32_t)(address_long))
1000
1001 /** \ingroup avr_pgmspace
1002 \def pgm_read_dword_far(address_long)
1003 Read a double 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_dword_far(address_long) __ELPM_dword((uint32_t)(address_long))
1009
1010 /** \ingroup avr_pgmspace
1011 \def pgm_read_float_far(address_long)
1012 Read a float 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_float_far(address_long) __ELPM_float((uint32_t)(address_long))
1018
1019 #endif /* RAMPZ or __DOXYGEN__ */
1020
1021 /** \ingroup avr_pgmspace
1022 \def pgm_read_byte(address_short)
1023 Read a byte from the program space with a 16-bit (near) address.
1024
1025 \note The address is a byte address.
1026 The address is in the program space. */
1027
1028 #define pgm_read_byte(address_short) pgm_read_byte_near(address_short)
1029
1030 /** \ingroup avr_pgmspace
1031 \def pgm_read_word(address_short)
1032 Read a word from the program space with a 16-bit (near) address.
1033
1034 \note The address is a byte address.
1035 The address is in the program space. */
1036
1037 #define pgm_read_word(address_short) pgm_read_word_near(address_short)
1038
1039 /** \ingroup avr_pgmspace
1040 \def pgm_read_dword(address_short)
1041 Read a double word 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_dword(address_short) pgm_read_dword_near(address_short)
1047
1048 /** \ingroup avr_pgmspace
1049 \def pgm_read_float(address_short)
1050 Read a float 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_float(address_short) pgm_read_float_near(address_short)
1056
1057 /* pgm_get_far_address() macro
1058
1059 This macro facilitates the obtention of a 32 bit "far" pointer (only 24 bits
1060 used) to data even passed the 64KB limit for the 16 bit ordinary pointer. It
1061 is similar to the '&' operator, with some limitations.
1062
1063 Comments:
1064
1065 - The overhead is minimal and it's mainly due to the 32 bit size operation.
1066
1067 - 24 bit sizes guarantees the code compatibility for use in future devices.
1068
1069 - hh8() is an undocumented feature but seems to give the third significant byte
1070 of a 32 bit data and accepts symbols, complementing the functionality of hi8()
1071 and lo8(). There is not an equivalent assembler function to get the high
1072 significant byte.
1073
1074 - 'var' has to be resolved at linking time as an existing symbol, i.e, a simple
1075 type variable name, an array name (not an indexed element of the array, if the
1076 index is a constant the compiler does not complain but fails to get the address
1077 if optimization is enabled), a struct name or a struct field name, a function
1078 identifier, a linker defined identifier,...
1079
1080 - The returned value is the identifier's VMA (virtual memory address) determined
1081 by the linker and falls in the corresponding memory region. The AVR Harvard
1082 architecture requires non overlapping VMA areas for the multiple address spaces
1083 in the processor: Flash ROM, RAM, and EEPROM. Typical offset for this are
1084 0x00000000, 0x00800xx0, and 0x00810000 respectively, derived from the linker
1085 script used and linker options. The value returned can be seen then as a
1086 universal pointer.
1087
1088 */
1089
1090 #define pgm_get_far_address(var) \
1091 ({ \
1092 uint_farptr_t tmp; \
1093 \
1094 __asm__ __volatile__( \
1095 \
1096 "ldi %A0, lo8(%1)" "\n\t" \
1097 "ldi %B0, hi8(%1)" "\n\t" \
1098 "ldi %C0, hh8(%1)" "\n\t" \
1099 "clr %D0" "\n\t" \
1100 : \
1101 "=d" (tmp) \
1102 : \
1103 "p" (&(var)) \
1104 ); \
1105 tmp; \
1106 })
1107
1108
1109
1110 extern const void * memchr_P(const void *, int __val, size_t __len) __ATTR_CONST__;
1111 extern int memcmp_P(const void *, const void *, size_t) __ATTR_PURE__;
1112 extern void *memccpy_P(void *, const void *, int __val, size_t);
1113 extern void *memcpy_P(void *, const void *, size_t);
1114 extern void *memmem_P(const void *, size_t, const void *, size_t) __ATTR_PURE__;
1115 extern const void * memrchr_P(const void *, int __val, size_t __len) __ATTR_CONST__;
1116 extern char *strcat_P(char *, const char *);
1117 extern const char * strchr_P(const char *, int __val) __ATTR_CONST__;
1118 extern const char * strchrnul_P(const char *, int __val) __ATTR_CONST__;
1119 extern int strcmp_P(const char *, const char *) __ATTR_PURE__;
1120 extern char *strcpy_P(char *, const char *);
1121 extern int strcasecmp_P(const char *, const char *) __ATTR_PURE__;
1122 extern char *strcasestr_P(const char *, const char *) __ATTR_PURE__;
1123 extern size_t strcspn_P(const char *__s, const char * __reject) __ATTR_PURE__;
1124 extern size_t strlcat_P (char *, const char *, size_t );
1125 extern size_t strlcpy_P (char *, const char *, size_t );
1126 extern size_t __strlen_P(const char *) __ATTR_CONST__; /* program memory can't change */
1127 extern size_t strnlen_P(const char *, size_t) __ATTR_CONST__; /* program memory can't change */
1128 extern int strncmp_P(const char *, const char *, size_t) __ATTR_PURE__;
1129 extern int strncasecmp_P(const char *, const char *, size_t) __ATTR_PURE__;
1130 extern char *strncat_P(char *, const char *, size_t);
1131 extern char *strncpy_P(char *, const char *, size_t);
1132 extern char *strpbrk_P(const char *__s, const char * __accept) __ATTR_PURE__;
1133 extern const char * strrchr_P(const char *, int __val) __ATTR_CONST__;
1134 extern char *strsep_P(char **__sp, const char * __delim);
1135 extern size_t strspn_P(const char *__s, const char * __accept) __ATTR_PURE__;
1136 extern char *strstr_P(const char *, const char *) __ATTR_PURE__;
1137 extern char *strtok_P(char *__s, const char * __delim);
1138 extern char *strtok_rP(char *__s, const char * __delim, char **__last);
1139
1140 extern size_t strlen_PF (uint_farptr_t src) __ATTR_CONST__; /* program memory can't change */
1141 extern size_t strnlen_PF (uint_farptr_t src, size_t len) __ATTR_CONST__; /* program memory can't change */
1142 extern void *memcpy_PF (void *dest, uint_farptr_t src, size_t len);
1143 extern char *strcpy_PF (char *dest, uint_farptr_t src);
1144 extern char *strncpy_PF (char *dest, uint_farptr_t src, size_t len);
1145 extern char *strcat_PF (char *dest, uint_farptr_t src);
1146 extern size_t strlcat_PF (char *dst, uint_farptr_t src, size_t siz);
1147 extern char *strncat_PF (char *dest, uint_farptr_t src, size_t len);
1148 extern int strcmp_PF (const char *s1, uint_farptr_t s2) __ATTR_PURE__;
1149 extern int strncmp_PF (const char *s1, uint_farptr_t s2, size_t n) __ATTR_PURE__;
1150 extern int strcasecmp_PF (const char *s1, uint_farptr_t s2) __ATTR_PURE__;
1151 extern int strncasecmp_PF (const char *s1, uint_farptr_t s2, size_t n) __ATTR_PURE__;
1152 extern char *strstr_PF (const char *s1, uint_farptr_t s2);
1153 extern size_t strlcpy_PF (char *dst, uint_farptr_t src, size_t siz);
1154 extern int memcmp_PF(const void *, uint_farptr_t, size_t) __ATTR_PURE__;
1155
1156
1157 __attribute__((__always_inline__)) static inline size_t strlen_P(const char * s);
1158 static inline size_t strlen_P(const char *s) {
1159 return __builtin_constant_p(__builtin_strlen(s))
1160 ? __builtin_strlen(s) : __strlen_P(s);
1161 }
1162
1163
1164
1165 #ifdef __cplusplus
1166 }
1167 #endif
1168
1169 #endif /* __PGMSPACE_H_ */

Automatically generated by Doxygen 1.8.1.1 on Fri Aug 17 2012.