@@ -34,7 +34,9 @@ extern "C" {
34
34
// PSTR() macro modified to start on a 32-bit boundary. This adds on average
35
35
// 1.5 bytes/string, but in return memcpy_P and strcpy_P will work 4~8x faster
36
36
#ifndef PSTR
37
- #define PSTR (s ) (__extension__({static const char __c[] __attribute__((__aligned__(4))) PROGMEM = (s); &__c[0];}))
37
+ // Adapted from AVR-specific code at https://forum.arduino.cc/index.php?topic=194603.0
38
+ // Uses C attribute section instead of ASM block to allow for C language string concatenation ("x" "y" === "xy")
39
+ #define PSTR (s ) (__extension__({static const char __c[] __attribute__ ((__aligned__ (4 ))) __attribute__ ((section ( " \" .irom0.pstr." __FILE__ " ." __STRINGIZE (__LINE__) " ." __STRINGIZE (__COUNTER__) " \" , \" aSM\" , @progbits, 1 #" ))) = (s); &__c[0 ];}))
38
40
#endif
39
41
40
42
// Flash memory must be read using 32 bit aligned addresses else a processor
@@ -66,18 +68,26 @@ extern "C" {
66
68
:"a15");
67
69
68
70
static inline uint8_t pgm_read_byte_inlined (const void * addr) {
69
- register uint32_t res ;
71
+ uint32_t res;
70
72
pgm_read_with_offset (addr, res);
71
73
return (uint8_t ) res; /* This masks the lower byte from the returned word */
72
74
}
73
75
74
76
/* Although this says "word", it's actually 16 bit, i.e. half word on Xtensa */
75
77
static inline uint16_t pgm_read_word_inlined (const void * addr) {
76
- register uint32_t res ;
78
+ uint32_t res;
77
79
pgm_read_with_offset (addr, res);
78
80
return (uint16_t ) res; /* This masks the lower half-word from the returned word */
79
81
}
80
82
83
+ /* Can't legally cast bits of uint32_t to a float w/o conversion or std::memcpy, which is inefficient. */
84
+ /* The ASM block doesn't care the type, so just pass in what C thinks is a float and return in custom fcn. */
85
+ static inline float pgm_read_float_unaligned (const void *addr) {
86
+ float res;
87
+ pgm_read_with_offset (addr, res);
88
+ return res;
89
+ }
90
+
81
91
#define pgm_read_byte (addr ) pgm_read_byte_inlined(addr)
82
92
#define pgm_read_word_aligned (addr ) pgm_read_word_inlined(addr)
83
93
#ifdef __cplusplus
@@ -96,7 +106,6 @@ static inline uint32_t pgm_read_dword_unaligned(const void *addr) {
96
106
return res;
97
107
}
98
108
99
- #define pgm_read_float_unaligned (addr ) ((float)pgm_read_dword_unaligned(addr))
100
109
#define pgm_read_ptr_unaligned (addr ) ((void *)pgm_read_dword_unaligned(addr))
101
110
#define pgm_read_word_unaligned (addr ) ((uint16_t )(pgm_read_dword_unaligned(addr) & 0xffff ))
102
111
0 commit comments