| 259 | } |
| 260 | |
| 261 | bool UartPeripheralEsp::waitTxDone(u32 timeout_ms) FL_NOEXCEPT { |
| 262 | if (!mInitialized) { |
| 263 | FL_WARN("UartPeripheralEsp: Cannot wait - not initialized"); |
| 264 | return false; |
| 265 | } |
| 266 | |
| 267 | uart_port_t uart_num = static_cast<uart_port_t>(mConfig.mUartNum); |
| 268 | |
| 269 | // Convert timeout to FreeRTOS ticks |
| 270 | TickType_t timeout_ticks; |
| 271 | if (timeout_ms == 0) { |
| 272 | timeout_ticks = 0; // Non-blocking poll |
| 273 | } else { |
| 274 | timeout_ticks = pdMS_TO_TICKS(timeout_ms); |
| 275 | } |
| 276 | |
| 277 | // Wait for TX FIFO to empty |
| 278 | esp_err_t err = uart_wait_tx_done(uart_num, timeout_ticks); |
| 279 | |
| 280 | // If transmission just completed, set reset timer |
| 281 | if (err == ESP_OK) { |
| 282 | // Calculate reset duration based on transmission time |
| 283 | // For UART: transmission_time_us = (byte_count * bits_per_frame * 1000000) / baud_rate |
| 284 | // Since we don't track byte count here, use a conservative estimate |
| 285 | // Minimum reset period is 50us (WS2812 requirement) |
| 286 | // Use a fixed reset period of 1000us (1ms) to ensure complete channel draining |
| 287 | const u64 MIN_RESET_DURATION_US = 50; |
| 288 | const u64 DEFAULT_RESET_DURATION_US = 1000; |
| 289 | |
| 290 | const u64 reset_duration = (mConfig.mBaudRate > 0) ? DEFAULT_RESET_DURATION_US : MIN_RESET_DURATION_US; |
| 291 | mResetExpireTime = fl::micros() + reset_duration; |
| 292 | } |
| 293 | |
| 294 | // ESP_OK means all done, ESP_ERR_TIMEOUT means still busy (not an error) |
| 295 | return (err == ESP_OK); |
| 296 | } |
| 297 | |
| 298 | bool UartPeripheralEsp::isBusy() const FL_NOEXCEPT { |
| 299 | if (!mInitialized) { |
no test coverage detected