BeRTOS
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> /* For intXX_t */
00052 #include <cpu/detect.h>
00053 #include <cpu/attr.h>     /* For CPU_HARVARD */
00054 #include <cpu/types.h>    /* For SIZEOF_INT */
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 /* !__AVR_ENHANCED__ */
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 /* !__AVR_ENHANCED__ */
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            /* nothing */
00158 #endif
00159 
00160 #ifndef PFUNC
00161 #define PFUNC(x) x
00162 #endif
00163 
00164 #ifndef PROGMEM
00165 #define PROGMEM         /* nothing */
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         /* nothing */
00226 #endif
00227 
00228 #define PGM_READ_CHAR(addr)      PGM_READ8(addr)
00229 
00230 /* \} */
00231 
00232 
00233 #endif /* MWARE_PGM_H */