1 #ifndef MOZZI_PGMSPACE_H 2 #define MOZZI_PGMSPACE_H 10 template<
typename T>
inline T FLASH_OR_RAM_READ(T* address) {
11 return (T) (*address);
13 #define CONSTTABLE_STORAGE(X) const X 15 #include <avr/pgmspace.h> 17 template<
typename T>
inline bool mozzi_is_const_pointer(T* x) {
return false; }
18 template<
typename T>
inline bool mozzi_is_const_pointer(
const T* x) {
return true; }
21 template<
typename T>
inline T mozzi_pgm_read_wrapper(
const T* address) {
22 static_assert(
sizeof(T) == 1 ||
sizeof(T) == 2 ||
sizeof(T) == 4 ||
sizeof(T) == 8,
"Data type not supported");
24 case 1:
return (T) pgm_read_byte_near(address);
25 case 2:
return (T) pgm_read_word_near(address);
26 case 4:
return (T) pgm_read_dword_near(address);
29 return (T) (pgm_read_dword_near(address) | (uint64_t) pgm_read_dword_near(((byte*) address) + 4) << 32);
31 template<>
inline float mozzi_pgm_read_wrapper(
const float* address) {
32 return pgm_read_float_near(address);
34 template<>
inline double mozzi_pgm_read_wrapper(
const double* address) {
35 static_assert(
sizeof(uint64_t) ==
sizeof(
double) ||
sizeof(
float) ==
sizeof(
double),
"Reading double from pgmspace memory not supported on this architecture");
36 if (
sizeof(
double) ==
sizeof(uint64_t)) {
37 union u { uint64_t i;
double d; };
38 return u{mozzi_pgm_read_wrapper((uint64_t*) address)}.d;
40 return pgm_read_float_near(address);
46 template<
typename T>
inline T FLASH_OR_RAM_READ(T* address) {
47 if(mozzi_is_const_pointer(address)) {
48 return mozzi_pgm_read_wrapper(address);
56 #define CONSTTABLE_STORAGE(X) const X __attribute__((section(".progmem.data")))