| 463 | } |
| 464 | |
| 465 | bool SPIDualRP2040::waitComplete(u32 timeout_ms) { |
| 466 | if (!mTransactionActive) { |
| 467 | return true; // Nothing to wait for |
| 468 | } |
| 469 | |
| 470 | // Poll with timeout checking |
| 471 | if (timeout_ms == fl::numeric_limits<u32>::max()) { |
| 472 | // Infinite timeout - just wait |
| 473 | dma_channel_wait_for_finish_blocking(mDMAChannel); |
| 474 | } else { |
| 475 | // Timeout-based polling with timestamp checking |
| 476 | fl::u32 start_time = fl::millis(); |
| 477 | while (dma_channel_is_busy(mDMAChannel)) { |
| 478 | if ((fl::millis() - start_time) >= timeout_ms) { |
| 479 | return false; // Timeout |
| 480 | } |
| 481 | } |
| 482 | } |
| 483 | |
| 484 | mTransactionActive = false; |
| 485 | |
| 486 | // Auto-release DMA buffer |
| 487 | mBufferAcquired = false; |
| 488 | mCurrentTotalSize = 0; |
| 489 | |
| 490 | return true; |
| 491 | } |
| 492 | |
| 493 | bool SPIDualRP2040::isBusy() const { |
| 494 | if (!mInitialized) { |