diff --git a/code/espurna/build.cpp b/code/espurna/build.cpp index f7ad3e67..d0872ebf 100644 --- a/code/espurna/build.cpp +++ b/code/espurna/build.cpp @@ -69,8 +69,8 @@ Sdk get() { namespace hardware { namespace internal { -alignas(4) static constexpr char Manufacturer[] PROGMEM = MANUFACTURER; -alignas(4) static constexpr char Device[] PROGMEM = DEVICE; +PROGMEM_STRING(Manufacturer, MANUFACTURER); +PROGMEM_STRING(Device, DEVICE); } // namespace internal @@ -94,7 +94,7 @@ constexpr Hardware get() { namespace app { namespace internal { -alignas(4) static constexpr char Modules[] PROGMEM = +alignas(4) static constexpr char Modules[] PROGMEM_STRING_ATTR = #if ALEXA_SUPPORT "ALEXA " #endif @@ -240,13 +240,13 @@ alignas(4) static constexpr char Modules[] PROGMEM = #endif ""; -alignas(4) static constexpr char Name[] PROGMEM = APP_NAME; -alignas(4) static constexpr char Version[] PROGMEM = APP_VERSION; -alignas(4) static constexpr char Author[] PROGMEM = APP_AUTHOR; -alignas(4) static constexpr char Website[] PROGMEM = APP_WEBSITE; +PROGMEM_STRING(Name, APP_NAME); +PROGMEM_STRING(Version, APP_VERSION); +PROGMEM_STRING(Author, APP_AUTHOR); +PROGMEM_STRING(Website, APP_WEBSITE); -alignas(4) static constexpr char BuildDate[] PROGMEM = __DATE__; -alignas(4) static constexpr char BuildTime[] PROGMEM = __TIME__; +PROGMEM_STRING(BuildDate, __DATE__); +PROGMEM_STRING(BuildTime, __TIME__); } // namespace internal diff --git a/code/espurna/button.cpp b/code/espurna/button.cpp index 80b43240..0df4983e 100644 --- a/code/espurna/button.cpp +++ b/code/espurna/button.cpp @@ -35,32 +35,32 @@ namespace settings { namespace keys { namespace { -alignas(4) static constexpr char Gpio[] PROGMEM = "btnGpio"; -alignas(4) static constexpr char GpioType[] PROGMEM = "btnGpioType"; -alignas(4) static constexpr char Provider[] PROGMEM = "btnProv"; -alignas(4) static constexpr char Mode[] PROGMEM = "btnMode"; -alignas(4) static constexpr char DefaultValue[] PROGMEM = "btnDefVal"; -alignas(4) static constexpr char PinMode[] PROGMEM = "btnPinMode"; +PROGMEM_STRING(Gpio, "btnGpio"); +PROGMEM_STRING(GpioType, "btnGpioType"); +PROGMEM_STRING(Provider, "btnProv"); +PROGMEM_STRING(Mode, "btnMode"); +PROGMEM_STRING(DefaultValue, "btnDefVal"); +PROGMEM_STRING(PinMode, "btnPinMode"); -alignas(4) static constexpr char Release[] PROGMEM = "btnRlse"; -alignas(4) static constexpr char Press[] PROGMEM = "btnPress"; -alignas(4) static constexpr char Click[] PROGMEM = "btnClick"; -alignas(4) static constexpr char DoubleClick[] PROGMEM = "btnDclk"; -alignas(4) static constexpr char TripleClick[] PROGMEM = "btnTclk"; -alignas(4) static constexpr char LongClick[] PROGMEM = "btnLclk"; -alignas(4) static constexpr char LongLongClick[] PROGMEM = "btnLLclk"; +PROGMEM_STRING(Release, "btnRlse"); +PROGMEM_STRING(Press, "btnPress"); +PROGMEM_STRING(Click, "btnClick"); +PROGMEM_STRING(DoubleClick, "btnDclk"); +PROGMEM_STRING(TripleClick, "btnTclk"); +PROGMEM_STRING(LongClick, "btnLclk"); +PROGMEM_STRING(LongLongClick, "btnLLclk"); -alignas(4) static constexpr char DebounceDelay[] PROGMEM = "btnDebDel"; -alignas(4) static constexpr char LongClickDelay[] PROGMEM = "btnLclkDel"; -alignas(4) static constexpr char LongLongClickDelay[] PROGMEM = "btnLLclkDel"; -alignas(4) static constexpr char RepeatDelay[] PROGMEM = "btnRepDel"; +PROGMEM_STRING(DebounceDelay, "btnDebDel"); +PROGMEM_STRING(LongClickDelay, "btnLclkDel"); +PROGMEM_STRING(LongLongClickDelay, "btnLLclkDel"); +PROGMEM_STRING(RepeatDelay, "btnRepDel"); -alignas(4) static constexpr char Relay[] PROGMEM = "btnRelay"; +PROGMEM_STRING(Relay, "btnRelay"); -alignas(4) static constexpr char MqttSendAll[] PROGMEM = "btnMqttSendAll"; -alignas(4) static constexpr char MqttRetain[] PROGMEM = "btnMqttRetain"; +PROGMEM_STRING(MqttSendAll, "btnMqttSendAll"); +PROGMEM_STRING(MqttRetain, "btnMqttRetain"); -[[gnu::unused]] alignas(4) static constexpr char AnalogLevel[] PROGMEM = "btnLevel"; +[[gnu::unused]] PROGMEM_STRING(AnalogLevel, "btnLevel"); } // namespace } // namespace keys @@ -70,17 +70,17 @@ namespace { using espurna::settings::options::Enumeration; -alignas(4) static constexpr char Switch[] PROGMEM = "switch"; -alignas(4) static constexpr char Pushbutton[] PROGMEM = "pushbutton"; +PROGMEM_STRING(Switch, "switch"); +PROGMEM_STRING(Pushbutton, "pushbutton"); static constexpr std::array, 2> DebounceEventMode PROGMEM { {{debounce_event::types::Mode::Switch, Switch}, {debounce_event::types::Mode::Pushbutton, Pushbutton}} }; -alignas(4) static constexpr char Low[] PROGMEM = "low"; -alignas(4) static constexpr char High[] PROGMEM = "high"; -alignas(4) static constexpr char Initial[] PROGMEM = "initial"; +PROGMEM_STRING(Low, "low"); +PROGMEM_STRING(High, "high"); +PROGMEM_STRING(Initial, "initial"); static constexpr std::array, 3> DebounceEventPinValue PROGMEM { {{debounce_event::types::PinValue::Low, Low}, @@ -88,9 +88,9 @@ static constexpr std::array, 3> Deb {debounce_event::types::PinValue::Initial, Initial}} }; -alignas(4) static constexpr char Input[] PROGMEM = "default"; -alignas(4) static constexpr char InputPullup[] PROGMEM = "pull-up"; -alignas(4) static constexpr char InputPulldown[] PROGMEM = "pull-down"; +PROGMEM_STRING(Input, "default"); +PROGMEM_STRING(InputPullup, "pull-up"); +PROGMEM_STRING(InputPulldown, "pull-down"); static constexpr std::array, 3> DebounceEventPinMode PROGMEM { {{debounce_event::types::PinMode::Input, Input}, @@ -98,9 +98,9 @@ static constexpr std::array, 3> Debo {debounce_event::types::PinMode::InputPulldown, InputPulldown}} }; -alignas(4) static constexpr char None[] PROGMEM = "none"; -alignas(4) static constexpr char Gpio[] PROGMEM = "gpio"; -alignas(4) static constexpr char Analog[] PROGMEM = "analog"; +PROGMEM_STRING(None, "none"); +PROGMEM_STRING(Gpio, "gpio"); +PROGMEM_STRING(Analog, "analog"); static constexpr std::array, 3> ButtonProviderOptions PROGMEM { {{ButtonProvider::None, None}, @@ -108,24 +108,24 @@ static constexpr std::array, 3> ButtonProviderOption {ButtonProvider::Analog, Analog}} }; -[[gnu::unused]] alignas(4) static constexpr char Toggle[] PROGMEM = "relay-toggle"; -[[gnu::unused]] alignas(4) static constexpr char On[] PROGMEM = "relay-on"; -[[gnu::unused]] alignas(4) static constexpr char Off[] PROGMEM = "relay-off"; +[[gnu::unused]] PROGMEM_STRING(Toggle, "relay-toggle"); +[[gnu::unused]] PROGMEM_STRING(On, "relay-on"); +[[gnu::unused]] PROGMEM_STRING(Off, "relay-off"); -alignas(4) static constexpr char AccessPoint[] PROGMEM = "wifi-ap"; -alignas(4) static constexpr char Reset[] PROGMEM = "reset"; -alignas(4) static constexpr char FactoryReset[] PROGMEM = "factory"; +PROGMEM_STRING(AccessPoint, "wifi-ap"); +PROGMEM_STRING(Reset, "reset"); +PROGMEM_STRING(FactoryReset, "factory"); -[[gnu::unused]] alignas(4) static constexpr char BrightnessIncrease[] PROGMEM = "bri-inc"; -[[gnu::unused]] alignas(4) static constexpr char BrightnessDecrease[] PROGMEM = "bri-dec"; +[[gnu::unused]] PROGMEM_STRING(BrightnessIncrease, "bri-inc"); +[[gnu::unused]] PROGMEM_STRING(BrightnessDecrease, "bri-dec"); -[[gnu::unused]] alignas(4) static constexpr char DisplayOn[] PROGMEM = "display-on"; +[[gnu::unused]] PROGMEM_STRING(DisplayOn, "display-on"); -alignas(4) static constexpr char Custom[] PROGMEM = "custom"; +PROGMEM_STRING(Custom, "custom"); -[[gnu::unused]] alignas(4) static constexpr char FanLow[] PROGMEM = "fan-low"; -[[gnu::unused]] alignas(4) static constexpr char FanMedium[] PROGMEM = "fan-medium"; -[[gnu::unused]] alignas(4) static constexpr char FanHigh[] PROGMEM = "fan-high"; +[[gnu::unused]] PROGMEM_STRING(FanLow, "fan-low"); +[[gnu::unused]] PROGMEM_STRING(FanMedium, "fan-medium"); +[[gnu::unused]] PROGMEM_STRING(FanHigh, "fan-high"); static constexpr Enumeration ButtonActionOptions[] PROGMEM { {ButtonAction::None, None}, @@ -793,7 +793,7 @@ void button(::terminal::CommandContext&& ctx) { } } -alignas(4) static constexpr char Button[] PROGMEM = "BUTTON"; +PROGMEM_STRING(Button, "BUTTON"); static constexpr ::terminal::Command Commands[] PROGMEM { {Button, button}, diff --git a/code/espurna/crash.cpp b/code/espurna/crash.cpp index f5358c5b..faf1f35b 100644 --- a/code/espurna/crash.cpp +++ b/code/espurna/crash.cpp @@ -223,7 +223,7 @@ void dump(Print& print) { } #if TERMINAL_SUPPORT -alignas(4) static constexpr char Name[] PROGMEM = "CRASH"; +PROGMEM_STRING(Name, "CRASH"); void command(::terminal::CommandContext&& ctx) { debug::crash::forceDump(ctx.output); diff --git a/code/espurna/debug.cpp b/code/espurna/debug.cpp index 54e7e82e..91a2b43a 100644 --- a/code/espurna/debug.cpp +++ b/code/espurna/debug.cpp @@ -36,9 +36,9 @@ namespace { using espurna::settings::options::Enumeration; -alignas(4) static constexpr char Disabled[] PROGMEM = "off"; -alignas(4) static constexpr char Enabled[] PROGMEM = "on"; -alignas(4) static constexpr char SkipBoot[] PROGMEM = "skip-boot"; +PROGMEM_STRING(Disabled, "off"); +PROGMEM_STRING(Enabled, "on"); +PROGMEM_STRING(SkipBoot, "skip-boot"); static constexpr Enumeration DebugLogModeOptions[] PROGMEM { {DebugLogMode::Disabled, Disabled}, @@ -52,13 +52,13 @@ static constexpr Enumeration DebugLogModeOptions[] PROGMEM { namespace keys { namespace { -alignas(4) static constexpr char SdkDebug[] PROGMEM = "dbgSDK"; -alignas(4) static constexpr char Mode[] PROGMEM = "dbgLogMode"; -alignas(4) static constexpr char Buffer[] PROGMEM = "dbgLogBuf"; -alignas(4) static constexpr char BufferSize[] PROGMEM = "dbgLogBufSize"; +PROGMEM_STRING(SdkDebug, "dbgSDK"); +PROGMEM_STRING(Mode, "dbgLogMode"); +PROGMEM_STRING(Buffer, "dbgLogBuf"); +PROGMEM_STRING(BufferSize, "dbgLogBufSize"); -alignas(4) static constexpr char HeartbeatMode[] PROGMEM = "dbgHbMode"; -alignas(4) static constexpr char HeartbeatInterval[] PROGMEM = "dbgHbIntvl"; +PROGMEM_STRING(HeartbeatMode, "dbgHbMode"); +PROGMEM_STRING(HeartbeatInterval, "dbgHbIntvl"); } // namespace } // namespace keys @@ -660,7 +660,7 @@ void onBoot() { #if TERMINAL_SUPPORT namespace terminal { -alignas(4) static constexpr char DebugBuffer[] PROGMEM = "DEBUG.BUFFER"; +PROGMEM_STRING(DebugBuffer, "DEBUG.BUFFER"); void debug_buffer(::terminal::CommandContext&& ctx) { debug::buffer::disable(); diff --git a/code/espurna/domoticz.cpp b/code/espurna/domoticz.cpp index dcae69dc..72710044 100644 --- a/code/espurna/domoticz.cpp +++ b/code/espurna/domoticz.cpp @@ -116,20 +116,20 @@ constexpr bool enabled() { namespace settings { namespace keys { -alignas(4) static constexpr char Enabled[] PROGMEM = "dczEnabled"; -alignas(4) static constexpr char TopicOut[] PROGMEM = "dczTopicOut"; -alignas(4) static constexpr char TopicIn[] PROGMEM = "dczTopicIn"; +PROGMEM_STRING(Enabled, "dczEnabled"); +PROGMEM_STRING(TopicOut, "dczTopicOut"); +PROGMEM_STRING(TopicIn, "dczTopicIn"); #if RELAY_SUPPORT -alignas(4) static constexpr char RelayIdx[] PROGMEM = "dczTopicIn"; +PROGMEM_STRING(RelayIdx, "dczTopicIn"); #endif #if SENSOR_SUPPORT -alignas(4) static constexpr char MagnitudeIdx[] PROGMEM = "dczTopicIn"; +PROGMEM_STRING(MagnitudeIdx, "dczTopicIn"); #endif #if LIGHT_PROVIDER != LIGHT_PROVIDER_NONE -alignas(4) static constexpr char LightIdx[] PROGMEM = "dczLightIdx"; +PROGMEM_STRING(LightIdx, "dczLightIdx"); #endif } // namespace keys @@ -430,7 +430,7 @@ void send(unsigned char index, const espurna::sensor::Value& value) { namespace web { namespace { -alignas(4) static constexpr char Prefix[] PROGMEM = "dcz"; +PROGMEM_STRING(Prefix, "dcz"); bool onKeyCheck(espurna::StringView key, const JsonVariant&) { return espurna::settings::query::samePrefix(key, Prefix); diff --git a/code/espurna/gpio.cpp b/code/espurna/gpio.cpp index c6c79280..397e461b 100644 --- a/code/espurna/gpio.cpp +++ b/code/espurna/gpio.cpp @@ -410,11 +410,11 @@ namespace options { using espurna::settings::options::Enumeration; -alignas(4) static constexpr char None[] PROGMEM = "none"; -alignas(4) static constexpr char Hardware[] PROGMEM = "hardware"; +PROGMEM_STRING(None, "none"); +PROGMEM_STRING(Hardware, "hardware"); #if MCP23S08_SUPPORT -alignas(4) static constexpr char Mcp23s08[] PROGMEM = "mcp23s08"; +PROGMEM_STRING(Mcp23s08, "mcp23s08"); #endif static constexpr Enumeration GpioTypeOptions[] PROGMEM { @@ -607,7 +607,7 @@ void add(Origin origin) { #if TERMINAL_SUPPORT namespace terminal { -alignas(4) static constexpr char GpioLocks[] PROGMEM = "GPIO.LOCKS"; +PROGMEM_STRING(GpioLocks, "GPIO.LOCKS"); void gpio_list_origins(::terminal::CommandContext&& ctx) { for (const auto& origin : origin::internal::origins) { @@ -620,7 +620,7 @@ void gpio_list_origins(::terminal::CommandContext&& ctx) { } } -alignas(4) static constexpr char Gpio[] PROGMEM = "GPIO"; +PROGMEM_STRING(Gpio, "GPIO"); void gpio_read_write(::terminal::CommandContext&& ctx) { const int pin = (ctx.argv.size() >= 2) @@ -696,7 +696,7 @@ void gpio_read_write(::terminal::CommandContext&& ctx) { terminalOK(ctx); } -alignas(4) static constexpr char RegRead[] PROGMEM = "REG.READ"; +PROGMEM_STRING(RegRead, "REG.READ"); void reg_read(::terminal::CommandContext&& ctx) { if (ctx.argv.size() == 2) { @@ -712,7 +712,7 @@ void reg_read(::terminal::CommandContext&& ctx) { terminalError(ctx, F("REG.READ
")); } -alignas(4) static constexpr char RegWrite[] PROGMEM = "REG.WRITE"; +PROGMEM_STRING(RegWrite, "REG.WRITE"); void reg_write(::terminal::CommandContext&& ctx) { if (ctx.argv.size() == 3) { diff --git a/code/espurna/homeassistant.cpp b/code/espurna/homeassistant.cpp index 70d6f65e..4c1fc11e 100644 --- a/code/espurna/homeassistant.cpp +++ b/code/espurna/homeassistant.cpp @@ -32,7 +32,7 @@ namespace { namespace build { -alignas(4) static constexpr char Prefix[] PROGMEM = HOMEASSISTANT_PREFIX; +PROGMEM_STRING(Prefix, HOMEASSISTANT_PREFIX); constexpr StringView prefix() { return Prefix; @@ -51,9 +51,9 @@ constexpr bool retain() { namespace settings { namespace keys { -alignas(4) static constexpr char Prefix[] PROGMEM = "haPrefix"; -alignas(4) static constexpr char Enabled[] PROGMEM = "haEnabled"; -alignas(4) static constexpr char Retain[] PROGMEM = "haRetain"; +PROGMEM_STRING(Prefix, "haPrefix"); +PROGMEM_STRING(Enabled, "haEnabled"); +PROGMEM_STRING(Retain, "haRetain"); } // namespace keys @@ -1061,7 +1061,7 @@ namespace web { #if WEB_SUPPORT -alignas(4) static constexpr char Prefix[] PROGMEM = "ha"; +PROGMEM_STRING(Prefix, "ha"); void onVisible(JsonObject& root) { wsPayloadModule(root, Prefix); @@ -1084,7 +1084,7 @@ bool onKeyCheck(StringView key, const JsonVariant& value) { #if TERMINAL_SUPPORT namespace terminal { -alignas(4) static constexpr char Send[] PROGMEM = "HA.SEND"; +PROGMEM_STRING(Send, "HA.SEND"); void send(::terminal::CommandContext&& ctx) { internal::state = internal::State::Pending; diff --git a/code/espurna/i2c.cpp b/code/espurna/i2c.cpp index 7c3f8412..07c8ea1f 100644 --- a/code/espurna/i2c.cpp +++ b/code/espurna/i2c.cpp @@ -314,7 +314,7 @@ void init() { #if TERMINAL_SUPPORT namespace terminal { -alignas(4) static constexpr char Locked[] PROGMEM = "I2C.LOCKED"; +PROGMEM_STRING(Locked, "I2C.LOCKED"); void locked(::terminal::CommandContext&& ctx) { for (size_t address = 0; address < lock::storage.size(); ++address) { @@ -326,7 +326,7 @@ void locked(::terminal::CommandContext&& ctx) { terminalOK(ctx); } -alignas(4) static constexpr char Scan[] PROGMEM = "I2C.SCAN"; +PROGMEM_STRING(Scan, "I2C.SCAN"); void scan(::terminal::CommandContext&& ctx) { size_t devices { 0 }; @@ -344,7 +344,7 @@ void scan(::terminal::CommandContext&& ctx) { terminalError(ctx, F("no devices found")); } -alignas(4) static constexpr char Clear[] PROGMEM = "I2C.CLEAR"; +PROGMEM_STRING(Clear, "I2C.CLEAR"); void clear(::terminal::CommandContext&& ctx) { ctx.output.printf_P(PSTR("result %d\n"), i2c::clear()); diff --git a/code/espurna/ifan.cpp b/code/espurna/ifan.cpp index af09c7a6..24dd5ce3 100644 --- a/code/espurna/ifan.cpp +++ b/code/espurna/ifan.cpp @@ -29,10 +29,10 @@ namespace settings { namespace options { namespace { -alignas(4) static constexpr char Off[] PROGMEM = "off"; -alignas(4) static constexpr char Low[] PROGMEM = "low"; -alignas(4) static constexpr char Medium[] PROGMEM = "medium"; -alignas(4) static constexpr char High[] PROGMEM = "high"; +PROGMEM_STRING(Off, "off"); +PROGMEM_STRING(Low, "low"); +PROGMEM_STRING(Medium, "medium"); +PROGMEM_STRING(High, "high"); static constexpr std::array, 4> FanSpeedOptions PROGMEM { {{FanSpeed::Off, Off}, @@ -285,7 +285,7 @@ private: #if TERMINAL_SUPPORT namespace terminal { -alignas(4) static constexpr char Speed[] PROGMEM = "SPEED"; +PROGMEM_STRING(Speed, "SPEED"); void speed(::terminal::CommandContext&& ctx) { if (ctx.argv.size() == 2) { diff --git a/code/espurna/influxdb.cpp b/code/espurna/influxdb.cpp index 67231f84..20d8891e 100644 --- a/code/espurna/influxdb.cpp +++ b/code/espurna/influxdb.cpp @@ -279,7 +279,7 @@ bool _idbHeartbeat(espurna::heartbeat::Mask mask) { } #if TERMINAL_SUPPORT -alignas(4) static constexpr char IdbSend[] PROGMEM = "IDB.SEND"; +PROGMEM_STRING(IdbSend, "IDB.SEND"); static void idbTerminalSend(::terminal::CommandContext&& ctx) { if (ctx.argv.size() != 4) { diff --git a/code/espurna/ir.cpp b/code/espurna/ir.cpp index 5a693381..1b208a68 100644 --- a/code/espurna/ir.cpp +++ b/code/espurna/ir.cpp @@ -1567,7 +1567,7 @@ void process(rx::DecodeResult& result) { } } -alignas(4) static constexpr char IrSend[] PROGMEM = "IR.SEND"; +PROGMEM_STRING(IrSend, "IR.SEND"); void send(::terminal::CommandContext&& ctx) { if (ctx.argv.size() == 2) { diff --git a/code/espurna/led.cpp b/code/espurna/led.cpp index 4e475732..a3fff6ba 100644 --- a/code/espurna/led.cpp +++ b/code/espurna/led.cpp @@ -365,11 +365,11 @@ bool Led::toggle() { namespace settings { namespace keys { -alignas(4) static constexpr char Gpio[] PROGMEM = "ledGpio"; -alignas(4) static constexpr char Inverse[] PROGMEM = "ledInv"; -alignas(4) static constexpr char Mode[] PROGMEM = "ledMode"; -alignas(4) static constexpr char Relay[] PROGMEM = "ledRelay"; -alignas(4) static constexpr char Pattern[] PROGMEM = "ledPattern"; +PROGMEM_STRING(Gpio, "ledGpio"); +PROGMEM_STRING(Inverse, "ledInv"); +PROGMEM_STRING(Mode, "ledMode"); +PROGMEM_STRING(Relay, "ledRelay"); +PROGMEM_STRING(Pattern, "ledPattern"); } // namespace keys @@ -377,20 +377,20 @@ namespace options { using espurna::settings::options::Enumeration; -alignas(4) static constexpr char Manual[] PROGMEM = "manual"; -alignas(4) static constexpr char WiFi[] PROGMEM = "wifi"; -alignas(4) static constexpr char On[] PROGMEM = "on"; -alignas(4) static constexpr char Off[] PROGMEM = "off"; +PROGMEM_STRING(Manual, "manual"); +PROGMEM_STRING(WiFi, "wifi"); +PROGMEM_STRING(On, "on"); +PROGMEM_STRING(Off, "off"); #if RELAY_SUPPORT -alignas(4) static constexpr char Relay[] PROGMEM = "relay"; -alignas(4) static constexpr char RelayInverse[] PROGMEM = "relay-inverse"; +PROGMEM_STRING(Relay, "relay"); +PROGMEM_STRING(RelayInverse, "relay-inverse"); -alignas(4) static constexpr char FindMe[] PROGMEM = "findme"; -alignas(4) static constexpr char FindMeWiFi[] PROGMEM = "findme-wifi"; +PROGMEM_STRING(FindMe, "findme"); +PROGMEM_STRING(FindMeWiFi, "findme-wifi"); -alignas(4) static constexpr char Relays[] PROGMEM = "relays"; -alignas(4) static constexpr char RelaysWiFi[] PROGMEM = "relays-wifi"; +PROGMEM_STRING(Relays, "relays"); +PROGMEM_STRING(RelaysWiFi, "relays-wifi"); #endif static constexpr Enumeration LedModeOptions[] PROGMEM { @@ -991,7 +991,7 @@ void onConnected(JsonObject& root) { #if TERMINAL_SUPPORT namespace terminal { -alignas(4) static constexpr char Led[] PROGMEM = "LED"; +PROGMEM_STRING(Led, "LED"); void led(::terminal::CommandContext&& ctx) { if (ctx.argv.size() > 1) { diff --git a/code/espurna/light.cpp b/code/espurna/light.cpp index df5106b8..4dde18fb 100644 --- a/code/espurna/light.cpp +++ b/code/espurna/light.cpp @@ -589,8 +589,8 @@ namespace internal { template <> my92xx_model_t convert(const String& value) { - alignas(4) static constexpr char MY9291[] PROGMEM = "9291"; - alignas(4) static constexpr char MY9231[] PROGMEM = "9231"; + PROGMEM_STRING(MY9291, "9291"); + PROGMEM_STRING(MY9231, "9231"); using Options = std::array, 2>; static constexpr Options options { @@ -2642,7 +2642,7 @@ void _lightNotificationInit(size_t channel) { lightState(true); } -alignas(4) static constexpr char LightCommandNotify[] PROGMEM = "NOTIFY"; +PROGMEM_STRING(LightCommandNotify, "NOTIFY"); static void _lightCommandNotify(::terminal::CommandContext&& ctx) { static constexpr auto NotifyTransition = LightTransition{ @@ -2711,7 +2711,7 @@ static void _lightCommandNotify(::terminal::CommandContext&& ctx) { lightSequence(std::move(callbacks)); } -alignas(4) static constexpr char LightCommand[] PROGMEM = "LIGHT"; +PROGMEM_STRING(LightCommand, "LIGHT"); static void _lightCommand(::terminal::CommandContext&& ctx) { if (ctx.argv.size() > 1) { @@ -2727,7 +2727,7 @@ static void _lightCommand(::terminal::CommandContext&& ctx) { terminalOK(ctx); } -alignas(4) static constexpr char LightCommandBrightness[] PROGMEM = "BRIGHTNESS"; +PROGMEM_STRING(LightCommandBrightness, "BRIGHTNESS"); static void _lightCommandBrightness(::terminal::CommandContext&& ctx) { if (ctx.argv.size() > 1) { @@ -2738,7 +2738,7 @@ static void _lightCommandBrightness(::terminal::CommandContext&& ctx) { terminalOK(ctx); } -alignas(4) static constexpr char LightCommandChannel[] PROGMEM = "CHANNEL"; +PROGMEM_STRING(LightCommandChannel, "CHANNEL"); static void _lightCommandChannel(::terminal::CommandContext&& ctx) { const size_t Channels { _light_channels.size() }; @@ -2776,7 +2776,7 @@ static void _lightCommandChannel(::terminal::CommandContext&& ctx) { terminalOK(ctx); } -alignas(4) static constexpr char LightCommandRgb[] PROGMEM = "RGB"; +PROGMEM_STRING(LightCommandRgb, "RGB"); static void _lightCommandColors(const ::terminal::CommandContext& ctx) { const auto rgb = _lightToTargetRgb(); @@ -2797,7 +2797,7 @@ static void _lightCommandRgb(::terminal::CommandContext&& ctx) { _lightCommandColors(ctx); } -alignas(4) static constexpr char LightCommandHsv[] PROGMEM = "HSV"; +PROGMEM_STRING(LightCommandHsv, "HSV"); static void _lightCommandHsv(::terminal::CommandContext&& ctx) { if (ctx.argv.size() > 1) { @@ -2808,7 +2808,7 @@ static void _lightCommandHsv(::terminal::CommandContext&& ctx) { _lightCommandColors(ctx); } -alignas(4) static constexpr char LightCommandKelvin[] PROGMEM = "KELVIN"; +PROGMEM_STRING(LightCommandKelvin, "KELVIN"); static void _lightCommandKelvin(::terminal::CommandContext&& ctx) { if (ctx.argv.size() > 1) { @@ -2821,7 +2821,7 @@ static void _lightCommandKelvin(::terminal::CommandContext&& ctx) { terminalOK(ctx); } -alignas(4) static constexpr char LightCommandMired[] PROGMEM = "MIRED"; +PROGMEM_STRING(LightCommandMired, "MIRED"); static void _lightCommandMired(::terminal::CommandContext&& ctx) { if (ctx.argv.size() > 1) { diff --git a/code/espurna/lightfox.cpp b/code/espurna/lightfox.cpp index dcd8614e..258d52c1 100644 --- a/code/espurna/lightfox.cpp +++ b/code/espurna/lightfox.cpp @@ -161,14 +161,14 @@ void _lightfoxWebSocketOnAction(uint32_t client_id, const char * action, JsonObj // ----------------------------------------------------------------------------- #if TERMINAL_SUPPORT -alignas(4) static constexpr char LightfoxCommandLearn[] PROGMEM = "LIGHTFOX.LEARN"; +PROGMEM_STRING(LightfoxCommandLearn, "LIGHTFOX.LEARN"); static void _lightfoxCommandLearn(::terminal::CommandContext&& ctx) { lightfoxLearn(); terminalOK(ctx); } -alignas(4) static constexpr char LightfoxCommandClear[] PROGMEM = "LIGHTFOX.LEARN"; +PROGMEM_STRING(LightfoxCommandClear, "LIGHTFOX.LEARN"); static void _lightfoxCommandClear(::terminal::CommandContext&& ctx) { lightfoxClear(); diff --git a/code/espurna/main.cpp b/code/espurna/main.cpp index 31c05bb2..4cb4312a 100644 --- a/code/espurna/main.cpp +++ b/code/espurna/main.cpp @@ -52,7 +52,7 @@ constexpr espurna::duration::Milliseconds loopDelay() { namespace settings { namespace keys { -alignas(4) static constexpr char LoopDelay[] PROGMEM = "loopDelay"; +PROGMEM_STRING(LoopDelay, "loopDelay"); } // namespace keys diff --git a/code/espurna/migrate.cpp b/code/espurna/migrate.cpp index 055236d8..347d61c9 100644 --- a/code/espurna/migrate.cpp +++ b/code/espurna/migrate.cpp @@ -24,7 +24,7 @@ namespace schema { // Configuration version for the internal key-value storage // Represented as a 32bit int, updates every time things change constexpr static int Version PROGMEM { CFG_VERSION }; -alignas(4) static constexpr char Key[] PROGMEM = "cfg"; +PROGMEM_STRING(Key, "cfg"); int version() { return getSetting(Key, Version); diff --git a/code/espurna/mqtt.cpp b/code/espurna/mqtt.cpp index 1f163f90..758b0de6 100644 --- a/code/espurna/mqtt.cpp +++ b/code/espurna/mqtt.cpp @@ -132,7 +132,7 @@ static constexpr espurna::duration::Milliseconds ReconnectStep { MQTT_RECONNECT_ static constexpr size_t MessageLogMax { 128ul }; -alignas(4) static constexpr char Server[] PROGMEM = MQTT_SERVER; +PROGMEM_STRING(Server, MQTT_SERVER); constexpr uint16_t port() { return MQTT_PORT; @@ -146,12 +146,12 @@ constexpr bool autoconnect() { return 1 == MQTT_AUTOCONNECT; } -alignas(4) static constexpr char Topic[] PROGMEM = MQTT_TOPIC; -alignas(4) static constexpr char Getter[] PROGMEM = MQTT_GETTER; -alignas(4) static constexpr char Setter[] PROGMEM = MQTT_SETTER; +PROGMEM_STRING(Topic, MQTT_TOPIC); +PROGMEM_STRING(Getter, MQTT_GETTER); +PROGMEM_STRING(Setter, MQTT_SETTER); -alignas(4) static constexpr char User[] PROGMEM = MQTT_USER; -alignas(4) static constexpr char Password[] PROGMEM = MQTT_PASS; +PROGMEM_STRING(User, MQTT_USER); +PROGMEM_STRING(Password, MQTT_PASS); constexpr int qos() { return MQTT_QOS; @@ -171,21 +171,21 @@ constexpr KeepAlive keepalive() { static_assert(keepalive() >= KeepaliveMin, ""); static_assert(keepalive() <= KeepaliveMax, ""); -alignas(4) static constexpr char TopicWill[] PROGMEM = MQTT_TOPIC_STATUS; +PROGMEM_STRING(TopicWill, MQTT_TOPIC_STATUS); constexpr bool json() { return 1 == MQTT_USE_JSON; } static constexpr auto JsonDelay = espurna::duration::Milliseconds(MQTT_USE_JSON_DELAY); -alignas(4) static constexpr char TopicJson[] PROGMEM = MQTT_TOPIC_JSON; +PROGMEM_STRING(TopicJson, MQTT_TOPIC_JSON); constexpr espurna::duration::Milliseconds skipTime() { return espurna::duration::Milliseconds(MQTT_SKIP_TIME); } -alignas(4) static constexpr char PayloadOnline[] PROGMEM = MQTT_STATUS_ONLINE; -alignas(4) static constexpr char PayloadOffline[] PROGMEM = MQTT_STATUS_OFFLINE; +PROGMEM_STRING(PayloadOnline, MQTT_STATUS_ONLINE); +PROGMEM_STRING(PayloadOffline, MQTT_STATUS_OFFLINE); constexpr bool secure() { return 1 == MQTT_SSL_ENABLED; @@ -195,7 +195,7 @@ int secureClientCheck() { return MQTT_SECURE_CLIENT_CHECK; } -alignas(4) static constexpr char Fingerprint[] PROGMEM = MQTT_SSL_FINGERPRINT; +PROGMEM_STRING(Fingerprint, MQTT_SSL_FINGERPRINT); constexpr uint16_t mfln() { return MQTT_SECURE_CLIENT_MFLN; @@ -208,38 +208,38 @@ namespace settings { namespace keys { namespace { -alignas(4) static constexpr char Server[] PROGMEM = "mqttServer"; -alignas(4) static constexpr char Port[] PROGMEM = "mqttPort"; +PROGMEM_STRING(Server, "mqttServer"); +PROGMEM_STRING(Port, "mqttPort"); -alignas(4) static constexpr char Enabled[] PROGMEM = "mqttEnabled"; -alignas(4) static constexpr char Autoconnect[] PROGMEM = "mqttAutoconnect"; +PROGMEM_STRING(Enabled, "mqttEnabled"); +PROGMEM_STRING(Autoconnect, "mqttAutoconnect"); -alignas(4) static constexpr char Topic[] PROGMEM = "mqttTopic"; -alignas(4) static constexpr char Getter[] PROGMEM = "mqttGetter"; -alignas(4) static constexpr char Setter[] PROGMEM = "mqttSetter"; +PROGMEM_STRING(Topic, "mqttTopic"); +PROGMEM_STRING(Getter, "mqttGetter"); +PROGMEM_STRING(Setter, "mqttSetter"); -alignas(4) static constexpr char User[] PROGMEM = "mqttUser"; -alignas(4) static constexpr char Password[] PROGMEM = "mqttPassword"; -alignas(4) static constexpr char QoS[] PROGMEM = "mqttQoS"; -alignas(4) static constexpr char Retain[] PROGMEM = "mqttRetain"; -alignas(4) static constexpr char Keepalive[] PROGMEM = "mqttKeep"; -alignas(4) static constexpr char ClientId[] PROGMEM = "mqttClientID"; -alignas(4) static constexpr char TopicWill[] PROGMEM = "mqttWill"; +PROGMEM_STRING(User, "mqttUser"); +PROGMEM_STRING(Password, "mqttPassword"); +PROGMEM_STRING(QoS, "mqttQoS"); +PROGMEM_STRING(Retain, "mqttRetain"); +PROGMEM_STRING(Keepalive, "mqttKeep"); +PROGMEM_STRING(ClientId, "mqttClientID"); +PROGMEM_STRING(TopicWill, "mqttWill"); -alignas(4) static constexpr char UseJson[] PROGMEM = "mqttUseJson"; -alignas(4) static constexpr char TopicJson[] PROGMEM = "mqttJson"; +PROGMEM_STRING(UseJson, "mqttUseJson"); +PROGMEM_STRING(TopicJson, "mqttJson"); -alignas(4) static constexpr char HeartbeatMode[] PROGMEM = "mqttHbMode"; -alignas(4) static constexpr char HeartbeatInterval[] PROGMEM = "mqttHbIntvl"; -alignas(4) static constexpr char SkipTime[] PROGMEM = "mqttSkipTime"; +PROGMEM_STRING(HeartbeatMode, "mqttHbMode"); +PROGMEM_STRING(HeartbeatInterval, "mqttHbIntvl"); +PROGMEM_STRING(SkipTime, "mqttSkipTime"); -alignas(4) static constexpr char PayloadOnline[] PROGMEM = "mqttPayloadOnline"; -alignas(4) static constexpr char PayloadOffline[] PROGMEM = "mqttPayloadOffline"; +PROGMEM_STRING(PayloadOnline, "mqttPayloadOnline"); +PROGMEM_STRING(PayloadOffline, "mqttPayloadOffline"); -alignas(4) static constexpr char Secure[] PROGMEM = "mqttUseSSL"; -alignas(4) static constexpr char Fingerprint[] PROGMEM = "mqttFP"; -alignas(4) static constexpr char SecureClientCheck[] PROGMEM = "mqttScCheck"; -alignas(4) static constexpr char SecureClientMfln[] PROGMEM = "mqttScMFLN"; +PROGMEM_STRING(Secure, "mqttUseSSL"); +PROGMEM_STRING(Fingerprint, "mqttFP"); +PROGMEM_STRING(SecureClientCheck, "mqttScCheck"); +PROGMEM_STRING(SecureClientMfln, "mqttScMFLN"); } // namespace } // namespace keys @@ -842,7 +842,7 @@ void _mqttBackwards() { const char* _mqttBuildInfo() { #define __MQTT_INFO_STR(X) #X #define _MQTT_INFO_STR(X) __MQTT_INFO_STR(X) - alignas(4) static constexpr char out[] PROGMEM { + alignas(4) static constexpr char out[] PROGMEM_STRING_ATTR { #if MQTT_LIBRARY == MQTT_LIBRARY_ASYNCMQTTCLIENT "AsyncMqttClient" #elif MQTT_LIBRARY == MQTT_LIBRARY_ARDUINOMQTT @@ -958,7 +958,7 @@ void _mqttWebSocketOnConnected(JsonObject& root) { #if TERMINAL_SUPPORT namespace { -alignas(4) static constexpr char MqttCommand[] PROGMEM = "MQTT"; +PROGMEM_STRING(MqttCommand, "MQTT"); static void _mqttCommand(::terminal::CommandContext&& ctx) { ctx.output.printf_P(PSTR("%s\n"), _mqttBuildInfo()); @@ -967,7 +967,7 @@ static void _mqttCommand(::terminal::CommandContext&& ctx) { terminalOK(ctx); } -alignas(4) static constexpr char MqttCommandReset[] PROGMEM = "MQTT.RESET"; +PROGMEM_STRING(MqttCommandReset, "MQTT.RESET"); static void _mqttCommandReset(::terminal::CommandContext&& ctx) { _mqttConfigure(); @@ -975,7 +975,7 @@ static void _mqttCommandReset(::terminal::CommandContext&& ctx) { terminalOK(ctx); } -alignas(4) static constexpr char MqttCommandSend[] PROGMEM = "MQTT.SEND"; +PROGMEM_STRING(MqttCommandSend, "MQTT.SEND"); static void _mqttCommandSend(::terminal::CommandContext&& ctx) { if (ctx.argv.size() == 3) { diff --git a/code/espurna/network.cpp b/code/espurna/network.cpp index 118b6130..16f05f48 100644 --- a/code/espurna/network.cpp +++ b/code/espurna/network.cpp @@ -103,7 +103,7 @@ void start(String hostname, IpFoundCallback callback) { namespace terminal { namespace commands { -alignas(4) static constexpr char Host[] PROGMEM = "HOST"; +PROGMEM_STRING(Host, "HOST"); void host(::terminal::CommandContext&& ctx) { if (ctx.argv.size() != 2) { @@ -127,7 +127,7 @@ void host(::terminal::CommandContext&& ctx) { } } -alignas(4) static constexpr char Netstat[] PROGMEM = "NETSTAT"; +PROGMEM_STRING(Netstat, "NETSTAT"); void netstat(::terminal::CommandContext&& ctx) { const struct tcp_pcb* pcbs[] { @@ -149,7 +149,7 @@ void netstat(::terminal::CommandContext&& ctx) { } #if SECURE_CLIENT == SECURE_CLIENT_BEARSSL -alignas(4) static constexpr char MflnProbe[] PROGMEM = "MFLN.PROBE"; +PROGMEM_STRING(MflnProbe, "MFLN.PROBE"); void mfln_probe(::terminal::CommandContext&& ctx) { if (ctx.argv.size() != 3) { diff --git a/code/espurna/nofuss.cpp b/code/espurna/nofuss.cpp index 8c9b3404..476a2abc 100644 --- a/code/espurna/nofuss.cpp +++ b/code/espurna/nofuss.cpp @@ -98,7 +98,7 @@ void _nofussLoop() { } #if TERMINAL_SUPPORT -alignas(4) static constexpr char NofussCommand[] PROGMEM = "NOFUSS"; +PROGMEM_STRING(NofussCommand, "NOFUSS"); static void _nofussCommand(::terminal::CommandContext&& ctx) { terminalOK(ctx); diff --git a/code/espurna/ntp.cpp b/code/espurna/ntp.cpp index 432008df..bdf16748 100644 --- a/code/espurna/ntp.cpp +++ b/code/espurna/ntp.cpp @@ -487,7 +487,7 @@ void report(Print& out) { namespace commands { -alignas(4) static constexpr char Ntp[] PROGMEM = "NTP"; +PROGMEM_STRING(Ntp, "NTP"); void ntp(::terminal::CommandContext&& ctx) { if (synced()) { @@ -499,7 +499,7 @@ void ntp(::terminal::CommandContext&& ctx) { terminalError(ctx, F("NTP not synced")); } -alignas(4) static constexpr char Sync[] PROGMEM = "NTP.SYNC"; +PROGMEM_STRING(Sync, "NTP.SYNC"); void sync(::terminal::CommandContext&& ctx) { if (synced()) { @@ -512,7 +512,7 @@ void sync(::terminal::CommandContext&& ctx) { terminalError(ctx, F("NTP waiting for initial sync")); } -alignas(4) static constexpr char Set[] PROGMEM = "NTP.SET"; +PROGMEM_STRING(Set, "NTP.SET"); [[gnu::unused]] void set_simple(::terminal::CommandContext&& ctx) { diff --git a/code/espurna/ota_asynctcp.cpp b/code/espurna/ota_asynctcp.cpp index 9f594ae6..6b591bb0 100644 --- a/code/espurna/ota_asynctcp.cpp +++ b/code/espurna/ota_asynctcp.cpp @@ -243,7 +243,7 @@ void clientFromUrl(StringView payload) { } #if TERMINAL_SUPPORT -alignas(4) static constexpr char OtaCommand[] PROGMEM = "OTA"; +PROGMEM_STRING(OtaCommand, "OTA"); static void otaCommand(::terminal::CommandContext&& ctx) { if (ctx.argv.size() != 2) { diff --git a/code/espurna/ota_httpupdate.cpp b/code/espurna/ota_httpupdate.cpp index 4e551b1e..cca26992 100644 --- a/code/espurna/ota_httpupdate.cpp +++ b/code/espurna/ota_httpupdate.cpp @@ -159,7 +159,7 @@ void clientQueueUrl(espurna::StringView url) { } #if TERMINAL_SUPPORT -alignas(4) static constexpr char OtaCommand[] PROGMEM = "OTA"; +PROGMEM_STRING(OtaCommand, "OTA"); static void otaCommand(::terminal::CommandContext&& ctx) { if (ctx.argv.size() != 2) { diff --git a/code/espurna/pwm.cpp b/code/espurna/pwm.cpp index b9ea2f03..37422183 100644 --- a/code/espurna/pwm.cpp +++ b/code/espurna/pwm.cpp @@ -48,9 +48,9 @@ constexpr float limit() { namespace settings { namespace keys { -alignas(4) static constexpr char Frequency[] PROGMEM = "pwmFreq"; -alignas(4) static constexpr char Resolution[] PROGMEM = "pwmRes"; -alignas(4) static constexpr char Limit[] PROGMEM = "pwmLimit"; +PROGMEM_STRING(Frequency, "pwmFreq"); +PROGMEM_STRING(Resolution, "pwmRes"); +PROGMEM_STRING(Limit, "pwmLimit"); } // namespace keys @@ -437,7 +437,7 @@ using namespace generic; #if TERMINAL_SUPPORT namespace terminal { -alignas(4) static constexpr char PwmWrite[] PROGMEM = "PWM.WRITE"; +PROGMEM_STRING(PwmWrite, "PWM.WRITE"); void pwm_write(::terminal::CommandContext&& ctx) { if (ctx.argv.size() == 3) { diff --git a/code/espurna/relay.cpp b/code/espurna/relay.cpp index 5da3171f..fe907667 100644 --- a/code/espurna/relay.cpp +++ b/code/espurna/relay.cpp @@ -57,8 +57,8 @@ namespace settings { namespace keys { namespace { -alignas(4) static constexpr char Time[] PROGMEM = "relayFloodTime"; -alignas(4) static constexpr char Changes[] PROGMEM = "relayFloodChanges"; +PROGMEM_STRING(Time, "relayFloodTime"); +PROGMEM_STRING(Changes, "relayFloodChanges"); } // namespace } // namespace keys @@ -217,9 +217,9 @@ constexpr RelayMqttTopicMode mqttTopicMode(size_t index) { ); } -alignas(4) static constexpr char PayloadOn[] PROGMEM = RELAY_MQTT_ON; -alignas(4) static constexpr char PayloadOff[] PROGMEM = RELAY_MQTT_OFF; -alignas(4) static constexpr char PayloadToggle[] PROGMEM = RELAY_MQTT_TOGGLE; +PROGMEM_STRING(PayloadOn, RELAY_MQTT_ON); +PROGMEM_STRING(PayloadOff, RELAY_MQTT_OFF); +PROGMEM_STRING(PayloadToggle, RELAY_MQTT_TOGGLE); const StringView mqttTopicSub(size_t index) { return ( @@ -328,8 +328,8 @@ namespace settings { namespace keys { namespace { -alignas(4) static constexpr char Time[] PROGMEM = "relayTime"; -alignas(4) static constexpr char Mode[] PROGMEM = "relayPulse"; +PROGMEM_STRING(Time, "relayTime"); +PROGMEM_STRING(Mode, "relayPulse"); } // namespace } // namespace keys @@ -517,9 +517,9 @@ namespace { using espurna::settings::options::Enumeration; -alignas(4) static constexpr char TristateNone[] PROGMEM = "none"; -alignas(4) static constexpr char TristateOff[] PROGMEM = "off"; -alignas(4) static constexpr char TristateOn[] PROGMEM = "on"; +PROGMEM_STRING(TristateNone, "none"); +PROGMEM_STRING(TristateOff, "off"); +PROGMEM_STRING(TristateOn, "on"); template struct RelayTristateHelper { @@ -541,10 +541,10 @@ struct RelayTristateHelper { template constexpr std::array, 3> RelayTristateHelper::Options; -alignas(4) static constexpr char PayloadStatusOff[] PROGMEM = "off"; -alignas(4) static constexpr char PayloadStatusOn[] PROGMEM = "on"; -alignas(4) static constexpr char PayloadStatusToggle[] PROGMEM = "toggle"; -alignas(4) static constexpr char PayloadStatusUnknown[] PROGMEM = "unknown"; +PROGMEM_STRING(PayloadStatusOff, "off"); +PROGMEM_STRING(PayloadStatusOn, "on"); +PROGMEM_STRING(PayloadStatusToggle, "toggle"); +PROGMEM_STRING(PayloadStatusUnknown, "unknown"); static constexpr std::array, 4> PayloadStatusOptions PROGMEM { {{PayloadStatus::Off, PayloadStatusOff}, @@ -553,20 +553,20 @@ static constexpr std::array, 4> PayloadStatusOptions {PayloadStatus::Unknown, PayloadStatusUnknown}} }; -alignas(4) static constexpr char Normal[] PROGMEM = "normal"; -alignas(4) static constexpr char Inverse[] PROGMEM = "inverse"; +PROGMEM_STRING(Normal, "normal"); +PROGMEM_STRING(Inverse, "inverse"); static constexpr std::array, 2> RelayMqttTopicModeOptions PROGMEM { {{RelayMqttTopicMode::Normal, Normal}, {RelayMqttTopicMode::Inverse, Inverse}} }; -alignas(4) static constexpr char RelayBootOff[] PROGMEM = "off"; -alignas(4) static constexpr char RelayBootOn[] PROGMEM = "on"; -alignas(4) static constexpr char RelayBootSame[] PROGMEM = "same"; -alignas(4) static constexpr char RelayBootToggle[] PROGMEM = "toggle"; -alignas(4) static constexpr char RelayBootLockedOff[] PROGMEM = "locked-off"; -alignas(4) static constexpr char RelayBootLockedOn[] PROGMEM = "locked-on"; +PROGMEM_STRING(RelayBootOff, "off"); +PROGMEM_STRING(RelayBootOn, "on"); +PROGMEM_STRING(RelayBootSame, "same"); +PROGMEM_STRING(RelayBootToggle, "toggle"); +PROGMEM_STRING(RelayBootLockedOff, "locked-off"); +PROGMEM_STRING(RelayBootLockedOn, "locked-on"); static constexpr std::array, 6> RelayBootOptions PROGMEM { {{RelayBoot::Off, RelayBootOff}, @@ -577,11 +577,11 @@ static constexpr std::array, 6> RelayBootOptions PROGMEM {RelayBoot::LockedOn, RelayBootLockedOn}} }; -alignas(4) static constexpr char RelayProviderNone[] PROGMEM = "none"; -alignas(4) static constexpr char RelayProviderDummy[] PROGMEM = "dummy"; -alignas(4) static constexpr char RelayProviderGpio[] PROGMEM = "gpio"; -alignas(4) static constexpr char RelayProviderDual[] PROGMEM = "dual"; -alignas(4) static constexpr char RelayProviderStm[] PROGMEM = "stm"; +PROGMEM_STRING(RelayProviderNone, "none"); +PROGMEM_STRING(RelayProviderDummy, "dummy"); +PROGMEM_STRING(RelayProviderGpio, "gpio"); +PROGMEM_STRING(RelayProviderDual, "dual"); +PROGMEM_STRING(RelayProviderStm, "stm"); static constexpr std::array, 5> RelayProviderOptions PROGMEM { {{RelayProvider::None, RelayProviderNone}, @@ -591,10 +591,10 @@ static constexpr std::array, 5> RelayProviderOptions {RelayProvider::Stm, RelayProviderStm}} }; -alignas(4) constexpr static char RelayTypeNormal[] PROGMEM = "normal"; -alignas(4) constexpr static char RelayTypeInverse[] PROGMEM = "inverse"; -alignas(4) constexpr static char RelayTypeLatched[] PROGMEM = "latched"; -alignas(4) constexpr static char RelayTypeLatchedInverse[] PROGMEM = "latched-inverse"; +PROGMEM_STRING(RelayTypeNormal, "normal"); +PROGMEM_STRING(RelayTypeInverse, "inverse"); +PROGMEM_STRING(RelayTypeLatched, "latched"); +PROGMEM_STRING(RelayTypeLatchedInverse, "latched-inverse"); static constexpr std::array, 4> RelayTypeOptions PROGMEM { {{RelayType::Normal, RelayTypeNormal}, @@ -603,11 +603,11 @@ static constexpr std::array, 4> RelayTypeOptions PROGMEM {RelayType::LatchedInverse, RelayTypeLatchedInverse}} }; -alignas(4) constexpr static char None[] PROGMEM = "none"; -alignas(4) constexpr static char ZeroOrOne[] PROGMEM = "zero-or-one"; -alignas(4) constexpr static char JustOne[] PROGMEM = "just-one"; -alignas(4) constexpr static char All[] PROGMEM = "all"; -alignas(4) constexpr static char First[] PROGMEM = "first"; +PROGMEM_STRING(None, "none"); +PROGMEM_STRING(ZeroOrOne, "zero-or-one"); +PROGMEM_STRING(JustOne, "just-one"); +PROGMEM_STRING(All, "all"); +PROGMEM_STRING(First, "first"); static constexpr std::array, 5> RelaySyncOptions PROGMEM { {{RelaySync::None, None}, @@ -769,31 +769,31 @@ namespace settings { namespace keys { namespace { -alignas(4) static constexpr char Name[] PROGMEM = "relayName"; -alignas(4) static constexpr char Provider[] PROGMEM = "relayProv"; -alignas(4) static constexpr char Type[] PROGMEM = "relayType"; -alignas(4) static constexpr char GpioType[] PROGMEM = "relayGpioType"; -alignas(4) static constexpr char Gpio[] PROGMEM = "relayGpio"; -alignas(4) static constexpr char ResetGpio[] PROGMEM = "relayResetGpio"; -alignas(4) static constexpr char Boot[] PROGMEM = "relayBoot"; -alignas(4) static constexpr char DelayOn[] PROGMEM = "relayDelayOn"; -alignas(4) static constexpr char DelayOff[] PROGMEM = "relayDelayOff"; +PROGMEM_STRING(Name, "relayName"); +PROGMEM_STRING(Provider, "relayProv"); +PROGMEM_STRING(Type, "relayType"); +PROGMEM_STRING(GpioType, "relayGpioType"); +PROGMEM_STRING(Gpio, "relayGpio"); +PROGMEM_STRING(ResetGpio, "relayResetGpio"); +PROGMEM_STRING(Boot, "relayBoot"); +PROGMEM_STRING(DelayOn, "relayDelayOn"); +PROGMEM_STRING(DelayOff, "relayDelayOff"); #if MQTT_SUPPORT -alignas(4) static constexpr char TopicPub[] PROGMEM = "relayTopicPub"; -alignas(4) static constexpr char TopicSub[] PROGMEM = "relayTopicSub"; -alignas(4) static constexpr char TopicMode[] PROGMEM = "relayTopicMode"; -alignas(4) static constexpr char MqttDisconnection[] PROGMEM = "relayMqttDisc"; +PROGMEM_STRING(TopicPub, "relayTopicPub"); +PROGMEM_STRING(TopicSub, "relayTopicSub"); +PROGMEM_STRING(TopicMode, "relayTopicMode"); +PROGMEM_STRING(MqttDisconnection, "relayMqttDisc"); #endif -alignas(4) static constexpr char Dummy[] PROGMEM = "relayDummy"; -alignas(4) static constexpr char BootMask[] PROGMEM = "relayBootMask"; -alignas(4) static constexpr char Interlock[] PROGMEM = "relayIlkDelay"; -alignas(4) static constexpr char Sync[] PROGMEM = "relaySync"; +PROGMEM_STRING(Dummy, "relayDummy"); +PROGMEM_STRING(BootMask, "relayBootMask"); +PROGMEM_STRING(Interlock, "relayIlkDelay"); +PROGMEM_STRING(Sync, "relaySync"); -alignas(4) static constexpr char PayloadOn[] PROGMEM = "relayPayloadOn"; -alignas(4) static constexpr char PayloadOff[] PROGMEM = "relayPayloadOff"; -alignas(4) static constexpr char PayloadToggle[] PROGMEM = "relayPayloadOff"; +PROGMEM_STRING(PayloadOn, "relayPayloadOn"); +PROGMEM_STRING(PayloadOff, "relayPayloadOff"); +PROGMEM_STRING(PayloadToggle, "relayPayloadOff"); } // namespace } // namespace keys @@ -2561,7 +2561,7 @@ void _relayPrint(Print& out, size_t start, size_t stop) { } } -alignas(4) static constexpr char RelayCommand[] PROGMEM = "RELAY"; +PROGMEM_STRING(RelayCommand, "RELAY"); static void _relayCommand(::terminal::CommandContext&& ctx) { if (ctx.argv.size() == 1) { @@ -2595,7 +2595,7 @@ static void _relayCommand(::terminal::CommandContext&& ctx) { terminalOK(ctx); } -alignas(4) static constexpr char PulseCommand[] PROGMEM = "PULSE"; +PROGMEM_STRING(PulseCommand, "PULSE"); static void _relayCommandPulse(::terminal::CommandContext&& ctx) { if (ctx.argv.size() < 3) { @@ -2860,7 +2860,7 @@ namespace query { namespace { bool checkSamePrefix(StringView key) { - alignas(4) static constexpr char Prefix[] PROGMEM = "relay"; + PROGMEM_STRING(Prefix, "relay"); return espurna::settings::query::samePrefix(key, Prefix); } diff --git a/code/espurna/rfbridge.cpp b/code/espurna/rfbridge.cpp index c378d4de..34aa7f59 100644 --- a/code/espurna/rfbridge.cpp +++ b/code/espurna/rfbridge.cpp @@ -338,8 +338,8 @@ namespace rfbridge { namespace settings { namespace keys { -alignas(4) static constexpr char On[] PROGMEM = "rfbON"; -alignas(4) static constexpr char Off[] PROGMEM = "rfbOFF"; +PROGMEM_STRING(On, "rfbON"); +PROGMEM_STRING(Off, "rfbOFF"); } // namespace keys @@ -1174,7 +1174,7 @@ void _rfbCommandStatusDispatch(::terminal::CommandContext&& ctx, size_t id, Rela } } -alignas(4) static constexpr char RfbCommandSend[] PROGMEM = "RFB.SEND"; +PROGMEM_STRING(RfbCommandSend, "RFB.SEND"); static void _rfbCommandSend(::terminal::CommandContext&& ctx) { if (ctx.argv.size() == 2) { @@ -1186,7 +1186,7 @@ static void _rfbCommandSend(::terminal::CommandContext&& ctx) { } #if RELAY_SUPPORT -alignas(4) static constexpr char RfbCommandLearn[] PROGMEM = "RFB.LEARN"; +PROGMEM_STRING(RfbCommandLearn, "RFB.LEARN"); static void _rfbCommandLearn(::terminal::CommandContext&& ctx) { if (ctx.argv.size() != 3) { @@ -1203,7 +1203,7 @@ static void _rfbCommandLearn(::terminal::CommandContext&& ctx) { _rfbCommandStatusDispatch(std::move(ctx), id, rfbLearn); } -alignas(4) static constexpr char RfbCommandForget[] PROGMEM = "RFB.FORGET"; +PROGMEM_STRING(RfbCommandForget, "RFB.FORGET"); static void _rfbCommandForget(::terminal::CommandContext&& ctx) { if (ctx.argv.size() < 2) { @@ -1230,7 +1230,7 @@ static void _rfbCommandForget(::terminal::CommandContext&& ctx) { #endif // if RELAY_SUPPORT #if RFB_PROVIDER == RFB_PROVIDER_EFM8BB1 -alignas(4) static constexpr char RfbCommandWrite[] PROGMEM = "RFB.WRITE"; +PROGMEM_STRING(RfbCommandWrite, "RFB.WRITE"); static void _rfbCommandWrite(::terminal::CommandContext&& ctx) { if (ctx.argv.size() != 2) { diff --git a/code/espurna/rpc.cpp b/code/espurna/rpc.cpp index 34007eb9..87d21341 100644 --- a/code/espurna/rpc.cpp +++ b/code/espurna/rpc.cpp @@ -18,12 +18,12 @@ namespace espurna { namespace rpc { namespace { -alignas(4) static constexpr char Reboot[] PROGMEM = "reboot"; -alignas(4) static constexpr char Heartbeat[] PROGMEM = "heartbeat"; +PROGMEM_STRING(Reboot, "reboot"); +PROGMEM_STRING(Heartbeat, "heartbeat"); -alignas(4) static constexpr char On[] PROGMEM = "on"; -alignas(4) static constexpr char Off[] PROGMEM = "off"; -alignas(4) static constexpr char Toggle[] PROGMEM = "toggle"; +PROGMEM_STRING(On, "on"); +PROGMEM_STRING(Off, "off"); +PROGMEM_STRING(Toggle, "toggle"); void rpcPrepareReset() { prepareReset(CustomResetReason::Rpc); diff --git a/code/espurna/rpnrules.cpp b/code/espurna/rpnrules.cpp index 26f394a7..92da5b36 100644 --- a/code/espurna/rpnrules.cpp +++ b/code/espurna/rpnrules.cpp @@ -111,12 +111,12 @@ constexpr unsigned long delay() { namespace settings { namespace keys { -alignas(4) static constexpr char Sticky[] PROGMEM = "rpnSticky"; -alignas(4) static constexpr char Delay[] PROGMEM = "rpnDelay"; -alignas(4) static constexpr char Rule[] PROGMEM = "rpnRule"; +PROGMEM_STRING(Sticky, "rpnSticky"); +PROGMEM_STRING(Delay, "rpnDelay"); +PROGMEM_STRING(Rule, "rpnRule"); -alignas(4) static constexpr char Topic[] PROGMEM = "rpnTopic"; -alignas(4) static constexpr char Name[] PROGMEM = "rpnName"; +PROGMEM_STRING(Topic, "rpnTopic"); +PROGMEM_STRING(Name, "rpnName"); } // namespace keys @@ -288,7 +288,7 @@ void showStack(Print& output) { output.print(F(" (empty)\n")); } -alignas(4) static constexpr char Runners[] PROGMEM = "RPN.RUNNERS"; +PROGMEM_STRING(Runners, "RPN.RUNNERS"); void runners(::terminal::CommandContext&& ctx) { if (internal::runners.empty()) { @@ -311,7 +311,7 @@ void runners(::terminal::CommandContext&& ctx) { terminalOK(ctx); } -alignas(4) static constexpr char Variables[] PROGMEM = "RPN.VARS"; +PROGMEM_STRING(Variables, "RPN.VARS"); void variables(::terminal::CommandContext&& ctx) { rpn_variables_foreach(internal::context, @@ -325,7 +325,7 @@ void variables(::terminal::CommandContext&& ctx) { terminalOK(ctx); } -alignas(4) static constexpr char Operators[] PROGMEM = "RPN.OPS"; +PROGMEM_STRING(Operators, "RPN.OPS"); void operators(::terminal::CommandContext&& ctx) { rpn_operators_foreach(internal::context, @@ -339,7 +339,7 @@ void operators(::terminal::CommandContext&& ctx) { terminalOK(ctx); } -alignas(4) static constexpr char Test[] PROGMEM = "RPN.TEST"; +PROGMEM_STRING(Test, "RPN.TEST"); void test(::terminal::CommandContext&& ctx) { if (ctx.argv.size() != 2) { @@ -853,9 +853,9 @@ constexpr uint32_t StaleDelay { 10000ul }; namespace settings { namespace keys { -alignas(4) static constexpr char RepeatWindow[] PROGMEM = "rfbRepeatWindow"; -alignas(4) static constexpr char MatchWindow[] PROGMEM = "rfbWatchWindow"; -alignas(4) static constexpr char StaleDelay[] PROGMEM = "rfbStaleDelay"; +PROGMEM_STRING(RepeatWindow, "rfbRepeatWindow"); +PROGMEM_STRING(MatchWindow, "rfbWatchWindow"); +PROGMEM_STRING(StaleDelay, "rfbStaleDelay"); } // namespace keys @@ -1048,7 +1048,7 @@ void codeHandler(unsigned char protocol, const char* raw_code) { schedule(); } -alignas(4) static constexpr char RfbCodes[] PROGMEM = "RFB.CODES"; +PROGMEM_STRING(RfbCodes, "RFB.CODES"); void rfb_codes(::terminal::CommandContext&& ctx) { for (auto& code : internal::codes) { diff --git a/code/espurna/rtcmem.cpp b/code/espurna/rtcmem.cpp index 25d74066..87225ef3 100644 --- a/code/espurna/rtcmem.cpp +++ b/code/espurna/rtcmem.cpp @@ -66,14 +66,14 @@ bool status() { #if TERMINAL_SUPPORT namespace terminal { -alignas(4) static constexpr char Init[] PROGMEM = "RTCMEM.INIT"; +PROGMEM_STRING(Init, "RTCMEM.INIT"); void init(::terminal::CommandContext&& ctx) { rtc::init(); terminalOK(ctx); } -alignas(4) static constexpr char Dump[] PROGMEM = "RTCMEM.DUMP"; +PROGMEM_STRING(Dump, "RTCMEM.DUMP"); void dump(::terminal::CommandContext&& ctx) { ctx.output.printf_P(PSTR("boot_status=%s status=%s capacity=%u\n"), diff --git a/code/espurna/scheduler.cpp b/code/espurna/scheduler.cpp index ea829af5..d2c3ee23 100644 --- a/code/espurna/scheduler.cpp +++ b/code/espurna/scheduler.cpp @@ -112,10 +112,10 @@ namespace settings { namespace options { namespace { -alignas(4) static constexpr char None[] PROGMEM = "none"; -alignas(4) static constexpr char Relay[] PROGMEM = "relay"; -alignas(4) static constexpr char Channel[] PROGMEM = "channel"; -alignas(4) static constexpr char Curtain[] PROGMEM = "curtain"; +PROGMEM_STRING(None, "none"); +PROGMEM_STRING(Relay, "relay"); +PROGMEM_STRING(Channel, "channel"); +PROGMEM_STRING(Curtain, "curtain"); static constexpr std::array, 4> SchedulerTypeOptions PROGMEM { {{scheduler::Type::None, None}, @@ -262,15 +262,15 @@ namespace settings { namespace keys { namespace { -alignas(4) static constexpr char Enabled[] PROGMEM = "schEnabled"; -alignas(4) static constexpr char Target[] PROGMEM = "schTarget"; -alignas(4) static constexpr char Type[] PROGMEM = "schType"; -alignas(4) static constexpr char Action[] PROGMEM = "schAction"; -alignas(4) static constexpr char Restore[] PROGMEM = "schRestore"; -alignas(4) static constexpr char UseUTC[] PROGMEM = "schUTC"; -alignas(4) static constexpr char Weekdays[] PROGMEM = "schWDs"; -alignas(4) static constexpr char Hour[] PROGMEM = "schHour"; -alignas(4) static constexpr char Minute[] PROGMEM = "schMinute"; +PROGMEM_STRING(Enabled, "schEnabled"); +PROGMEM_STRING(Target, "schTarget"); +PROGMEM_STRING(Type, "schType"); +PROGMEM_STRING(Action, "schAction"); +PROGMEM_STRING(Restore, "schRestore"); +PROGMEM_STRING(UseUTC, "schUTC"); +PROGMEM_STRING(Weekdays, "schWDs"); +PROGMEM_STRING(Hour, "schHour"); +PROGMEM_STRING(Minute, "schMinute"); } // namespace } // namespace keys @@ -414,7 +414,7 @@ void migrate(int version) { namespace query { bool checkSamePrefix(StringView key) { - alignas(4) static constexpr char Prefix[] PROGMEM = "sch"; + PROGMEM_STRING(Prefix, "sch"); return espurna::settings::query::samePrefix(key, Prefix); } @@ -438,15 +438,15 @@ void setup() { namespace api { namespace keys { -alignas(4) static constexpr char Enabled[] PROGMEM = "enabled"; -alignas(4) static constexpr char Target[] PROGMEM = "enabled"; -alignas(4) static constexpr char Type[] PROGMEM = "type"; -alignas(4) static constexpr char Action[] PROGMEM = "action"; -alignas(4) static constexpr char Restore[] PROGMEM = "restore"; -alignas(4) static constexpr char UseUTC[] PROGMEM = "utc"; -alignas(4) static constexpr char Weekdays[] PROGMEM = "weekdays"; -alignas(4) static constexpr char Hour[] PROGMEM = "hour"; -alignas(4) static constexpr char Minute[] PROGMEM = "minute"; +PROGMEM_STRING(Enabled, "enabled"); +PROGMEM_STRING(Target, "enabled"); +PROGMEM_STRING(Type, "type"); +PROGMEM_STRING(Action, "action"); +PROGMEM_STRING(Restore, "restore"); +PROGMEM_STRING(UseUTC, "utc"); +PROGMEM_STRING(Weekdays, "weekdays"); +PROGMEM_STRING(Hour, "hour"); +PROGMEM_STRING(Minute, "minute"); } // namespace keys diff --git a/code/espurna/sensor.cpp b/code/espurna/sensor.cpp index 12bb4e08..93bf7668 100644 --- a/code/espurna/sensor.cpp +++ b/code/espurna/sensor.cpp @@ -891,11 +891,11 @@ namespace settings { namespace filters { namespace { -alignas(4) static constexpr char Last[] PROGMEM = "last"; -alignas(4) static constexpr char Max[] PROGMEM = "max"; -alignas(4) static constexpr char Median[] PROGMEM = "median"; -alignas(4) static constexpr char MovingAverage[] PROGMEM = "moving-average"; -alignas(4) static constexpr char Sum[] PROGMEM = "sum"; +PROGMEM_STRING(Last, "last"); +PROGMEM_STRING(Max, "max"); +PROGMEM_STRING(Median, "median"); +PROGMEM_STRING(MovingAverage, "moving-average"); +PROGMEM_STRING(Sum, "sum"); static constexpr espurna::settings::options::Enumeration Options[] PROGMEM { {Filter::Last, Last}, @@ -911,33 +911,33 @@ static constexpr espurna::settings::options::Enumeration Options[] PROGM namespace units { namespace { -alignas(4) static constexpr char Farenheit[] PROGMEM = "°F"; -alignas(4) static constexpr char Celcius[] PROGMEM = "°C"; -alignas(4) static constexpr char Kelvin[] PROGMEM = "K"; -alignas(4) static constexpr char Percentage[] PROGMEM = "%"; -alignas(4) static constexpr char Hectopascal[] PROGMEM = "hPa"; -alignas(4) static constexpr char Ampere[] PROGMEM = "A"; -alignas(4) static constexpr char Volt[] PROGMEM = "V"; -alignas(4) static constexpr char Watt[] PROGMEM = "W"; -alignas(4) static constexpr char Kilowatt[] PROGMEM = "kW"; -alignas(4) static constexpr char Voltampere[] PROGMEM = "VA"; -alignas(4) static constexpr char Kilovoltampere[] PROGMEM = "kVA"; -alignas(4) static constexpr char VoltampereReactive[] PROGMEM = "VAR"; -alignas(4) static constexpr char KilovoltampereReactive[] PROGMEM = "kVAR"; -alignas(4) static constexpr char Joule[] PROGMEM = "J"; -alignas(4) static constexpr char KilowattHour[] PROGMEM = "kWh"; -alignas(4) static constexpr char MicrogrammPerCubicMeter[] PROGMEM = "µg/m³"; -alignas(4) static constexpr char PartsPerMillion[] PROGMEM = "ppm"; -alignas(4) static constexpr char Lux[] PROGMEM = "lux"; -alignas(4) static constexpr char UltravioletIndex[] PROGMEM = "UVindex"; -alignas(4) static constexpr char Ohm[] PROGMEM = "ohm"; -alignas(4) static constexpr char MilligrammPerCubicMeter[] PROGMEM = "mg/m³"; -alignas(4) static constexpr char CountsPerMinute[] PROGMEM = "cpm"; -alignas(4) static constexpr char MicrosievertPerHour[] PROGMEM = "µSv/h"; -alignas(4) static constexpr char Meter[] PROGMEM = "m"; -alignas(4) static constexpr char Hertz[] PROGMEM = "Hz"; -alignas(4) static constexpr char Ph[] PROGMEM = "pH"; -alignas(4) static constexpr char None[] PROGMEM = "none"; +PROGMEM_STRING(Farenheit, "°F"); +PROGMEM_STRING(Celcius, "°C"); +PROGMEM_STRING(Kelvin, "K"); +PROGMEM_STRING(Percentage, "%"); +PROGMEM_STRING(Hectopascal, "hPa"); +PROGMEM_STRING(Ampere, "A"); +PROGMEM_STRING(Volt, "V"); +PROGMEM_STRING(Watt, "W"); +PROGMEM_STRING(Kilowatt, "kW"); +PROGMEM_STRING(Voltampere, "VA"); +PROGMEM_STRING(Kilovoltampere, "kVA"); +PROGMEM_STRING(VoltampereReactive, "VAR"); +PROGMEM_STRING(KilovoltampereReactive, "kVAR"); +PROGMEM_STRING(Joule, "J"); +PROGMEM_STRING(KilowattHour, "kWh"); +PROGMEM_STRING(MicrogrammPerCubicMeter, "µg/m³"); +PROGMEM_STRING(PartsPerMillion, "ppm"); +PROGMEM_STRING(Lux, "lux"); +PROGMEM_STRING(UltravioletIndex, "UVindex"); +PROGMEM_STRING(Ohm, "ohm"); +PROGMEM_STRING(MilligrammPerCubicMeter, "mg/m³"); +PROGMEM_STRING(CountsPerMinute, "cpm"); +PROGMEM_STRING(MicrosievertPerHour, "µSv/h"); +PROGMEM_STRING(Meter, "m"); +PROGMEM_STRING(Hertz, "Hz"); +PROGMEM_STRING(Ph, "pH"); +PROGMEM_STRING(None, "none"); static constexpr espurna::settings::options::Enumeration Options[] PROGMEM { {Unit::Farenheit, Farenheit}, @@ -976,49 +976,49 @@ static constexpr espurna::settings::options::Enumeration Options[] PROGMEM namespace prefix { namespace { -alignas(4) static constexpr char Sensor[] PROGMEM = "sns"; -alignas(4) static constexpr char Power[] PROGMEM = "pwr"; +PROGMEM_STRING(Sensor, "sns"); +PROGMEM_STRING(Power, "pwr"); -alignas(4) static constexpr char Temperature[] PROGMEM = "tmp"; -alignas(4) static constexpr char Humidity[] PROGMEM = "hum"; -alignas(4) static constexpr char Pressure[] PROGMEM = "press"; -alignas(4) static constexpr char Current[] PROGMEM = "curr"; -alignas(4) static constexpr char Voltage[] PROGMEM = "volt"; -alignas(4) static constexpr char PowerActive[] PROGMEM = "pwrP"; -alignas(4) static constexpr char PowerApparent[] PROGMEM = "pwrQ"; -alignas(4) static constexpr char PowerReactive[] PROGMEM = "pwrModS"; -alignas(4) static constexpr char PowerFactor[] PROGMEM = "pwrPF"; -alignas(4) static constexpr char Energy[] PROGMEM = "ene"; -alignas(4) static constexpr char EnergyDelta[] PROGMEM = "eneDelta"; -alignas(4) static constexpr char Analog[] PROGMEM = "analog"; -alignas(4) static constexpr char Digital[] PROGMEM = "digital"; -alignas(4) static constexpr char Event[] PROGMEM = "event"; -alignas(4) static constexpr char Pm1Dot0[] PROGMEM = "pm1dot0"; -alignas(4) static constexpr char Pm2Dot5[] PROGMEM = "pm2dot5"; -alignas(4) static constexpr char Pm10[] PROGMEM = "pm10"; -alignas(4) static constexpr char Co2[] PROGMEM = "co2"; -alignas(4) static constexpr char Voc[] PROGMEM = "voc"; -alignas(4) static constexpr char Iaq[] PROGMEM = "iaq"; -alignas(4) static constexpr char IaqAccuracy[] PROGMEM = "iaqAccuracy"; -alignas(4) static constexpr char IaqStatic[] PROGMEM = "iaqStatic"; -alignas(4) static constexpr char Lux[] PROGMEM = "lux"; -alignas(4) static constexpr char Uva[] PROGMEM = "uva"; -alignas(4) static constexpr char Uvb[] PROGMEM = "uvb"; -alignas(4) static constexpr char Uvi[] PROGMEM = "uvi"; -alignas(4) static constexpr char Distance[] PROGMEM = "distance"; -alignas(4) static constexpr char Hcho[] PROGMEM = "hcho"; -alignas(4) static constexpr char GeigerCpm[] PROGMEM = "gcpm"; -alignas(4) static constexpr char GeigerSievert[] PROGMEM = "gsiev"; -alignas(4) static constexpr char Count[] PROGMEM = "count"; -alignas(4) static constexpr char No2[] PROGMEM = "no2"; -alignas(4) static constexpr char Co[] PROGMEM = "co"; -alignas(4) static constexpr char Resistance[] PROGMEM = "res"; -alignas(4) static constexpr char Ph[] PROGMEM = "ph"; -alignas(4) static constexpr char Frequency[] PROGMEM = "freq"; -alignas(4) static constexpr char Tvoc[] PROGMEM = "tvoc"; -alignas(4) static constexpr char Ch2o[] PROGMEM = "ch2o"; +PROGMEM_STRING(Temperature, "tmp"); +PROGMEM_STRING(Humidity, "hum"); +PROGMEM_STRING(Pressure, "press"); +PROGMEM_STRING(Current, "curr"); +PROGMEM_STRING(Voltage, "volt"); +PROGMEM_STRING(PowerActive, "pwrP"); +PROGMEM_STRING(PowerApparent, "pwrQ"); +PROGMEM_STRING(PowerReactive, "pwrModS"); +PROGMEM_STRING(PowerFactor, "pwrPF"); +PROGMEM_STRING(Energy, "ene"); +PROGMEM_STRING(EnergyDelta, "eneDelta"); +PROGMEM_STRING(Analog, "analog"); +PROGMEM_STRING(Digital, "digital"); +PROGMEM_STRING(Event, "event"); +PROGMEM_STRING(Pm1Dot0, "pm1dot0"); +PROGMEM_STRING(Pm2Dot5, "pm2dot5"); +PROGMEM_STRING(Pm10, "pm10"); +PROGMEM_STRING(Co2, "co2"); +PROGMEM_STRING(Voc, "voc"); +PROGMEM_STRING(Iaq, "iaq"); +PROGMEM_STRING(IaqAccuracy, "iaqAccuracy"); +PROGMEM_STRING(IaqStatic, "iaqStatic"); +PROGMEM_STRING(Lux, "lux"); +PROGMEM_STRING(Uva, "uva"); +PROGMEM_STRING(Uvb, "uvb"); +PROGMEM_STRING(Uvi, "uvi"); +PROGMEM_STRING(Distance, "distance"); +PROGMEM_STRING(Hcho, "hcho"); +PROGMEM_STRING(GeigerCpm, "gcpm"); +PROGMEM_STRING(GeigerSievert, "gsiev"); +PROGMEM_STRING(Count, "count"); +PROGMEM_STRING(No2, "no2"); +PROGMEM_STRING(Co, "co"); +PROGMEM_STRING(Resistance, "res"); +PROGMEM_STRING(Ph, "ph"); +PROGMEM_STRING(Frequency, "freq"); +PROGMEM_STRING(Tvoc, "tvoc"); +PROGMEM_STRING(Ch2o, "ch2o"); -alignas(4) static constexpr char Unknown[] PROGMEM = "unknown"; +PROGMEM_STRING(Unknown, "unknown"); constexpr StringView get(unsigned char type) { return (type == MAGNITUDE_TEMPERATURE) ? Temperature : @@ -1068,19 +1068,19 @@ constexpr StringView get(unsigned char type) { namespace suffix { namespace { -alignas(4) static constexpr char Units[] PROGMEM = "Units"; -alignas(4) static constexpr char Ratio[] PROGMEM = "Ratio"; -alignas(4) static constexpr char Correction[] PROGMEM = "Correction"; -alignas(4) static constexpr char ZeroThreshold[] PROGMEM = "ZeroThreshold"; -alignas(4) static constexpr char MinDelta[] PROGMEM = "MinDelta"; -alignas(4) static constexpr char MaxDelta[] PROGMEM = "MaxDelta"; +PROGMEM_STRING(Units, "Units"); +PROGMEM_STRING(Ratio, "Ratio"); +PROGMEM_STRING(Correction, "Correction"); +PROGMEM_STRING(ZeroThreshold, "ZeroThreshold"); +PROGMEM_STRING(MinDelta, "MinDelta"); +PROGMEM_STRING(MaxDelta, "MaxDelta"); -alignas(4) static constexpr char Mains[] PROGMEM = "Mains"; -alignas(4) static constexpr char Reference[] PROGMEM = "Reference"; +PROGMEM_STRING(Mains, "Mains"); +PROGMEM_STRING(Reference, "Reference"); -alignas(4) static constexpr char Total[] PROGMEM = "Total"; +PROGMEM_STRING(Total, "Total"); -alignas(4) static constexpr char Filter[] PROGMEM = "Filter"; +PROGMEM_STRING(Filter, "Filter"); } // namespace } // namespace suffix @@ -1088,11 +1088,11 @@ alignas(4) static constexpr char Filter[] PROGMEM = "Filter"; namespace keys { namespace { -alignas(4) static constexpr char ReadInterval[] PROGMEM = "snsRead"; -alignas(4) static constexpr char InitInterval[] PROGMEM = "snsInit"; -alignas(4) static constexpr char ReportEvery[] PROGMEM = "snsReport"; -alignas(4) static constexpr char SaveEvery[] PROGMEM = "snsSave"; -alignas(4) static constexpr char RealTimeValues[] PROGMEM = "snsRealTime"; +PROGMEM_STRING(ReadInterval, "snsRead"); +PROGMEM_STRING(InitInterval, "snsInit"); +PROGMEM_STRING(ReportEvery, "snsReport"); +PROGMEM_STRING(SaveEvery, "snsSave"); +PROGMEM_STRING(RealTimeValues, "snsRealTime"); espurna::settings::Key get(espurna::StringView prefix, espurna::StringView suffix, size_t index) { String key; @@ -1138,7 +1138,7 @@ bool realTimeValues() { } // namespace } // namespace settings -alignas(4) static constexpr char List[] PROGMEM = +alignas(4) static constexpr char List[] PROGMEM_STRING_ATTR = #if ADE7953_SUPPORT "ADE7953 " #endif @@ -3664,7 +3664,7 @@ namespace { namespace commands { -alignas(4) static constexpr char Magnitudes[] PROGMEM = "MAGNITUDES"; +PROGMEM_STRING(Magnitudes, "MAGNITUDES"); void magnitudes(::terminal::CommandContext&& ctx) { if (!magnitude::count()) { @@ -3685,7 +3685,7 @@ void magnitudes(::terminal::CommandContext&& ctx) { terminalOK(ctx); } -alignas(4) static constexpr char Expected[] PROGMEM = "EXPECTED"; +PROGMEM_STRING(Expected, "EXPECTED"); void expected(::terminal::CommandContext&& ctx) { if (ctx.argv.size() == 3) { @@ -3709,14 +3709,14 @@ void expected(::terminal::CommandContext&& ctx) { terminalError(ctx, F("EXPECTED ")); } -alignas(4) static constexpr char ResetRatios[] PROGMEM = "RESET.RATIOS"; +PROGMEM_STRING(ResetRatios, "RESET.RATIOS"); void reset_ratios(::terminal::CommandContext&& ctx) { energy::reset(); terminalOK(ctx); } -alignas(4) static constexpr char Energy[] PROGMEM = "ENERGY"; +PROGMEM_STRING(Energy, "ENERGY"); void energy(::terminal::CommandContext&& ctx) { using IndexType = decltype(Magnitude::index_global); diff --git a/code/espurna/sensors/PZEM004TSensor.h b/code/espurna/sensors/PZEM004TSensor.h index 920640e6..4b44fd68 100644 --- a/code/espurna/sensors/PZEM004TSensor.h +++ b/code/espurna/sensors/PZEM004TSensor.h @@ -591,7 +591,7 @@ constexpr BaseEmonSensor::Magnitude PZEM004TSensor::Magnitudes[]; #endif #if TERMINAL_SUPPORT -alignas(4) static constexpr char PzemDevices[] PROGMEM = "PZ.DEVICES"; +PROGMEM_STRING(PzemDevices, "PZ.DEVICES"); void PZEM004TSensor::command_devices(::terminal::CommandContext&& ctx) { foreach([&](const PZEM004TSensor&, const IPAddress& address) { @@ -600,7 +600,7 @@ void PZEM004TSensor::command_devices(::terminal::CommandContext&& ctx) { terminalOK(ctx); } -alignas(4) static constexpr char PzemPorts[] PROGMEM = "PZ.PORTS"; +PROGMEM_STRING(PzemPorts, "PZ.PORTS"); void PZEM004TSensor::command_ports(::terminal::CommandContext&& ctx) { auto it = _ports.begin(); @@ -646,7 +646,7 @@ void PZEM004TSensor::command_ports(::terminal::CommandContext&& ctx) { terminalOK(ctx); } -alignas(4) static constexpr char PzemAddress[] PROGMEM = "PZ.ADDRESS"; +PROGMEM_STRING(PzemAddress, "PZ.ADDRESS"); // Set the *currently connected* device address // (ref. comment at the top, shouldn't do this when multiple devices are connected) diff --git a/code/espurna/sensors/PZEM004TV30Sensor.h b/code/espurna/sensors/PZEM004TV30Sensor.h index 8a6989bf..6c8e4e3a 100644 --- a/code/espurna/sensors/PZEM004TV30Sensor.h +++ b/code/espurna/sensors/PZEM004TV30Sensor.h @@ -608,7 +608,7 @@ constexpr espurna::duration::Milliseconds PZEM004TV30Sensor::DefaultUpdateInterv PZEM004TV30Sensor::Instance PZEM004TV30Sensor::_instance{}; -alignas(4) static constexpr char PzemV3Address[] PROGMEM = "PZ.ADDRESS"; +PROGMEM_STRING(PzemV3Address, "PZ.ADDRESS"); void PZEM004TV30Sensor::command_address(::terminal::CommandContext&& ctx) { if (ctx.argv.size() != 2) { diff --git a/code/espurna/settings.cpp b/code/espurna/settings.cpp index 6523a555..e8efe507 100644 --- a/code/espurna/settings.cpp +++ b/code/espurna/settings.cpp @@ -300,7 +300,7 @@ void dump(const ::terminal::CommandContext& ctx, const query::IndexedSetting* be namespace commands { -alignas(4) static constexpr char Config[] PROGMEM = "CONFIG"; +PROGMEM_STRING(Config, "CONFIG"); void config(::terminal::CommandContext&& ctx) { DynamicJsonBuffer jsonBuffer(1024); @@ -310,7 +310,7 @@ void config(::terminal::CommandContext&& ctx) { terminalOK(ctx); } -alignas(4) static constexpr char Keys[] PROGMEM = "KEYS"; +PROGMEM_STRING(Keys, "KEYS"); void keys(::terminal::CommandContext&& ctx) { const auto keys = settings::sorted_keys(); @@ -333,7 +333,7 @@ void keys(::terminal::CommandContext&& ctx) { terminalOK(ctx); } -alignas(4) static constexpr char Gc[] PROGMEM = "GC"; +PROGMEM_STRING(Gc, "GC"); void gc(::terminal::CommandContext&& ctx) { struct KeyRef { @@ -379,7 +379,7 @@ void gc(::terminal::CommandContext&& ctx) { terminalOK(ctx); } -alignas(4) static constexpr char Del[] PROGMEM = "DEL"; +PROGMEM_STRING(Del, "DEL"); void del(::terminal::CommandContext&& ctx) { if (ctx.argv.size() < 2) { @@ -399,7 +399,7 @@ void del(::terminal::CommandContext&& ctx) { } } -alignas(4) static constexpr char Set[] PROGMEM = "SET"; +PROGMEM_STRING(Set, "SET"); void set(::terminal::CommandContext&& ctx) { if (ctx.argv.size() != 3) { @@ -415,7 +415,7 @@ void set(::terminal::CommandContext&& ctx) { terminalError(ctx, F("could not set the key")); } -alignas(4) static constexpr char Get[] PROGMEM = "GET"; +PROGMEM_STRING(Get, "GET"); void get(::terminal::CommandContext&& ctx) { if (ctx.argv.size() < 2) { @@ -442,14 +442,14 @@ void get(::terminal::CommandContext&& ctx) { terminalOK(ctx); } -alignas(4) static constexpr char Reload[] PROGMEM = "RELOAD"; +PROGMEM_STRING(Reload, "RELOAD"); void reload(::terminal::CommandContext&& ctx) { espurnaReload(); terminalOK(ctx); } -alignas(4) static constexpr char FactoryReset[] PROGMEM = "FACTORY.RESET"; +PROGMEM_STRING(FactoryReset, "FACTORY.RESET"); void factory_reset(::terminal::CommandContext&& ctx) { factoryReset(); @@ -457,7 +457,7 @@ void factory_reset(::terminal::CommandContext&& ctx) { } [[gnu::unused]] -alignas(4) static constexpr char Save[] PROGMEM = "SAVE"; +PROGMEM_STRING(Save, "SAVE"); [[gnu::unused]] void save(::terminal::CommandContext&& ctx) { diff --git a/code/espurna/storage_eeprom.cpp b/code/espurna/storage_eeprom.cpp index 779b9a36..9d5c4a7a 100644 --- a/code/espurna/storage_eeprom.cpp +++ b/code/espurna/storage_eeprom.cpp @@ -71,7 +71,7 @@ void eepromBackup(uint32_t index){ } #if TERMINAL_SUPPORT -alignas(4) static constexpr char EepromCommand[] PROGMEM = "EEPROM"; +PROGMEM_STRING(EepromCommand, "EEPROM"); static void _eepromCommand(::terminal::CommandContext&& ctx) { ctx.output.printf_P(PSTR("Sectors: %s, current: %lu\n"), @@ -83,21 +83,21 @@ static void _eepromCommand(::terminal::CommandContext&& ctx) { terminalOK(ctx); } -alignas(4) static constexpr char EepromCommit[] PROGMEM = "EEPROM.COMMIT"; +PROGMEM_STRING(EepromCommit, "EEPROM.COMMIT"); static void _eepromCommandCommit(::terminal::CommandContext&& ctx) { _eepromCommit(); terminalOK(ctx); } -alignas(4) static constexpr char EepromDump[] PROGMEM = "EEPROM.DUMP"; +PROGMEM_STRING(EepromDump, "EEPROM.DUMP"); static void _eepromCommandDump(::terminal::CommandContext&& ctx) { EEPROMr.dump(static_cast(ctx.output)); // XXX: only Print interface is used terminalOK(ctx); } -alignas(4) static constexpr char FlashDump[] PROGMEM = "FLASH.DUMP"; +PROGMEM_STRING(FlashDump, "FLASH.DUMP"); static void _flashCommandDump(::terminal::CommandContext&& ctx) { if (ctx.argv.size() < 2) { diff --git a/code/espurna/system.cpp b/code/espurna/system.cpp index 6af01cce..1c54ac4f 100644 --- a/code/espurna/system.cpp +++ b/code/espurna/system.cpp @@ -45,9 +45,9 @@ namespace { namespace settings { namespace options { -alignas(4) static constexpr char None[] PROGMEM = "none"; -alignas(4) static constexpr char Once[] PROGMEM = "once"; -alignas(4) static constexpr char Repeat[] PROGMEM = "repeat"; +PROGMEM_STRING(None, "none"); +PROGMEM_STRING(Once, "once"); +PROGMEM_STRING(Repeat, "repeat"); static constexpr espurna::settings::options::Enumeration HeartbeatModeOptions[] PROGMEM { {heartbeat::Mode::None, None}, @@ -59,9 +59,9 @@ static constexpr espurna::settings::options::Enumeration Heartb namespace keys { -alignas(4) static constexpr char Hostname[] PROGMEM = "hostname"; -alignas(4) static constexpr char Description[] PROGMEM = "desc"; -alignas(4) static constexpr char Password[] PROGMEM = "adminPass"; +PROGMEM_STRING(Hostname, "hostname"); +PROGMEM_STRING(Description, "desc"); +PROGMEM_STRING(Password, "adminPass"); } // namespace keys @@ -133,8 +133,8 @@ namespace { namespace internal { -alignas(4) static constexpr char Hostname[] PROGMEM = HOSTNAME; -alignas(4) static constexpr char Password[] PROGMEM = ADMIN_PASS; +PROGMEM_STRING(Hostname, HOSTNAME); +PROGMEM_STRING(Password, ADMIN_PASS); } // namespace internal @@ -875,9 +875,9 @@ constexpr Mask value() { namespace settings { namespace keys { -alignas(4) static constexpr char Mode[] PROGMEM = "hbMode"; -alignas(4) static constexpr char Interval[] PROGMEM = "hbInterval"; -alignas(4) static constexpr char Report[] PROGMEM = "hbReport"; +PROGMEM_STRING(Mode, "hbMode"); +PROGMEM_STRING(Interval, "hbInterval"); +PROGMEM_STRING(Report, "hbReport"); } // namespace keys diff --git a/code/espurna/telnet.cpp b/code/espurna/telnet.cpp index ce81c97e..de579dcf 100644 --- a/code/espurna/telnet.cpp +++ b/code/espurna/telnet.cpp @@ -75,11 +75,11 @@ constexpr bool authentication() { namespace settings { namespace keys { -alignas(4) static constexpr char Prefix[] PROGMEM = "telnet"; +PROGMEM_STRING(Prefix, "telnet"); -alignas(4) static constexpr char Station[] PROGMEM = "telnetSTA"; -alignas(4) static constexpr char Authentication[] PROGMEM = "telnetAuth"; -alignas(4) static constexpr char Port[] PROGMEM = "telnetPort"; +PROGMEM_STRING(Station, "telnetSTA"); +PROGMEM_STRING(Authentication, "telnetAuth"); +PROGMEM_STRING(Port, "telnetPort"); } // namespace keys @@ -268,9 +268,9 @@ private: namespace message { -alignas(4) static constexpr char PasswordRequest[] = "Password (disconnects after 1 failed attempt): "; -alignas(4) static constexpr char InvalidPassword[] = "-ERROR: Invalid password\n"; -alignas(4) static constexpr char OkPassword[] = "+OK\n"; +PROGMEM_STRING(PasswordRequest, "Password (disconnects after 1 failed attempt): "); +PROGMEM_STRING(InvalidPassword, "-ERROR: Invalid password\n"); +PROGMEM_STRING(OkPassword, "+OK\n"); } // namespace message @@ -864,7 +864,7 @@ bool connect(Address address) { namespace terminal { namespace commands { -alignas(4) static constexpr char Reverse[] PROGMEM = "TELNET.REVERSE"; +PROGMEM_STRING(Reverse, "TELNET.REVERSE"); void reverse(::terminal::CommandContext&& ctx) { if (ctx.argv.size() != 3) { diff --git a/code/espurna/terminal.cpp b/code/espurna/terminal.cpp index 48fd0fa4..bf272011 100644 --- a/code/espurna/terminal.cpp +++ b/code/espurna/terminal.cpp @@ -60,8 +60,8 @@ constexpr size_t serialPort() { namespace commands { -alignas(4) static constexpr char Commands[] PROGMEM = "COMMANDS"; -alignas(4) static constexpr char Help[] PROGMEM = "HELP"; +PROGMEM_STRING(Commands, "COMMANDS"); +PROGMEM_STRING(Help, "HELP"); void help(CommandContext&& ctx) { auto names = terminal::names(); @@ -83,14 +83,14 @@ void help(CommandContext&& ctx) { terminalOK(ctx); } -alignas(4) static constexpr char Reset[] PROGMEM = "RESET"; +PROGMEM_STRING(Reset, "RESET"); void reset(CommandContext&& ctx) { prepareReset(CustomResetReason::Terminal); terminalOK(ctx); } -alignas(4) static constexpr char EraseConfig[] PROGMEM = "ERASE.CONFIG"; +PROGMEM_STRING(EraseConfig, "ERASE.CONFIG"); void erase_config(CommandContext&& ctx) { terminalOK(ctx); @@ -98,7 +98,7 @@ void erase_config(CommandContext&& ctx) { forceEraseSDKConfig(); } -alignas(4) static constexpr char Heap[] PROGMEM = "HEAP"; +PROGMEM_STRING(Heap, "HEAP"); void heap(CommandContext&& ctx) { const auto stats = systemHeapStats(); @@ -108,7 +108,7 @@ void heap(CommandContext&& ctx) { terminalOK(ctx); } -alignas(4) static constexpr char Uptime[] PROGMEM = "UPTIME"; +PROGMEM_STRING(Uptime, "UPTIME"); void uptime(CommandContext&& ctx) { ctx.output.printf_P(PSTR("uptime %s\n"), @@ -116,7 +116,7 @@ void uptime(CommandContext&& ctx) { terminalOK(ctx); } -alignas(4) static constexpr char Info[] PROGMEM = "INFO"; +PROGMEM_STRING(Info, "INFO"); void info(CommandContext&& ctx) { const auto app = buildApp(); @@ -276,7 +276,7 @@ StringView flash_chip_mode() { return out; } -alignas(4) static constexpr char Storage[] PROGMEM = "STORAGE"; +PROGMEM_STRING(Storage, "STORAGE"); void storage(CommandContext&& ctx) { ctx.output.printf_P(PSTR("flash chip ID: 0x%06X\n"), ESP.getFlashChipId()); @@ -317,7 +317,7 @@ void storage(CommandContext&& ctx) { terminalOK(ctx); } -alignas(4) static constexpr char Adc[] PROGMEM = "ADC"; +PROGMEM_STRING(Adc, "ADC"); void adc(CommandContext&& ctx) { const int pin = (ctx.argv.size() == 2) @@ -329,21 +329,21 @@ void adc(CommandContext&& ctx) { } #if SYSTEM_CHECK_ENABLED -alignas(4) static constexpr char Stable[] PROGMEM = "STABLE"; +PROGMEM_STRING(Stable, "STABLE"); void stable(CommandContext&& ctx) { systemForceStable(); prepareReset(CustomResetReason::Stability); } -alignas(4) static constexpr char Unstable[] PROGMEM = "UNSTABLE"; +PROGMEM_STRING(Unstable, "UNSTABLE"); void unstable(CommandContext&& ctx) { systemForceUnstable(); prepareReset(CustomResetReason::Stability); } -alignas(4) static constexpr char Trap[] PROGMEM = "TRAP"; +PROGMEM_STRING(Trap, "TRAP"); void trap(CommandContext&& ctx) { __builtin_trap(); @@ -606,12 +606,12 @@ void onVisible(JsonObject& root) { } void onAction(uint32_t client_id, const char* action, JsonObject& data) { - alignas(4) static constexpr char Cmd[] PROGMEM = "cmd"; + PROGMEM_STRING(Cmd, "cmd"); if (strncmp_P(action, &Cmd[0], __builtin_strlen(Cmd)) != 0) { return; } - alignas(4) static constexpr char Line[] PROGMEM = "line"; + PROGMEM_STRING(Line, "line"); if (!data.containsKey(FPSTR(Line)) || !data[FPSTR(Line)].is()) { return; } diff --git a/code/espurna/thingspeak.cpp b/code/espurna/thingspeak.cpp index b1809a55..0ce6a6b9 100644 --- a/code/espurna/thingspeak.cpp +++ b/code/espurna/thingspeak.cpp @@ -47,8 +47,8 @@ static constexpr auto FlushInterval = espurna::duration::Milliseconds(THINGSPEAK static constexpr size_t Retries { THINGSPEAK_TRIES }; static constexpr size_t BufferSize { 256 }; -alignas(4) static constexpr char ApiKey[] PROGMEM = THINGSPEAK_APIKEY; -alignas(4) static constexpr char Address[] PROGMEM = THINGSPEAK_ADDRESS; +PROGMEM_STRING(ApiKey, THINGSPEAK_APIKEY); +PROGMEM_STRING(Address, THINGSPEAK_ADDRESS); constexpr bool enabled() { return 1 == THINGSPEAK_ENABLED; @@ -63,18 +63,18 @@ constexpr bool clearCache() { namespace settings { namespace keys { -alignas(4) static constexpr char Enabled[] PROGMEM = "tspkEnabled"; -alignas(4) static constexpr char ApiKey[] PROGMEM = "tspkKey"; -alignas(4) static constexpr char ClearCache[] PROGMEM = "tspkClear"; -alignas(4) static constexpr char Address[] PROGMEM = "tspkAddress"; +PROGMEM_STRING(Enabled, "tspkEnabled"); +PROGMEM_STRING(ApiKey, "tspkKey"); +PROGMEM_STRING(ClearCache, "tspkClear"); +PROGMEM_STRING(Address, "tspkAddress"); -alignas(4) static constexpr char Relay[] PROGMEM = "tspkRelay"; -alignas(4) static constexpr char Magnitude[] PROGMEM = "tspkMagnitude"; +PROGMEM_STRING(Relay, "tspkRelay"); +PROGMEM_STRING(Magnitude, "tspkMagnitude"); #if THINGSPEAK_USE_SSL && (SECURE_CLIENT != SECURE_CLIENT_NONE) -alignas(4) static constexpr char Check[] PROGMEM = "tspkScCheck"; -alignas(4) static constexpr char Fingerprint[] PROGMEM = "tspkFP"; -alignas(4) static constexpr char Mfln[] PROGMEM = "tspkMfln"; +PROGMEM_STRING(Check, "tspkScCheck"); +PROGMEM_STRING(Fingerprint, "tspkFP"); +PROGMEM_STRING(Mfln, "tspkMfln"); #endif } // namespace keys @@ -222,8 +222,8 @@ namespace { static constexpr int Check { THINGSPEAK_SECURE_CLIENT_CHECK }; static constexpr uint16_t Mfln { THINGSPEAK_SECURE_CLIENT_MFLN }; -alignas(4) static constexpr char Tag[] PROGMEM = "THINGSPEAK"; -alignas(4) static constexpr char Fingerprint[] PROGMEM = THINGSPEAK_FINGERPRINT; +PROGMEM_STRING(Tag, "THINGSPEAK"); +PROGMEM_STRING(Fingerprint, THINGSPEAK_FINGERPRINT); SecureClientConfig secure_config { .tag = Tag, @@ -471,8 +471,8 @@ private: return; } - alignas(4) static constexpr char Status[] PROGMEM = "HTTP/1.1 200 OK"; - alignas(4) static constexpr char Break[] PROGMEM = "\r\n\r\n"; + PROGMEM_STRING(Status, "HTTP/1.1 200 OK"); + PROGMEM_STRING(Break, "\r\n\r\n"); auto begin = reinterpret_cast(data); auto end = begin + len; @@ -679,7 +679,7 @@ void loop() { namespace web { namespace { -alignas(4) static constexpr char Prefix[] PROGMEM = "tspk"; +PROGMEM_STRING(Prefix, "tspk"); bool onKeyCheck(StringView key, const JsonVariant&) { return espurna::settings::query::samePrefix(key, Prefix); diff --git a/code/espurna/tuya.cpp b/code/espurna/tuya.cpp index 68617615..9825f8f2 100644 --- a/code/espurna/tuya.cpp +++ b/code/espurna/tuya.cpp @@ -604,7 +604,7 @@ error: #endif #if TERMINAL_SUPPORT - alignas(4) static constexpr char TuyaShow[] PROGMEM = "TUYA.SHOW"; + PROGMEM_STRING(TuyaShow, "TUYA.SHOW"); static void terminalShow(::terminal::CommandContext&& ctx) { ctx.output.printf_P(PSTR("Product: %s\n"), product.length() ? product.c_str() : "(unknown)"); @@ -636,7 +636,7 @@ error: } } - alignas(4) static constexpr char TuyaSave[] PROGMEM = "TUYA.SAVE"; + PROGMEM_STRING(TuyaSave, "TUYA.SAVE"); static void terminalSave(::terminal::CommandContext&& ctx) { for (auto& kv : config) { diff --git a/code/espurna/types.h b/code/espurna/types.h index f13f7ade..7c97d755 100644 --- a/code/espurna/types.h +++ b/code/espurna/types.h @@ -341,13 +341,19 @@ inline String operator+=(String& lhs, StringView rhs) { return lhs; } +#define PROGMEM_STRING_ATTR __attribute__((section( "\".irom0.pstr." __FILE__ "." __STRINGIZE(__LINE__) "." __STRINGIZE(__COUNTER__) "\", \"aSM\", @progbits, 1 #"))) + +#define PROGMEM_STRING(NAME, X)\ + alignas(4) static constexpr char NAME[] PROGMEM_STRING_ATTR = (X) + + #define STRING_VIEW(X) ({\ - alignas(4) static constexpr char __pstr__[] PROGMEM = (X);\ + alignas(4) static constexpr char __pstr__[] PROGMEM_STRING_ATTR = (X);\ ::espurna::StringView{__pstr__};\ }) #define STRING_VIEW_INLINE(NAME, X)\ - alignas(4) static constexpr char __pstr__ ## NAME ## __ [] PROGMEM = (X);\ + alignas(4) static constexpr char __pstr__ ## NAME ## __ [] PROGMEM_STRING_ATTR = (X);\ constexpr auto NAME = ::espurna::StringView(__pstr__ ## NAME ## __) } // namespace espurna diff --git a/code/espurna/uart.cpp b/code/espurna/uart.cpp index ee0cadc2..1ec481e3 100644 --- a/code/espurna/uart.cpp +++ b/code/espurna/uart.cpp @@ -45,9 +45,9 @@ namespace settings { namespace internal { namespace { -alignas(4) static constexpr char ParityNone[] PROGMEM = "none"; -alignas(4) static constexpr char ParityEven[] PROGMEM = "even"; -alignas(4) static constexpr char ParityOdd[] PROGMEM = "odd"; +PROGMEM_STRING(ParityNone, "none"); +PROGMEM_STRING(ParityEven, "even"); +PROGMEM_STRING(ParityOdd, "odd"); static constexpr std::array, 3> ParityOptions PROGMEM { {{driver::uart::Parity::None, ParityNone}, @@ -183,16 +183,16 @@ constexpr ::SerialConfig from_config(Config config) { namespace settings { namespace keys { -alignas(4) static constexpr char TxPin[] PROGMEM = "uartTx"; -alignas(4) static constexpr char RxPin[] PROGMEM = "uartRx"; +PROGMEM_STRING(TxPin, "uartTx"); +PROGMEM_STRING(RxPin, "uartRx"); -alignas(4) static constexpr char Baudrate[] PROGMEM = "uartBaud"; +PROGMEM_STRING(Baudrate, "uartBaud"); -alignas(4) static constexpr char DataBits[] PROGMEM = "uartDataBits"; -alignas(4) static constexpr char StopBits[] PROGMEM = "uartStopBits"; -alignas(4) static constexpr char Parity[] PROGMEM = "uartParity"; +PROGMEM_STRING(DataBits, "uartDataBits"); +PROGMEM_STRING(StopBits, "uartStopBits"); +PROGMEM_STRING(Parity, "uartParity"); -alignas(4) static constexpr char Invert[] PROGMEM = "uartInv"; +PROGMEM_STRING(Invert, "uartInv"); } // namespace keys @@ -426,7 +426,7 @@ static constexpr espurna::settings::query::IndexedSetting IndexedSettings[] PROG }; bool checkSamePrefix(StringView key) { - alignas(4) static constexpr char Prefix[] PROGMEM = "uart"; + PROGMEM_STRING(Prefix, "uart"); return espurna::settings::query::samePrefix(key, Prefix); } @@ -502,7 +502,7 @@ void uart(::terminal::CommandContext&& ctx) { terminalOK(ctx); } -alignas(4) static constexpr char Uart[] PROGMEM = "UART"; +PROGMEM_STRING(Uart, "UART"); static constexpr ::terminal::Command List[] PROGMEM { {Uart, commands::uart}, diff --git a/code/espurna/web.cpp b/code/espurna/web.cpp index 4c557c05..ee13a6ae 100644 --- a/code/espurna/web.cpp +++ b/code/espurna/web.cpp @@ -215,7 +215,7 @@ size_t AsyncWebPrint::write(const uint8_t* data, size_t size) { namespace { -alignas(4) static constexpr char LastModified[] PROGMEM = __DATE__ " " __TIME__ " GMT"; +PROGMEM_STRING(LastModified, __DATE__ " " __TIME__ " GMT"); static constexpr size_t WebConfigBufferMax { 4096 }; // server instance can't (yet) be static, port is the ctor argument :/ @@ -467,7 +467,7 @@ void _onAPCaptiveRequest(AsyncWebServerRequest* request) { #endif #if WEB_EMBEDDED -alignas(4) static constexpr char IfModifiedSince[] PROGMEM = "If-Modified-Since"; +PROGMEM_STRING(IfModifiedSince, "If-Modified-Since"); void _onHome(AsyncWebServerRequest *request) { if (!_isAPModeRequest(request) && !_authenticateRequest(request)) { diff --git a/code/espurna/wifi.cpp b/code/espurna/wifi.cpp index b2c86039..1a0a6289 100644 --- a/code/espurna/wifi.cpp +++ b/code/espurna/wifi.cpp @@ -68,9 +68,9 @@ namespace ap { namespace settings { namespace options { -alignas(4) static constexpr char Disabled[] PROGMEM = "off"; -alignas(4) static constexpr char Enabled[] PROGMEM = "on"; -alignas(4) static constexpr char Fallback[] PROGMEM = "fallback"; +PROGMEM_STRING(Disabled, "off"); +PROGMEM_STRING(Enabled, "on"); +PROGMEM_STRING(Fallback, "fallback"); static constexpr espurna::settings::options::Enumeration ApModeOptions[] PROGMEM { {wifi::ApMode::Disabled, Disabled}, @@ -85,9 +85,9 @@ static constexpr espurna::settings::options::Enumeration ApModeOpt namespace settings { namespace options { -alignas(4) static constexpr char None[] PROGMEM = "none"; -alignas(4) static constexpr char Modem[] PROGMEM = "modem"; -alignas(4) static constexpr char Light[] PROGMEM = "light"; +PROGMEM_STRING(None, "none"); +PROGMEM_STRING(Modem, "modem"); +PROGMEM_STRING(Light, "light"); static constexpr espurna::settings::options::Enumeration WiFiSleepTypeOptions[] PROGMEM { {WIFI_NONE_SLEEP, None}, @@ -465,8 +465,8 @@ String opmode(uint8_t mode) { namespace settings { namespace keys { -alignas(4) static constexpr char TxPower[] PROGMEM = "wifiTxPwr"; -alignas(4) static constexpr char Sleep[] PROGMEM = "wifiSleep"; +PROGMEM_STRING(TxPower, "wifiTxPwr"); +PROGMEM_STRING(Sleep, "wifiSleep"); } // namespace keys @@ -898,18 +898,18 @@ constexpr uint8_t channel(size_t index) { namespace settings { namespace keys { -alignas(4) static constexpr char Mode[] PROGMEM = "wifiStaMode"; +PROGMEM_STRING(Mode, "wifiStaMode"); -alignas(4) static constexpr char Ssid[] PROGMEM = "ssid"; -alignas(4) static constexpr char Passphrase[] PROGMEM = "pass"; +PROGMEM_STRING(Ssid, "ssid"); +PROGMEM_STRING(Passphrase, "pass"); -alignas(4) static constexpr char Ip[] PROGMEM = "ip"; -alignas(4) static constexpr char Gateway[] PROGMEM = "gw"; -alignas(4) static constexpr char Netmask[] PROGMEM = "mask"; -alignas(4) static constexpr char Dns[] PROGMEM = "dns"; +PROGMEM_STRING(Ip, "ip"); +PROGMEM_STRING(Gateway, "gw"); +PROGMEM_STRING(Netmask, "mask"); +PROGMEM_STRING(Dns, "dns"); -alignas(4) static constexpr char Bssid[] PROGMEM = "bssid"; -alignas(4) static constexpr char Channel[] PROGMEM = "chan"; +PROGMEM_STRING(Bssid, "bssid"); +PROGMEM_STRING(Channel, "chan"); } // namespace keys @@ -1159,7 +1159,7 @@ namespace scan { namespace settings { namespace keys { -alignas(4) static constexpr char Enabled[] PROGMEM = "wifiScan"; +PROGMEM_STRING(Enabled, "wifiScan"); } // namespace keys } // namespace settings @@ -1708,7 +1708,7 @@ constexpr int8_t threshold() { namespace settings { namespace keys { -alignas(4) static constexpr char Threshold[] PROGMEM = "wifiScanRssi"; +PROGMEM_STRING(Threshold, "wifiScanRssi"); } // namespace keys @@ -1913,14 +1913,14 @@ constexpr uint8_t channel() { namespace settings { namespace keys { -alignas(4) static constexpr char Mode[] PROGMEM = "wifiApMode"; +PROGMEM_STRING(Mode, "wifiApMode"); -alignas(4) static constexpr char Ssid[] PROGMEM = "wifiApSsid"; -alignas(4) static constexpr char Passphrase[] PROGMEM = "wifiApPass"; +PROGMEM_STRING(Ssid, "wifiApSsid"); +PROGMEM_STRING(Passphrase, "wifiApPass"); -alignas(4) static constexpr char Channel[] PROGMEM = "wifiApChan"; +PROGMEM_STRING(Channel, "wifiApChan"); -[[gnu::unused]] alignas(4) static constexpr char Captive[] PROGMEM = "wifiApCaptive"; +[[gnu::unused]] PROGMEM_STRING(Captive, "wifiApCaptive"); } // namespace keys @@ -2181,7 +2181,7 @@ bool checkIndexedPrefix(StringView key) { // generic 'ap' and 'modem' configuration bool checkExactPrefix(StringView key) { - alignas(4) static constexpr char Prefix[] PROGMEM = "wifi"; + PROGMEM_STRING(Prefix, "wifi"); if (espurna::settings::query::samePrefix(key, Prefix)) { return true; } @@ -2235,7 +2235,7 @@ void configure() { namespace terminal { namespace commands { -alignas(4) static constexpr char Stations[] PROGMEM = "WIFI.STATIONS"; +PROGMEM_STRING(Stations, "WIFI.STATIONS"); void stations(::terminal::CommandContext&& ctx) { size_t stations { 0ul }; @@ -2255,7 +2255,7 @@ void stations(::terminal::CommandContext&& ctx) { terminalOK(ctx); } -alignas(4) static constexpr char Network[] PROGMEM = "NETWORK"; +PROGMEM_STRING(Network, "NETWORK"); void network(::terminal::CommandContext&& ctx) { for (auto& addr : addrList) { @@ -2294,7 +2294,7 @@ void network(::terminal::CommandContext&& ctx) { } } -alignas(4) static constexpr char Wifi[] PROGMEM = "WIFI"; +PROGMEM_STRING(Wifi, "WIFI"); void wifi(::terminal::CommandContext&& ctx) { if (ctx.argv.size() == 2) { @@ -2341,7 +2341,7 @@ void wifi(::terminal::CommandContext&& ctx) { terminalOK(ctx); } -alignas(4) static constexpr char Reset[] PROGMEM = "WIFI.RESET"; +PROGMEM_STRING(Reset, "WIFI.RESET"); void reset(::terminal::CommandContext&& ctx) { wifi::sta::disconnect(); @@ -2349,21 +2349,21 @@ void reset(::terminal::CommandContext&& ctx) { terminalOK(ctx); } -alignas(4) static constexpr char Station[] PROGMEM = "WIFI.STA"; +PROGMEM_STRING(Station, "WIFI.STA"); void station(::terminal::CommandContext&& ctx) { wifi::sta::toggle(); terminalOK(ctx); } -alignas(4) static constexpr char AccessPoint[] PROGMEM = "WIFI.AP"; +PROGMEM_STRING(AccessPoint, "WIFI.AP"); void access_point(::terminal::CommandContext&& ctx) { wifi::ap::toggle(); terminalOK(ctx); } -alignas(4) static constexpr char Scan[] PROGMEM = "WIFI.SCAN"; +PROGMEM_STRING(Scan, "WIFI.SCAN"); void scan(::terminal::CommandContext&& ctx) { wifi::sta::scan::wait( diff --git a/code/espurna/ws.cpp b/code/espurna/ws.cpp index 3dd44c62..fcda3fd0 100644 --- a/code/espurna/ws.cpp +++ b/code/espurna/ws.cpp @@ -34,7 +34,7 @@ namespace { namespace internal { -alignas(4) static constexpr char SchemaKey[] PROGMEM = "schema"; +PROGMEM_STRING(SchemaKey, "schema"); } // namespace internal @@ -822,7 +822,7 @@ bool wsConnected(uint32_t client_id) { } void wsPayloadModule(JsonObject& root, const char* name) { - alignas(4) static constexpr char Key[] PROGMEM = "modulesVisible"; + PROGMEM_STRING(Key, "modulesVisible"); JsonArray& modules = root.containsKey(FPSTR(Key)) ? root[FPSTR(Key)] : root.createNestedArray(FPSTR(Key));