| 284 | } |
| 285 | |
| 286 | fl::optional<fl::task::Error> Device::transmit(DMABuffer& buffer, bool async) { |
| 287 | if (!isReady()) { |
| 288 | return fl::task::Error("Device not initialized"); |
| 289 | } |
| 290 | |
| 291 | if (!buffer.ok()) { |
| 292 | return fl::task::Error("Invalid buffer"); |
| 293 | } |
| 294 | |
| 295 | // Get hardware controller |
| 296 | if (!pImpl->hw_backend) { |
| 297 | FL_WARN("SPI Device: No hardware controller available"); |
| 298 | return fl::task::Error("No hardware controller"); |
| 299 | } |
| 300 | |
| 301 | // Use polymorphic interface (works for SpiHw1/2/4/8) |
| 302 | SpiHwBase* hw = pImpl->hw_backend.get(); |
| 303 | |
| 304 | // Start transmission |
| 305 | TransmitMode mode = async ? TransmitMode::ASYNC : TransmitMode::SYNC; |
| 306 | bool success = hw->transmit(mode); |
| 307 | |
| 308 | if (!success) { |
| 309 | FL_WARN("SPI Device: Transmission failed"); |
| 310 | return fl::task::Error("Transmission failed"); |
| 311 | } |
| 312 | |
| 313 | // If blocking mode, wait for completion |
| 314 | if (!async) { |
| 315 | if (!hw->waitComplete()) { |
| 316 | FL_WARN("SPI Device: Wait for completion failed"); |
| 317 | return fl::task::Error("Wait for completion failed"); |
| 318 | } |
| 319 | } |
| 320 | |
| 321 | FL_LOG_SPI("SPI Device: Transmission started (" << (async ? "async" : "blocking") << ")"); |
| 322 | return fl::nullopt; |
| 323 | } |
| 324 | |
| 325 | bool Device::waitComplete(u32 timeout_ms) { |
| 326 | if (!isReady()) { |
no test coverage detected