From e7a3df6c18173ad12750faa56cb8a8f6c68874cb Mon Sep 17 00:00:00 2001 From: barthess Date: Tue, 4 Aug 2015 13:30:01 +0300 Subject: Improved FSMC. SRAM configuration is much more flexible now. --- os/hal/ports/STM32/LLD/FSMCv1/fsmc.h | 38 ++++++++----- os/hal/ports/STM32/LLD/FSMCv1/fsmc_sram.c | 5 +- os/hal/ports/STM32/LLD/FSMCv1/fsmc_sram.h | 5 +- os/various/memtest.cpp | 2 +- os/various/memtest.h | 88 +++++++++++++++++++++++++++++ os/various/memtest.hpp | 88 ----------------------------- testhal/STM32/STM32F4xx/FSMC_SDRAM/Makefile | 2 +- testhal/STM32/STM32F4xx/FSMC_SDRAM/main.c | 21 ++++--- testhal/STM32/STM32F4xx/FSMC_SRAM/Makefile | 2 +- testhal/STM32/STM32F4xx/FSMC_SRAM/main.c | 25 ++++---- 10 files changed, 150 insertions(+), 126 deletions(-) create mode 100644 os/various/memtest.h delete mode 100644 os/various/memtest.hpp diff --git a/os/hal/ports/STM32/LLD/FSMCv1/fsmc.h b/os/hal/ports/STM32/LLD/FSMCv1/fsmc.h index 1377735..c21884c 100644 --- a/os/hal/ports/STM32/LLD/FSMCv1/fsmc.h +++ b/os/hal/ports/STM32/LLD/FSMCv1/fsmc.h @@ -196,19 +196,31 @@ typedef struct { /** * @brief BCR register */ -#define FSMC_BCR_MBKEN ((uint32_t)0x00000001) -#define FSMC_BCR_MUXEN ((uint32_t)0x00000002) -#define FSMC_BCR_MWID_0 ((uint32_t)0x00000010) -#define FSMC_BCR_FACCEN ((uint32_t)0x00000040) -#define FSMC_BCR_BURSTEN ((uint32_t)0x00000100) -#define FSMC_BCR_WAITPOL ((uint32_t)0x00000200) -#define FSMC_BCR_WRAPMOD ((uint32_t)0x00000400) -#define FSMC_BCR_WAITCFG ((uint32_t)0x00000800) -#define FSMC_BCR_WREN ((uint32_t)0x00001000) -#define FSMC_BCR_WAITEN ((uint32_t)0x00002000) -#define FSMC_BCR_EXTMOD ((uint32_t)0x00004000) -#define FSMC_BCR_ASYNCWAIT ((uint32_t)0x00008000) -#define FSMC_BCR_CBURSTRW ((uint32_t)0x00080000) +#define FSMC_BCR_MBKEN ((uint32_t)1 << 0) +#define FSMC_BCR_MUXEN ((uint32_t)1 << 1) +#define FSMC_BCR_MTYP_SRAM ((uint32_t)0 << 2) +#define FSMC_BCR_MTYP_PSRAM ((uint32_t)1 << 2) +#define FSMC_BCR_MTYP_NOR_NAND ((uint32_t)2 << 2) +#define FSMC_BCR_MTYP_RESERVED ((uint32_t)3 << 2) +#define FSMC_BCR_MWID_8 ((uint32_t)0 << 4) +#define FSMC_BCR_MWID_16 ((uint32_t)1 << 4) +#if (defined(STM32F427xx) || defined(STM32F437xx) || \ + defined(STM32F429xx) || defined(STM32F439xx)) +#define FSMC_BCR_MWID_32 ((uint32_t)2 << 4) +#else +#define FSMC_BCR_MWID_RESERVED1 ((uint32_t)2 << 4) +#endif +#define FSMC_BCR_MWID_RESERVED2 ((uint32_t)3 << 4) +#define FSMC_BCR_FACCEN ((uint32_t)1 << 6) +#define FSMC_BCR_BURSTEN ((uint32_t)1 << 8) +#define FSMC_BCR_WAITPOL ((uint32_t)1 << 9) +#define FSMC_BCR_WRAPMOD ((uint32_t)1 << 10) +#define FSMC_BCR_WAITCFG ((uint32_t)1 << 11) +#define FSMC_BCR_WREN ((uint32_t)1 << 12) +#define FSMC_BCR_WAITEN ((uint32_t)1 << 13) +#define FSMC_BCR_EXTMOD ((uint32_t)1 << 14) +#define FSMC_BCR_ASYNCWAIT ((uint32_t)1 << 15) +#define FSMC_BCR_CBURSTRW ((uint32_t)1 << 19) /*===========================================================================*/ /* Driver pre-compile time settings. */ diff --git a/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sram.c b/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sram.c index 22ec255..114f9bc 100644 --- a/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sram.c +++ b/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sram.c @@ -128,8 +128,9 @@ void fsmcSramStart(SRAMDriver *sramp, const SRAMConfig *cfgp) { "invalid state"); if (sramp->state == SRAM_STOP) { - sramp->sram->BCR = FSMC_BCR_WREN | FSMC_BCR_MBKEN | FSMC_BCR_MWID_0; - sramp->sram->BTR = cfgp->btr; + sramp->sram->BCR = cfgp->bcr | FSMC_BCR_MBKEN; + sramp->sram->BTR = cfgp->btr; + sramp->sram->BWTR = cfgp->bwtr; sramp->state = SRAM_READY; } } diff --git a/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sram.h b/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sram.h index a915d75..0abfd86 100644 --- a/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sram.h +++ b/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sram.h @@ -109,9 +109,12 @@ typedef struct SRAMDriver SRAMDriver; /** * @brief Driver configuration structure. * @note It could be empty on some architectures. + * @note Some bits in BCR register will be forced by driver. */ typedef struct { - uint32_t btr; + uint32_t bcr; + uint32_t btr; + uint32_t bwtr; } SRAMConfig; /** diff --git a/os/various/memtest.cpp b/os/various/memtest.cpp index 175ac56..b853fe7 100644 --- a/os/various/memtest.cpp +++ b/os/various/memtest.cpp @@ -18,7 +18,7 @@ #include #include -#include "memtest.hpp" +#include "memtest.h" static unsigned int prng_seed = 42; diff --git a/os/various/memtest.h b/os/various/memtest.h new file mode 100644 index 0000000..721b36b --- /dev/null +++ b/os/various/memtest.h @@ -0,0 +1,88 @@ +/* + 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 MEMTEST_H_ +#define MEMTEST_H_ + +#define MEMTEST_WALKING_ONE (1 << 0) +#define MEMTEST_WALKING_ZERO (1 << 1) +#define MEMTEST_OWN_ADDRESS (1 << 2) +#define MEMTEST_MOVING_INVERSION_ZERO (1 << 3) +#define MEMTEST_MOVING_INVERSION_55AA (1 << 4) +#define MEMTEST_MOVING_INVERSION_RAND (1 << 5) + +#define MEMTEST_RUN_ALL (MEMTEST_WALKING_ONE | \ + MEMTEST_WALKING_ZERO | \ + MEMTEST_OWN_ADDRESS | \ + MEMTEST_MOVING_INVERSION_ZERO | \ + MEMTEST_MOVING_INVERSION_55AA | \ + MEMTEST_MOVING_INVERSION_RAND) + +typedef struct memtest_t memtest_t; +typedef uint32_t testtype; + +/* + * Error call back. + */ +typedef void (*memtestecb_t)(memtest_t *testp, testtype type, size_t index, + size_t current_width, uint32_t got, uint32_t expect); + +/* + * + */ +typedef enum { + MEMTEST_WIDTH_8, + MEMTEST_WIDTH_16, + MEMTEST_WIDTH_32, +} memtest_bus_width_t; + +/* + * + */ +struct memtest_t { + /* + * Pointer to the test area start. Must be word aligned. + */ + void *start; + /* + * Test area size in bytes. + */ + size_t size; + /* + * Maximum width of transactions. + * Note: it implies all narrower tests. + * Note: width my be wider then your memory interface because AHB is + * smart enough to split big transactions to smaller ones. + */ + memtest_bus_width_t width; + /* + * Error callback pointer. Set to NULL if unused. + */ + memtestecb_t errcb; +}; + +/* + * + */ +#ifdef __cplusplus +extern "C" { +#endif + void memtest_run(memtest_t *testp, uint32_t testmask); +#ifdef __cplusplus +} +#endif + +#endif /* MEMTEST_H_ */ diff --git a/os/various/memtest.hpp b/os/various/memtest.hpp deleted file mode 100644 index ba686a3..0000000 --- a/os/various/memtest.hpp +++ /dev/null @@ -1,88 +0,0 @@ -/* - 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 MEMTEST_HPP_ -#define MEMTEST_HPP_ - -#define MEMTEST_WALKING_ONE (1 << 0) -#define MEMTEST_WALKING_ZERO (1 << 1) -#define MEMTEST_OWN_ADDRESS (1 << 2) -#define MEMTEST_MOVING_INVERSION_ZERO (1 << 3) -#define MEMTEST_MOVING_INVERSION_55AA (1 << 4) -#define MEMTEST_MOVING_INVERSION_RAND (1 << 5) - -#define MEMTEST_RUN_ALL (MEMTEST_WALKING_ONE | \ - MEMTEST_WALKING_ZERO | \ - MEMTEST_OWN_ADDRESS | \ - MEMTEST_MOVING_INVERSION_ZERO | \ - MEMTEST_MOVING_INVERSION_55AA | \ - MEMTEST_MOVING_INVERSION_RAND) - -typedef struct memtest_t memtest_t; -typedef uint32_t testtype; - -/* - * Error call back. - */ -typedef void (*memtestecb_t)(memtest_t *testp, testtype type, size_t offset, - size_t current_width, uint32_t got, uint32_t expect); - -/* - * - */ -typedef enum { - MEMTEST_WIDTH_8, - MEMTEST_WIDTH_16, - MEMTEST_WIDTH_32, -} memtest_bus_width_t; - -/* - * - */ -struct memtest_t { - /* - * Pointer to the test area start. Must be word aligned. - */ - void *start; - /* - * Test area size in bytes. - */ - size_t size; - /* - * Maximum width of transactions. - * Note: it implies all narrower tests. - * Note: width my be wider then your memory interface because AHB is - * smart enough to split big transactions to smaller ones. - */ - memtest_bus_width_t width; - /* - * Error callback pointer. Set to NULL if unused. - */ - memtestecb_t errcb; -}; - -/* - * - */ -#ifdef __cplusplus -extern "C" { -#endif - void memtest_run(memtest_t *testp, uint32_t testmask); -#ifdef __cplusplus -} -#endif - -#endif /* MEMTEST_HPP_ */ diff --git a/testhal/STM32/STM32F4xx/FSMC_SDRAM/Makefile b/testhal/STM32/STM32F4xx/FSMC_SDRAM/Makefile index 2cc9d5a..49c5d5e 100644 --- a/testhal/STM32/STM32F4xx/FSMC_SDRAM/Makefile +++ b/testhal/STM32/STM32F4xx/FSMC_SDRAM/Makefile @@ -15,7 +15,7 @@ endif # C++ specific options here (added to USE_OPT). ifeq ($(USE_CPPOPT),) - USE_CPPOPT = -fno-rtti + USE_CPPOPT = -fno-rtti -std=c++11 endif # Enable this if you want the linker to remove unused code and data diff --git a/testhal/STM32/STM32F4xx/FSMC_SDRAM/main.c b/testhal/STM32/STM32F4xx/FSMC_SDRAM/main.c index 5f93520..e07d6d3 100644 --- a/testhal/STM32/STM32F4xx/FSMC_SDRAM/main.c +++ b/testhal/STM32/STM32F4xx/FSMC_SDRAM/main.c @@ -25,7 +25,7 @@ #include "fsmc_sdram.h" #include "membench.h" -#include "memtest.hpp" +#include "memtest.h" /* ****************************************************************************** @@ -127,7 +127,8 @@ ****************************************************************************** */ -static void mem_error_cb(memtest_t *memp, testtype e, size_t address); +static void mem_error_cb(memtest_t *memp, testtype type, size_t index, + size_t width, uint32_t got, uint32_t expect); /* ****************************************************************************** @@ -176,9 +177,8 @@ static uint8_t int_buf[64*1024]; static memtest_t memtest_struct = { SDRAM_START, SDRAM_SIZE, - MEMTEST_WIDTH_16, - mem_error_cb, - 42 + MEMTEST_WIDTH_32, + mem_error_cb }; /* @@ -211,10 +211,14 @@ static membench_result_t membench_result_int2ext; ****************************************************************************** */ -void mem_error_cb(memtest_t *memp, testtype e, size_t address) { +static void mem_error_cb(memtest_t *memp, testtype type, size_t index, + size_t width, uint32_t got, uint32_t expect) { (void)memp; - (void)e; - (void)address; + (void)type; + (void)index; + (void)width; + (void)got; + (void)expect; osalSysHalt("Memory broken"); } @@ -225,7 +229,6 @@ void mem_error_cb(memtest_t *memp, testtype e, size_t address) { static void memtest(void) { while (true) { - memtest_struct.rand_seed = chSysGetRealtimeCounterX(); memtest_run(&memtest_struct, MEMTEST_RUN_ALL); } } diff --git a/testhal/STM32/STM32F4xx/FSMC_SRAM/Makefile b/testhal/STM32/STM32F4xx/FSMC_SRAM/Makefile index e3d83c4..48376a8 100644 --- a/testhal/STM32/STM32F4xx/FSMC_SRAM/Makefile +++ b/testhal/STM32/STM32F4xx/FSMC_SRAM/Makefile @@ -15,7 +15,7 @@ endif # C++ specific options here (added to USE_OPT). ifeq ($(USE_CPPOPT),) - USE_CPPOPT = -fno-rtti + USE_CPPOPT = -fno-rtti -std=c++11 endif # Enable this if you want the linker to remove unused code and data diff --git a/testhal/STM32/STM32F4xx/FSMC_SRAM/main.c b/testhal/STM32/STM32F4xx/FSMC_SRAM/main.c index 03d7f1d..604591d 100644 --- a/testhal/STM32/STM32F4xx/FSMC_SRAM/main.c +++ b/testhal/STM32/STM32F4xx/FSMC_SRAM/main.c @@ -19,7 +19,7 @@ #include "fsmc_sram.h" #include "membench.h" -#include "memtest.hpp" +#include "memtest.h" /* ****************************************************************************** @@ -41,7 +41,8 @@ ****************************************************************************** */ -static void mem_error_cb(memtest_t *memp, testtype e, size_t address); +static void mem_error_cb(memtest_t *memp, testtype type, size_t index, + size_t width, uint32_t got, uint32_t expect); /* ****************************************************************************** @@ -60,7 +61,9 @@ static uint8_t int_buf[64*1024]; * SRAM driver configuration structure. */ static const SRAMConfig sram_cfg = { - (0 << 16) | (2 << 8) | (1 << 0) + .bcr = (FSMC_BCR_MWID_16 | FSMC_BCR_MTYP_SRAM | FSMC_BCR_WREN), + .btr = (0 << 16) | (2 << 8) | (1 << 0), + .bwtr = (0 << 16) | (2 << 8) | (1 << 0) }; /* @@ -69,9 +72,8 @@ static const SRAMConfig sram_cfg = { static memtest_t memtest_struct = { SRAM_START, SRAM_SIZE, - MEMTEST_WIDTH_16, - mem_error_cb, - 42 + MEMTEST_WIDTH_32, + mem_error_cb }; /* @@ -110,10 +112,14 @@ static inline void green_led_on(void) {palSetPad(GPIOI, GPIOI_LED_G);} static inline void green_led_off(void) {palClearPad(GPIOI, GPIOI_LED_G);} static inline void green_led_toggle(void) {palTogglePad(GPIOI, GPIOI_LED_G);} -void mem_error_cb(memtest_t *memp, testtype e, size_t address) { +static void mem_error_cb(memtest_t *memp, testtype type, size_t index, + size_t width, uint32_t got, uint32_t expect) { (void)memp; - (void)e; - (void)address; + (void)type; + (void)index; + (void)width; + (void)got; + (void)expect; green_led_off(); red_led_on(); @@ -130,7 +136,6 @@ static void memtest(void) { red_led_off(); while (true) { - memtest_struct.rand_seed = chSysGetRealtimeCounterX(); memtest_run(&memtest_struct, MEMTEST_RUN_ALL); green_led_toggle(); } -- cgit v1.2.3