You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
79 lines
2.1 KiB
79 lines
2.1 KiB
|
|
#ifndef __AP_PROGMEM_AVR_H__ |
|
#define __AP_PROGMEM_AVR_H__ |
|
|
|
#include <avr/pgmspace.h> |
|
|
|
// prog_char_t is used as a wrapper type for prog_char, which is |
|
// a character stored in flash. By using this wrapper type we can |
|
// auto-detect at compile time if a call to a string function is using |
|
// a flash-stored string or not |
|
typedef struct { |
|
char c; |
|
} prog_char_t; |
|
|
|
#undef PROGMEM |
|
#define PROGMEM __attribute__(( section(".progmem.data") )) |
|
|
|
#undef PSTR |
|
/* need to define prog_char in avr-gcc 4.7 */ |
|
#if __AVR__ && __GNUC__ == 4 && __GNUC_MINOR__ > 6 |
|
typedef char prog_char; |
|
#endif |
|
/* Need const type for progmem - new for avr-gcc 4.6 */ |
|
#if __AVR__ && __GNUC__ == 4 && __GNUC_MINOR__ > 5 |
|
#define PSTR(s) (__extension__({static const prog_char __c[] PROGMEM = (s); \ |
|
(const prog_char_t *)&__c[0]; })) |
|
#else |
|
#define PSTR(s) (__extension__({static prog_char __c[] PROGMEM = (s); \ |
|
(prog_char_t *)&__c[0]; })) |
|
#endif |
|
|
|
|
|
static inline int strcasecmp_P(const char *str1, const prog_char_t *pstr) |
|
{ |
|
return strcasecmp_P(str1, (const prog_char *)pstr); |
|
} |
|
|
|
static inline int strcmp_P(const char *str1, const prog_char_t *pstr) |
|
{ |
|
return strcmp_P(str1, (const prog_char *)pstr); |
|
} |
|
|
|
static inline size_t strlen_P(const prog_char_t *pstr) |
|
{ |
|
return strlen_P((const prog_char *)pstr); |
|
} |
|
|
|
static inline void *memcpy_P(void *dest, const prog_char_t *src, size_t n) |
|
{ |
|
return memcpy_P(dest, (const prog_char *)src, n); |
|
} |
|
|
|
|
|
static inline char *strncpy_P(char *buffer, const prog_char_t *pstr, size_t buffer_size) |
|
{ |
|
return strncpy_P(buffer, (const prog_char *)pstr, buffer_size); |
|
} |
|
|
|
|
|
// read something the size of a pointer. This makes the menu code more |
|
// portable |
|
static inline uintptr_t pgm_read_pointer(const void *s) |
|
{ |
|
if (sizeof(uintptr_t) == sizeof(uint16_t)) { |
|
return (uintptr_t)pgm_read_word(s); |
|
} else { |
|
union { |
|
uintptr_t p; |
|
uint8_t a[sizeof(uintptr_t)]; |
|
} u; |
|
uint8_t i; |
|
for (i=0; i< sizeof(uintptr_t); i++) { |
|
u.a[i] = pgm_read_byte(i + (const prog_char *)s); |
|
} |
|
return u.p; |
|
} |
|
} |
|
|
|
#endif // __AP_PROGMEM_AVR_H__
|
|
|