diff --git a/os/src/userspace/data_server.hpp b/os/src/userspace/data_server.hpp index 666dd7a..caa8813 100644 --- a/os/src/userspace/data_server.hpp +++ b/os/src/userspace/data_server.hpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -202,6 +203,30 @@ public: } private: + /** + * Re-initialize DMA stream and discard stale data from the DMA buffer. + * + * Do not call this while an async_send() operation is in progress. + */ + void discard_stale_data() + { + // Re-init DMA and clear buffer. + m_dma_stream.init(); + + // The DMA buffer and the internal RAM buffer in the FPGA are now empty. + // But the front-end logic in the FPGA may still contain some stale + // data as well as an overflow record. These will flow into the RAM + // buffer within a microsecond. Let's wait for that. + // Sleeping in an Asio handler is bad, but 1 microsecond is so short + // that it won't hurt. + std::this_thread::sleep_for(std::chrono::microseconds(1)); + + // Assuming no new data is being produced, the front-end buffer is + // now clean and overflow cleared. A little data may have moved into + // the FPGA RAM buffer. Re-init DMA again to discard that. + m_dma_stream.init(); + } + /** Accept completion handler. */ void handle_accept(const boost::system::error_code& error, asio::ip::tcp::socket conn) @@ -281,10 +306,10 @@ private: } // Clear buffer, then enable DMA stream. - m_dma_stream.init(); + discard_stale_data(); m_dma_stream.set_enabled(true); - // Try to send some data. + // Prepare to send data. transmit_data(false); }