83 #define __PGMSPACE_H_ 1
90 #ifndef __ATTR_CONST__
91 #define __ATTR_CONST__ __attribute__((__const__))
94 #ifndef __ATTR_PROGMEM__
95 #define __ATTR_PROGMEM__ __attribute__((__progmem__))
99 #define __ATTR_PURE__ __attribute__((__pure__))
109 #define PROGMEM __ATTR_PROGMEM__
115 #if defined(__DOXYGEN__)
335 #define PGM_P const char *
344 #define PGM_VOID_P const void *
347 #elif defined(__PROG_TYPES_COMPAT__)
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.")));
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.")));
364 #define PGM_P const prog_char *
368 #define PGM_VOID_P const prog_void *
374 #define PGM_P const char *
378 #define PGM_VOID_P const void *
392 #if defined(__DOXYGEN__)
401 # define PSTR(s) ((const PROGMEM char *)(s))
404 # define PSTR(s) (__extension__({static const char __c[] PROGMEM = (s); &__c[0];}))
407 #define __LPM_classic__(addr) \
409 uint16_t __addr16 = (uint16_t)(addr); \
414 "mov %0, r0" "\n\t" \
422 #define __LPM_tiny__(addr) \
424 uint16_t __addr16 = (uint16_t)(addr) + __AVR_TINY_PM_BASE_ADDRESS__; \
435 #define __LPM_enhanced__(addr) \
437 uint16_t __addr16 = (uint16_t)(addr); \
448 #define __LPM_word_classic__(addr) \
450 uint16_t __addr16 = (uint16_t)(addr); \
455 "mov %A0, r0" "\n\t" \
456 "adiw r30, 1" "\n\t" \
458 "mov %B0, r0" "\n\t" \
459 : "=r" (__result), "=z" (__addr16) \
466 #define __LPM_word_tiny__(addr) \
468 uint16_t __addr16 = (uint16_t)(addr) + __AVR_TINY_PM_BASE_ADDRESS__; \
472 "ld %A0, z+" "\n\t" \
474 : "=r" (__result), "=z" (__addr16) \
480 #define __LPM_word_enhanced__(addr) \
482 uint16_t __addr16 = (uint16_t)(addr); \
486 "lpm %A0, Z+" "\n\t" \
487 "lpm %B0, Z" "\n\t" \
488 : "=r" (__result), "=z" (__addr16) \
494 #define __LPM_dword_classic__(addr) \
496 uint16_t __addr16 = (uint16_t)(addr); \
501 "mov %A0, r0" "\n\t" \
502 "adiw r30, 1" "\n\t" \
504 "mov %B0, r0" "\n\t" \
505 "adiw r30, 1" "\n\t" \
507 "mov %C0, r0" "\n\t" \
508 "adiw r30, 1" "\n\t" \
510 "mov %D0, r0" "\n\t" \
511 : "=r" (__result), "=z" (__addr16) \
518 #define __LPM_dword_tiny__(addr) \
520 uint16_t __addr16 = (uint16_t)(addr) + __AVR_TINY_PM_BASE_ADDRESS__; \
524 "ld %A0, z+" "\n\t" \
525 "ld %B0, z+" "\n\t" \
526 "ld %C0, z+" "\n\t" \
528 : "=r" (__result), "=z" (__addr16) \
534 #define __LPM_dword_enhanced__(addr) \
536 uint16_t __addr16 = (uint16_t)(addr); \
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) \
550 #define __LPM_float_classic__(addr) \
552 uint16_t __addr16 = (uint16_t)(addr); \
557 "mov %A0, r0" "\n\t" \
558 "adiw r30, 1" "\n\t" \
560 "mov %B0, r0" "\n\t" \
561 "adiw r30, 1" "\n\t" \
563 "mov %C0, r0" "\n\t" \
564 "adiw r30, 1" "\n\t" \
566 "mov %D0, r0" "\n\t" \
567 : "=r" (__result), "=z" (__addr16) \
574 #define __LPM_float_tiny__(addr) \
576 uint16_t __addr16 = (uint16_t)(addr) + __AVR_TINY_PM_BASE_ADDRESS__; \
580 "ld %A0, z+" "\n\t" \
581 "ld %B0, z+" "\n\t" \
582 "ld %C0, z+" "\n\t" \
584 : "=r" (__result), "=z" (__addr16) \
590 #define __LPM_float_enhanced__(addr) \
592 uint16_t __addr16 = (uint16_t)(addr); \
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) \
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)
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)
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)
638 #define pgm_read_byte_near(address_short) __LPM((uint16_t)(address_short))
646 #define pgm_read_word_near(address_short) __LPM_word((uint16_t)(address_short))
654 #define pgm_read_dword_near(address_short) \
655 __LPM_dword((uint16_t)(address_short))
663 #define pgm_read_float_near(address_short) \
664 __LPM_float((uint16_t)(address_short))
666 #if defined(RAMPZ) || defined(__DOXYGEN__)
674 #define __ELPM_classic__(addr) \
676 uint32_t __addr32 = (uint32_t)(addr); \
680 "out %2, %C1" "\n\t" \
681 "mov r31, %B1" "\n\t" \
682 "mov r30, %A1" "\n\t" \
684 "mov %0, r0" "\n\t" \
687 "I" (_SFR_IO_ADDR(RAMPZ)) \
688 : "r0", "r30", "r31" \
693 #define __ELPM_enhanced__(addr) \
695 uint32_t __addr32 = (uint32_t)(addr); \
699 "out %2, %C1" "\n\t" \
700 "movw r30, %1" "\n\t" \
701 "elpm %0, Z+" "\n\t" \
704 "I" (_SFR_IO_ADDR(RAMPZ)) \
710 #define __ELPM_xmega__(addr) \
712 uint32_t __addr32 = (uint32_t)(addr); \
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__" \
723 "I" (_SFR_IO_ADDR(RAMPZ)) \
729 #define __ELPM_word_classic__(addr) \
731 uint32_t __addr32 = (uint32_t)(addr); \
735 "out %2, %C1" "\n\t" \
736 "mov r31, %B1" "\n\t" \
737 "mov r30, %A1" "\n\t" \
739 "mov %A0, r0" "\n\t" \
741 "adiw r30, 1" "\n\t" \
742 "adc r0, __zero_reg__" "\n\t" \
743 "out %2, r0" "\n\t" \
745 "mov %B0, r0" "\n\t" \
748 "I" (_SFR_IO_ADDR(RAMPZ)) \
749 : "r0", "r30", "r31" \
754 #define __ELPM_word_enhanced__(addr) \
756 uint32_t __addr32 = (uint32_t)(addr); \
760 "out %2, %C1" "\n\t" \
761 "movw r30, %1" "\n\t" \
762 "elpm %A0, Z+" "\n\t" \
763 "elpm %B0, Z" "\n\t" \
766 "I" (_SFR_IO_ADDR(RAMPZ)) \
772 #define __ELPM_word_xmega__(addr) \
774 uint32_t __addr32 = (uint32_t)(addr); \
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__" \
786 "I" (_SFR_IO_ADDR(RAMPZ)) \
792 #define __ELPM_dword_classic__(addr) \
794 uint32_t __addr32 = (uint32_t)(addr); \
798 "out %2, %C1" "\n\t" \
799 "mov r31, %B1" "\n\t" \
800 "mov r30, %A1" "\n\t" \
802 "mov %A0, r0" "\n\t" \
804 "adiw r30, 1" "\n\t" \
805 "adc r0, __zero_reg__" "\n\t" \
806 "out %2, r0" "\n\t" \
808 "mov %B0, r0" "\n\t" \
810 "adiw r30, 1" "\n\t" \
811 "adc r0, __zero_reg__" "\n\t" \
812 "out %2, r0" "\n\t" \
814 "mov %C0, r0" "\n\t" \
816 "adiw r30, 1" "\n\t" \
817 "adc r0, __zero_reg__" "\n\t" \
818 "out %2, r0" "\n\t" \
820 "mov %D0, r0" "\n\t" \
823 "I" (_SFR_IO_ADDR(RAMPZ)) \
824 : "r0", "r30", "r31" \
829 #define __ELPM_dword_enhanced__(addr) \
831 uint32_t __addr32 = (uint32_t)(addr); \
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" \
843 "I" (_SFR_IO_ADDR(RAMPZ)) \
849 #define __ELPM_dword_xmega__(addr) \
851 uint32_t __addr32 = (uint32_t)(addr); \
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__" \
865 "I" (_SFR_IO_ADDR(RAMPZ)) \
871 #define __ELPM_float_classic__(addr) \
873 uint32_t __addr32 = (uint32_t)(addr); \
877 "out %2, %C1" "\n\t" \
878 "mov r31, %B1" "\n\t" \
879 "mov r30, %A1" "\n\t" \
881 "mov %A0, r0" "\n\t" \
883 "adiw r30, 1" "\n\t" \
884 "adc r0, __zero_reg__" "\n\t" \
885 "out %2, r0" "\n\t" \
887 "mov %B0, r0" "\n\t" \
889 "adiw r30, 1" "\n\t" \
890 "adc r0, __zero_reg__" "\n\t" \
891 "out %2, r0" "\n\t" \
893 "mov %C0, r0" "\n\t" \
895 "adiw r30, 1" "\n\t" \
896 "adc r0, __zero_reg__" "\n\t" \
897 "out %2, r0" "\n\t" \
899 "mov %D0, r0" "\n\t" \
902 "I" (_SFR_IO_ADDR(RAMPZ)) \
903 : "r0", "r30", "r31" \
908 #define __ELPM_float_enhanced__(addr) \
910 uint32_t __addr32 = (uint32_t)(addr); \
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" \
922 "I" (_SFR_IO_ADDR(RAMPZ)) \
928 #define __ELPM_float_xmega__(addr) \
930 uint32_t __addr32 = (uint32_t)(addr); \
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__" \
944 "I" (_SFR_IO_ADDR(RAMPZ)) \
955 #if defined (__AVR_HAVE_RAMPD__)
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)
964 #if defined (__AVR_HAVE_LPMX__)
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)
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)
990 #define pgm_read_byte_far(address_long) __ELPM((uint32_t)(address_long))
999 #define pgm_read_word_far(address_long) __ELPM_word((uint32_t)(address_long))
1008 #define pgm_read_dword_far(address_long) __ELPM_dword((uint32_t)(address_long))
1017 #define pgm_read_float_far(address_long) __ELPM_float((uint32_t)(address_long))
1028 #define pgm_read_byte(address_short) pgm_read_byte_near(address_short)
1037 #define pgm_read_word(address_short) pgm_read_word_near(address_short)
1046 #define pgm_read_dword(address_short) pgm_read_dword_near(address_short)
1055 #define pgm_read_float(address_short) pgm_read_float_near(address_short)
1090 #define pgm_get_far_address(var) \
1092 uint_farptr_t tmp; \
1094 __asm__ __volatile__( \
1096 "ldi %A0, lo8(%1)" "\n\t" \
1097 "ldi %B0, hi8(%1)" "\n\t" \
1098 "ldi %C0, hh8(%1)" "\n\t" \
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__;
1127 extern
size_t strnlen_P(const
char *,
size_t) __ATTR_CONST__;
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);
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);