From 98749d68eb90f4f2d08e0cc265e32561f62a7b98 Mon Sep 17 00:00:00 2001 From: Gunar Schorcht Date: Sat, 22 Jul 2023 16:59:49 +0200 Subject: [PATCH] tests/drivers/stm32_fmc: add test for STM32 FMC --- tests/drivers/stm32_fmc/Makefile | 8 ++ tests/drivers/stm32_fmc/README.md | 24 ++++ tests/drivers/stm32_fmc/app.config.test | 3 + tests/drivers/stm32_fmc/main.c | 161 ++++++++++++++++++++++++ tests/drivers/stm32_fmc/tests/01-run.py | 18 +++ 5 files changed, 214 insertions(+) create mode 100644 tests/drivers/stm32_fmc/Makefile create mode 100644 tests/drivers/stm32_fmc/README.md create mode 100644 tests/drivers/stm32_fmc/app.config.test create mode 100644 tests/drivers/stm32_fmc/main.c create mode 100755 tests/drivers/stm32_fmc/tests/01-run.py diff --git a/tests/drivers/stm32_fmc/Makefile b/tests/drivers/stm32_fmc/Makefile new file mode 100644 index 0000000000..8c2d5570ff --- /dev/null +++ b/tests/drivers/stm32_fmc/Makefile @@ -0,0 +1,8 @@ +BOARD ?= stm32f429i-disc1 +include ../Makefile.drivers_common + +USEMODULE += benchmark +USEMODULE += periph_fmc +USEMODULE += od + +include $(RIOTBASE)/Makefile.include diff --git a/tests/drivers/stm32_fmc/README.md b/tests/drivers/stm32_fmc/README.md new file mode 100644 index 0000000000..c035ef76d4 --- /dev/null +++ b/tests/drivers/stm32_fmc/README.md @@ -0,0 +1,24 @@ +Peripheral STM32 FMC Test Application +===================================== + +This application tests basic STM32 FMC functionality: + +- 8-bit, 16-bit and 32-bit write and read access +- availability of the whole memory + +Configuration +------------- + +The bank to be used is defined by environment variable `FMC_BANK`. For example, +if the board configures two banks with RAM, the second bank can be tested by +specifying the `FMC_BANK` variable as follows: +``` +FMC_BANK=1 BOARD=... make -j8 -C tests/drivers/stm32_fmc flash test +``` + +Expected Output on Success +-------------------------- + + main(): This is RIOT! (Version: ) + ... + [SUCCESS] diff --git a/tests/drivers/stm32_fmc/app.config.test b/tests/drivers/stm32_fmc/app.config.test new file mode 100644 index 0000000000..b651e9e402 --- /dev/null +++ b/tests/drivers/stm32_fmc/app.config.test @@ -0,0 +1,3 @@ +CONFIG_MODULE_BENCHMARK=y +CONFIG_MODULE_PERIPH_FMC=y +CONFIG_MODULE_OD=y diff --git a/tests/drivers/stm32_fmc/main.c b/tests/drivers/stm32_fmc/main.c new file mode 100644 index 0000000000..683f7f7ceb --- /dev/null +++ b/tests/drivers/stm32_fmc/main.c @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2023 Gunar Schorcht + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @file + * @brief Test for memories connected to the STM32 FMC/FSMC peripheral + * + * @author Gunar Schorcht + */ + +#include +#include + +#include "benchmark.h" +#include "od.h" +#include "periph_conf.h" + +#ifndef FMC_BANK +#define FMC_BANK 0 +#endif + +#ifndef MEM_BUFSIZ +#define MEM_BUFSIZ 1024 +#endif + +uint8_t mem_buf[MEM_BUFSIZ] = {}; + +void bench_mem_write(uint32_t addr, uint32_t len) +{ + uint8_t *mem = (uint8_t *)addr; + uint32_t i = 0; + + while (i < len) { + memcpy(mem + i, mem_buf, MEM_BUFSIZ); + i += MEM_BUFSIZ; + } +} + +int main(void) +{ + printf("HCLK freq %lu MHz\n", CLOCK_AHB/MHZ(1)); + + uint8_t *data8 = (uint8_t *)(fmc_bank_config[FMC_BANK].address); + uint16_t *data16 = (uint16_t *)((fmc_bank_config[FMC_BANK].address) + 256); + uint32_t *data32 = (uint32_t *)((fmc_bank_config[FMC_BANK].address) + + (fmc_bank_config[FMC_BANK].size) - 256); + + printf("8-bit data @%p, 16-bit data @%p, 32-bit data @%p\n", + data8, data16, data32); + puts("------------------------------------------------------------------------"); + + for (unsigned i = 0; i < 256; i++) + { + data8[i] = i; + } + od_hex_dump_ext(data8, 256, 16, fmc_bank_config[FMC_BANK].address); + + for (unsigned i = 0; i < 256; i++) + { + if (data8[i] != i) { + printf("memory content did not match @%p\n", &data8[i]); + return 1; + } + } + puts("------------------------------------------------------------------------"); + + for (unsigned i = 0; i < 128; i++) + { + data16[i] = ((128 + i) << 8) + i; + } + od_hex_dump_ext(data16, 256, 16, fmc_bank_config[FMC_BANK].address + 256); + + for (unsigned i = 0; i < 128; i++) + { + if (data16[i] != ((128 + i) << 8) + i) { + printf("memory content did not match @%p\n", &data16[i]); + return 1; + } + } + puts("------------------------------------------------------------------------"); + + for (unsigned i = 0; i < 64; i++) + { + data32[i] = ((192 + i) << 24) + ((128 + i) << 16) + ((64 + i) << 8) + i; + } + od_hex_dump_ext(data32, 256, 16, (fmc_bank_config[FMC_BANK].address) + + (fmc_bank_config[FMC_BANK].size) - 256); + + for (unsigned i = 0; i < 64; i++) + { + if (data32[i] != ((192 + i) << 24) + ((128 + i) << 16) + ((64 + i) << 8) + i) { + printf("memory content did not match @%p\n", &data32[i]); + return 1; + } + } + puts("------------------------------------------------------------------------"); + + printf("fill complete memory of %lu kByte (. represents 16 kByte)\n", + fmc_bank_config[FMC_BANK].size >> 10); + for (uint32_t i = 0; i < fmc_bank_config[FMC_BANK].size; i++) { + data8[i] = (i % 256); + if ((i % KiB(16)) == 0) { + printf("."); + } + } + puts("\nready"); + puts("------------------------------------------------------------------------"); + + puts("check memory content (+ represents 16 kByte of matching data)"); + for (uint32_t i = 0; i < fmc_bank_config[FMC_BANK].size; i++) { + if (data8[i] != (i % 256)) { + printf("memory content did not match @%08"PRIx32"\n", + fmc_bank_config[FMC_BANK].address + i); + return 1; + } + if ((i % KiB(16)) == 0) { + printf("+"); + } + } + puts("\nready"); + puts("------------------------------------------------------------------------"); + + puts("Doing some benchmarks\n"); + + volatile uint8_t val8 = 0xf0; + volatile uint16_t val16 = 0x5555; + volatile uint32_t val32 = 0xaaaaaaaa; + + BENCHMARK_FUNC("write 8 bit", fmc_bank_config[FMC_BANK].size, + ((uint8_t *)(fmc_bank_config[FMC_BANK].address))[i] = val8); + BENCHMARK_FUNC("write 16 bit", fmc_bank_config[FMC_BANK].size / 2, + ((uint16_t *)(fmc_bank_config[FMC_BANK].address))[i] = val16); + BENCHMARK_FUNC("write 32 bit", fmc_bank_config[FMC_BANK].size / 4, + ((uint32_t *)(fmc_bank_config[FMC_BANK].address))[i] = val32); + + BENCHMARK_FUNC("read 8 bit", fmc_bank_config[FMC_BANK].size, + val8 = ((uint8_t *)(fmc_bank_config[FMC_BANK].address))[i]); + BENCHMARK_FUNC("read 16 bit", fmc_bank_config[FMC_BANK].size / 2, + val16 = ((uint16_t *)(fmc_bank_config[FMC_BANK].address))[i]); + BENCHMARK_FUNC("read 32 bit", fmc_bank_config[FMC_BANK].size / 4, + val32 = ((uint32_t *)(fmc_bank_config[FMC_BANK].address))[i]); + + puts("\nready"); + puts("------------------------------------------------------------------------"); + + puts("print first and last memory block after benchmark, should be 0xaa\n"); + od_hex_dump_ext(data8, 256, 16, fmc_bank_config[FMC_BANK].address); + puts(""); + od_hex_dump_ext(data32, 256, 16, (fmc_bank_config[FMC_BANK].address) + + (fmc_bank_config[FMC_BANK].size) - 256); + puts("------------------------------------------------------------------------"); + + puts("\n[SUCCESS]\n"); + + return 0; +} diff --git a/tests/drivers/stm32_fmc/tests/01-run.py b/tests/drivers/stm32_fmc/tests/01-run.py new file mode 100755 index 0000000000..d8bccef43b --- /dev/null +++ b/tests/drivers/stm32_fmc/tests/01-run.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 + +# Copyright (C) 2023 Gunar Schorcht +# +# This file is subject to the terms and conditions of the GNU Lesser +# General Public License v2.1. See the file LICENSE in the top level +# directory for more details. + +import sys +from testrunner import run + + +def testfunc(child): + child.expect_exact("[SUCCESS]") + + +if __name__ == "__main__": + sys.exit(run(testfunc))