Arch/Esp32/Components/libc/include/sys/pgmspace.h
Go to the documentation of this file.
1 /****
2  * Sming Framework Project - Open Source framework for high efficiency native ESP8266 development.
3  * Created 2015 by Skurydin Alexey
4  * http://github.com/SmingHub/Sming
5  * All files of the Sming Core are provided under the LGPL v3 license.
6  *
7  * pgmspace.h - Support for reading flash memory
8  *
9  ****/
10 
11 #pragma once
12 
13 #include <esp_attr.h>
14 #include <c_types.h>
15 #include <soc/soc.h>
16 
17 #ifdef __cplusplus
18 extern "C" {
19 #endif
20 
24 #define isFlashPtr(ptr) \
25  (((uint32_t)(ptr) >= SOC_DROM_LOW && (uint32_t)(ptr) < SOC_DROM_HIGH) || \
26  ((uint32_t)(ptr) >= SOC_IROM_LOW && (uint32_t)(ptr) < SOC_IROM_HIGH))
27 
28 #define PROGMEM STORE_ATTR
29 #define PROGMEM_PSTR PROGMEM
30 #define PSTR(str) (str)
31 
32 #define PGM_P const char*
33 #define PGM_VOID_P const void*
34 
35 // flash memory must be read using 32 bit aligned addresses else a processor exception will be triggered
36 // order within the 32 bit values are
37 // --------------
38 // b3, b2, b1, b0
39 // w1, w0
40 
41 #define pgm_read_with_offset(addr, res) \
42  __asm__("extui %0, %1, 0, 2\n" /* Extract offset within word (in bytes) */ \
43  "sub %1, %1, %0\n" /* Subtract offset from addr, yielding an aligned address */ \
44  "l32i.n %1, %1, 0x0\n" /* Load word from aligned address */ \
45  "ssa8l %0\n" /* Prepare to shift by offset (in bits) */ \
46  "src %0, %1, %1\n" /* Shift right; now the requested byte is the first one */ \
47  : "=r"(res), "=r"(addr) \
48  : "1"(addr) \
49  :);
50 
51 static inline uint8_t pgm_read_byte_inlined(const void* addr)
52 {
53  uint32_t res;
54  pgm_read_with_offset(addr, res);
55  return (uint8_t)res; /* This masks the lower byte from the returned word */
56 }
57 
58 /* Although this says "word", it's actually 16 bit, i.e. half word on Xtensa */
59 static inline uint16_t pgm_read_word_inlined(const void* addr)
60 {
61  uint32_t res;
62  pgm_read_with_offset(addr, res);
63  return (uint16_t)res; /* This masks the lower half-word from the returned word */
64 }
65 
71 // Make sure, that libraries checking existence of this macro are not failing
72 #define pgm_read_byte(addr) pgm_read_byte_inlined(addr)
73 #define pgm_read_word(addr) pgm_read_word_inlined(addr)
74 
75 // No translation necessary (provided address is aligned)
76 #define pgm_read_dword(addr) (*(const unsigned long*)(addr))
77 #define pgm_read_float(addr) (*(const float*)(addr))
78 
81 #define pgm_read_byte_near(addr) pgm_read_byte(addr)
82 #define pgm_read_word_near(addr) pgm_read_word(addr)
83 #define pgm_read_dword_near(addr) pgm_read_dword(addr)
84 #define pgm_read_float_near(addr) pgm_read_float(addr)
85 #define pgm_read_byte_far(addr) pgm_read_byte(addr)
86 #define pgm_read_word_far(addr) pgm_read_word(addr)
87 #define pgm_read_dword_far(addr) pgm_read_dword(addr)
88 #define pgm_read_float_far(addr) pgm_read_float(addr)
89 
90 #define memcpy_P(dest, src, num) memcpy(dest, src, num)
91 #define memcmp_P(a1, b1, len) memcmp(a1, b1, len)
92 #define strlen_P(a) strlen(a)
93 #define strcpy_P(dest, src) strcpy(dest, src)
94 #define strncpy_P(dest, src, size) strncpy(dest, src, size)
95 #define strcmp_P(a, b) strcmp(a, b)
96 #define strncmp_P(str1, str2_P, size) strncmp(str1, str2_P, size)
97 #define strcasecmp_P(a, b) strcasecmp(a, b)
98 #define strcat_P(dest, src) strcat(dest, src)
99 #define strstr_P(a, b) strstr(a, b)
100 #define sprintf_P(s, f, ...) m_snprintf(s, 1024, f, ##__VA_ARGS__)
101 
102 #ifdef __cplusplus
103 }
104 #endif
static uint8_t pgm_read_byte_inlined(const void *addr)
Definition: Arch/Esp32/Components/libc/include/sys/pgmspace.h:51
static uint16_t pgm_read_word_inlined(const void *addr)
Definition: Arch/Esp32/Components/libc/include/sys/pgmspace.h:59
#define pgm_read_with_offset(addr, res)
Definition: Arch/Esp32/Components/libc/include/sys/pgmspace.h:41