FastLED 3.10.8
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 339 of file spi_channel_adapter.cpp.hpp.

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

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

Referenced by show().

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