diff --git a/example/demo_cpp/src/axi_dma_demo.cpp b/example/demo_cpp/src/axi_dma_demo.cpp index 9ffc06c8..8935d9d4 100644 --- a/example/demo_cpp/src/axi_dma_demo.cpp +++ b/example/demo_cpp/src/axi_dma_demo.cpp @@ -147,6 +147,7 @@ int main(int argc, char* argv[]) { if (g_stop_loop) { data_handler.stop(); fut.wait(); + axi_dma->dump_status(); break; } } diff --git a/example/demo_python/axi_dma_demo.py b/example/demo_python/axi_dma_demo.py index 90061a1a..570e67e6 100755 --- a/example/demo_python/axi_dma_demo.py +++ b/example/demo_python/axi_dma_demo.py @@ -169,6 +169,7 @@ def main(): print(f'{words_total} words OK') traffic_gen.stop() data_handler.stop() + axi_dma.dump_status() if __name__ == '__main__': diff --git a/inc/udmaio/UioAxiDmaIf.hpp b/inc/udmaio/UioAxiDmaIf.hpp index 189b2c48..3e441bab 100644 --- a/inc/udmaio/UioAxiDmaIf.hpp +++ b/inc/udmaio/UioAxiDmaIf.hpp @@ -41,6 +41,9 @@ class UioAxiDmaIf : public UioIf, AxiDmaBlock { /// @brief Check status register and log any errors /// @return true if any error occurred bool check_for_errors(); + + /// @brief Dump all status register flags in the log + void dump_status(); }; } // namespace udmaio diff --git a/pyudmaio/src/PythonBinding.cpp b/pyudmaio/src/PythonBinding.cpp index ccb8ca8d..d8d79dc6 100644 --- a/pyudmaio/src/PythonBinding.cpp +++ b/pyudmaio/src/PythonBinding.cpp @@ -109,7 +109,8 @@ PYBIND11_MODULE(binding, m) { py::class_>( m, "UioAxiDmaIf") - .def(py::init()); + .def(py::init()) + .def("dump_status", &udmaio::UioAxiDmaIf::dump_status); py::class_>( m, diff --git a/src/DataHandlerAbstract.cpp b/src/DataHandlerAbstract.cpp index 4010536f..4884077e 100644 --- a/src/DataHandlerAbstract.cpp +++ b/src/DataHandlerAbstract.cpp @@ -64,6 +64,7 @@ void DataHandlerAbstract::_handle_input(const boost::system::error_code& ec) { if (dma_stat.err_irq && _dma.check_for_errors()) { BOOST_LOG_SEV(_lg, bls::fatal) << "DMA error, curr.desc 0x" << std::hex << _dma.get_curr_desc(); + _dma.dump_status(); _desc.print_descs(); throw std::runtime_error("DMA engine error raised"); } diff --git a/src/UioAxiDmaIf.cpp b/src/UioAxiDmaIf.cpp index aa924b1b..c28c0564 100644 --- a/src/UioAxiDmaIf.cpp +++ b/src/UioAxiDmaIf.cpp @@ -15,6 +15,29 @@ #include #include +#include "udmaio/FrameFormat.hpp" + +namespace axi_dma { + +std::ostream& operator<<(std::ostream& os, const s2mm_dmasr_t& stat) { + auto fmt = [](std::string name, bool val) { return (val ? "+" : "-") + name; }; + os << fmt("halted", stat.halted) << " "; + os << fmt("idle", stat.idle) << " "; + os << fmt("sg_incld", stat.sg_incld) << " "; + os << fmt("dma_int_err", stat.dma_int_err) << " "; + os << fmt("dma_slv_err", stat.dma_slv_err) << " "; + os << fmt("dma_dec_err", stat.dma_dec_err) << " "; + os << fmt("sg_int_err", stat.sg_int_err) << " "; + os << fmt("sg_slv_err", stat.sg_slv_err) << " "; + os << fmt("sg_dec_err", stat.sg_dec_err) << " "; + os << fmt("ioc_irq", stat.ioc_irq) << " "; + os << fmt("dly_irq", stat.dly_irq) << " "; + os << fmt("err_irq", stat.err_irq); + return os; +} + +} // namespace axi_dma + namespace udmaio { void UioAxiDmaIf::start(uintptr_t start_desc) { @@ -123,4 +146,7 @@ bool UioAxiDmaIf::check_for_errors() { return has_errors; } +void UioAxiDmaIf::dump_status() { + BOOST_LOG_SEV(_lg, bls::info) << s2mm_dmasr.rd(); +} } // namespace udmaio