1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

tests/drivers/stm32_fmc: add test for STM32 FMC

This commit is contained in:
Gunar Schorcht 2023-07-22 16:59:49 +02:00
parent 3472e27ba0
commit 98749d68eb
5 changed files with 214 additions and 0 deletions

View File

@ -0,0 +1,8 @@
BOARD ?= stm32f429i-disc1
include ../Makefile.drivers_common
USEMODULE += benchmark
USEMODULE += periph_fmc
USEMODULE += od
include $(RIOTBASE)/Makefile.include

View File

@ -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: <INSERT VERSION HERE>)
...
[SUCCESS]

View File

@ -0,0 +1,3 @@
CONFIG_MODULE_BENCHMARK=y
CONFIG_MODULE_PERIPH_FMC=y
CONFIG_MODULE_OD=y

View File

@ -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 <gunar@schorcht.net>
*/
#include <stdio.h>
#include <string.h>
#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;
}

View File

@ -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))