From 95da8798dd924b6eceb60c41f26d262d83799acb Mon Sep 17 00:00:00 2001 From: barthess Date: Tue, 30 Jun 2015 23:53:35 +0300 Subject: Added SDRAM teshtal. Not tested in hardware --- testhal/STM32/STM32F4xx/FSMC_SDRAM/Makefile | 7 +- testhal/STM32/STM32F4xx/FSMC_SDRAM/main.c | 132 ++++++++++---------- .../STM32/STM32F4xx/FSMC_SDRAM/mcuconf_community.h | 3 +- testhal/STM32/STM32F4xx/FSMC_SDRAM/membench.c | 133 +++++++++++++++++++++ testhal/STM32/STM32F4xx/FSMC_SDRAM/membench.h | 49 ++++++++ testhal/STM32/STM32F4xx/FSMC_SDRAM/memcpy_dma.c | 105 ++++++++++++++++ testhal/STM32/STM32F4xx/FSMC_SDRAM/memcpy_dma.h | 40 +++++++ 7 files changed, 400 insertions(+), 69 deletions(-) create mode 100644 testhal/STM32/STM32F4xx/FSMC_SDRAM/membench.c create mode 100644 testhal/STM32/STM32F4xx/FSMC_SDRAM/membench.h create mode 100644 testhal/STM32/STM32F4xx/FSMC_SDRAM/memcpy_dma.c create mode 100644 testhal/STM32/STM32F4xx/FSMC_SDRAM/memcpy_dma.h (limited to 'testhal/STM32/STM32F4xx/FSMC_SDRAM') diff --git a/testhal/STM32/STM32F4xx/FSMC_SDRAM/Makefile b/testhal/STM32/STM32F4xx/FSMC_SDRAM/Makefile index 0a2e1c8..2cc9d5a 100644 --- a/testhal/STM32/STM32F4xx/FSMC_SDRAM/Makefile +++ b/testhal/STM32/STM32F4xx/FSMC_SDRAM/Makefile @@ -107,11 +107,14 @@ CSRC = $(STARTUPSRC) \ $(PLATFORMSRC) \ $(BOARDSRC) \ $(TESTSRC) \ - main.c + main.c \ + memcpy_dma.c \ + membench.c # C++ sources that can be compiled in ARM or THUMB mode depending on the global # setting. -CPPSRC = +CPPSRC = $(CHCPPSRC) \ + $(CHIBIOS)/community/os/various/memtest.cpp # C sources to be compiled in ARM mode regardless of the global setting. # NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler diff --git a/testhal/STM32/STM32F4xx/FSMC_SDRAM/main.c b/testhal/STM32/STM32F4xx/FSMC_SDRAM/main.c index 68d9b44..5f93520 100644 --- a/testhal/STM32/STM32F4xx/FSMC_SDRAM/main.c +++ b/testhal/STM32/STM32F4xx/FSMC_SDRAM/main.c @@ -18,24 +18,20 @@ aka barthess. */ -/* -TODO: -write memtest function using ideas from http://www.memtest86.com/technical.htm -*/ - #include "ch.h" #include "hal.h" #include "string.h" #include "fsmc_sdram.h" +#include "membench.h" +#include "memtest.hpp" /* ****************************************************************************** * DEFINES ****************************************************************************** */ -#define USE_INFINITE_MEMTEST FALSE /* * FMC SDRAM Mode definition register defines @@ -116,6 +112,9 @@ write memtest function using ideas from http://www.memtest86.com/technical.htm #define FMC_Write_Protection_Disable ((uint32_t)0x00000000) #define FMC_Write_Protection_Enable ((uint32_t)0x00000200) +#define SDRAM_SIZE (8 * 1024 * 1024) +#define SDRAM_START ((void *)FSMC_Bank6_MAP_BASE) + /* ****************************************************************************** * EXTERNS @@ -128,14 +127,13 @@ write memtest function using ideas from http://www.memtest86.com/technical.htm ****************************************************************************** */ +static void mem_error_cb(memtest_t *memp, testtype e, size_t address); + /* ****************************************************************************** * GLOBAL VARIABLES ****************************************************************************** */ -static uint32_t extram_check_buf[16 * 1024]; -static uint32_t *extram_start = (uint32_t *)STM32_SDRAM1_MAP_BASE; -static const size_t extram_size = 1024*1024; /* * SDRAM driver configuration structure. @@ -164,17 +162,46 @@ static const SDRAMConfig sdram_cfg = { FMC_SDCMR_MRD_OPERATING_MODE_STANDARD | FMC_SDCMR_MRD_WRITEBURST_MODE_SINGLE) << 9, - /* if (STM32_SYSCLK == 180000000) -> - 64ms/4096=15.625us - 15.625us*90MHz=1406-20=1386 */ - .sdrtr = 1386 << 1 + .sdrtr = (uint32_t)(683 << 1), +}; + +/* + * + */ +static uint8_t int_buf[64*1024]; + +/* + * + */ +static memtest_t memtest_struct = { + SDRAM_START, + SDRAM_SIZE, + MEMTEST_WIDTH_16, + mem_error_cb, + 42 +}; + +/* + * + */ +static membench_t membench_ext = { + SDRAM_START, + SDRAM_SIZE, +}; + +/* + * + */ +static membench_t membench_int = { + int_buf, + sizeof(int_buf), }; -/* benchmarking results in MiB/S */ -double memset_speed_ext; -double memset_speed_int; -double memcpy_speed_ext2int; -double memcpy_speed_int2ext; +/* + * + */ +static membench_result_t membench_result_ext2int; +static membench_result_t membench_result_int2ext; /* ****************************************************************************** @@ -183,58 +210,33 @@ double memcpy_speed_int2ext; ****************************************************************************** ****************************************************************************** */ -/** - * - */ -static void extram_benchmark(void){ - - size_t i=0; - time_measurement_t mem_tmu; - - /* memset speed ext */ - chTMObjectInit(&mem_tmu); - chTMStartMeasurementX(&mem_tmu); - memset(extram_start, 0x55, extram_size); - //memset(extram_start, 0x00, extram_size); - chTMStopMeasurementX(&mem_tmu); - memset_speed_ext = 1 / (mem_tmu.cumulative / (double)STM32_SYSCLK); - - /* memset speed int */ - chTMObjectInit(&mem_tmu); - chTMStartMeasurementX(&mem_tmu); - for (i=0; i<16; i++) - memset(extram_check_buf, i, sizeof(extram_check_buf)); - chTMStopMeasurementX(&mem_tmu); - memset_speed_int = 1 / (mem_tmu.cumulative / (double)STM32_SYSCLK); - - /* memcpy ext2int */ - chTMObjectInit(&mem_tmu); - chTMStartMeasurementX(&mem_tmu); - for (i=0; i<16; i++) - memcpy(extram_check_buf, extram_start+ i * sizeof(extram_check_buf), sizeof(extram_check_buf)); - chTMStopMeasurementX(&mem_tmu); - memcpy_speed_ext2int = 1 / (mem_tmu.cumulative / (double)STM32_SYSCLK); - - /* memcpy int2ext */ - chTMObjectInit(&mem_tmu); - memset(extram_check_buf, 0xAA, sizeof(extram_check_buf)); - chTMStartMeasurementX(&mem_tmu); - for (i=0; i<16; i++) - memcpy(extram_start + i * sizeof(extram_check_buf), extram_check_buf, sizeof(extram_check_buf)); - chTMStopMeasurementX(&mem_tmu); - memcpy_speed_int2ext = 1 / (mem_tmu.cumulative / (double)STM32_SYSCLK); + +void mem_error_cb(memtest_t *memp, testtype e, size_t address) { + (void)memp; + (void)e; + (void)address; + + osalSysHalt("Memory broken"); } -/** +/* * */ -#if USE_INFINITE_MEMTEST -static void memstest(void){ +static void memtest(void) { + while (true) { - ; + memtest_struct.rand_seed = chSysGetRealtimeCounterX(); + memtest_run(&memtest_struct, MEMTEST_RUN_ALL); } } -#endif /* USE_INFINITE_MEMTEST */ + +/* + * + */ +static void membench(void) { + membench_run(&membench_ext, &membench_int, &membench_result_int2ext); + membench_run(&membench_int, &membench_ext, &membench_result_ext2int); +} /* ****************************************************************************** @@ -259,11 +261,9 @@ int main(void) { fsmcSdramInit(); fsmcSdramStart(&SDRAMD, &sdram_cfg); - extram_benchmark(); -#if USE_INFINITE_MEMTEST + membench(); memtest(); -#endif /* * Normal main() thread activity, in this demo it does nothing. diff --git a/testhal/STM32/STM32F4xx/FSMC_SDRAM/mcuconf_community.h b/testhal/STM32/STM32F4xx/FSMC_SDRAM/mcuconf_community.h index 95a584c..81c7e2c 100644 --- a/testhal/STM32/STM32F4xx/FSMC_SDRAM/mcuconf_community.h +++ b/testhal/STM32/STM32F4xx/FSMC_SDRAM/mcuconf_community.h @@ -24,4 +24,5 @@ * FSMC SDRAM driver system settings. */ #define STM32_USE_FSMC_SDRAM TRUE -#define STM32_SDRAM_USE_FSMC_SDRAM1 TRUE +#define STM32_SDRAM_USE_FSMC_SDRAM1 FALSE +#define STM32_SDRAM_USE_FSMC_SDRAM2 TRUE diff --git a/testhal/STM32/STM32F4xx/FSMC_SDRAM/membench.c b/testhal/STM32/STM32F4xx/FSMC_SDRAM/membench.c new file mode 100644 index 0000000..91b9aee --- /dev/null +++ b/testhal/STM32/STM32F4xx/FSMC_SDRAM/membench.c @@ -0,0 +1,133 @@ +/* + ChibiOS/RT - Copyright (C) 2013-2014 Uladzimir Pylinsky aka barthess + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include + +#include "ch.h" +#include "hal.h" + +#include "membench.h" +#include "memcpy_dma.h" + +/* + ****************************************************************************** + * DEFINES + ****************************************************************************** + */ + +/* + ****************************************************************************** + * EXTERNS + ****************************************************************************** + */ + +/* + ****************************************************************************** + * PROTOTYPES + ****************************************************************************** + */ + +/* + ****************************************************************************** + * GLOBAL VARIABLES + ****************************************************************************** + */ +volatile int warning_suppressor; + +/* + ****************************************************************************** + ****************************************************************************** + * LOCAL FUNCTIONS + ****************************************************************************** + ****************************************************************************** + */ +/* + * Calculates memory access time in MiB/s. + */ +double speed_mibps(const time_measurement_t *tmu, size_t len) { + double size; // MiB + double time; // sec + + size = len; + size /= 1024 * 1024; + + time = tmu->last; + time /= STM32_SYSCLK; + + return size / time; +} + +/* + * Calculates memory access time in B/s. + */ +uint32_t speed_bps(const time_measurement_t *tmu, size_t len) { + + uint64_t tmp = len; + tmp *= STM32_SYSCLK; + + return tmp / tmu->last; +} + +/* + ****************************************************************************** + * EXPORTED FUNCTIONS + ****************************************************************************** + */ + +/* + * + */ +void membench_run(membench_t *dest, const membench_t *src, + membench_result_t *result) { + time_measurement_t mem_tmu; + size_t len; + + if (src->size < dest->size) + len = src->size; + else + len = dest->size; + + /* memset */ + chTMObjectInit(&mem_tmu); + chTMStartMeasurementX(&mem_tmu); + memset(dest->start, 0x55, dest->size); + chTMStopMeasurementX(&mem_tmu); + result->memset = speed_bps(&mem_tmu, dest->size); + + /* memcpy */ + chTMObjectInit(&mem_tmu); + chTMStartMeasurementX(&mem_tmu); + memcpy(dest->start, src->start, len); + chTMStopMeasurementX(&mem_tmu); + result->memcpy = speed_bps(&mem_tmu, len); + + /* memcmp */ + chTMObjectInit(&mem_tmu); + chTMStartMeasurementX(&mem_tmu); + warning_suppressor = memcmp(dest->start, src->start, len); + chTMStopMeasurementX(&mem_tmu); + result->memcmp = speed_bps(&mem_tmu, len); + + /* memcpy DMA */ + memcpy_dma_start(); + chTMObjectInit(&mem_tmu); + chTMStartMeasurementX(&mem_tmu); + memcpy_dma(dest->start, src->start, len); + chTMStopMeasurementX(&mem_tmu); + result->memcpy_dma = speed_bps(&mem_tmu, len); + memcpy_dma_stop(); +} + diff --git a/testhal/STM32/STM32F4xx/FSMC_SDRAM/membench.h b/testhal/STM32/STM32F4xx/FSMC_SDRAM/membench.h new file mode 100644 index 0000000..1169145 --- /dev/null +++ b/testhal/STM32/STM32F4xx/FSMC_SDRAM/membench.h @@ -0,0 +1,49 @@ +/* + ChibiOS/RT - Copyright (C) 2013-2014 Uladzimir Pylinsky aka barthess + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef MEMBENCH_H_ +#define MEMBENCH_H_ + +/* + * + */ +typedef struct { + void *start; + size_t size; +} membench_t; + +/* + * all values in B/s + */ +typedef struct { + uint32_t memset; + uint32_t memcpy; + uint32_t memcpy_dma; + uint32_t memcmp; +} membench_result_t; + +/* + * + */ +#ifdef __cplusplus +extern "C" { +#endif + void membench_run(membench_t *dest, const membench_t *src, membench_result_t *ret); +#ifdef __cplusplus +} +#endif + +#endif /* MEMBENCH_H_ */ diff --git a/testhal/STM32/STM32F4xx/FSMC_SDRAM/memcpy_dma.c b/testhal/STM32/STM32F4xx/FSMC_SDRAM/memcpy_dma.c new file mode 100644 index 0000000..4961c7c --- /dev/null +++ b/testhal/STM32/STM32F4xx/FSMC_SDRAM/memcpy_dma.c @@ -0,0 +1,105 @@ +/* + ChibiOS/RT - Copyright (C) 2013-2014 Uladzimir Pylinsky aka barthess + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include + +#include "ch.h" +#include "hal.h" + +#include "memcpy_dma.h" + +/* + ****************************************************************************** + * DEFINES + ****************************************************************************** + */ +#define STM32_MEMCPY_DMA_PRIORITY 0 +#define STM32_MEMCPY_DMA_STREAM STM32_DMA_STREAM_ID(2, 6) + +/* + ****************************************************************************** + * EXTERNS + ****************************************************************************** + */ + +/* + ****************************************************************************** + * PROTOTYPES + ****************************************************************************** + */ + +/* + ****************************************************************************** + * GLOBAL VARIABLES + ****************************************************************************** + */ +static memcpy_dma_engine_t engine; + +/* + ****************************************************************************** + ****************************************************************************** + * LOCAL FUNCTIONS + ****************************************************************************** + ****************************************************************************** + */ + +/* + ****************************************************************************** + * EXPORTED FUNCTIONS + ****************************************************************************** + */ +/* + * + */ +void memcpy_dma_start(void) { + bool b; + + engine.dma = STM32_DMA_STREAM(STM32_MEMCPY_DMA_STREAM); + b = dmaStreamAllocate(engine.dma, STM32_MEMCPY_DMA_PRIORITY, NULL, NULL); + osalDbgAssert(!b, "stream already allocated"); +} + +/* + * + */ +void memcpy_dma_stop(void) { + dmaStreamRelease(engine.dma); +} + +/* + * + */ +void memcpy_dma(void *dest, const void *src, size_t size) { + + size_t words = size / 4; + size_t remainder = size % 4; + size_t max_block = 0xFFFF; /* DMA limitation */ + + uint32_t cr = STM32_DMA_CR_PSIZE_WORD | STM32_DMA_CR_MSIZE_WORD; + + while (words > max_block) { + dmaStartMemCopy(engine.dma, cr, src, dest, max_block) + dmaWaitCompletion(engine.dma); + words -= max_block; + } + + dmaStartMemCopy(engine.dma, cr, src, dest, words) + dmaWaitCompletion(engine.dma); + + if (remainder > 0) + memcpy(dest+size-remainder, src+size-remainder, remainder); +} + diff --git a/testhal/STM32/STM32F4xx/FSMC_SDRAM/memcpy_dma.h b/testhal/STM32/STM32F4xx/FSMC_SDRAM/memcpy_dma.h new file mode 100644 index 0000000..8d6212c --- /dev/null +++ b/testhal/STM32/STM32F4xx/FSMC_SDRAM/memcpy_dma.h @@ -0,0 +1,40 @@ +/* + ChibiOS/RT - Copyright (C) 2013-2014 Uladzimir Pylinsky aka barthess + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef MEMCPY_DMA_H_ +#define MEMCPY_DMA_H_ + +/* + * + */ +typedef struct { + const stm32_dma_stream_t *dma; +} memcpy_dma_engine_t; + +/* + * + */ +#ifdef __cplusplus +extern "C" { +#endif + void memcpy_dma_start(void); + void memcpy_dma_stop(void); + void memcpy_dma(void *dest, const void *src, size_t size); +#ifdef __cplusplus +} +#endif + +#endif /* MEMCPY_DMA_H_ */ -- cgit v1.2.3