| 400 | } |
| 401 | |
| 402 | bool SPIDualSAMD21::waitComplete(u32 timeout_ms) { |
| 403 | if (!mTransactionActive) { |
| 404 | return true; // Nothing to wait for |
| 405 | } |
| 406 | |
| 407 | // Implementation Note: |
| 408 | // Current transmit() implementation is synchronous (polling-based), |
| 409 | // waiting for SERCOM TXC (Transmit Complete) flag before returning. |
| 410 | // Therefore, by the time waitComplete() is called, the transaction |
| 411 | // is already complete. |
| 412 | // |
| 413 | // This timeout logic is provided for API consistency and future-proofing |
| 414 | // in case async DMA implementation is added later. |
| 415 | |
| 416 | fl::u32 start_time = fl::millis(); |
| 417 | |
| 418 | // Poll SERCOM status to verify transmission actually completed |
| 419 | // Check TXC (Transmit Complete) flag in INTFLAG register |
| 420 | while (mSercom && !mSercom->SPI.INTFLAG.bit.TXC) { |
| 421 | if ((fl::millis() - start_time) >= timeout_ms) { |
| 422 | FL_WARN("SPIDualSAMD21: waitComplete timeout"); |
| 423 | return false; // Timeout |
| 424 | } |
| 425 | } |
| 426 | |
| 427 | mTransactionActive = false; |
| 428 | |
| 429 | // Auto-release DMA buffer |
| 430 | mBufferAcquired = false; |
| 431 | mDMABuffer.reset(); |
| 432 | |
| 433 | return true; |
| 434 | } |
| 435 | |
| 436 | bool SPIDualSAMD21::isBusy() const { |
| 437 | if (!mInitialized) { |