FastLED 3.9.15
Loading...
Searching...
No Matches

◆ begin()

fl::optional< fl::task::Error > fl::spi::MultiLaneDevice::begin ( )

Initialize hardware.

Returns
Optional error (nullopt on success)
Note
Auto-selects SpiHw1/2/4/8 based on number of data pins

Definition at line 78 of file multi_lane_device.cpp.hpp.

78 {
79 if (!pImpl) {
80 return fl::task::Error("Device not initialized");
81 }
82
83 if (pImpl->initialized) {
84 // Already initialized - idempotent
85 return fl::nullopt;
86 }
87
88 size_t num_lanes = pImpl->config.data_pins.size();
89
90 // Validate lane count
91 if (num_lanes < 1 || num_lanes > 8) {
92 return fl::task::Error("Invalid number of lanes (must be 1-8)");
93 }
94
95 // Auto-select appropriate hardware backend based on lane count
96 if (num_lanes == 1) {
97 // Try Single-SPI (SpiHw1)
98 const auto& controllers = SpiHw1::getAll();
99 if (controllers.empty()) {
100 FL_WARN("MultiLaneDevice: No Single-SPI hardware available");
101 return fl::task::Error("Single-SPI hardware not available");
102 }
103
104 // Find first available controller
105 fl::shared_ptr<SpiHw1> hw;
106 for (const auto& ctrl : controllers) {
107 if (!ctrl->isInitialized()) {
108 hw = ctrl;
109 break;
110 }
111 }
112
113 if (!hw) {
114 FL_WARN("MultiLaneDevice: All Single-SPI controllers in use");
115 return fl::task::Error("All Single-SPI controllers already in use");
116 }
117
118 // Configure Single-SPI
119 SpiHw1::Config hw_config;
120 hw_config.bus_num = static_cast<u8>(hw->getBusId());
121 hw_config.clock_speed_hz = pImpl->config.clock_speed_hz;
122 hw_config.clock_pin = pImpl->config.clock_pin;
123 hw_config.data_pin = pImpl->config.data_pins[0];
124
125 if (!hw->begin(hw_config)) {
126 FL_WARN("MultiLaneDevice: Failed to initialize Single-SPI hardware");
127 return fl::task::Error("Failed to initialize Single-SPI hardware");
128 }
129
130 pImpl->backend = hw;
131 pImpl->backend_type = 1;
132 FL_DBG("MultiLaneDevice: Initialized Single-SPI (" << hw->getName() << ")");
133
134 } else if (num_lanes == 2) {
135 // Try Dual-SPI (SpiHw2)
136 const auto& controllers = SpiHw2::getAll();
137 if (controllers.empty()) {
138 FL_WARN("MultiLaneDevice: No Dual-SPI hardware available");
139 return fl::task::Error("Dual-SPI hardware not available");
140 }
141
142 // Find first available controller
143 fl::shared_ptr<SpiHw2> hw;
144 for (const auto& ctrl : controllers) {
145 if (!ctrl->isInitialized()) {
146 hw = ctrl;
147 break;
148 }
149 }
150
151 if (!hw) {
152 FL_WARN("MultiLaneDevice: All Dual-SPI controllers in use");
153 return fl::task::Error("All Dual-SPI controllers already in use");
154 }
155
156 // Configure Dual-SPI
157 SpiHw2::Config hw_config;
158 hw_config.bus_num = static_cast<u8>(hw->getBusId());
159 hw_config.clock_speed_hz = pImpl->config.clock_speed_hz;
160 hw_config.clock_pin = pImpl->config.clock_pin;
161 hw_config.data0_pin = pImpl->config.data_pins[0];
162 hw_config.data1_pin = pImpl->config.data_pins[1];
163
164 if (!hw->begin(hw_config)) {
165 FL_WARN("MultiLaneDevice: Failed to initialize Dual-SPI hardware");
166 return fl::task::Error("Failed to initialize Dual-SPI hardware");
167 }
168
169 pImpl->backend = hw;
170 pImpl->backend_type = 2;
171 FL_DBG("MultiLaneDevice: Initialized Dual-SPI (" << hw->getName() << ")");
172
173 } else if (num_lanes >= 3 && num_lanes <= 4) {
174 // Try Quad-SPI (SpiHw4)
175 const auto& controllers = SpiHw4::getAll();
176 if (controllers.empty()) {
177 FL_WARN("MultiLaneDevice: No Quad-SPI hardware available");
178 return fl::task::Error("Quad-SPI hardware not available");
179 }
180
181 // Find first available controller
182 fl::shared_ptr<SpiHw4> hw;
183 for (const auto& ctrl : controllers) {
184 if (!ctrl->isInitialized()) {
185 hw = ctrl;
186 break;
187 }
188 }
189
190 if (!hw) {
191 FL_WARN("MultiLaneDevice: All Quad-SPI controllers in use");
192 return fl::task::Error("All Quad-SPI controllers already in use");
193 }
194
195 // Configure Quad-SPI
196 SpiHw4::Config hw_config;
197 hw_config.bus_num = static_cast<u8>(hw->getBusId());
198 hw_config.clock_speed_hz = pImpl->config.clock_speed_hz;
199 hw_config.clock_pin = pImpl->config.clock_pin;
200 hw_config.data0_pin = pImpl->config.data_pins[0];
201 hw_config.data1_pin = (num_lanes > 1) ? pImpl->config.data_pins[1] : -1;
202 hw_config.data2_pin = (num_lanes > 2) ? pImpl->config.data_pins[2] : -1;
203 hw_config.data3_pin = (num_lanes > 3) ? pImpl->config.data_pins[3] : -1;
204
205 if (!hw->begin(hw_config)) {
206 FL_WARN("MultiLaneDevice: Failed to initialize Quad-SPI hardware");
207 return fl::task::Error("Failed to initialize Quad-SPI hardware");
208 }
209
210 pImpl->backend = hw;
211 pImpl->backend_type = 4;
212 FL_DBG("MultiLaneDevice: Initialized Quad-SPI (" << hw->getName() << ")");
213
214 } else if (num_lanes >= 5 && num_lanes <= 8) {
215 // Try Octal-SPI (SpiHw8)
216 const auto& controllers = SpiHw8::getAll();
217 if (controllers.empty()) {
218 FL_WARN("MultiLaneDevice: No Octal-SPI hardware available");
219 return fl::task::Error("Octal-SPI hardware not available");
220 }
221
222 // Find first available controller
223 fl::shared_ptr<SpiHw8> hw;
224 for (const auto& ctrl : controllers) {
225 if (!ctrl->isInitialized()) {
226 hw = ctrl;
227 break;
228 }
229 }
230
231 if (!hw) {
232 FL_WARN("MultiLaneDevice: All Octal-SPI controllers in use");
233 return fl::task::Error("All Octal-SPI controllers already in use");
234 }
235
236 // Configure Octal-SPI
237 SpiHw8::Config hw_config;
238 hw_config.bus_num = static_cast<u8>(hw->getBusId());
239 hw_config.clock_speed_hz = pImpl->config.clock_speed_hz;
240 hw_config.clock_pin = pImpl->config.clock_pin;
241 hw_config.data0_pin = pImpl->config.data_pins[0];
242 hw_config.data1_pin = (num_lanes > 1) ? pImpl->config.data_pins[1] : -1;
243 hw_config.data2_pin = (num_lanes > 2) ? pImpl->config.data_pins[2] : -1;
244 hw_config.data3_pin = (num_lanes > 3) ? pImpl->config.data_pins[3] : -1;
245 hw_config.data4_pin = (num_lanes > 4) ? pImpl->config.data_pins[4] : -1;
246 hw_config.data5_pin = (num_lanes > 5) ? pImpl->config.data_pins[5] : -1;
247 hw_config.data6_pin = (num_lanes > 6) ? pImpl->config.data_pins[6] : -1;
248 hw_config.data7_pin = (num_lanes > 7) ? pImpl->config.data_pins[7] : -1;
249
250 if (!hw->begin(hw_config)) {
251 FL_WARN("MultiLaneDevice: Failed to initialize Octal-SPI hardware");
252 return fl::task::Error("Failed to initialize Octal-SPI hardware");
253 }
254
255 pImpl->backend = hw;
256 pImpl->backend_type = 8;
257 FL_DBG("MultiLaneDevice: Initialized Octal-SPI (" << hw->getName() << ")");
258 }
259
260 pImpl->initialized = true;
261 return fl::nullopt;
262}
fl::unique_ptr< Impl > pImpl
#define FL_WARN(X)
Definition log.h:276
#define FL_DBG
Definition log.h:388
unsigned char u8
Definition stdint.h:131
constexpr nullopt_t nullopt
Definition optional.h:13

References FL_DBG, FL_WARN, fl::nullopt, and pImpl.

Referenced by operator=().

+ Here is the caller graph for this function: