cpu/pgm.h

Go to the documentation of this file.
00001 
00049 #ifndef MWARE_PGM_H
00050 #define MWARE_PGM_H
00051 
00052 #include <cfg/compiler.h> /* For intXX_t */
00053 #include <cpu/detect.h>
00054 #include <cpu/attr.h>     /* For CPU_HARVARD */
00055 #include <cpu/types.h>    /* For SIZEOF_INT */
00056 
00057 #if CPU_AVR
00058 
00059     #ifdef __AVR_ENHANCED__
00060         #define pgm_read_char(addr) \
00061         ({ \
00062             uint16_t __addr16 = (uint16_t)(addr); \
00063             uint8_t __result; \
00064             __asm__ \
00065             ( \
00066                 "lpm %0, Z" "\n\t" \
00067                 : "=r" (__result) \
00068                 : "z" (__addr16) \
00069             ); \
00070             __result; \
00071         })
00072         #define pgm_read_uint16_t(addr) \
00073         ({ \
00074             uint16_t __addr16 = (uint16_t)(addr); \
00075             uint16_t __result; \
00076             __asm__ \
00077             ( \
00078                 "lpm %A0, Z+"   "\n\t" \
00079                 "lpm %B0, Z"    "\n\t" \
00080                 : "=r" (__result), "=z" (__addr16) \
00081                 : "1" (__addr16) \
00082             ); \
00083             __result; \
00084         })
00085 
00086 
00087     #else /* !__AVR_ENHANCED__ */
00088 
00089         #define pgm_read_char(addr) \
00090         ({ \
00091             uint16_t __addr16 = (uint16_t)(addr); \
00092             uint8_t __result; \
00093             __asm__ \
00094             ( \
00095                 "lpm" "\n\t" \
00096                 "mov %0, r0" "\n\t" \
00097                 : "=r" (__result) \
00098                 : "z" (__addr16) \
00099                 : "r0" \
00100             ); \
00101             __result; \
00102         })
00103         #define pgm_read_uint16_t(addr) \
00104         ({ \
00105             uint16_t __addr16 = (uint16_t)(addr); \
00106             uint16_t __result; \
00107             __asm__ \
00108             ( \
00109                 "lpm"           "\n\t" \
00110                 "mov %A0, r0"   "\n\t" \
00111                 "adiw r30, 1"   "\n\t" \
00112                 "lpm"           "\n\t" \
00113                 "mov %B0, r0"   "\n\t" \
00114                 : "=r" (__result), "=z" (__addr16) \
00115                 : "1" (__addr16) \
00116                 : "r0" \
00117             ); \
00118             __result; \
00119         })
00120 
00121     #endif /* !__AVR_ENHANCED__ */
00122 
00123     #if SIZEOF_INT == 2
00124         #define pgm_read_int(addr) ((int)pgm_read_uint16_t(addr))
00125     #else
00126         #error Missing support for CPU word size != 16bit
00127     #endif
00128 
00129     #ifndef PROGMEM
00130     #define PROGMEM  __attribute__((__progmem__))
00131     #endif
00132     #ifndef PSTR
00133     #define PSTR(s) ({ static const char __c[] PROGMEM = (s); &__c[0]; })
00134     #endif
00135     #ifndef PFUNC
00136     #define PFUNC(x)      x ## _P
00137     #endif
00138 
00139 #elif CPU_HARVARD
00140     #error Missing CPU support
00141 #endif
00142 
00143 #ifndef PSTR
00144 #define PSTR            /* nothing */
00145 #endif
00146 
00147 #ifndef PFUNC
00148 #define PFUNC(x) x
00149 #endif
00150 
00151 #ifndef PROGMEM
00152 #define PROGMEM         /* nothing */
00153 #endif
00154 
00159 typedef PROGMEM char pgm_char;
00160 typedef PROGMEM int8_t pgm_int8_t;
00161 typedef PROGMEM uint8_t pgm_uint8_t;
00162 typedef PROGMEM int16_t pgm_int16_t;
00163 typedef PROGMEM uint16_t pgm_uint16_t;
00164 typedef PROGMEM int32_t pgm_int32_t;
00165 typedef PROGMEM uint32_t pgm_uint32_t;
00166 /*\}*/
00167 
00199 #ifdef _PROGMEM
00200     #define PGM_READ_CHAR(s) pgm_read_char(s)
00201     #define PGM_FUNC(x)      PFUNC(x)
00202     #define PGM_STR(x)       PSTR(x)
00203     #define PGM_ATTR         PROGMEM
00204 #else
00205     #define PGM_READ_CHAR(s) (*(s))
00206     #define PGM_FUNC(x)      x
00207     #define PGM_STR(x)       x
00208     #define PGM_ATTR         /* nothing */
00209 #endif
00210 /* \} */
00211 
00212 
00213 #endif /* MWARE_PGM_H */