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

◆ begin()

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

Initialize the SPI hardware.

Returns
Result indicating success or error
Note
Must be called before any communication methods

Definition at line 45 of file device.cpp.hpp.

45 {
46 if (!pImpl) {
47 return fl::task::Error("Device not initialized");
48 }
49
50 if (pImpl->initialized) {
51 // Already initialized - idempotent
52 return fl::nullopt;
53 }
54
55 // Validate SPI mode (0-3 for CPOL/CPHA combinations)
56 if (pImpl->config.spi_mode > 3) {
57 FL_WARN("SPI Device: Invalid SPI mode " << pImpl->config.spi_mode << " (must be 0-3)");
58 return fl::task::Error("Invalid SPI mode");
59 }
60
61 // Note: SPI mode configuration is not yet supported by the hardware layer
62 // All devices currently operate in mode 0 (CPOL=0, CPHA=0)
63 if (pImpl->config.spi_mode != 0) {
64 FL_WARN("SPI Device: SPI mode " << pImpl->config.spi_mode
65 << " requested but hardware layer only supports mode 0 - ignoring");
66 }
67
68 // Register with SPIBusManager
69 SPIBusManager& mgr = getSPIBusManager();
70 int data_pin = pImpl->config.data_pins.empty() ? -1 : pImpl->config.data_pins[0];
71 pImpl->bus_handle = mgr.registerDevice(
72 pImpl->config.clock_pin,
73 data_pin,
74 pImpl->config.clock_speed_hz,
75 this // controller pointer
76 );
77
78 if (!pImpl->bus_handle.is_valid) {
79 FL_WARN("SPI Device: Failed to register with bus manager");
80 return fl::task::Error("Failed to register with bus manager");
81 }
82
83 // Initialize the bus
84 if (!mgr.initialize()) {
85 FL_WARN("SPI Device: Bus initialization failed");
86 return fl::task::Error("Bus initialization failed");
87 }
88
89 // Check if we need to create our own SpiHw1 controller (SINGLE_SPI/passthrough mode)
90 const SPIBusInfo* bus_info = mgr.getBusInfo(pImpl->bus_handle.bus_id);
91 if (bus_info && bus_info->bus_type == SPIBusType::SINGLE_SPI && !bus_info->hw_controller) {
92 // Create and initialize a SpiHw1 controller
93 const fl::vector<fl::shared_ptr<SpiHw1>>& controllers = SpiHw1::getAll();
94 if (controllers.empty()) {
95 FL_WARN("SPI Device: No SpiHw1 controllers available on this platform");
96 return fl::task::Error("No SpiHw1 controllers available");
97 }
98
99 // Use the first available controller (could be improved with bus number selection)
100 fl::shared_ptr<SpiHw1> hw = controllers[0];
101
102 SpiHw1::Config hw_config;
103 hw_config.clock_pin = pImpl->config.clock_pin;
104 hw_config.data_pin = pImpl->config.data_pins.empty() ? -1 : pImpl->config.data_pins[0];
105 hw_config.clock_speed_hz = pImpl->config.clock_speed_hz;
106 hw_config.bus_num = 0; // Default to bus 0
107
108 if (!hw->begin(hw_config)) {
109 FL_WARN("SPI Device: Failed to initialize SpiHw1 controller");
110 return fl::task::Error("Failed to initialize SpiHw1");
111 }
112
113 pImpl->hw_backend = hw;
114 pImpl->owns_backend = false; // We don't own it (it's from the static pool)
115 FL_LOG_SPI("SPI Device: Created SpiHw1 controller for SINGLE_SPI mode");
116 } else {
117 // Multi-lane or hardware controller already exists
118 pImpl->hw_backend = bus_info ? bus_info->hw_controller : nullptr;
119 pImpl->owns_backend = false;
120 }
121
122 pImpl->initialized = true;
123 FL_LOG_SPI("SPI Device: Initialized successfully");
124 return fl::nullopt;
125}
fl::unique_ptr< Impl > pImpl
Definition device.h:134
bool empty() const FL_NOEXCEPT
#define FL_LOG_SPI(X)
Serial Peripheral Interface (SPI) logging Logs SPI configuration, initialization, and transfers.
Definition log.h:474
#define FL_WARN(X)
Definition log.h:276
constexpr nullopt_t nullopt
Definition optional.h:13

References fl::vector_basic::empty(), FL_LOG_SPI, FL_WARN, fl::nullopt, and pImpl.

+ Here is the call graph for this function: