| 1343 | //============================================================================= |
| 1344 | |
| 1345 | bool ParlioEngine::initialize(size_t dataWidth, |
| 1346 | const fl::vector<int>& pins, |
| 1347 | const ChipsetTimingConfig& timing, |
| 1348 | size_t maxLedsPerChannel) FL_NOEXCEPT { |
| 1349 | FL_LOG_PARLIO("PARLIO_INIT: initialize() called - dataWidth=" << dataWidth << " pins=" << pins.size()); |
| 1350 | |
| 1351 | // Get peripheral first (needed for both initial and re-initialization) |
| 1352 | if (mPeripheral == nullptr) { |
| 1353 | mPeripheral = getParlioPeripheral(); |
| 1354 | } |
| 1355 | |
| 1356 | // Check if already initialized AND peripheral is still initialized AND configuration matches |
| 1357 | // This handles the case where: |
| 1358 | // 1. mock.reset() was called but engine still thinks it's initialized |
| 1359 | // 2. Parameters changed (different dataWidth, pins, etc.) requiring reconfiguration |
| 1360 | // CRITICAL: Must compare configuration to avoid buffer overflows when tests |
| 1361 | // change lane count without calling mock.reset() |
| 1362 | bool config_matches = (mDataWidth == dataWidth && |
| 1363 | mPins.size() == pins.size() && |
| 1364 | mTimingT1Ns == timing.t1_ns && |
| 1365 | mTimingT2Ns == timing.t2_ns && |
| 1366 | mTimingT3Ns == timing.t3_ns); |
| 1367 | if (mInitialized && mPeripheral && mPeripheral->isInitialized() && config_matches) { |
| 1368 | // Config matches but check if ring buffers need reallocation for larger LED count |
| 1369 | if (maxLedsPerChannel > mMaxLedsPerChannel) { |
| 1370 | FL_LOG_PARLIO("PARLIO_INIT: Config matches but maxLeds increased from " |
| 1371 | << mMaxLedsPerChannel << " to " << maxLedsPerChannel |
| 1372 | << " - reallocating ring buffers"); |
| 1373 | |
| 1374 | // Recalculate ring buffer capacity for larger LED count |
| 1375 | ParlioBufferCalculator calc(mDataWidth, mUseWave3, mClockFreqHz); // ok no noexcept |
| 1376 | const bool psram_cap_available = parlioDmaPsramAvailable(); |
| 1377 | size_t raw_capacity = calc.calculateRingBufferCapacity( |
| 1378 | maxLedsPerChannel, mResetUs, ParlioRingBuffer3::RING_BUFFER_COUNT, |
| 1379 | psram_cap_available ? FASTLED_PARLIO_MAX_RING_BUFFER_TOTAL_BYTES_PSRAM |
| 1380 | : FASTLED_PARLIO_MAX_RING_BUFFER_TOTAL_BYTES); |
| 1381 | size_t new_capacity = ((raw_capacity + 63) / 64) * 64; |
| 1382 | |
| 1383 | if (new_capacity > mRingBufferCapacity) { |
| 1384 | mRingBufferCapacity = new_capacity; |
| 1385 | // Release old ring buffers before allocating new ones |
| 1386 | mRingBuffer.reset(); |
| 1387 | if (!allocateRingBuffers()) { |
| 1388 | if (psram_cap_available) { |
| 1389 | // PSRAM-sized allocation failed, retry with SRAM cap |
| 1390 | raw_capacity = calc.calculateRingBufferCapacity( |
| 1391 | maxLedsPerChannel, mResetUs, ParlioRingBuffer3::RING_BUFFER_COUNT, |
| 1392 | FASTLED_PARLIO_MAX_RING_BUFFER_TOTAL_BYTES); |
| 1393 | mRingBufferCapacity = ((raw_capacity + 63) / 64) * 64; |
| 1394 | } |
| 1395 | if (!psram_cap_available || !allocateRingBuffers()) { |
| 1396 | FL_LOG_PARLIO("PARLIO_INIT: FAILED to reallocate ring buffers"); |
| 1397 | mInitialized = false; |
| 1398 | return false; |
| 1399 | } |
| 1400 | } |
| 1401 | FL_LOG_PARLIO("PARLIO_INIT: Ring buffers reallocated (capacity=" << mRingBufferCapacity << ")"); |
| 1402 | } |
nothing calls this directly
no test coverage detected