| 450 | } |
| 451 | |
| 452 | bool SPIDualSAMD51::waitComplete(u32 timeout_ms) { |
| 453 | if (!mTransactionActive) { |
| 454 | return true; // Nothing to wait for |
| 455 | } |
| 456 | |
| 457 | // Implementation Note: |
| 458 | // Current transmit() implementation is synchronous (polling-based), |
| 459 | // waiting for SERCOM TXC (Transmit Complete) flag before returning. |
| 460 | // Therefore, by the time waitComplete() is called, the transaction |
| 461 | // is already complete. |
| 462 | // |
| 463 | // This timeout logic is provided for API consistency and future-proofing |
| 464 | // in case async DMA implementation is added later. |
| 465 | |
| 466 | fl::u32 start_time = fl::millis(); |
| 467 | |
| 468 | // Poll SERCOM status to verify transmission actually completed |
| 469 | // Check TXC (Transmit Complete) flag in INTFLAG register |
| 470 | while (mSercom && !mSercom->SPI.INTFLAG.bit.TXC) { |
| 471 | if ((fl::millis() - start_time) >= timeout_ms) { |
| 472 | FL_WARN("SPIDualSAMD51: waitComplete timeout"); |
| 473 | return false; // Timeout |
| 474 | } |
| 475 | } |
| 476 | |
| 477 | mTransactionActive = false; |
| 478 | |
| 479 | // Auto-release DMA buffer |
| 480 | mBufferAcquired = false; |
| 481 | mDMABuffer.reset(); |
| 482 | |
| 483 | return true; |
| 484 | } |
| 485 | |
| 486 | bool SPIDualSAMD51::isBusy() const { |
| 487 | if (!mInitialized) { |