LSH-Core
Deterministic firmware core for Controllino-based Labo Smart Home nodes
 
Loading...
Searching...
No Matches
user_config_bridge.hpp
Go to the documentation of this file.
1
21#ifndef LSH_CORE_INTERNAL_USER_CONFIG_BRIDGE_HPP
22#define LSH_CORE_INTERNAL_USER_CONFIG_BRIDGE_HPP
23
24#include <stdint.h>
25
26#if defined(LSH_CUSTOM_USER_CONFIG_HEADER)
27#include LSH_CUSTOM_USER_CONFIG_HEADER
28#else
29#include "lsh_user_config.hpp"
30#endif
31
33
34// The generated router is deliberately included through a pass macro. Resource
35// pass only emits compile-time capacities and feature switches, keeping this
36// bridge light enough to be included by almost every translation unit.
37#define LSH_STATIC_CONFIG_RESOURCE_PASS 1
38#if defined(LSH_CUSTOM_STATIC_CONFIG_ROUTER_HEADER)
39#include LSH_CUSTOM_STATIC_CONFIG_ROUTER_HEADER
40#else
41#include "lsh_static_config_router.hpp"
42#endif
43#undef LSH_STATIC_CONFIG_RESOURCE_PASS
44
45#define CONFIG_HAS_STATIC_CONFIG 1
46
47#ifndef LSH_STATIC_CONFIG_CLICKABLES
48#error "LSH_STATIC_CONFIG_CLICKABLES must be defined by the static profile."
49#endif
50#ifndef LSH_STATIC_CONFIG_ACTUATORS
51#error "LSH_STATIC_CONFIG_ACTUATORS must be defined by the static profile."
52#endif
53#ifndef LSH_STATIC_CONFIG_INDICATORS
54#error "LSH_STATIC_CONFIG_INDICATORS must be defined by the static profile."
55#endif
56#ifndef LSH_STATIC_CONFIG_MAX_CLICKABLE_ID
57#error "LSH_STATIC_CONFIG_MAX_CLICKABLE_ID must be defined by the static profile."
58#endif
59#ifndef LSH_STATIC_CONFIG_MAX_ACTUATOR_ID
60#error "LSH_STATIC_CONFIG_MAX_ACTUATOR_ID must be defined by the static profile."
61#endif
62#ifndef LSH_STATIC_CONFIG_SHORT_CLICK_ACTUATOR_LINKS
63#error "LSH_STATIC_CONFIG_SHORT_CLICK_ACTUATOR_LINKS must be defined by the static profile."
64#endif
65#ifndef LSH_STATIC_CONFIG_LONG_CLICK_ACTUATOR_LINKS
66#error "LSH_STATIC_CONFIG_LONG_CLICK_ACTUATOR_LINKS must be defined by the static profile."
67#endif
68#ifndef LSH_STATIC_CONFIG_SUPER_LONG_CLICK_ACTUATOR_LINKS
69#error "LSH_STATIC_CONFIG_SUPER_LONG_CLICK_ACTUATOR_LINKS must be defined by the static profile."
70#endif
71#ifndef LSH_STATIC_CONFIG_INDICATOR_ACTUATOR_LINKS
72#error "LSH_STATIC_CONFIG_INDICATOR_ACTUATOR_LINKS must be defined by the static profile."
73#endif
74#ifndef LSH_STATIC_CONFIG_AUTO_OFF_ACTUATORS
75#error "LSH_STATIC_CONFIG_AUTO_OFF_ACTUATORS must be defined by the static profile."
76#endif
77#ifndef LSH_STATIC_CONFIG_PULSE_ACTUATORS
78#error "LSH_STATIC_CONFIG_PULSE_ACTUATORS must be defined by the static profile."
79#endif
80#ifndef LSH_STATIC_CONFIG_ACTIVE_NETWORK_CLICKS
81#error "LSH_STATIC_CONFIG_ACTIVE_NETWORK_CLICKS must be defined by the static profile."
82#endif
83#ifndef LSH_STATIC_CONFIG_DISABLE_NETWORK_CLICKS
84#error "LSH_STATIC_CONFIG_DISABLE_NETWORK_CLICKS must be defined by the static profile."
85#endif
86
87static_assert(LSH_STATIC_CONFIG_CLICKABLES >= 0, "LSH_STATIC_CONFIG_CLICKABLES must be non-negative.");
88static_assert(LSH_STATIC_CONFIG_CLICKABLES <= UINT8_MAX, "LSH_STATIC_CONFIG_CLICKABLES must fit in uint8_t.");
89static_assert(LSH_STATIC_CONFIG_ACTUATORS >= 0, "LSH_STATIC_CONFIG_ACTUATORS must be non-negative.");
90static_assert(LSH_STATIC_CONFIG_ACTUATORS <= UINT8_MAX, "LSH_STATIC_CONFIG_ACTUATORS must fit in uint8_t.");
91static_assert(LSH_STATIC_CONFIG_INDICATORS >= 0, "LSH_STATIC_CONFIG_INDICATORS must be non-negative.");
92static_assert(LSH_STATIC_CONFIG_INDICATORS <= UINT8_MAX, "LSH_STATIC_CONFIG_INDICATORS must fit in uint8_t.");
93static_assert(LSH_STATIC_CONFIG_MAX_CLICKABLE_ID > 0, "LSH_STATIC_CONFIG_MAX_CLICKABLE_ID must be greater than zero.");
94static_assert(LSH_STATIC_CONFIG_MAX_CLICKABLE_ID <= UINT8_MAX, "LSH_STATIC_CONFIG_MAX_CLICKABLE_ID must fit in uint8_t.");
95static_assert(LSH_STATIC_CONFIG_MAX_ACTUATOR_ID > 0, "LSH_STATIC_CONFIG_MAX_ACTUATOR_ID must be greater than zero.");
96static_assert(LSH_STATIC_CONFIG_MAX_ACTUATOR_ID <= UINT8_MAX, "LSH_STATIC_CONFIG_MAX_ACTUATOR_ID must fit in uint8_t.");
97static_assert(LSH_STATIC_CONFIG_DISABLE_NETWORK_CLICKS == 0U || LSH_STATIC_CONFIG_DISABLE_NETWORK_CLICKS == 1U,
98 "LSH_STATIC_CONFIG_DISABLE_NETWORK_CLICKS must be 0 or 1.");
99
100static constexpr const char *CONFIG_DEVICE_NAME = LSH_DEVICE_NAME();
101static constexpr uint8_t CONFIG_MAX_CLICKABLES =
102 LSH_STATIC_CONFIG_CLICKABLES;
103static constexpr uint8_t CONFIG_MAX_ACTUATORS =
104 LSH_STATIC_CONFIG_ACTUATORS;
105static constexpr uint8_t CONFIG_MAX_INDICATORS =
106 LSH_STATIC_CONFIG_INDICATORS;
107static constexpr uint8_t CONFIG_PACKED_ACTUATOR_STATE_BYTES =
108 static_cast<uint8_t>((CONFIG_MAX_ACTUATORS + 7U) >> 3U);
109static constexpr uint8_t CONFIG_PACKED_ACTUATOR_STATE_STORAGE_CAPACITY =
110 (CONFIG_PACKED_ACTUATOR_STATE_BYTES == 0U)
111 ? 1U
112 : CONFIG_PACKED_ACTUATOR_STATE_BYTES;
113
114// Compute worst-case compact-pool budgets in 32 bits first, then downcast only
115// after a static check. Today the device counts are 8-bit, so the product still
116// fits in 16 bits, but keeping the wide intermediate makes the intent explicit
117// and protects future maintenance if the count types ever grow.
118static constexpr uint32_t CONFIG_CLICKABLE_ACTUATOR_LINKS_WORST_CASE =
119 static_cast<uint32_t>(CONFIG_MAX_CLICKABLES) * static_cast<uint32_t>(CONFIG_MAX_ACTUATORS);
120static constexpr uint32_t CONFIG_INDICATOR_ACTUATOR_LINKS_WORST_CASE =
121 static_cast<uint32_t>(CONFIG_MAX_INDICATORS) * static_cast<uint32_t>(CONFIG_MAX_ACTUATORS);
122static constexpr uint16_t CONFIG_NETWORK_CLICK_TRANSACTIONS_WORST_CASE =
123 static_cast<uint16_t>(static_cast<uint16_t>(CONFIG_MAX_CLICKABLES) * 2U);
124static_assert(CONFIG_CLICKABLE_ACTUATOR_LINKS_WORST_CASE <= UINT16_MAX,
125 "Worst-case clickable actuator-link budget exceeds 16-bit storage.");
126static_assert(CONFIG_INDICATOR_ACTUATOR_LINKS_WORST_CASE <= UINT16_MAX,
127 "Worst-case indicator actuator-link budget exceeds 16-bit storage.");
128
129#if LSH_STATIC_CONFIG_DISABLE_NETWORK_CLICKS
130#define CONFIG_USE_NETWORK_CLICKS 0
131#else
132#define CONFIG_USE_NETWORK_CLICKS 1
133#endif
134
135#if defined(LSH_NETWORK_CLICKS)
136#error "LSH_NETWORK_CLICKS was removed; network-click support is derived from network=true click actions."
137#endif
138
139static_assert(LSH_STATIC_CONFIG_ACTIVE_NETWORK_CLICKS >= 0, "LSH_STATIC_CONFIG_ACTIVE_NETWORK_CLICKS must be non-negative.");
140static_assert(LSH_STATIC_CONFIG_ACTIVE_NETWORK_CLICKS <= UINT8_MAX, "LSH_STATIC_CONFIG_ACTIVE_NETWORK_CLICKS must fit in uint8_t.");
141static_assert(LSH_STATIC_CONFIG_ACTIVE_NETWORK_CLICKS <= CONFIG_NETWORK_CLICK_TRANSACTIONS_WORST_CASE,
142 "LSH_STATIC_CONFIG_ACTIVE_NETWORK_CLICKS cannot exceed two network-click transactions per clickable.");
143static_assert((CONFIG_USE_NETWORK_CLICKS && LSH_STATIC_CONFIG_ACTIVE_NETWORK_CLICKS > 0U) ||
144 (!CONFIG_USE_NETWORK_CLICKS && LSH_STATIC_CONFIG_ACTIVE_NETWORK_CLICKS == 0U),
145 "Static network-click profile must use a positive pool only when network clicks are enabled.");
146static constexpr uint8_t CONFIG_MAX_ACTIVE_NETWORK_CLICKS =
147 LSH_STATIC_CONFIG_ACTIVE_NETWORK_CLICKS;
148static constexpr uint8_t CONFIG_ACTIVE_NETWORK_CLICK_STORAGE_CAPACITY =
149 (CONFIG_MAX_ACTIVE_NETWORK_CLICKS == 0U) ? 1U : CONFIG_MAX_ACTIVE_NETWORK_CLICKS;
150
151static_assert(LSH_STATIC_CONFIG_AUTO_OFF_ACTUATORS >= 0, "LSH_STATIC_CONFIG_AUTO_OFF_ACTUATORS must be non-negative.");
152static_assert(LSH_STATIC_CONFIG_AUTO_OFF_ACTUATORS <= UINT8_MAX, "LSH_STATIC_CONFIG_AUTO_OFF_ACTUATORS must fit in uint8_t.");
153static constexpr uint16_t CONFIG_MAX_AUTO_OFF_ACTUATORS_WIDE = static_cast<uint16_t>(LSH_STATIC_CONFIG_AUTO_OFF_ACTUATORS);
154static_assert(CONFIG_MAX_AUTO_OFF_ACTUATORS_WIDE <= static_cast<uint16_t>(CONFIG_MAX_ACTUATORS),
155 "LSH_STATIC_CONFIG_AUTO_OFF_ACTUATORS cannot exceed LSH_STATIC_CONFIG_ACTUATORS.");
156static constexpr uint8_t CONFIG_MAX_AUTO_OFF_ACTUATORS =
157 static_cast<uint8_t>(CONFIG_MAX_AUTO_OFF_ACTUATORS_WIDE);
158static constexpr uint8_t CONFIG_AUTO_OFF_STORAGE_CAPACITY = (CONFIG_MAX_AUTO_OFF_ACTUATORS == 0U) ? 1U : CONFIG_MAX_AUTO_OFF_ACTUATORS;
159
160static_assert(LSH_STATIC_CONFIG_PULSE_ACTUATORS >= 0, "LSH_STATIC_CONFIG_PULSE_ACTUATORS must be non-negative.");
161static_assert(LSH_STATIC_CONFIG_PULSE_ACTUATORS <= UINT8_MAX, "LSH_STATIC_CONFIG_PULSE_ACTUATORS must fit in uint8_t.");
162static constexpr uint16_t CONFIG_MAX_PULSE_ACTUATORS_WIDE = static_cast<uint16_t>(LSH_STATIC_CONFIG_PULSE_ACTUATORS);
163static_assert(CONFIG_MAX_PULSE_ACTUATORS_WIDE <= static_cast<uint16_t>(CONFIG_MAX_ACTUATORS),
164 "LSH_STATIC_CONFIG_PULSE_ACTUATORS cannot exceed LSH_STATIC_CONFIG_ACTUATORS.");
165static constexpr uint8_t CONFIG_MAX_PULSE_ACTUATORS =
166 static_cast<uint8_t>(CONFIG_MAX_PULSE_ACTUATORS_WIDE);
167static constexpr uint8_t CONFIG_PULSE_STORAGE_CAPACITY = (CONFIG_MAX_PULSE_ACTUATORS == 0U) ? 1U : CONFIG_MAX_PULSE_ACTUATORS;
168
169#if defined(LSH_COMPACT_ACTUATOR_SWITCH_TIMES)
170#error "LSH_COMPACT_ACTUATOR_SWITCH_TIMES was removed; set CONFIG_ACTUATOR_DEBOUNCE_TIME_MS=0 for automatic compact storage."
171#endif
172
173#if (LSH_STATIC_CONFIG_AUTO_OFF_ACTUATORS > 0) && defined(CONFIG_ACTUATOR_DEBOUNCE_TIME_MS) && (CONFIG_ACTUATOR_DEBOUNCE_TIME_MS == 0)
174#define CONFIG_USE_COMPACT_ACTUATOR_SWITCH_TIMES 1
175#else
176#define CONFIG_USE_COMPACT_ACTUATOR_SWITCH_TIMES 0
177#endif
178
179static constexpr uint8_t CONFIG_MAX_CLICKABLE_ID =
180 LSH_STATIC_CONFIG_MAX_CLICKABLE_ID;
181
182static constexpr uint8_t CONFIG_MAX_ACTUATOR_ID =
183 LSH_STATIC_CONFIG_MAX_ACTUATOR_ID;
184
185static_assert(LSH_STATIC_CONFIG_SHORT_CLICK_ACTUATOR_LINKS >= 0, "LSH_STATIC_CONFIG_SHORT_CLICK_ACTUATOR_LINKS must be non-negative.");
186static_assert(LSH_STATIC_CONFIG_SHORT_CLICK_ACTUATOR_LINKS <= CONFIG_CLICKABLE_ACTUATOR_LINKS_WORST_CASE,
187 "LSH_STATIC_CONFIG_SHORT_CLICK_ACTUATOR_LINKS exceeds the clickable*actuator worst case.");
188static constexpr uint16_t CONFIG_MAX_SHORT_CLICK_ACTUATOR_LINKS =
189 LSH_STATIC_CONFIG_SHORT_CLICK_ACTUATOR_LINKS;
190
191static_assert(LSH_STATIC_CONFIG_LONG_CLICK_ACTUATOR_LINKS >= 0, "LSH_STATIC_CONFIG_LONG_CLICK_ACTUATOR_LINKS must be non-negative.");
192static_assert(LSH_STATIC_CONFIG_LONG_CLICK_ACTUATOR_LINKS <= CONFIG_CLICKABLE_ACTUATOR_LINKS_WORST_CASE,
193 "LSH_STATIC_CONFIG_LONG_CLICK_ACTUATOR_LINKS exceeds the clickable*actuator worst case.");
194static constexpr uint16_t CONFIG_MAX_LONG_CLICK_ACTUATOR_LINKS =
195 LSH_STATIC_CONFIG_LONG_CLICK_ACTUATOR_LINKS;
196
197static_assert(LSH_STATIC_CONFIG_SUPER_LONG_CLICK_ACTUATOR_LINKS >= 0,
198 "LSH_STATIC_CONFIG_SUPER_LONG_CLICK_ACTUATOR_LINKS must be non-negative.");
199static_assert(LSH_STATIC_CONFIG_SUPER_LONG_CLICK_ACTUATOR_LINKS <= CONFIG_CLICKABLE_ACTUATOR_LINKS_WORST_CASE,
200 "LSH_STATIC_CONFIG_SUPER_LONG_CLICK_ACTUATOR_LINKS exceeds the clickable*actuator worst case.");
201static constexpr uint16_t CONFIG_MAX_SUPER_LONG_CLICK_ACTUATOR_LINKS =
202 LSH_STATIC_CONFIG_SUPER_LONG_CLICK_ACTUATOR_LINKS;
203
204static_assert(LSH_STATIC_CONFIG_INDICATOR_ACTUATOR_LINKS >= 0, "LSH_STATIC_CONFIG_INDICATOR_ACTUATOR_LINKS must be non-negative.");
205static_assert(LSH_STATIC_CONFIG_INDICATOR_ACTUATOR_LINKS <= CONFIG_INDICATOR_ACTUATOR_LINKS_WORST_CASE,
206 "LSH_STATIC_CONFIG_INDICATOR_ACTUATOR_LINKS exceeds the indicator*actuator worst case.");
207static constexpr uint16_t CONFIG_MAX_INDICATOR_ACTUATOR_LINKS =
208 LSH_STATIC_CONFIG_INDICATOR_ACTUATOR_LINKS;
209
210// ETL arrays must have a strictly positive compile-time capacity.
211// A device may legitimately configure zero links of one category, so the
212// runtime keeps two numbers:
213// - CONFIG_MAX_*_LINKS: the real logical maximum used for validation
214// - CONFIG_*_STORAGE_CAPACITY: the physical ETL capacity, clamped to at least 1
215//
216// When the logical maximum is zero, the extra ETL slot is never used at runtime.
217static constexpr uint16_t CONFIG_SHORT_CLICK_ACTUATOR_LINK_STORAGE_CAPACITY =
218 (CONFIG_MAX_SHORT_CLICK_ACTUATOR_LINKS == 0U)
219 ? 1U
220 : CONFIG_MAX_SHORT_CLICK_ACTUATOR_LINKS;
221static constexpr uint16_t CONFIG_LONG_CLICK_ACTUATOR_LINK_STORAGE_CAPACITY =
222 (CONFIG_MAX_LONG_CLICK_ACTUATOR_LINKS == 0U)
223 ? 1U
224 : CONFIG_MAX_LONG_CLICK_ACTUATOR_LINKS;
225static constexpr uint16_t CONFIG_SUPER_LONG_CLICK_ACTUATOR_LINK_STORAGE_CAPACITY =
226 (CONFIG_MAX_SUPER_LONG_CLICK_ACTUATOR_LINKS == 0U)
227 ? 1U
228 : CONFIG_MAX_SUPER_LONG_CLICK_ACTUATOR_LINKS;
229static constexpr uint16_t CONFIG_INDICATOR_ACTUATOR_LINK_STORAGE_CAPACITY =
230 (CONFIG_MAX_INDICATOR_ACTUATOR_LINKS == 0U)
231 ? 1U
232 : CONFIG_MAX_INDICATOR_ACTUATOR_LINKS;
233
234static constexpr HardwareSerial *const CONFIG_COM_SERIAL = LSH_COM_SERIAL();
235static constexpr HardwareSerial *const CONFIG_DEBUG_SERIAL = LSH_DEBUG_SERIAL();
236
237#endif // LSH_CORE_INTERNAL_USER_CONFIG_BRIDGE_HPP
Internal bridge to include the user-specified hardware library (e.g., Arduino.h).