12 #ifndef MOZZI_PGMSPACE_H
13 #define MOZZI_PGMSPACE_H
21 template<
typename T>
inline T FLASH_OR_RAM_READ(T* address) {
22 return (T) (*address);
24 #define CONSTTABLE_STORAGE(X) const X
26 #include <avr/pgmspace.h>
28 template<
typename T>
inline bool mozzi_is_const_pointer(T*) {
return false; }
29 template<
typename T>
inline bool mozzi_is_const_pointer(
const T*) {
return true; }
33 static_assert(
sizeof(T) == 1 ||
sizeof(T) == 2 ||
sizeof(T) == 4 ||
sizeof(T) == 8,
"Data type not supported");
35 case 1:
return (T) pgm_read_byte_near(address);
36 case 2:
return (T) pgm_read_word_near(address);
37 case 4:
return (T) pgm_read_dword_near(address);
40 return (T) (pgm_read_dword_near(address) | (uint64_t) pgm_read_dword_near(((byte*) address) + 4) << 32);
42 template<>
inline float mozzi_pgm_read_wrapper(
const float* address) {
43 return pgm_read_float_near(address);
45 template<>
inline double mozzi_pgm_read_wrapper(
const double* address) {
46 static_assert(
sizeof(uint64_t) ==
sizeof(
double) ||
sizeof(
float) ==
sizeof(
double),
"Reading double from pgmspace memory not supported on this architecture");
47 if (
sizeof(
double) ==
sizeof(uint64_t)) {
48 union u { uint64_t i;
double d; };
49 return u{mozzi_pgm_read_wrapper((uint64_t*) address)}.d;
51 return pgm_read_float_near(address);
58 if(mozzi_is_const_pointer(address)) {
59 return mozzi_pgm_read_wrapper(address);
67 #define CONSTTABLE_STORAGE(X) const X __attribute__((section(".progmem.data")))