Transmit a batch of channels sharing one SPI configuration.
343 {
344 if (channels.
empty()) {
345 return true;
346 }
347
348
349 const auto& chipset = channels[0]->getChipset();
350 if (!chipset.is<SpiChipsetConfig>()) {
351 FL_WARN(
"SpiChannelEngineAdapter: Non-SPI chipset in transmitBatch");
352 return false;
353 }
354
355 const SpiChipsetConfig& spiConfig = chipset.get<SpiChipsetConfig>();
356 int clockPin = spiConfig.clockPin;
357 int dataPin = channels[0]->getPin();
358
359
361 if (controllerIndex < 0) {
362 FL_WARN(
"SpiChannelEngineAdapter: No available controller for clock pin " << clockPin);
363 return false;
364 }
365
367
368
370 spiConfig.timing.clock_hz)) {
371 return false;
372 }
373
374
375 for (const auto& channel : channels) {
376 if (!channel) {
377 continue;
378 }
379
380
381 channel->setInUse(true);
382
383
384 const auto& data = channel->getData();
385 if (data.empty()) {
386 FL_WARN(
"SpiChannelEngineAdapter: Empty channel data");
387 channel->setInUse(false);
388 continue;
389 }
390
391 FL_DBG(
"SpiChannelEngineAdapter: Transmitting channel via " << ctrl.name <<
" (pin " << channel->getPin() <<
", " << data.size() <<
" bytes)");
392
393
394 DMABuffer dmaBuffer = ctrl.controller->acquireDMABuffer(data.size());
395 if (!dmaBuffer.ok()) {
396 FL_WARN(
"SpiChannelEngineAdapter: Failed to acquire DMA buffer (error " << (
static_cast<int>(dmaBuffer.error())) <<
")");
397 channel->setInUse(false);
398 return false;
399 }
400
401
402 fl::span<u8> buffer = dmaBuffer.data();
403 if (buffer.
size() < data.size()) {
404 FL_WARN(
"SpiChannelEngineAdapter: DMA buffer too small (" << buffer.
size() <<
" < " << data.size() <<
")");
405 channel->setInUse(false);
406 return false;
407 }
408
410
411
412 if (!ctrl.controller->transmit(TransmitMode::ASYNC)) {
413 FL_WARN(
"SpiChannelEngineAdapter: Transmission failed");
414 channel->setInUse(false);
415 return false;
416 }
417
418 FL_DBG(
"SpiChannelEngineAdapter: Transmission queued successfully");
419 }
420
421
422
423 if (!ctrl.controller->waitComplete(1000)) {
424 FL_WARN(
"SpiChannelEngineAdapter: Transmission timeout");
425 return false;
426 }
427
428 FL_DBG(
"SpiChannelEngineAdapter: Batch transmission complete");
429 return true;
430}
fl::vector< ControllerInfo > mControllers
All managed controllers.
bool initializeControllerIfNeeded(ControllerInfo &ctrl, int clockPin, int dataPin, u32 clockSpeedHz) FL_NO_EXCEPT
Initialize controller if needed for this clock pin.
int selectControllerForClockPin(int clockPin, Esp32SpiBus requestedBus) FL_NO_EXCEPT
Select best controller for a given clock pin.
constexpr bool empty() const FL_NO_EXCEPT
const T * data() const FL_NO_EXCEPT
constexpr fl::size size() const FL_NO_EXCEPT
FASTLED_FORCE_INLINE void * memcpy(void *dest, const void *src, size_t n) FL_NO_EXCEPT
Information about a registered SPI hardware controller.