| 292 | } |
| 293 | |
| 294 | void BitBangChannelDriver::show() FL_NOEXCEPT { |
| 295 | if (mEnqueuedChannels.empty()) return; |
| 296 | |
| 297 | // Move enqueued to transmitting |
| 298 | mTransmittingChannels = fl::move(mEnqueuedChannels); |
| 299 | mEnqueuedChannels.clear(); |
| 300 | |
| 301 | // Mark all as in-use |
| 302 | for (fl::size i = 0; i < mTransmittingChannels.size(); ++i) { |
| 303 | if (mTransmittingChannels[i]) { |
| 304 | mTransmittingChannels[i]->setInUse(true); |
| 305 | } |
| 306 | } |
| 307 | |
| 308 | // Rebuild pin config from current channels |
| 309 | rebuildPinConfig(mTransmittingChannels); |
| 310 | |
| 311 | // Separate clockless vs SPI |
| 312 | fl::vector<ChannelDataPtr> clockless; |
| 313 | fl::vector<ChannelDataPtr> spi; |
| 314 | for (fl::size i = 0; i < mTransmittingChannels.size(); ++i) { |
| 315 | const auto& ch = mTransmittingChannels[i]; |
| 316 | if (!ch) continue; |
| 317 | int pin = ch->getPin(); |
| 318 | if (pin < 0 || pin > 255 || mSlotForPin[pin] < 0) { |
| 319 | continue; // skipped (>8 pins) |
| 320 | } |
| 321 | if (ch->isClockless()) { |
| 322 | clockless.push_back(ch); |
| 323 | } else if (ch->isSpi()) { |
| 324 | spi.push_back(ch); |
| 325 | } |
| 326 | } |
| 327 | |
| 328 | // Clockless first (timing-critical), then SPI |
| 329 | if (!clockless.empty()) { |
| 330 | transmitClockless(clockless); |
| 331 | } |
| 332 | if (!spi.empty()) { |
| 333 | transmitSpi(spi); |
| 334 | } |
| 335 | |
| 336 | // Done — clear in-use flags |
| 337 | for (fl::size i = 0; i < mTransmittingChannels.size(); ++i) { |
| 338 | if (mTransmittingChannels[i]) { |
| 339 | mTransmittingChannels[i]->setInUse(false); |
| 340 | } |
| 341 | } |
| 342 | mTransmittingChannels.clear(); |
| 343 | } |
| 344 | |
| 345 | } // namespace fl |