| 153 | } |
| 154 | |
| 155 | fl::optional<fl::task::Error> ParallelDevice::begin() { |
| 156 | if (!pImpl) { |
| 157 | return fl::task::Error("Device not initialized"); |
| 158 | } |
| 159 | |
| 160 | if (pImpl->initialized) { |
| 161 | // Already initialized - idempotent |
| 162 | return fl::nullopt; |
| 163 | } |
| 164 | |
| 165 | size_t num_pins = pImpl->config.gpio_pins.size(); |
| 166 | |
| 167 | // Validate pin count |
| 168 | if (num_pins == 0 || num_pins > 32) { |
| 169 | return fl::task::Error("Invalid number of GPIO pins (must be 1-32)"); |
| 170 | } |
| 171 | |
| 172 | // Determine backend width (round up to next supported width: 1,2,4,8,16,32) |
| 173 | u8 backend_width = 1; |
| 174 | if (num_pins > 16) backend_width = 32; |
| 175 | else if (num_pins > 8) backend_width = 16; |
| 176 | else if (num_pins > 4) backend_width = 8; |
| 177 | else if (num_pins > 2) backend_width = 4; |
| 178 | else if (num_pins > 1) backend_width = 2; |
| 179 | |
| 180 | pImpl->backend_width = backend_width; |
| 181 | |
| 182 | // Determine execution mode |
| 183 | bool use_isr = (pImpl->config.mode == SpiParallelMode::ISR_ASYNC) || |
| 184 | (pImpl->config.mode == SpiParallelMode::AUTO); // Default to ISR if AUTO |
| 185 | pImpl->is_isr_mode = use_isr; |
| 186 | |
| 187 | // Build default LUT |
| 188 | u32 set_masks[256]; |
| 189 | u32 clear_masks[256]; |
| 190 | buildDefaultLUT(pImpl->config.gpio_pins, set_masks, clear_masks); |
| 191 | |
| 192 | // Create and initialize backend |
| 193 | // Note: We can't use polymorphism here due to different backend types |
| 194 | // Instead, we use type-erasure with void* and manual dispatch |
| 195 | |
| 196 | if (use_isr) { |
| 197 | // ISR-based backend |
| 198 | FL_DBG("ParallelDevice: Initializing ISR mode (width=" << (int)backend_width << ")"); |
| 199 | |
| 200 | // Note: These need to be heap-allocated for type-erasure |
| 201 | // For now, return error indicating ISR mode not yet implemented |
| 202 | return fl::task::Error("ISR mode not yet implemented for ParallelDevice"); |
| 203 | |
| 204 | } else { |
| 205 | // Bit-bang (blocking) backend |
| 206 | FL_DBG("ParallelDevice: Initializing bit-bang mode (width=" << (int)backend_width << ")"); |
| 207 | |
| 208 | // Note: These need to be heap-allocated for type-erasure |
| 209 | // For now, return error indicating bit-bang mode not yet implemented |
| 210 | return fl::task::Error("Bit-bang mode not yet implemented for ParallelDevice"); |
| 211 | } |
| 212 |
nothing calls this directly
no test coverage detected