FastLED 3.10.8
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 77 of file multi_lane_device.cpp.hpp.

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

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

Referenced by operator=().

+ Here is the caller graph for this function: