From c05ae4d2829a555c1e48c09af678ce37a64994f6 Mon Sep 17 00:00:00 2001 From: Niklas Eiling Date: Tue, 21 Mar 2023 10:47:45 +0100 Subject: [PATCH] add C bindings for DMA interactions and add a test/example Signed-off-by: Niklas Eiling --- fpga/include/villas/fpga/villasfpga_dma.h | 15 +++-- fpga/lib/villasfpga_dma.cpp | 4 +- fpga/tests/unit/CMakeLists.txt | 10 +++ fpga/tests/unit/villasfpga_dma.c | 82 +++++++++++++++++++++++ 4 files changed, 105 insertions(+), 6 deletions(-) create mode 100644 fpga/tests/unit/villasfpga_dma.c diff --git a/fpga/include/villas/fpga/villasfpga_dma.h b/fpga/include/villas/fpga/villasfpga_dma.h index 353a7eb75..f6491ddd8 100644 --- a/fpga/include/villas/fpga/villasfpga_dma.h +++ b/fpga/include/villas/fpga/villasfpga_dma.h @@ -5,9 +5,12 @@ * SPDX-License-Identifier: Apache-2.0 ******************************************************************************/ -#pragma once - +#ifndef _VILLASFPGA_DMA_H +#define _VILLASFPGA_DMA_H +#ifdef __cplusplus extern "C" { +#endif + #include @@ -23,9 +26,13 @@ int villasfpga_register(villasfpga_handle handle, villasfpga_memory *mem); int villasfpga_free(villasfpga_memory mem); int villasfpga_read(villasfpga_handle handle, villasfpga_memory mem, size_t size); -int vilalsfpga_read_complete(villasfpga_handle handle, size_t *size); +int villasfpga_read_complete(villasfpga_handle handle, size_t *size); int villasfpga_write(villasfpga_handle handle, villasfpga_memory mem, size_t size); -int vilalsfpga_write_complete(villasfpga_handle handle, size_t *size); +int villasfpga_write_complete(villasfpga_handle handle, size_t *size); +#ifdef __cplusplus } // extern "C" +#endif + +#endif /* _VILLASFPGA_DMA_H */ diff --git a/fpga/lib/villasfpga_dma.cpp b/fpga/lib/villasfpga_dma.cpp index 31699cf55..872813c59 100644 --- a/fpga/lib/villasfpga_dma.cpp +++ b/fpga/lib/villasfpga_dma.cpp @@ -154,7 +154,7 @@ int villasfpga_read(villasfpga_handle handle, villasfpga_memory mem, size_t size } } -int vilalsfpga_read_complete(villasfpga_handle handle, size_t *size) +int villasfpga_read_complete(villasfpga_handle handle, size_t *size) { try { auto readComp = handle->dma->readComplete(); @@ -181,7 +181,7 @@ int villasfpga_write(villasfpga_handle handle, villasfpga_memory mem, size_t siz } } -int vilalsfpga_write_complete(villasfpga_handle handle, size_t *size) +int villasfpga_write_complete(villasfpga_handle handle, size_t *size) { try { auto writeComp = handle->dma->writeComplete(); diff --git a/fpga/tests/unit/CMakeLists.txt b/fpga/tests/unit/CMakeLists.txt index a114eea99..454525714 100644 --- a/fpga/tests/unit/CMakeLists.txt +++ b/fpga/tests/unit/CMakeLists.txt @@ -36,3 +36,13 @@ target_link_libraries(unit-tests-fpga PUBLIC villas-fpga ${CRITERION_LIBRARIES} ) + +add_executable(villasfpga-dma villasfpga_dma.c) + +target_include_directories(villasfpga-dma PUBLIC + ../include +) + +target_link_libraries(villasfpga-dma PUBLIC + villas-fpga +) diff --git a/fpga/tests/unit/villasfpga_dma.c b/fpga/tests/unit/villasfpga_dma.c new file mode 100644 index 000000000..cfb70e3e7 --- /dev/null +++ b/fpga/tests/unit/villasfpga_dma.c @@ -0,0 +1,82 @@ +#include +#include +#include + +#include + +int main(int argc, char *argv[]) +{ + int ret; + villasfpga_handle vh; + villasfpga_memory mem1, mem2; + char line[1024]; + float f; + size_t size; + + if (argc != 2 && argv != NULL) { + fprintf(stderr, "Usage: %s \n", argv[0]); + } + + if ((vh = villasfpga_init(argv[1])) == NULL) { + fprintf(stderr, "Failed to initialize FPGA\n"); + ret = 1; + goto out; + } + + if (villasfpga_alloc(vh, &mem1, 0x200 * sizeof(uint32_t)) != 0) { + fprintf(stderr, "Failed to allocate DMA memory 1\n"); + ret = 1; + goto out; + } + + if (villasfpga_alloc(vh, &mem2, 0x200 * sizeof(uint32_t)) != 0) { + fprintf(stderr, "Failed to allocate DMA memory 2\n"); + ret = 1; + goto out; + } + + while (1) { + // Setup read transfer + if ((ret = villasfpga_read(vh, mem1, 0x200 * sizeof(uint32_t))) != 0) { + fprintf(stderr, "Failed to initiate read transfer\n"); + ret = 1; + goto out; + } + + printf("Enter a float:\n"); + if ((ret = sscanf(line, "%f")) != 1) { + fprintf(stderr, "Failed to parse input: sscanf returned %d\n", ret); + ret = 1; + goto out; + } + + ((float*)mem2)[0] = atof(line); + printf("Read %f\n", ((float*)mem2)[0]); + // Initiate write transfer + if ((ret = villasfpga_write(vh, mem2, sizeof(float))) != 0) { + fprintf(stderr, "Failed to initiate write transfer\n"); + ret = 1; + goto out; + } + + if ((ret = villasfpga_write_complete(vh, &size)) != 0) { + fprintf(stderr, "Failed to write complete\n"); + ret = 1; + goto out; + } + printf("Wrote %zu bytes", size); + + if ((ret = villasfpga_read_complete(vh, &size)) != 0) { + fprintf(stderr, "Failed to write complete\n"); + ret = 1; + goto out; + } + printf("Read %zu bytes", size); + + printf("Read %f\n", ((float*)mem1)[0]); + } + + ret = 0; + out: + return ret; +}