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

◆ transmitBatch()

bool fl::SpiChannelEngineAdapter::transmitBatch ( fl::span< const ChannelDataPtr > channels)
private

Transmit a batch of channels (all same clock pin)

Parameters
channelsChannels to transmit (must have same clock pin)
Returns
true on success, false on error

Definition at line 340 of file spi_channel_adapter.cpp.hpp.

340 {
341 if (channels.empty()) {
342 return true;
343 }
344
345 // Extract clock pin and data pin from first channel (all same in batch)
346 const auto& chipset = channels[0]->getChipset();
347 if (!chipset.is<SpiChipsetConfig>()) {
348 FL_WARN("SpiChannelEngineAdapter: Non-SPI chipset in transmitBatch");
349 return false;
350 }
351
352 const SpiChipsetConfig& spiConfig = chipset.get<SpiChipsetConfig>();
353 int clockPin = spiConfig.clockPin;
354 int dataPin = channels[0]->getPin(); // MOSI pin from channel config
355
356 // Select controller for this clock pin
357 int controllerIndex = selectControllerForClockPin(clockPin);
358 if (controllerIndex < 0) {
359 FL_WARN("SpiChannelEngineAdapter: No available controller for clock pin " << clockPin);
360 return false;
361 }
362
363 ControllerInfo& ctrl = mControllers[controllerIndex];
364
365 // Initialize controller if needed
366 if (!initializeControllerIfNeeded(ctrl, clockPin, dataPin)) {
367 return false;
368 }
369
370 // Transmit using selected controller
371 for (const auto& channel : channels) {
372 if (!channel) {
373 continue;
374 }
375
376 // Mark channel as in use
377 channel->setInUse(true);
378
379 // Get encoded data
380 const auto& data = channel->getData();
381 if (data.empty()) {
382 FL_WARN("SpiChannelEngineAdapter: Empty channel data");
383 channel->setInUse(false);
384 continue;
385 }
386
387 FL_DBG("SpiChannelEngineAdapter: Transmitting channel via " << ctrl.name
388 << " (pin " << channel->getPin() << ", " << data.size() << " bytes)");
389
390 // Acquire DMA buffer
391 DMABuffer dmaBuffer = ctrl.controller->acquireDMABuffer(data.size());
392 if (!dmaBuffer.ok()) {
393 FL_WARN("SpiChannelEngineAdapter: Failed to acquire DMA buffer (error "
394 << static_cast<int>(dmaBuffer.error()) << ")");
395 channel->setInUse(false);
396 return false;
397 }
398
399 // Copy data to DMA buffer
400 fl::span<u8> buffer = dmaBuffer.data();
401 if (buffer.size() < data.size()) {
402 FL_WARN("SpiChannelEngineAdapter: DMA buffer too small ("
403 << buffer.size() << " < " << data.size() << ")");
404 channel->setInUse(false);
405 return false;
406 }
407
408 fl::memcpy(buffer.data(), data.data(), data.size());
409
410 // Transmit (async mode for non-blocking operation)
411 if (!ctrl.controller->transmit(TransmitMode::ASYNC)) {
412 FL_WARN("SpiChannelEngineAdapter: Transmission failed");
413 channel->setInUse(false);
414 return false;
415 }
416
417 FL_DBG("SpiChannelEngineAdapter: Transmission queued successfully");
418 }
419
420 // Wait for transmission to complete (synchronous for now)
421 // TODO: Make fully async by returning BUSY state and polling in poll()
422 if (!ctrl.controller->waitComplete(1000)) { // 1 second timeout
423 FL_WARN("SpiChannelEngineAdapter: Transmission timeout");
424 return false;
425 }
426
427 FL_DBG("SpiChannelEngineAdapter: Batch transmission complete");
428 return true;
429}
fl::vector< ControllerInfo > mControllers
All managed controllers.
bool initializeControllerIfNeeded(ControllerInfo &ctrl, int clockPin, int dataPin)
Initialize controller if needed for this clock pin.
int selectControllerForClockPin(int clockPin)
Select best controller for a given clock pin.
constexpr bool empty() const FL_NOEXCEPT
Definition span.h:510
const T * data() const FL_NOEXCEPT
Definition span.h:461
constexpr fl::size size() const FL_NOEXCEPT
Definition span.h:458
#define FL_WARN(X)
Definition log.h:276
#define FL_DBG
Definition log.h:388
void * memcpy(void *dest, const void *src, size_t n) FL_NOEXCEPT
Information about a registered SPI hardware controller.

References fl::SpiChipsetConfig::clockPin, fl::SpiChannelEngineAdapter::ControllerInfo::controller, fl::span< T, Extent >::data(), FL_DBG, FL_WARN, initializeControllerIfNeeded(), mControllers, fl::memcpy(), fl::SpiChannelEngineAdapter::ControllerInfo::name, selectControllerForClockPin(), fl::basic_string::size(), and fl::span< T, Extent >::size().

Referenced by show().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: