cpu/pgm.h
Go to the documentation of this file.00001
00048 #ifndef MWARE_PGM_H
00049 #define MWARE_PGM_H
00050
00051 #include <cfg/compiler.h>
00052 #include <cpu/detect.h>
00053 #include <cpu/attr.h>
00054 #include <cpu/types.h>
00055
00056 #if CPU_AVR
00057
00058 #ifdef __AVR_ENHANCED__
00059 #define pgm_read8(addr) \
00060 ({ \
00061 uint16_t __addr16 = (uint16_t)(addr); \
00062 uint8_t __result; \
00063 __asm__ \
00064 ( \
00065 "lpm %0, Z" "\n\t" \
00066 : "=r" (__result) \
00067 : "z" (__addr16) \
00068 ); \
00069 __result; \
00070 })
00071 #define pgm_read16(addr) \
00072 ({ \
00073 uint16_t __addr16 = (uint16_t)(addr); \
00074 uint16_t __result; \
00075 __asm__ \
00076 ( \
00077 "lpm %A0, Z+" "\n\t" \
00078 "lpm %B0, Z" "\n\t" \
00079 : "=r" (__result), "=z" (__addr16) \
00080 : "1" (__addr16) \
00081 ); \
00082 __result; \
00083 })
00084
00085
00086 #else
00087
00088 #define pgm_read8(addr) \
00089 ({ \
00090 uint16_t __addr16 = (uint16_t)(addr); \
00091 uint8_t __result; \
00092 __asm__ \
00093 ( \
00094 "lpm" "\n\t" \
00095 "mov %0, r0" "\n\t" \
00096 : "=r" (__result) \
00097 : "z" (__addr16) \
00098 : "r0" \
00099 ); \
00100 __result; \
00101 })
00102 #define pgm_read16(addr) \
00103 ({ \
00104 uint16_t __addr16 = (uint16_t)(addr); \
00105 uint16_t __result; \
00106 __asm__ \
00107 ( \
00108 "lpm" "\n\t" \
00109 "mov %A0, r0" "\n\t" \
00110 "adiw r30, 1" "\n\t" \
00111 "lpm" "\n\t" \
00112 "mov %B0, r0" "\n\t" \
00113 : "=r" (__result), "=z" (__addr16) \
00114 : "1" (__addr16) \
00115 : "r0" \
00116 ); \
00117 __result; \
00118 })
00119
00120 #endif
00121
00122 #define pgm_read32(addr) ((uint32_t)(pgm_read16(addr) | (((uint32_t)pgm_read16(((const uint8_t *)(addr)) + 2)) << 16)))
00123 #ifndef PROGMEM
00124 #define PROGMEM __attribute__((__progmem__))
00125 #endif
00126 #ifndef PSTR
00127 #define PSTR(s) ({ static const char __c[] PROGMEM = (s); &__c[0]; })
00128 #endif
00129 #ifndef PFUNC
00130 #define PFUNC(x) x ## _P
00131 #endif
00132
00133 #elif CPU_HARVARD
00134 #error Missing CPU support
00135 #endif
00136
00137
00138 #if !CPU_HARVARD
00139 #define pgm_read8(a) (*(const uint8_t *)(a))
00140 #define pgm_read16(a) (*(const uint16_t *)(a))
00141 #define pgm_read32(a) (*(const uint32_t *)(a))
00142 #endif
00143
00144 #define pgm_read_char(a) pgm_read8(a)
00145 #define pgm_read_uint16_t(addr) pgm_read16(addr)
00146
00147
00148 #if SIZEOF_INT == 2
00149 #define pgm_read_int(addr) ((int)pgm_read16(addr))
00150 #elif SIZEOF_INT == 4
00151 #define pgm_read_int(addr) ((int)pgm_read32(addr))
00152 #else
00153 #error Missing support for CPU word size!
00154 #endif
00155
00156 #ifndef PSTR
00157 #define PSTR
00158 #endif
00159
00160 #ifndef PFUNC
00161 #define PFUNC(x) x
00162 #endif
00163
00164 #ifndef PROGMEM
00165 #define PROGMEM
00166 #endif
00167
00172 typedef PROGMEM char pgm_char;
00173 typedef PROGMEM int8_t pgm_int8_t;
00174 typedef PROGMEM uint8_t pgm_uint8_t;
00175 typedef PROGMEM int16_t pgm_int16_t;
00176 typedef PROGMEM uint16_t pgm_uint16_t;
00177 typedef PROGMEM int32_t pgm_int32_t;
00178 typedef PROGMEM uint32_t pgm_uint32_t;
00179
00180
00212 #ifdef _PROGMEM
00213 #define PGM_READ8(a) pgm_read8(a)
00214 #define PGM_READ16(a) pgm_read16(a)
00215 #define PGM_READ32(a) pgm_read32(a)
00216 #define PGM_FUNC(x) PFUNC(x)
00217 #define PGM_STR(x) PSTR(x)
00218 #define PGM_ATTR PROGMEM
00219 #else
00220 #define PGM_READ8(a) (*(const uint8_t *)(a))
00221 #define PGM_READ16(a) (*(const uint16_t *)(a))
00222 #define PGM_READ32(a) (*(const uint32_t *)(a))
00223 #define PGM_FUNC(x) x
00224 #define PGM_STR(x) x
00225 #define PGM_ATTR
00226 #endif
00227
00228 #define PGM_READ_CHAR(addr) PGM_READ8(addr)
00229
00230
00231
00232
00233 #endif