From 41eabcc9b8aa55fa3095dd5024c7a8b05545e00d Mon Sep 17 00:00:00 2001 From: Wolfgang Kraft Date: Thu, 1 Jun 2017 11:59:28 +0200 Subject: [PATCH] Make pgm_read_byte() and pgm_read_word() again backwards compatible compatible to the Arduino implementation. In result to issue #3140 they were converted from preprocessoer macros to functions. This however breaks other libraries, which are checking the existence of those functions and otherwise redefining them. --- cores/esp8266/pgmspace.h | 41 ++++++++++++++++++---------------------- 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/cores/esp8266/pgmspace.h b/cores/esp8266/pgmspace.h index e8ecd1d999..00f2b05ff1 100644 --- a/cores/esp8266/pgmspace.h +++ b/cores/esp8266/pgmspace.h @@ -88,29 +88,24 @@ int vsnprintf_P(char *str, size_t strSize, PGM_P formatP, va_list ap) __attribut #ifdef __ets__ -#define pgm_read_with_offset(addr, res) \ - asm("extui %0, %1, 0, 2\n" /* Extract offset within word (in bytes) */ \ - "sub %1, %1, %0\n" /* Subtract offset from addr, yielding an aligned address */ \ - "l32i.n %1, %1, 0x0\n" /* Load word from aligned address */ \ - "slli %0, %0, 3\n" /* Mulitiply offset by 8, yielding an offset in bits */ \ - "ssr %0\n" /* Prepare to shift by offset (in bits) */ \ - "srl %0, %1\n" /* Shift right; now the requested byte is the first one */ \ - :"=r"(res), "=r"(addr) \ - :"1"(addr) \ - :); - -static inline uint8_t pgm_read_byte(const void* addr) { - register uint32_t res; - pgm_read_with_offset(addr, res); - return (uint8_t) res; /* This masks the lower byte from the returned word */ -} - -/* Although this says "word", it's actually 16 bit, i.e. half word on Xtensa */ -static inline uint16_t pgm_read_word(const void* addr) { - register uint32_t res; - pgm_read_with_offset(addr, res); - return (uint16_t) res; /* This masks the lower half-word from the returned word */ -} +#define pgm_read_abstract(addr, result_type) \ +(__extension__({ \ + PGM_P __local = (PGM_P)(addr); \ + register uint32_t __res; \ + asm volatile("extui %0, %1, 0, 2\n" /* Extract offset within word (in bytes) */\ + "sub %1, %1, %0\n" /* Subtract offset from addr, yielding an aligned address */\ + "_l32i %1, %1, 0x0\n" /* Load word from aligned address */\ + "slli %0, %0, 3\n" /* Multiply offset by 8, yielding an offset in bits */\ + "ssr %0\n" /* Prepare to shift by offset (in bits) */\ + "srl %0, %1\n" /* Shift right; now the requested byte is the first one */\ + :"=r"(__res), "=r"(__local) \ + :"1"(__local) \ + :); \ + (result_type) __res; \ +})) + +#define pgm_read_byte(addr) pgm_read_abstract(addr, uint8_t) +#define pgm_read_word(addr) pgm_read_abstract(addr, uint16_t) #else //__ets__ #define pgm_read_byte(addr) (*reinterpret_cast(addr))