| 2114 | } |
| 2115 | |
| 2116 | ParlioEngineState ParlioEngine::poll() FL_NOEXCEPT { |
| 2117 | if (!mInitialized || !mPeripheral || !mIsrContext) { |
| 2118 | return ParlioEngineState::READY; |
| 2119 | } |
| 2120 | |
| 2121 | // Check for errors |
| 2122 | if (mErrorOccurred) { |
| 2123 | FL_LOG_PARLIO("PARLIO: Error occurred during transmission"); |
| 2124 | mIsrContext->mTransmitting.store(false, fl::memory_order_release); |
| 2125 | mErrorOccurred = false; |
| 2126 | return ParlioEngineState::ERROR; |
| 2127 | } |
| 2128 | |
| 2129 | // Check if streaming is complete |
| 2130 | if (mIsrContext->mStreamComplete.load(fl::memory_order_acquire)) { |
| 2131 | // Wait for final chunk to complete (non-blocking poll) |
| 2132 | if (mPeripheral->waitAllDone(0)) { |
| 2133 | // Clear completion flags only once the peripheral is truly idle. |
| 2134 | mIsrContext->mTransmitting.store(false, fl::memory_order_release); |
| 2135 | mIsrContext->mStreamComplete.store(false, fl::memory_order_release); |
| 2136 | |
| 2137 | // All transmissions complete - disable peripheral (only if currently enabled) |
| 2138 | if (mTxUnitEnabled) { |
| 2139 | if (!mPeripheral->disable()) { |
| 2140 | FL_LOG_PARLIO("PARLIO: Failed to disable peripheral"); |
| 2141 | } else { |
| 2142 | mTxUnitEnabled = false; |
| 2143 | } |
| 2144 | } |
| 2145 | |
| 2146 | // Short delay for GPIO stabilization |
| 2147 | mPeripheral->delayMicroseconds(100); |
| 2148 | |
| 2149 | return ParlioEngineState::READY; |
| 2150 | } else { |
| 2151 | // Still draining final transmission |
| 2152 | return ParlioEngineState::DRAINING; |
| 2153 | } |
| 2154 | } |
| 2155 | |
| 2156 | // If not transmitting, we're ready |
| 2157 | if (!mIsrContext->mTransmitting.load(fl::memory_order_acquire)) { |
| 2158 | return ParlioEngineState::READY; |
| 2159 | } |
| 2160 | |
| 2161 | // Incremental ring buffer refill during transmission |
| 2162 | while (hasRingSpace() && populateNextDMABuffer()) { |
| 2163 | // Continue populating buffers |
| 2164 | } |
| 2165 | |
| 2166 | // Transmission in progress (ISR-driven, async) |
| 2167 | return ParlioEngineState::DRAINING; |
| 2168 | } |
| 2169 | |
| 2170 | bool ParlioEngine::isTransmitting() const FL_NOEXCEPT { |
| 2171 | if (!mIsrContext) { |
no test coverage detected