From 7355cbd461771f0d38cc2066f7a93b081ce38394 Mon Sep 17 00:00:00 2001 From: barthess Date: Sat, 18 Oct 2014 16:34:12 +0300 Subject: Added fsmc code --- os/hal/ports/STM32/LLD/FSMCv1/fsmc.c | 188 +++++++++++ os/hal/ports/STM32/LLD/FSMCv1/fsmc.h | 311 ++++++++++++++++++ os/hal/ports/STM32/LLD/FSMCv1/fsmc_sram.c | 159 +++++++++ os/hal/ports/STM32/LLD/FSMCv1/fsmc_sram.h | 173 ++++++++++ os/hal/ports/STM32/LLD/FSMCv1/nand_lld.c | 515 ++++++++++++++++++++++++++++++ os/hal/ports/STM32/LLD/FSMCv1/nand_lld.h | 335 +++++++++++++++++++ os/hal/ports/STM32/STM32F4xx/platform.mk | 7 + 7 files changed, 1688 insertions(+) create mode 100644 os/hal/ports/STM32/LLD/FSMCv1/fsmc.c create mode 100644 os/hal/ports/STM32/LLD/FSMCv1/fsmc.h create mode 100644 os/hal/ports/STM32/LLD/FSMCv1/fsmc_sram.c create mode 100644 os/hal/ports/STM32/LLD/FSMCv1/fsmc_sram.h create mode 100644 os/hal/ports/STM32/LLD/FSMCv1/nand_lld.c create mode 100644 os/hal/ports/STM32/LLD/FSMCv1/nand_lld.h create mode 100644 os/hal/ports/STM32/STM32F4xx/platform.mk (limited to 'os/hal/ports') diff --git a/os/hal/ports/STM32/LLD/FSMCv1/fsmc.c b/os/hal/ports/STM32/LLD/FSMCv1/fsmc.c new file mode 100644 index 0000000..4c1a197 --- /dev/null +++ b/os/hal/ports/STM32/LLD/FSMCv1/fsmc.c @@ -0,0 +1,188 @@ +/* + ChibiOS/HAL - Copyright (C) 2006-2014 Giovanni Di Sirio + + 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. +*/ +/* + Concepts and parts of this file have been contributed by Uladzimir Pylinsky + aka barthess. + */ + +/** + * @file fsmc.c + * @brief FSMC Driver subsystem low level driver source template. + * + * @addtogroup FSMC + * @{ + */ +#include "hal.h" +#include "fsmc.h" + +#if HAL_USE_NAND || STM32_USE_FSMC_SRAM || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** + * @brief FSMC1 driver identifier. + */ +#if STM32_FSMC_USE_FSMC1 || defined(__DOXYGEN__) +FSMCDriver FSMCD1; +#endif + +/*===========================================================================*/ +/* Driver local types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level FSMC driver initialization. + * + * @notapi + */ +void fsmc_init(void) { + + if (FSMCD1.state == FSMC_UNINIT) { + FSMCD1.state = FSMC_STOP; + +#if STM32_SRAM_USE_FSMC_SRAM1 + FSMCD1.sram1 = (FSMC_SRAM_NOR_TypeDef *)(FSMC_Bank1_R_BASE); +#endif + +#if STM32_SRAM_USE_FSMC_SRAM2 + FSMCD1.sram2 = (FSMC_SRAM_NOR_TypeDef *)(FSMC_Bank1_R_BASE + 8); +#endif + +#if STM32_SRAM_USE_FSMC_SRAM3 + FSMCD1.sram3 = (FSMC_SRAM_NOR_TypeDef *)(FSMC_Bank1_R_BASE + 8 * 2); +#endif + +#if STM32_SRAM_USE_FSMC_SRAM4 + FSMCD1.sram4 = (FSMC_SRAM_NOR_TypeDef *)(FSMC_Bank1_R_BASE + 8 * 3); +#endif + +#if STM32_NAND_USE_FSMC_NAND1 + FSMCD1.nand1 = (FSMC_NAND_TypeDef *)FSMC_Bank2_R_BASE; +#endif + +#if STM32_NAND_USE_FSMC_NAND2 + FSMCD1.nand2 = (FSMC_NAND_TypeDef *)FSMC_Bank3_R_BASE; +#endif + +#if STM32_USE_FSMC_PCCARD + FSMCD1.pccard = (FSMC_PCCARD_TypeDef *)FSMC_Bank4_R_BASE; +#endif + } +} + +/** + * @brief Configures and activates the FSMC peripheral. + * + * @param[in] fsmcp pointer to the @p FSMCDriver object + * + * @notapi + */ +void fsmc_start(FSMCDriver *fsmcp) { + + osalDbgAssert((fsmcp->state == FSMC_STOP) || (fsmcp->state == FSMC_READY), + "invalid state"); + + if (fsmcp->state == FSMC_STOP) { + /* Enables the peripheral.*/ +#if STM32_FSMC_USE_FSMC1 + if (&FSMCD1 == fsmcp) { + rccResetFSMC(); + rccEnableFSMC(FALSE); +#if (!STM32_NAND_USE_EXT_INT && HAL_USE_NAND) + nvicEnableVector(STM32_FSMC_NUMBER, STM32_FSMC_FSMC1_IRQ_PRIORITY); +#endif + } +#endif /* STM32_FSMC_USE_FSMC1 */ + + fsmcp->state = FSMC_READY; + } +} + +/** + * @brief Deactivates the FSMC peripheral. + * + * @param[in] emcp pointer to the @p FSMCDriver object + * + * @notapi + */ +void fsmc_stop(FSMCDriver *fsmcp) { + + if (fsmcp->state == FSMC_READY) { + /* Resets the peripheral.*/ + rccResetFSMC(); + + /* Disables the peripheral.*/ +#if STM32_FSMC_USE_FSMC1 + if (&FSMCD1 == fsmcp) { +#if (!STM32_NAND_USE_EXT_INT && HAL_USE_NAND) + nvicDisableVector(STM32_FSMC_NUMBER); +#endif + rccDisableFSMC(FALSE); + } +#endif /* STM32_FSMC_USE_FSMC1 */ + + fsmcp->state = FSMC_STOP; + } +} + +#if !STM32_NAND_USE_EXT_INT +/** + * @brief FSMC shared interrupt handler. + * + * @notapi + */ +CH_IRQ_HANDLER(STM32_FSMC_HANDLER) { + + CH_IRQ_PROLOGUE(); +#if STM32_NAND_USE_FSMC_NAND1 + if (FSMCD1.nand1->SR & FSMC_SR_ISR_MASK){ + NANDD1.isr_handler(&NANDD1); + } +#endif +#if STM32_NAND_USE_FSMC_NAND2 + if (FSMCD1.nand2->SR & FSMC_SR_ISR_MASK){ + NANDD2.isr_handler(&NANDD2); + } +#endif + CH_IRQ_EPILOGUE(); +} +#endif /* !STM32_NAND_USE_EXT_INT */ + +#endif /* HAL_USE_FSMC || STM32_USE_FSMC_SRAM */ + +/** @} */ diff --git a/os/hal/ports/STM32/LLD/FSMCv1/fsmc.h b/os/hal/ports/STM32/LLD/FSMCv1/fsmc.h new file mode 100644 index 0000000..2b579a2 --- /dev/null +++ b/os/hal/ports/STM32/LLD/FSMCv1/fsmc.h @@ -0,0 +1,311 @@ +/* + ChibiOS/HAL - Copyright (C) 2006-2014 Giovanni Di Sirio + + 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. +*/ +/* + Concepts and parts of this file have been contributed by Uladzimir Pylinsky + aka barthess. + */ + +/** + * @file fsmc.h + * @brief FSMC Driver subsystem low level driver header. + * + * @addtogroup FSMC + * @{ + */ + +#ifndef _FSMC_H_ +#define _FSMC_H_ + +#if HAL_USE_NAND || STM32_USE_FSMC_SRAM || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/* + * (Re)define if needed base address constants supplied in ST's CMSIS + */ +#if (defined(STM32F427xx) || defined(STM32F437xx) || \ + defined(STM32F429xx) || defined(STM32F439xx)) + #if !defined(FSMC_Bank1_R_BASE) + #define FSMC_Bank1_R_BASE (FMC_R_BASE + 0x0000) + #endif + #if !defined(FSMC_Bank1E_R_BASE) + #define FSMC_Bank1E_R_BASE (FMC_R_BASE + 0x0104) + #endif + #if !defined(FSMC_Bank2_R_BASE) + #define FSMC_Bank2_R_BASE (FMC_R_BASE + 0x0060) + #endif + #if !defined(FSMC_Bank3_R_BASE) + #define FSMC_Bank3_R_BASE (FMC_R_BASE + 0x0080) + #endif + #if !defined(FSMC_Bank4_R_BASE) + #define FSMC_Bank4_R_BASE (FMC_R_BASE + 0x00A0) + #endif + #if !defined(FSMC_Bank5_R_BASE) + #define FSMC_Bank5_R_BASE (FMC_R_BASE + 0x0140) + #endif + #if !defined(FSMC_Bank_R_BASE) + #define FSMC_Bank6_R_BASE (FMC_R_BASE + 0x0144) + #endif +#else + #if !defined(FSMC_Bank1_R_BASE) + #define FSMC_Bank1_R_BASE (FSMC_R_BASE + 0x0000) + #endif + #if !defined(FSMC_Bank1E_R_BASE) + #define FSMC_Bank1E_R_BASE (FSMC_R_BASE + 0x0104) + #endif + #if !defined(FSMC_Bank2_R_BASE) + #define FSMC_Bank2_R_BASE (FSMC_R_BASE + 0x0060) + #endif + #if !defined(FSMC_Bank3_R_BASE) + #define FSMC_Bank3_R_BASE (FSMC_R_BASE + 0x0080) + #endif + #if !defined(FSMC_Bank4_R_BASE) + #define FSMC_Bank4_R_BASE (FSMC_R_BASE + 0x00A0) + #endif +#endif + +/* + * Base bank mappings + */ +#define FSMC_Bank1_MAP_BASE ((uint32_t) 0x60000000) +#define FSMC_Bank2_MAP_BASE ((uint32_t) 0x70000000) +#define FSMC_Bank3_MAP_BASE ((uint32_t) 0x80000000) +#define FSMC_Bank4_MAP_BASE ((uint32_t) 0x90000000) + +/* + * Subbunks of bank1 + */ +#define FSMC_SUBBUNK_OFFSET (1024 * 1024 * 64) +#define FSMC_Bank1_1_MAP (FSMC_Bank1_MAP_BASE) +#define FSMC_Bank1_2_MAP (FSMC_Bank1_1_MAP + FSMC_SUBBUNK_OFFSET) +#define FSMC_Bank1_3_MAP (FSMC_Bank1_2_MAP + FSMC_SUBBUNK_OFFSET) +#define FSMC_Bank1_4_MAP (FSMC_Bank1_3_MAP + FSMC_SUBBUNK_OFFSET) + +/* + * Bank 2 (NAND) + */ +#define FSMC_Bank2_MAP_COMMON (FSMC_Bank2_MAP_BASE + 0) +#define FSMC_Bank2_MAP_ATTR (FSMC_Bank2_MAP_BASE + 0x8000000) + +#define FSMC_Bank2_MAP_COMMON_DATA (FSMC_Bank2_MAP_COMMON + 0) +#define FSMC_Bank2_MAP_COMMON_CMD (FSMC_Bank2_MAP_COMMON + 0x10000) +#define FSMC_Bank2_MAP_COMMON_ADDR (FSMC_Bank2_MAP_COMMON + 0x20000) + +#define FSMC_Bank2_MAP_ATTR_DATA (FSMC_Bank2_MAP_ATTR + 0) +#define FSMC_Bank2_MAP_ATTR_CMD (FSMC_Bank2_MAP_ATTR + 0x10000) +#define FSMC_Bank2_MAP_ATTR_ADDR (FSMC_Bank2_MAP_ATTR + 0x20000) + +/* + * Bank 3 (NAND) + */ +#define FSMC_Bank3_MAP_COMMON (FSMC_Bank3_MAP_BASE + 0) +#define FSMC_Bank3_MAP_ATTR (FSMC_Bank3_MAP_BASE + 0x8000000) + +#define FSMC_Bank3_MAP_COMMON_DATA (FSMC_Bank3_MAP_COMMON + 0) +#define FSMC_Bank3_MAP_COMMON_CMD (FSMC_Bank3_MAP_COMMON + 0x10000) +#define FSMC_Bank3_MAP_COMMON_ADDR (FSMC_Bank3_MAP_COMMON + 0x20000) + +#define FSMC_Bank3_MAP_ATTR_DATA (FSMC_Bank3_MAP_ATTR + 0) +#define FSMC_Bank3_MAP_ATTR_CMD (FSMC_Bank3_MAP_ATTR + 0x10000) +#define FSMC_Bank3_MAP_ATTR_ADDR (FSMC_Bank3_MAP_ATTR + 0x20000) + +/* + * Bank 4 (PC card) + */ +#define FSMC_Bank4_MAP_COMMON (FSMC_Bank4_MAP_BASE + 0) +#define FSMC_Bank4_MAP_ATTR (FSMC_Bank4_MAP_BASE + 0x8000000) +#define FSMC_Bank4_MAP_IO (FSMC_Bank4_MAP_BASE + 0xC000000) + +/* + * More convenient typedefs than CMSIS has + */ +typedef struct { + __IO uint32_t PCR; /**< NAND Flash control */ + __IO uint32_t SR; /**< NAND Flash FIFO status and interrupt */ + __IO uint32_t PMEM; /**< NAND Flash Common memory space timing */ + __IO uint32_t PATT; /**< NAND Flash Attribute memory space timing */ + uint32_t RESERVED0; /**< Reserved, 0x70 */ + __IO uint32_t ECCR; /**< NAND Flash ECC result registers */ +} FSMC_NAND_TypeDef; + +typedef struct { + __IO uint32_t PCR; /**< PC Card control */ + __IO uint32_t SR; /**< PC Card FIFO status and interrupt */ + __IO uint32_t PMEM; /**< PC Card Common memory space timing */ + __IO uint32_t PATT; /**< PC Card Attribute memory space timing */ + __IO uint32_t PIO; /**< PC Card I/O space timing */ +} FSMC_PCCard_TypeDef; + +typedef struct { + __IO uint32_t BCR; /**< SRAM/NOR chip-select control registers */ + __IO uint32_t BTR; /**< SRAM/NOR chip-select timing registers */ + uint32_t RESERVED[63]; /**< Reserved */ + __IO uint32_t BWTR; /**< SRAM/NOR write timing registers */ +} FSMC_SRAM_NOR_TypeDef; + +/** + * @brief PCR register + */ +#define FSMC_PCR_PWAITEN ((uint32_t)0x00000002) +#define FSMC_PCR_PBKEN ((uint32_t)0x00000004) +#define FSMC_PCR_PTYP ((uint32_t)0x00000008) +#define FSMC_PCR_ECCEN ((uint32_t)0x00000040) +#define FSMC_PCR_PTYP_PCCARD 0 +#define FSMC_PCR_PTYP_NAND FSMC_PCR_PTYP + +/** + * @brief SR register + */ +#define FSMC_SR_IRS ((uint8_t)0x01) +#define FSMC_SR_ILS ((uint8_t)0x02) +#define FSMC_SR_IFS ((uint8_t)0x04) +#define FSMC_SR_IREN ((uint8_t)0x08) +#define FSMC_SR_ILEN ((uint8_t)0x10) +#define FSMC_SR_IFEN ((uint8_t)0x20) +#define FSMC_SR_FEMPT ((uint8_t)0x40) +#define FSMC_SR_ISR_MASK (FSMC_SR_IRS | FSMC_SR_ILS | FSMC_SR_IFS) + +/** + * @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) + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @name Configuration options + * @{ + */ +/** + * @brief FSMC driver enable switch. + * @details If set to @p TRUE the support for FSMC is included. + */ +#if !defined(STM32_FSMC_USE_FSMC1) || defined(__DOXYGEN__) +#define STM32_FSMC_USE_FSMC1 FALSE +#endif + +/** + * @brief Internal FSMC interrupt enable switch + * @details MCUs in 100-pin package has no dedicated interrupt pin for FSMC. + * You have to use EXTI module instead to workaround this issue. + */ +#if !defined(STM32_NAND_USE_EXT_INT) || defined(__DOXYGEN__) +#define STM32_NAND_USE_EXT_INT FALSE +#endif + +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ +#if !STM32_FSMC_USE_FSMC1 +#error "FSMC driver activated but no FSMC peripheral assigned" +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief Type of a structure representing an FSMC driver. + */ +typedef struct FSMCDriver FSMCDriver; + +/** + * @brief Driver state machine possible states. + */ +typedef enum { + FSMC_UNINIT = 0, /**< Not initialized. */ + FSMC_STOP = 1, /**< Stopped. */ + FSMC_READY = 2, /**< Ready. */ +} fsmcstate_t; + +/** + * @brief Structure representing an FSMC driver. + */ +struct FSMCDriver { + /** + * @brief Driver state. + */ + fsmcstate_t state; + /* End of the mandatory fields.*/ + +#if STM32_SRAM_USE_FSMC_SRAM1 + FSMC_SRAM_NOR_TypeDef *sram1; +#endif +#if STM32_SRAM_USE_FSMC_SRAM2 + FSMC_SRAM_NOR_TypeDef *sram2; +#endif +#if STM32_SRAM_USE_FSMC_SRAM3 + FSMC_SRAM_NOR_TypeDef *sram3; +#endif +#if STM32_SRAM_USE_FSMC_SRAM4 + FSMC_SRAM_NOR_TypeDef *sram4; +#endif +#if STM32_NAND_USE_FSMC_NAND1 + FSMC_NAND_TypeDef *nand1; +#endif +#if STM32_NAND_USE_FSMC_NAND2 + FSMC_NAND_TypeDef *nand2; +#endif +#if STM32_USE_FSMC_PCCARD + FSMC_PCCard_TypeDef *pccard; +#endif +}; + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if STM32_FSMC_USE_FSMC1 && !defined(__DOXYGEN__) +extern FSMCDriver FSMCD1; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + void fsmc_init(void); + void fsmc_start(FSMCDriver *fsmcp); + void fsmc_stop(FSMCDriver *fsmcp); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_NAND || STM32_USE_FSMC_SRAM */ + +#endif /* _FSMC_H_ */ + +/** @} */ diff --git a/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sram.c b/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sram.c new file mode 100644 index 0000000..44f7ff2 --- /dev/null +++ b/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sram.c @@ -0,0 +1,159 @@ +/* + ChibiOS/HAL - Copyright (C) 2006-2014 Giovanni Di Sirio + + 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. +*/ +/* + Concepts and parts of this file have been contributed by Uladzimir Pylinsky + aka barthess. + */ + +/** + * @file fsmc_sram.c + * @brief SRAM Driver subsystem low level driver source. + * + * @addtogroup SRAM + * @{ + */ +#include "hal.h" +#include "fsmc_sram.h" + +#if STM32_USE_FSMC_SRAM || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ +/** + * @brief SRAM1 driver identifier. + */ +#if STM32_SRAM_USE_FSMC_SRAM1 || defined(__DOXYGEN__) +SRAMDriver SRAMD1; +#endif + +/** + * @brief SRAM2 driver identifier. + */ +#if STM32_SRAM_USE_FSMC_SRAM2 || defined(__DOXYGEN__) +SRAMDriver SRAMD2; +#endif + +/** + * @brief SRAM3 driver identifier. + */ +#if STM32_SRAM_USE_FSMC_SRAM3 || defined(__DOXYGEN__) +SRAMDriver SRAMD3; +#endif + +/** + * @brief SRAM4 driver identifier. + */ +#if STM32_SRAM_USE_FSMC_SRAM4 || defined(__DOXYGEN__) +SRAMDriver SRAMD4; +#endif + +/*===========================================================================*/ +/* Driver local types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level SRAM driver initialization. + * + * @notapi + */ +void fsmcSramInit(void) { + + fsmc_init(); + +#if STM32_SRAM_USE_FSMC_SRAM1 + SRAMD1.sram = FSMCD1.sram1; + SRAMD1.state = SRAM_STOP; +#endif /* STM32_SRAM_USE_FSMC_SRAM1 */ + +#if STM32_SRAM_USE_FSMC_SRAM2 + SRAMD2.sram = FSMCD1.sram2; + SRAMD2.state = SRAM_STOP; +#endif /* STM32_SRAM_USE_FSMC_SRAM2 */ + +#if STM32_SRAM_USE_FSMC_SRAM3 + SRAMD3.sram = FSMCD1.sram3; + SRAMD3.state = SRAM_STOP; +#endif /* STM32_SRAM_USE_FSMC_SRAM3 */ + +#if STM32_SRAM_USE_FSMC_SRAM4 + SRAMD4.sram = FSMCD1.sram4; + SRAMD4.state = SRAM_STOP; +#endif /* STM32_SRAM_USE_FSMC_SRAM4 */ +} + +/** + * @brief Configures and activates the SRAM peripheral. + * + * @param[in] sramp pointer to the @p SRAMDriver object + * @param[in] cfgp pointer to the @p SRAMConfig object + * + * @notapi + */ +void fsmcSramStart(SRAMDriver *sramp, const SRAMConfig *cfgp) { + + if (FSMCD1.state == FSMC_STOP) + fsmc_start(&FSMCD1); + + osalDbgAssert((sramp->state == SRAM_STOP) || (sramp->state == SRAM_READY), + "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->state = SRAM_READY; + } +} + +/** + * @brief Deactivates the SRAM peripheral. + * + * @param[in] sramp pointer to the @p SRAMDriver object + * + * @notapi + */ +void fsmcSramStop(SRAMDriver *sramp) { + + if (sramp->state == SRAM_READY) { + sramp->sram->BCR &= ~FSMC_BCR_MBKEN; + sramp->state = SRAM_STOP; + } +} + +#endif /* STM32_USE_FSMC_SRAM */ + +/** @} */ + diff --git a/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sram.h b/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sram.h new file mode 100644 index 0000000..0113a04 --- /dev/null +++ b/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sram.h @@ -0,0 +1,173 @@ +/* + ChibiOS/HAL - Copyright (C) 2006-2014 Giovanni Di Sirio + + 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. +*/ +/* + Concepts and parts of this file have been contributed by Uladzimir Pylinsky + aka barthess. + */ + +/** + * @file fsmc_sram.h + * @brief SRAM Driver subsystem low level driver header. + * + * @addtogroup SRAM + * @{ + */ + +#ifndef _FSMC_SRAM_H_ +#define _FSMC_SRAM_H_ + +#include "fsmc.h" + +#if STM32_USE_FSMC_SRAM || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ +/** + * @name Configuration options + * @{ + */ + +/** + * @brief SRAM driver enable switch. + * @details If set to @p TRUE the support for SRAM1 is included. + */ +#if !defined(STM32_SRAM_USE_FSMC_SRAM1) || defined(__DOXYGEN__) +#define STM32_SRAM_USE_FSMC_SRAM1 FALSE +#endif + +/** + * @brief SRAM driver enable switch. + * @details If set to @p TRUE the support for SRAM2 is included. + */ +#if !defined(STM32_SRAM_USE_FSMC_SRAM2) || defined(__DOXYGEN__) +#define STM32_SRAM_USE_FSMC_SRAM2 FALSE +#endif + +/** + * @brief SRAM driver enable switch. + * @details If set to @p TRUE the support for SRAM3 is included. + */ +#if !defined(STM32_SRAM_USE_FSMC_SRAM3) || defined(__DOXYGEN__) +#define STM32_SRAM_USE_FSMC_SRAM3 FALSE +#endif + +/** + * @brief SRAM driver enable switch. + * @details If set to @p TRUE the support for SRAM4 is included. + */ +#if !defined(STM32_SRAM_USE_FSMC_SRAM4) || defined(__DOXYGEN__) +#define STM32_SRAM_USE_FSMC_SRAM4 FALSE +#endif + +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +#if !STM32_SRAM_USE_FSMC_SRAM1 && !STM32_SRAM_USE_FSMC_SRAM2 && \ + !STM32_SRAM_USE_FSMC_SRAM3 && !STM32_SRAM_USE_FSMC_SRAM4 +#error "SRAM driver activated but no SRAM peripheral assigned" +#endif + +#if (STM32_SRAM_USE_FSMC_SRAM1 || STM32_SRAM_USE_FSMC_SRAM2 || \ + STM32_SRAM_USE_FSMC_SRAM3 || STM32_SRAM_USE_FSMC_SRAM4) && !STM32_HAS_FSMC +#error "FSMC not present in the selected device" +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ +/** + * @brief Driver state machine possible states. + */ +typedef enum { + SRAM_UNINIT = 0, /**< Not initialized. */ + SRAM_STOP = 1, /**< Stopped. */ + SRAM_READY = 2, /**< Ready. */ +} sramstate_t; + +/** + * @brief Type of a structure representing an NAND driver. + */ +typedef struct SRAMDriver SRAMDriver; + +/** + * @brief Driver configuration structure. + * @note It could be empty on some architectures. + */ +typedef struct { + uint32_t btr; +} SRAMConfig; + +/** + * @brief Structure representing an NAND driver. + */ +struct SRAMDriver { + /** + * @brief Driver state. + */ + sramstate_t state; + /** + * @brief Pointer to the FSMC SRAM registers block. + */ + FSMC_SRAM_NOR_TypeDef *sram; +}; + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if STM32_SRAM_USE_FSMC_SRAM1 && !defined(__DOXYGEN__) +extern SRAMDriver SRAMD1; +#endif + +#if STM32_SRAM_USE_FSMC_SRAM2 && !defined(__DOXYGEN__) +extern SRAMDriver SRAMD2; +#endif + +#if STM32_SRAM_USE_FSMC_SRAM3 && !defined(__DOXYGEN__) +extern SRAMDriver SRAMD3; +#endif + +#if STM32_SRAM_USE_FSMC_SRAM4 && !defined(__DOXYGEN__) +extern SRAMDriver SRAMD4; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + void fsmcSramInit(void); + void fsmcSramStart(SRAMDriver *sramp, const SRAMConfig *cfgp); + void fsmcSramStop(SRAMDriver *sramp); +#ifdef __cplusplus +} +#endif + +#endif /* STM32_USE_FSMC_SRAM */ + +#endif /* _FSMC_SRAM_H_ */ + +/** @} */ diff --git a/os/hal/ports/STM32/LLD/FSMCv1/nand_lld.c b/os/hal/ports/STM32/LLD/FSMCv1/nand_lld.c new file mode 100644 index 0000000..3739e88 --- /dev/null +++ b/os/hal/ports/STM32/LLD/FSMCv1/nand_lld.c @@ -0,0 +1,515 @@ +/* + ChibiOS/HAL - Copyright (C) 2006-2014 Giovanni Di Sirio + + 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. +*/ +/* + Concepts and parts of this file have been contributed by Uladzimir Pylinsky + aka barthess. + */ + +/** + * @file nand_lld.c + * @brief NAND Driver subsystem low level driver source. + * + * @addtogroup NAND + * @{ + */ + +#include "hal.h" + +#if HAL_USE_NAND || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ +#define NAND_DMA_CHANNEL \ + STM32_DMA_GETCHANNEL(STM32_NAND_DMA_STREAM, \ + STM32_FSMC_DMA_CHN) + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** + * @brief NAND1 driver identifier. + */ +#if STM32_NAND_USE_FSMC_NAND1 || defined(__DOXYGEN__) +NANDDriver NANDD1; +#endif + +/** + * @brief NAND2 driver identifier. + */ +#if STM32_NAND_USE_FSMC_NAND2 || defined(__DOXYGEN__) +NANDDriver NANDD2; +#endif + +/*===========================================================================*/ +/* Driver local types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ +/** + * @brief Wakes up the waiting thread. + * + * @param[in] nandp pointer to the @p NANDDriver object + * @param[in] msg wakeup message + * + * @notapi + */ +static void wakeup_isr(NANDDriver *nandp){ + + osalDbgCheck(nandp->thread != NULL); + osalThreadResumeI(&nandp->thread, MSG_OK); +} + +/** + * @brief Put calling thread in suspend and switch driver state + * + * @param[in] nandp pointer to the @p NANDDriver object + */ +static void nand_lld_suspend_thread(NANDDriver *nandp) { + + osalThreadSuspendS(&nandp->thread); +} + +/** + * @brief Caclulate ECCPS register value + * + * @param[in] nandp pointer to the @p NANDDriver object + */ +static uint32_t calc_eccps(NANDDriver *nandp){ + + uint32_t i = 0; + uint32_t eccps = nandp->config->page_data_size; + + eccps = eccps >> 9; + while (eccps > 0){ + i++; + eccps >>= 1; + } + + return i << 17; +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/** + * @brief Enable interrupts from NAND + * + * @param[in] nandp pointer to the @p NANDDriver object + * + * @notapi + */ +static void nand_ready_isr_enable(NANDDriver *nandp) { +#if STM32_NAND_USE_EXT_INT + nandp->config->ext_nand_isr_enable(); +#else + nandp->nand->SR &= ~(FSMC_SR_IRS | FSMC_SR_ILS | FSMC_SR_IFS | + FSMC_SR_ILEN | FSMC_SR_IFEN); + nandp->nand->SR |= FSMC_SR_IREN; +#endif +} + +/** + * @brief Disable interrupts from NAND + * + * @param[in] nandp pointer to the @p NANDDriver object + * + * @notapi + */ +static void nand_ready_isr_disable(NANDDriver *nandp) { +#if STM32_NAND_USE_EXT_INT + nandp->config->ext_nand_isr_disable(); +#else + nandp->nand->SR &= ~FSMC_SR_IREN; +#endif +} + +/** + * @brief Ready interrupt handler + * + * @param[in] nandp pointer to the @p NANDDriver object + * + * @notapi + */ +static void nand_isr_handler (NANDDriver *nandp){ + + osalSysLockFromISR(); + +#if !STM32_NAND_USE_EXT_INT + osalDbgCheck(nandp->nand->SR & FSMC_SR_IRS); /* spurious interrupt happened */ + nandp->nand->SR &= ~FSMC_SR_IRS; +#endif + + switch (nandp->state){ + case NAND_READ: + nandp->state = NAND_DMA_RX; + dmaStartMemCopy(nandp->dma, nandp->dmamode, + nandp->map_data, nandp->rxdata, nandp->datalen); + /* thread will be waked up from DMA ISR */ + break; + + case NAND_ERASE: + /* NAND reports about erase finish */ + nandp->state = NAND_READY; + wakeup_isr(nandp); + break; + + case NAND_PROGRAM: + /* NAND reports about page programming finish */ + nandp->state = NAND_READY; + wakeup_isr(nandp); + break; + + default: + osalSysHalt("Unhandled case"); + break; + } + osalSysUnlockFromISR(); +} + +/** + * @brief DMA RX end IRQ handler. + * + * @param[in] nandp pointer to the @p NANDDriver object + * @param[in] flags pre-shifted content of the ISR register + * + * @notapi + */ +static void nand_lld_serve_transfer_end_irq(NANDDriver *nandp, uint32_t flags) { + /* DMA errors handling.*/ +#if defined(STM32_NAND_DMA_ERROR_HOOK) + if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) { + STM32_NAND_DMA_ERROR_HOOK(nandp); + } +#else + (void)flags; +#endif + + osalSysLockFromISR(); + + dmaStreamDisable(nandp->dma); + + switch (nandp->state){ + case NAND_DMA_TX: + nandp->state = NAND_PROGRAM; + nandp->map_cmd[0] = NAND_CMD_PAGEPROG; + /* thread will be woken from ready_isr() */ + break; + + case NAND_DMA_RX: + nandp->state = NAND_READY; + nandp->rxdata = NULL; + nandp->datalen = 0; + wakeup_isr(nandp); + break; + + default: + osalSysHalt("Unhandled case"); + break; + } + + osalSysUnlockFromISR(); +} + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level NAND driver initialization. + * + * @notapi + */ +void nand_lld_init(void) { + + fsmc_init(); + +#if STM32_NAND_USE_FSMC_NAND1 + /* Driver initialization.*/ + nandObjectInit(&NANDD1); + NANDD1.rxdata = NULL; + NANDD1.datalen = 0; + NANDD1.thread = NULL; + NANDD1.dma = STM32_DMA_STREAM(STM32_NAND_DMA_STREAM); + NANDD1.nand = FSMCD1.nand1; + NANDD1.map_data = (uint8_t*)FSMC_Bank2_MAP_COMMON_DATA; + NANDD1.map_cmd = (uint8_t*)FSMC_Bank2_MAP_COMMON_CMD; + NANDD1.map_addr = (uint8_t*)FSMC_Bank2_MAP_COMMON_ADDR; +#endif /* STM32_NAND_USE_FSMC_NAND1 */ + +#if STM32_NAND_USE_FSMC_NAND2 + /* Driver initialization.*/ + nandObjectInit(&NANDD2); + NANDD2.rxdata = NULL; + NANDD2.datalen = 0; + NANDD2.thread = NULL; + NANDD2.dma = STM32_DMA_STREAM(STM32_NAND_DMA_STREAM); + NANDD2.nand = FSMCD1.nand2; + NANDD2.map_data = (uint8_t*)FSMC_Bank3_MAP_COMMON_DATA; + NANDD2.map_cmd = (uint8_t*)FSMC_Bank3_MAP_COMMON_CMD; + NANDD2.map_addr = (uint8_t*)FSMC_Bank3_MAP_COMMON_ADDR; +#endif /* STM32_NAND_USE_FSMC_NAND2 */ +} + +/** + * @brief Configures and activates the NAND peripheral. + * + * @param[in] nandp pointer to the @p NANDDriver object + * + * @notapi + */ +void nand_lld_start(NANDDriver *nandp) { + + bool b; + + if (FSMCD1.state == FSMC_STOP) + fsmc_start(&FSMCD1); + + if (nandp->state == NAND_STOP) { + b = dmaStreamAllocate(nandp->dma, + STM32_EMC_FSMC1_IRQ_PRIORITY, + (stm32_dmaisr_t)nand_lld_serve_transfer_end_irq, + (void *)nandp); + osalDbgAssert(!b, "stream already allocated"); + nandp->dmamode = STM32_DMA_CR_CHSEL(NAND_DMA_CHANNEL) | + STM32_DMA_CR_PL(STM32_NAND_NAND1_DMA_PRIORITY) | + STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE | + STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE | + STM32_DMA_CR_TCIE; + /* dmaStreamSetFIFO(nandp->dma, + STM32_DMA_FCR_DMDIS | NAND_STM32_DMA_FCR_FTH_LVL); */ + nandp->nand->PCR = calc_eccps(nandp) | FSMC_PCR_PTYP | FSMC_PCR_PBKEN; + nandp->nand->PMEM = nandp->config->pmem; + nandp->nand->PATT = nandp->config->pmem; + nandp->isr_handler = nand_isr_handler; + nand_ready_isr_enable(nandp); + } +} + +/** + * @brief Deactivates the NAND peripheral. + * + * @param[in] nandp pointer to the @p NANDDriver object + * + * @notapi + */ +void nand_lld_stop(NANDDriver *nandp) { + + if (nandp->state == NAND_READY) { + dmaStreamRelease(nandp->dma); + nandp->nand->PCR &= ~FSMC_PCR_PBKEN; + nand_ready_isr_disable(nandp); + nandp->isr_handler = NULL; + } +} + +/** + * @brief Read data from NAND. + * + * @param[in] nandp pointer to the @p NANDDriver object + * @param[out] data pointer to data buffer + * @param[in] datalen size of data buffer + * @param[in] addr pointer to address buffer + * @param[in] addrlen length of address + * @param[out] ecc pointer to store computed ECC. Ignored when NULL. + * + * @notapi + */ +void nand_lld_read_data(NANDDriver *nandp, uint8_t *data, + size_t datalen, uint8_t *addr, size_t addrlen, uint32_t *ecc){ + + nandp->state = NAND_READ; + nandp->rxdata = data; + nandp->datalen = datalen; + + nand_lld_write_cmd (nandp, NAND_CMD_READ0); + nand_lld_write_addr(nandp, addr, addrlen); + osalSysLock(); + nand_lld_write_cmd (nandp, NAND_CMD_READ0_CONFIRM); + + /* Here NAND asserts busy signal and starts transferring from memory + array to page buffer. After the end of transmission ready_isr functions + starts DMA transfer from page buffer to MCU's RAM.*/ + osalDbgAssert((nandp->nand->PCR & FSMC_PCR_ECCEN) == 0, + "State machine broken. ECCEN must be previously disabled."); + + if (NULL != ecc){ + nandp->nand->PCR |= FSMC_PCR_ECCEN; + } + + nand_lld_suspend_thread(nandp); + osalSysUnlock(); + + /* thread was woken up from DMA ISR */ + if (NULL != ecc){ + while (! (nandp->nand->SR & FSMC_SR_FEMPT)) + ; + *ecc = nandp->nand->ECCR; + nandp->nand->PCR &= ~FSMC_PCR_ECCEN; + } +} + +/** + * @brief Write data to NAND. + * + * @param[in] nandp pointer to the @p NANDDriver object + * @param[in] data buffer with data to be written + * @param[in] datalen size of data buffer + * @param[in] addr pointer to address buffer + * @param[in] addrlen length of address + * @param[out] ecc pointer to store computed ECC. Ignored when NULL. + * + * @return The operation status reported by NAND IC (0x70 command). + * + * @notapi + */ +uint8_t nand_lld_write_data(NANDDriver *nandp, const uint8_t *data, + size_t datalen, uint8_t *addr, size_t addrlen, uint32_t *ecc){ + + nandp->state = NAND_WRITE; + + nand_lld_write_cmd (nandp, NAND_CMD_WRITE); + osalSysLock(); + nand_lld_write_addr(nandp, addr, addrlen); + + /* Now start DMA transfer to NAND buffer and put thread in sleep state. + Tread will we woken up from ready ISR. */ + nandp->state = NAND_DMA_TX; + osalDbgAssert((nandp->nand->PCR & FSMC_PCR_ECCEN) == 0, + "State machine broken. ECCEN must be previously disabled."); + + if (NULL != ecc){ + nandp->nand->PCR |= FSMC_PCR_ECCEN; + } + + dmaStartMemCopy(nandp->dma, nandp->dmamode, data, nandp->map_data, datalen); + + nand_lld_suspend_thread(nandp); + osalSysUnlock(); + + if (NULL != ecc){ + while (! (nandp->nand->SR & FSMC_SR_FEMPT)) + ; + *ecc = nandp->nand->ECCR; + nandp->nand->PCR &= ~FSMC_PCR_ECCEN; + } + + return nand_lld_read_status(nandp); +} + +/** + * @brief Erase block. + * + * @param[in] nandp pointer to the @p NANDDriver object + * @param[in] addr pointer to address buffer + * @param[in] addrlen length of address + * + * @return The operation status reported by NAND IC (0x70 command). + * + * @notapi + */ +uint8_t nand_lld_erase(NANDDriver *nandp, uint8_t *addr, size_t addrlen){ + + nandp->state = NAND_ERASE; + + nand_lld_write_cmd (nandp, NAND_CMD_ERASE); + nand_lld_write_addr(nandp, addr, addrlen); + osalSysLock(); + nand_lld_write_cmd (nandp, NAND_CMD_ERASE_CONFIRM); + nand_lld_suspend_thread(nandp); + osalSysUnlock(); + + return nand_lld_read_status(nandp); +} + +/** + * @brief Read data from NAND using polling approach. + * + * @detatils Use this function to read data when no waiting expected. For + * Example read status word after 0x70 command + * + * @param[in] nandp pointer to the @p NANDDriver object + * @param[out] data pointer to output buffer + * @param[in] len length of data to be read + * + * @notapi + */ +void nand_lld_polled_read_data(NANDDriver *nandp, uint8_t *data, size_t len){ + size_t i = 0; + + for (i=0; imap_data[i]; +} + +/** + * @brief Send addres to NAND. + * + * @param[in] nandp pointer to the @p NANDDriver object + * @param[in] len length of address array + * @param[in] addr pointer to address array + * + * @notapi + */ +void nand_lld_write_addr(NANDDriver *nandp, const uint8_t *addr, size_t len){ + size_t i = 0; + + for (i=0; imap_addr[i] = addr[i]; +} + +/** + * @brief Send command to NAND. + * + * @param[in] nandp pointer to the @p NANDDriver object + * @param[in] cmd command value + * + * @notapi + */ +void nand_lld_write_cmd(NANDDriver *nandp, uint8_t cmd){ + nandp->map_cmd[0] = cmd; +} + +/** + * @brief Read status byte from NAND. + * + * @param[in] nandp pointer to the @p NANDDriver object + * + * @return Status byte. + * + * @notapi + */ +uint8_t nand_lld_read_status(NANDDriver *nandp) { + + uint8_t status[1] = {0x01}; /* presume worse */ + + nand_lld_write_cmd(nandp, NAND_CMD_STATUS); + nand_lld_polled_read_data(nandp, status, 1); + + return status[0]; +} + +#endif /* HAL_USE_NAND */ + +/** @} */ + diff --git a/os/hal/ports/STM32/LLD/FSMCv1/nand_lld.h b/os/hal/ports/STM32/LLD/FSMCv1/nand_lld.h new file mode 100644 index 0000000..618255f --- /dev/null +++ b/os/hal/ports/STM32/LLD/FSMCv1/nand_lld.h @@ -0,0 +1,335 @@ +/* + ChibiOS/HAL - Copyright (C) 2006-2014 Giovanni Di Sirio + + 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. +*/ +/* + Concepts and parts of this file have been contributed by Uladzimir Pylinsky + aka barthess. + */ + +/** + * @file nand_lld.h + * @brief NAND Driver subsystem low level driver header. + * + * @addtogroup NAND + * @{ + */ + +#ifndef _NAND_LLD_H_ +#define _NAND_LLD_H_ + +#include "fsmc.h" + +#if HAL_USE_NAND || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ +#define NAND_MIN_PAGE_SIZE 256 +#define NAND_MAX_PAGE_SIZE 8192 + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @name Configuration options + * @{ + */ +/** + * @brief FSMC1 interrupt priority level setting. + */ +#if !defined(STM32_EMC_FSMC1_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_EMC_FSMC1_IRQ_PRIORITY 10 +#endif + +/** + * @brief NAND driver enable switch. + * @details If set to @p TRUE the support for NAND1 is included. + */ +#if !defined(STM32_NAND_USE_NAND1) || defined(__DOXYGEN__) +#define STM32_NAND_USE_NAND1 FALSE +#endif + +/** + * @brief NAND driver enable switch. + * @details If set to @p TRUE the support for NAND2 is included. + */ +#if !defined(STM32_NAND_USE_NAND2) || defined(__DOXYGEN__) +#define STM32_NAND_USE_NAND2 FALSE +#endif + +/** + * @brief NAND DMA error hook. + * @note The default action for DMA errors is a system halt because DMA + * error can only happen because programming errors. + */ +#if !defined(STM32_NAND_DMA_ERROR_HOOK) || defined(__DOXYGEN__) +#define STM32_NAND_DMA_ERROR_HOOK(nandp) osalSysHalt("DMA failure") +#endif + +/** + * @brief NAND interrupt enable switch. + * @details If set to @p TRUE the support for internal FSMC interrupt included. + */ +#if !defined(STM32_NAND_USE_INT) || defined(__DOXYGEN__) +#define STM32_NAND_USE_INT FALSE +#endif + +/** +* @brief NAND1 DMA priority (0..3|lowest..highest). +*/ +#if !defined(STM32_NAND_NAND1_DMA_PRIORITY) || defined(__DOXYGEN__) +#define STM32_NAND_NAND1_DMA_PRIORITY 0 +#endif + +/** +* @brief NAND2 DMA priority (0..3|lowest..highest). +*/ +#if !defined(STM32_NAND_NAND2_DMA_PRIORITY) || defined(__DOXYGEN__) +#define STM32_NAND_NAND2_DMA_PRIORITY 0 +#endif + +/** + * @brief DMA stream used for NAND operations. + * @note This option is only available on platforms with enhanced DMA. + */ +#if !defined(STM32_NAND_DMA_STREAM) || defined(__DOXYGEN__) +#define STM32_NAND_DMA_STREAM STM32_DMA_STREAM_ID(2, 6) +#endif + +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +#if !STM32_NAND_USE_FSMC_NAND1 && !STM32_NAND_USE_FSMC_NAND2 +#error "NAND driver activated but no NAND peripheral assigned" +#endif + +#if (STM32_NAND_USE_FSMC_NAND2 || STM32_NAND_USE_FSMC_NAND1) && !STM32_HAS_FSMC +#error "FSMC not present in the selected device" +#endif + +#if STM32_NAND_USE_EXT_INT && !HAL_USE_EXT +#error "External interrupt controller must be enabled to use this feature" +#endif + +#if (STM32_NAND_USE_FSMC_NAND2 || STM32_NAND_USE_FSMC_NAND1) && \ + !STM32_DMA_IS_VALID_ID(STM32_NAND_DMA_STREAM, \ + STM32_FSMC_DMA_MSK) +#error "invalid DMA stream associated to NAND" +#endif + +#if !defined(STM32_DMA_REQUIRED) +#define STM32_DMA_REQUIRED +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief NAND driver condition flags type. + */ +typedef uint32_t nandflags_t; + +/** + * @brief Type of a structure representing an NAND driver. + */ +typedef struct NANDDriver NANDDriver; + +/** + * @brief Type of interrupt handler function + */ +typedef void (*nandisrhandler_t)(NANDDriver *nandp); + +#if STM32_NAND_USE_EXT_INT +/** + * @brief Type of function switching external interrupts on and off. + */ +typedef void (*nandisrswitch_t)(void); +#endif /* STM32_NAND_USE_EXT_INT */ + +/** + * @brief Driver configuration structure. + * @note It could be empty on some architectures. + */ +typedef struct { + /** + * @brief Pointer to lower level driver. + */ + FSMCDriver *fsmcp; + /** + * @brief Number of erase blocks in NAND device. + */ + uint32_t blocks; + /** + * @brief Number of data bytes in page. + */ + uint32_t page_data_size; + /** + * @brief Number of spare bytes in page. + */ + uint32_t page_spare_size; + /** + * @brief Number of pages in block. + */ + uint32_t pages_per_block; +#if NAND_USE_BAD_MAP + /** + * @brief Pointer to bad block map. + * @details One bit per block. Memory for map must be allocated by user. + */ + uint32_t *bb_map; +#endif /* NAND_USE_BAD_MAP */ + /** + * @brief Number of write cycles for row addressing. + */ + uint8_t rowcycles; + /** + * @brief Number of write cycles for column addressing. + */ + uint8_t colcycles; + + /* End of the mandatory fields.*/ + /** + * @brief Number of wait cycles. This value will be used both for + * PMEM and PATTR registers + * + * @note For proper calculation procedure please look at AN2784 document + * from STMicroelectronics. + */ + uint32_t pmem; +#if STM32_NAND_USE_EXT_INT + /** + * @brief Function enabling interrupts from EXTI + */ + nandisrswitch_t ext_nand_isr_enable; + /** + * @brief Function disabling interrupts from EXTI + */ + nandisrswitch_t ext_nand_isr_disable; +#endif /* STM32_NAND_USE_EXT_INT */ +} NANDConfig; + +/** + * @brief Structure representing an NAND driver. + */ +struct NANDDriver { + /** + * @brief Driver state. + */ + nandstate_t state; + /** + * @brief Current configuration data. + */ + const NANDConfig *config; + /** + * @brief Array to store bad block map. + */ +#if NAND_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__) +#if CH_CFG_USE_MUTEXES || defined(__DOXYGEN__) + /** + * @brief Mutex protecting the bus. + */ + mutex_t mutex; +#elif CH_CFG_USE_SEMAPHORES + semaphore_t semaphore; +#endif +#endif /* NAND_USE_MUTUAL_EXCLUSION */ + /* End of the mandatory fields.*/ + /** + * @brief Function enabling interrupts from FSMC + */ + nandisrhandler_t isr_handler; + /** + * @brief Pointer to current transaction buffer + */ + uint8_t *rxdata; + /** + * @brief Current transaction length + */ + size_t datalen; + /** + * @brief DMA mode bit mask. + */ + uint32_t dmamode; + /** + * @brief DMA channel. + */ + const stm32_dma_stream_t *dma; + /** + * @brief Thread waiting for I/O completion. + */ + thread_t *thread; + /** + * @brief Pointer to the FSMC NAND registers block. + */ + FSMC_NAND_TypeDef *nand; + /** + * @brief Memory mapping for data. + */ + uint8_t *map_data; + /** + * @brief Memory mapping for commands. + */ + uint8_t *map_cmd; + /** + * @brief Memory mapping for addresses. + */ + uint8_t *map_addr; +}; + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if STM32_NAND_USE_FSMC_NAND1 && !defined(__DOXYGEN__) +extern NANDDriver NANDD1; +#endif + +#if STM32_NAND_USE_FSMC_NAND2 && !defined(__DOXYGEN__) +extern NANDDriver NANDD2; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + void nand_lld_init(void); + void nand_lld_start(NANDDriver *nandp); + void nand_lld_stop(NANDDriver *nandp); + uint8_t nand_lld_write_data(NANDDriver *nandp, const uint8_t *data, + size_t datalen, uint8_t *addr, size_t addrlen, uint32_t *ecc); + void nand_lld_read_data(NANDDriver *nandp, uint8_t *data, + size_t datalen, uint8_t *addr, size_t addrlen, uint32_t *ecc); + void nand_lld_polled_read_data(NANDDriver *nandp, uint8_t *data, size_t len); + uint8_t nand_lld_erase(NANDDriver *nandp, uint8_t *addr, size_t addrlen); + void nand_lld_write_addr(NANDDriver *nandp, const uint8_t *addr, size_t len); + void nand_lld_write_cmd(NANDDriver *nandp, uint8_t cmd); + uint8_t nand_lld_read_status(NANDDriver *nandp); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_NAND */ + +#endif /* _NAND_LLD_H_ */ + +/** @} */ diff --git a/os/hal/ports/STM32/STM32F4xx/platform.mk b/os/hal/ports/STM32/STM32F4xx/platform.mk new file mode 100644 index 0000000..0fa3ce0 --- /dev/null +++ b/os/hal/ports/STM32/STM32F4xx/platform.mk @@ -0,0 +1,7 @@ +include ${CHIBIOS}/os/hal/ports/STM32/STM32F4xx/platform.mk + +PLATFORMSRC += ${CHIBIOS}/os/hal/ports/STM32/LLD/FSMCv1/fsmc.c \ + ${CHIBIOS}/os/hal/ports/STM32/LLD/FSMCv1/nand_lld.c \ + ${CHIBIOS}/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sram.c + +PLATFORMINC += ${CHIBIOS}/os/hal/ports/STM32/LLD/FSMCv1 -- cgit v1.2.3 From 721c48bc978edeeff89e4b1169cb96b1569fdc3a Mon Sep 17 00:00:00 2001 From: barthess Date: Sat, 18 Oct 2014 17:20:29 +0300 Subject: FSMC. Build fixed after code moving from SVN --- os/hal/ports/STM32/STM32F4xx/platform.mk | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'os/hal/ports') diff --git a/os/hal/ports/STM32/STM32F4xx/platform.mk b/os/hal/ports/STM32/STM32F4xx/platform.mk index 0fa3ce0..dc8f1c4 100644 --- a/os/hal/ports/STM32/STM32F4xx/platform.mk +++ b/os/hal/ports/STM32/STM32F4xx/platform.mk @@ -1,7 +1,7 @@ include ${CHIBIOS}/os/hal/ports/STM32/STM32F4xx/platform.mk -PLATFORMSRC += ${CHIBIOS}/os/hal/ports/STM32/LLD/FSMCv1/fsmc.c \ - ${CHIBIOS}/os/hal/ports/STM32/LLD/FSMCv1/nand_lld.c \ - ${CHIBIOS}/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sram.c +PLATFORMSRC += ${CHIBIOS}/community/os/hal/ports/STM32/LLD/FSMCv1/fsmc.c \ + ${CHIBIOS}/community/os/hal/ports/STM32/LLD/FSMCv1/nand_lld.c \ + ${CHIBIOS}/community/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sram.c -PLATFORMINC += ${CHIBIOS}/os/hal/ports/STM32/LLD/FSMCv1 +PLATFORMINC += ${CHIBIOS}/community/os/hal/ports/STM32/LLD/FSMCv1 -- cgit v1.2.3 From 8dabb3b8f529dafece19b728899290ad3deb8fb5 Mon Sep 17 00:00:00 2001 From: barthess Date: Sun, 19 Oct 2014 23:58:48 +0300 Subject: Added SDRAM support via FSMC --- os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.c | 264 ++++++++++++++++++++ os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.h | 382 +++++++++++++++++++++++++++++ 2 files changed, 646 insertions(+) create mode 100644 os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.c create mode 100644 os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.h (limited to 'os/hal/ports') diff --git a/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.c b/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.c new file mode 100644 index 0000000..eca66ea --- /dev/null +++ b/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.c @@ -0,0 +1,264 @@ +/* + ChibiOS/HAL - Copyright (C) 2006-2014 Giovanni Di Sirio + + 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. +*/ +/* + Concepts and parts of this file have been contributed by Uladzimir Pylinsky + aka barthess (SDRAM routines added by Nick Klimov aka progfin). + */ + +/** + * @file fsmc_sdram.c + * @brief SDRAM Driver subsystem low level driver source. + * + * @addtogroup SDRAM + * @{ + */ + +#include "hal.h" + +#if (defined(STM32F427xx) || defined(STM32F437xx) || \ + defined(STM32F429xx) || defined(STM32F439xx)) + +#if STM32_USE_FSMC_SDRAM || defined(__DOXYGEN__) + +#include "fsmc_sdram.h" + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ +/** + * @brief SDRAM1 driver identifier. + */ +#if STM32_SDRAM_USE_FSMC_SDRAM1 || defined(__DOXYGEN__) +SDRAMDriver SDRAMD1; +#endif + +/** + * @brief SDRAM2 driver identifier. + */ +#if STM32_SDRAM_USE_FSMC_SDRAM2 || defined(__DOXYGEN__) +SDRAMDriver SDRAMD2; +#endif + +/*===========================================================================*/ +/* Driver local types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/** + * @brief Executes the SDRAM memory initialization sequence. + * + * @param[in] sdramp pointer to the @p SDRAMDriver object + * + * @notapi + */ +static void fsmcSdramInitSequence(uint32_t CommandTarget) { + uint32_t tmpreg; + /* Step 3 -----------------------------------------------------------------*/ + /* Wait until the SDRAM controller is ready */ + while (FMC_Bank5_6->SDSR & FMC_SDSR_BUSY); + /* Configure a clock configuration enable command */ + FMC_Bank5_6->SDCMR = (uint32_t) FMC_Command_Mode_CLK_Enabled | + CommandTarget | + ((1 -1) << 5) | // FMC_AutoRefreshNumber = 1 + (0 << 9); // FMC_ModeRegisterDefinition = 0 + /* Step 4 -----------------------------------------------------------------*/ + /* Insert 10 ms delay */ + chSysPolledDelayX(MS2ST(10)); + /* Step 5 -----------------------------------------------------------------*/ + /* Wait until the SDRAM controller is ready */ + while (FMC_Bank5_6->SDSR & FMC_SDSR_BUSY); + /* Configure a PALL (precharge all) command */ + FMC_Bank5_6->SDCMR = (uint32_t) FMC_Command_Mode_PALL | + CommandTarget | + ((1 -1) << 5) | // FMC_AutoRefreshNumber = 1 + (0 << 9); // FMC_ModeRegisterDefinition = 0 + /* Step 6 -----------------------------------------------------------------*/ + /* Wait until the SDRAM controller is ready */ + while (FMC_Bank5_6->SDSR & FMC_SDSR_BUSY); + /* Configure a Auto-Refresh command: Send the first command */ + FMC_Bank5_6->SDCMR = (uint32_t) FMC_Command_Mode_AutoRefresh | + CommandTarget | + ((4 -1) << 5) | // FMC_AutoRefreshNumber = 4 + (0 << 9); // FMC_ModeRegisterDefinition = 0 + /* Wait until the SDRAM controller is ready */ + while (FMC_Bank5_6->SDSR & FMC_SDSR_BUSY); + /* Configure a Auto-Refresh command: Send the second command*/ + FMC_Bank5_6->SDCMR = (uint32_t) FMC_Command_Mode_AutoRefresh | + CommandTarget | + ((4 -1) << 5) | // FMC_AutoRefreshNumber = 4 + (0 << 9); // FMC_ModeRegisterDefinition = 0 + /* Step 7 -----------------------------------------------------------------*/ + /* Wait until the SDRAM controller is ready */ + while (FMC_Bank5_6->SDSR & FMC_SDSR_BUSY); + /* Program the external memory mode register */ + tmpreg = FMC_SDCMR_MRD_BURST_LENGTH_2 | + FMC_SDCMR_MRD_BURST_TYPE_SEQUENTIAL | + FMC_SDCMR_MRD_CAS_LATENCY_3 | + FMC_SDCMR_MRD_OPERATING_MODE_STANDARD | + FMC_SDCMR_MRD_WRITEBURST_MODE_SINGLE; + /* Send the command */ + FMC_Bank5_6->SDCMR = (uint32_t) FMC_Command_Mode_LoadMode | + CommandTarget | + ((1 -1) << 5) | // FMC_AutoRefreshNumber = 1 + (tmpreg << 9); + /* Step 8 -----------------------------------------------------------------*/ + /* Wait until the SDRAM controller is ready */ + while (FMC_Bank5_6->SDSR & FMC_SDSR_BUSY); + // 64ms/4096=15.625us +#if (STM32_SYSCLK == 180000000) + //15.625us*90MHz=1406-20=1386 + FMC_Bank5_6->SDRTR=1386<<1; +#elif (STM32_SYSCLK == 168000000) + //15.625us*84MHz=1312-20=1292 + FMC_Bank5_6->SDRTR=1292<<1; +#else + #error No refresh timings for this clock +#endif + /* Wait until the SDRAM controller is ready */ + while (FMC_Bank5_6->SDSR & FMC_SDSR_BUSY); +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level SDRAM driver initialization. + * + * @notapi + */ +void fsmcSdramInit(void) { + + fsmc_init(); + +#if STM32_SDRAM_USE_FSMC_SDRAM1 + SDRAMD1.sdram = FSMCD1.sdram1; + SDRAMD1.state = SDRAM_STOP; +#endif /* STM32_SDRAM_USE_FSMC_SDRAM1 */ + +#if STM32_SDRAM_USE_FSMC_SDRAM2 + SDRAMD2.sdram = FSMCD1.sdram2; + SDRAMD2.state = SDRAM_STOP; +#endif /* STM32_SDRAM_USE_FSMC_SDRAM2 */ + +} + +/** + * @brief Configures and activates the SDRAM peripheral. + * + * @param[in] sdramp pointer to the @p SDRAMDriver object + * @param[in] cfgp pointer to the @p SDRAMConfig object + * + * @notapi + */ +#define SDCR2_DONTCARE_BITS (FMC_SDClock_Period_Mask | \ + FMC_Read_Burst_Mask | \ + FMC_ReadPipe_Delay_Mask) +#define SDTR2_DONTCARE_BITS (FMC_RowCycleDelay_Mask | FMC_RPDelay_Mask) +void fsmcSdramStart(SDRAMDriver *sdramp, const SDRAMConfig *cfgp) { + + if (FSMCD1.state == FSMC_STOP) + fsmc_start(&FSMCD1); + + osalDbgAssert((sdramp->state == SDRAM_STOP) || (sdramp->state == SDRAM_READY), + "invalid state"); + + if (sdramp->state == SDRAM_STOP) { + // Executes the SDRAM memory initialization sequence. + if (sdramp->sdram == (FSMC_SDRAM_TypeDef *)FSMC_Bank5_R_BASE) { + sdramp->sdram->SDCR = cfgp->sdcr; + sdramp->sdram->SDTR = cfgp->sdtr; + fsmcSdramInitSequence(FMC_Command_Target_bank1); + } else { /* SDCR2 "don't care" bits configuration */ + ((FSMC_SDRAM_TypeDef *)FSMC_Bank5_R_BASE)->SDCR = + cfgp->sdcr & SDCR2_DONTCARE_BITS; + sdramp->sdram->SDCR = cfgp->sdcr; + ((FSMC_SDRAM_TypeDef *)FSMC_Bank5_R_BASE)->SDTR = + cfgp->sdtr & SDTR2_DONTCARE_BITS; + sdramp->sdram->SDTR = cfgp->sdtr; + fsmcSdramInitSequence(FMC_Command_Target_bank2); + } + sdramp->state = SDRAM_READY; + } + +} + +/** + * @brief Deactivates the SDRAM peripheral. + * + * @param[in] sdramp pointer to the @p SDRAMDriver object + * + * @notapi + */ +void fsmcSdramStop(SDRAMDriver *sdramp) { + + if (sdramp->state == SDRAM_READY) { + sdramp->state = SDRAM_STOP; + } +} + + +/** + * @brief Wait until the SDRAM controller is ready. + * + * @notapi + */ +void fsmcSdram_WaitReady(void) { + /* Wait until the SDRAM controller is ready */ + while (FMC_Bank5_6->SDSR & FMC_SDSR_BUSY); +} + +/** + * @brief Enables or disables write protection to the specified SDRAM Bank. + * @param SDRAM_Bank: Defines the FMC SDRAM bank. This parameter can be + * FMC_Bank1_SDRAM or FMC_Bank2_SDRAM. + * @param NewState: new state of the write protection flag. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +/* FMC SDCRx write protection Mask*/ +#define SDCR_WriteProtection_RESET ((uint32_t)0x00007DFF) +void fsmcSdram_WriteProtectionConfig(SDRAMDriver *sdramp, int State) { + + if (State) + sdramp->sdram->SDCR |= FMC_Write_Protection_Enable; + else + sdramp->sdram->SDCR &= SDCR_WriteProtection_RESET; + +} + + +#endif /* STM32_USE_FSMC_SDRAM */ + +#endif /* STM32F427xx / STM32F429xx / STM32F437xx / STM32F439xx */ + +/** @} */ + diff --git a/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.h b/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.h new file mode 100644 index 0000000..17fc28d --- /dev/null +++ b/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.h @@ -0,0 +1,382 @@ +/* + ChibiOS/HAL - Copyright (C) 2006-2014 Giovanni Di Sirio + + 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. +*/ +/* + Concepts and parts of this file have been contributed by Uladzimir Pylinsky + aka barthess (SDRAM routines added by Nick Klimov aka progfin). + */ + +/** + * @file fsmc_sdram.h + * @brief SDRAM Driver subsystem low level driver header. + * + * @addtogroup SDRAM + * @{ + */ + +#ifndef _FMC_SDRAM_H_ +#define _FMC_SDRAM_H_ + +#if (defined(STM32F427xx) || defined(STM32F437xx) || \ + defined(STM32F429xx) || defined(STM32F439xx)) + +#include "fsmc.h" + +#if STM32_USE_FSMC_SDRAM || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** @defgroup FMC_ColumnBits_Number + * @{ + */ +#define FMC_ColumnBits_Number_8b ((uint32_t)0x00000000) +#define FMC_ColumnBits_Number_9b ((uint32_t)0x00000001) +#define FMC_ColumnBits_Number_10b ((uint32_t)0x00000002) +#define FMC_ColumnBits_Number_11b ((uint32_t)0x00000003) + +#define IS_FMC_COLUMNBITS_NUMBER(COLUMN) \ + (((COLUMN) == FMC_ColumnBits_Number_8b) || \ + ((COLUMN) == FMC_ColumnBits_Number_9b) || \ + ((COLUMN) == FMC_ColumnBits_Number_10b) || \ + ((COLUMN) == FMC_ColumnBits_Number_11b)) + +/** + * @} + */ + +/** @defgroup FMC_RowBits_Number + * @{ + */ +#define FMC_RowBits_Number_11b ((uint32_t)0x00000000) +#define FMC_RowBits_Number_12b ((uint32_t)0x00000004) +#define FMC_RowBits_Number_13b ((uint32_t)0x00000008) + +#define IS_FMC_ROWBITS_NUMBER(ROW) \ + (((ROW) == FMC_RowBits_Number_11b) || \ + ((ROW) == FMC_RowBits_Number_12b) || \ + ((ROW) == FMC_RowBits_Number_13b)) + +/** + * @} + */ + +/** @defgroup FMC_SDMemory_Data_Width + * @{ + */ +#define FMC_SDMemory_Width_8b ((uint32_t)0x00000000) +#define FMC_SDMemory_Width_16b ((uint32_t)0x00000010) +#define FMC_SDMemory_Width_32b ((uint32_t)0x00000020) + +#define IS_FMC_SDMEMORY_WIDTH(WIDTH) \ + (((WIDTH) == FMC_SDMemory_Width_8b) || \ + ((WIDTH) == FMC_SDMemory_Width_16b) || \ + ((WIDTH) == FMC_SDMemory_Width_32b)) + +/** + * @} + */ + +/** @defgroup FMC_InternalBank_Number + * @{ + */ +#define FMC_InternalBank_Number_2 ((uint32_t)0x00000000) +#define FMC_InternalBank_Number_4 ((uint32_t)0x00000040) + +#define IS_FMC_INTERNALBANK_NUMBER(NUMBER) \ + (((NUMBER) == FMC_InternalBank_Number_2) || \ + ((NUMBER) == FMC_InternalBank_Number_4)) + +/** + * @} + */ + + +/** @defgroup FMC_CAS_Latency + * @{ + */ +#define FMC_CAS_Latency_1 ((uint32_t)0x00000080) +#define FMC_CAS_Latency_2 ((uint32_t)0x00000100) +#define FMC_CAS_Latency_3 ((uint32_t)0x00000180) + +#define IS_FMC_CAS_LATENCY(LATENCY) \ + (((LATENCY) == FMC_CAS_Latency_1) || \ + ((LATENCY) == FMC_CAS_Latency_2) || \ + ((LATENCY) == FMC_CAS_Latency_3)) + +/** + * @} + */ + +/** @defgroup FMC_Write_Protection + * @{ + */ +#define FMC_Write_Protection_Disable ((uint32_t)0x00000000) +#define FMC_Write_Protection_Enable ((uint32_t)0x00000200) + +#define IS_FMC_WRITE_PROTECTION(WRITE) \ + (((WRITE) == FMC_Write_Protection_Disable) || \ + ((WRITE) == FMC_Write_Protection_Enable)) + +/** + * @} + */ + + +/** @defgroup FMC_SDClock_Period + * @{ + */ +#define FMC_SDClock_Disable ((uint32_t)0x00000000) +#define FMC_SDClock_Period_2 ((uint32_t)0x00000800) +#define FMC_SDClock_Period_3 ((uint32_t)0x00000C00) +#define FMC_SDClock_Period_Mask ((uint32_t)0x00000C00) + +#define IS_FMC_SDCLOCK_PERIOD(PERIOD) \ + (((PERIOD) == FMC_SDClock_Disable) || \ + ((PERIOD) == FMC_SDClock_Period_2) || \ + ((PERIOD) == FMC_SDClock_Period_3)) + +/** + * @} + */ + +/** @defgroup FMC_Read_Burst + * @{ + */ +#define FMC_Read_Burst_Disable ((uint32_t)0x00000000) +#define FMC_Read_Burst_Enable ((uint32_t)0x00001000) +#define FMC_Read_Burst_Mask ((uint32_t)0x00001000) + +#define IS_FMC_READ_BURST(RBURST) \ + (((RBURST) == FMC_Read_Burst_Disable) || \ + ((RBURST) == FMC_Read_Burst_Enable)) + +/** + * @} + */ + +/** @defgroup FMC_ReadPipe_Delay + * @{ + */ +#define FMC_ReadPipe_Delay_0 ((uint32_t)0x00000000) +#define FMC_ReadPipe_Delay_1 ((uint32_t)0x00002000) +#define FMC_ReadPipe_Delay_2 ((uint32_t)0x00004000) +#define FMC_ReadPipe_Delay_Mask ((uint32_t)0x00006000) + +#define IS_FMC_READPIPE_DELAY(DELAY) \ + (((DELAY) == FMC_ReadPipe_Delay_0) || \ + ((DELAY) == FMC_ReadPipe_Delay_1) || \ + ((DELAY) == FMC_ReadPipe_Delay_2)) + +/** + * @} + */ + +/** @defgroup FMC_Command_Mode + * @{ + */ +#define FMC_Command_Mode_normal ((uint32_t)0x00000000) +#define FMC_Command_Mode_CLK_Enabled ((uint32_t)0x00000001) +#define FMC_Command_Mode_PALL ((uint32_t)0x00000002) +#define FMC_Command_Mode_AutoRefresh ((uint32_t)0x00000003) +#define FMC_Command_Mode_LoadMode ((uint32_t)0x00000004) +#define FMC_Command_Mode_Selfrefresh ((uint32_t)0x00000005) +#define FMC_Command_Mode_PowerDown ((uint32_t)0x00000006) + +#define IS_FMC_COMMAND_MODE(COMMAND) \ + (((COMMAND) == FMC_Command_Mode_normal) || \ + ((COMMAND) == FMC_Command_Mode_CLK_Enabled) || \ + ((COMMAND) == FMC_Command_Mode_PALL) || \ + ((COMMAND) == FMC_Command_Mode_AutoRefresh) || \ + ((COMMAND) == FMC_Command_Mode_LoadMode) || \ + ((COMMAND) == FMC_Command_Mode_Selfrefresh) || \ + ((COMMAND) == FMC_Command_Mode_PowerDown)) + +/** + * @} + */ + +/** @defgroup FMC_Command_Target + * @{ + */ +#define FMC_Command_Target_bank2 ((uint32_t)0x00000008) +#define FMC_Command_Target_bank1 ((uint32_t)0x00000010) +#define FMC_Command_Target_bank1_2 ((uint32_t)0x00000018) + +#define IS_FMC_COMMAND_TARGET(TARGET) \ + (((TARGET) == FMC_Command_Target_bank1) || \ + ((TARGET) == FMC_Command_Target_bank2) || \ + ((TARGET) == FMC_Command_Target_bank1_2)) + +/** + * @} + */ + +/** @defgroup FMC_AutoRefresh_Number + * @{ + */ +#define IS_FMC_AUTOREFRESH_NUMBER(NUMBER) (((NUMBER) > 0) && ((NUMBER) <= 16)) + +/** + * @} + */ + +/** @defgroup FMC_ModeRegister_Definition + * @{ + */ +#define IS_FMC_MODE_REGISTER(CONTENT) ((CONTENT) <= 8191) + +/** + * @} + */ + + +/** + * @brief FMC SDRAM Mode definition register defines + */ +#define FMC_SDCMR_MRD_BURST_LENGTH_1 ((uint16_t)0x0000) +#define FMC_SDCMR_MRD_BURST_LENGTH_2 ((uint16_t)0x0001) +#define FMC_SDCMR_MRD_BURST_LENGTH_4 ((uint16_t)0x0002) +#define FMC_SDCMR_MRD_BURST_LENGTH_8 ((uint16_t)0x0004) +#define FMC_SDCMR_MRD_BURST_TYPE_SEQUENTIAL ((uint16_t)0x0000) +#define FMC_SDCMR_MRD_BURST_TYPE_INTERLEAVED ((uint16_t)0x0008) +#define FMC_SDCMR_MRD_CAS_LATENCY_2 ((uint16_t)0x0020) +#define FMC_SDCMR_MRD_CAS_LATENCY_3 ((uint16_t)0x0030) +#define FMC_SDCMR_MRD_OPERATING_MODE_STANDARD ((uint16_t)0x0000) +#define FMC_SDCMR_MRD_WRITEBURST_MODE_PROGRAMMED ((uint16_t)0x0000) +#define FMC_SDCMR_MRD_WRITEBURST_MODE_SINGLE ((uint16_t)0x0200) + + +#define FMC_RowCycleDelay_Mask ((uint16_t)0x0000000F << 12) +#define FMC_RPDelay_Mask ((uint16_t)0x0000000F << 20) + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ +/** + * @name Configuration options + * @{ + */ + +/** + * @brief SDRAM driver enable switch. + * @details If set to @p TRUE the support for SDRAM1 is included. + */ +#if !defined(STM32_SDRAM_USE_FSMC_SDRAM1) || defined(__DOXYGEN__) +#define STM32_SDRAM_USE_FSMC_SDRAM1 FALSE +#else +#define STM32_SDRAM1_MAP_BASE FSMC_Bank5_MAP_BASE +#endif + +/** + * @brief SDRAM driver enable switch. + * @details If set to @p TRUE the support for SDRAM2 is included. + */ +#if !defined(STM32_SDRAM_USE_FSMC_SDRAM2) || defined(__DOXYGEN__) +#define STM32_SDRAM_USE_FSMC_SDRAM2 FALSE +#else +#define STM32_SDRAM2_MAP_BASE FSMC_Bank6_MAP_BASE +#endif + +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +#if !STM32_SDRAM_USE_FSMC_SDRAM1 && !STM32_SDRAM_USE_FSMC_SDRAM2 +#error "SDRAM driver activated but no SDRAM peripheral assigned" +#endif + +#if (STM32_SDRAM_USE_FSMC_SDRAM1 || STM32_SDRAM_USE_FSMC_SDRAM2) && !STM32_HAS_FSMC +#error "FMC not present in the selected device" +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ +/** + * @brief Driver state machine possible states. + */ +typedef enum { + SDRAM_UNINIT = 0, /**< Not initialized. */ + SDRAM_STOP = 1, /**< Stopped. */ + SDRAM_READY = 2, /**< Ready. */ +} sdramstate_t; + +/** + * @brief Type of a structure representing an SDRAM driver. + */ +typedef struct SDRAMDriver SDRAMDriver; + +/** + * @brief Driver configuration structure. + * @note It could be empty on some architectures. + */ +typedef struct { + uint32_t sdcr; + uint32_t sdtr; +} SDRAMConfig; + +/** + * @brief Structure representing an SDRAM driver. + */ +struct SDRAMDriver { + /** + * @brief Driver state. + */ + sdramstate_t state; + /** + * @brief Pointer to the FMC SDRAM registers block. + */ + FSMC_SDRAM_TypeDef *sdram; +}; + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if STM32_SDRAM_USE_FSMC_SDRAM1 && !defined(__DOXYGEN__) +extern SDRAMDriver SDRAMD1; +#endif + +#if STM32_SDRAM_USE_FSMC_SDRAM2 && !defined(__DOXYGEN__) +extern SDRAMDriver SDRAMD2; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + void fsmcSdramInit(void); + void fsmcSdramStart(SDRAMDriver *sdramp, const SDRAMConfig *cfgp); + void fsmcSdramStop(SDRAMDriver *sdramp); + void fsmcSdram_WaitReady(void); + void fsmcSdram_WriteProtectionConfig(SDRAMDriver *sdramp, int State); +#ifdef __cplusplus +} +#endif + +#endif /* STM32_USE_FSMC_SDRAM */ + +#endif /* STM32F427xx / STM32F429xx / STM32F437xx / STM32F439xx */ + +#endif /* _FMC_SDRAM_H_ */ + +/** @} */ -- cgit v1.2.3 From 5f231b6aaf4f3506b462faed77db0b3a5595d918 Mon Sep 17 00:00:00 2001 From: barthess Date: Wed, 22 Oct 2014 10:33:02 +0300 Subject: FSMC. SDRAM. Style cleanup --- os/hal/ports/STM32/LLD/FSMCv1/fsmc.c | 16 ++- os/hal/ports/STM32/LLD/FSMCv1/fsmc.h | 27 +++++- os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.c | 63 ++++++------ os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.h | 151 ++++++++++++++++------------- os/hal/ports/STM32/STM32F4xx/platform.mk | 3 +- 5 files changed, 153 insertions(+), 107 deletions(-) (limited to 'os/hal/ports') diff --git a/os/hal/ports/STM32/LLD/FSMCv1/fsmc.c b/os/hal/ports/STM32/LLD/FSMCv1/fsmc.c index 4c1a197..65f3baf 100644 --- a/os/hal/ports/STM32/LLD/FSMCv1/fsmc.c +++ b/os/hal/ports/STM32/LLD/FSMCv1/fsmc.c @@ -28,7 +28,8 @@ #include "hal.h" #include "fsmc.h" -#if HAL_USE_NAND || STM32_USE_FSMC_SRAM || defined(__DOXYGEN__) +#if HAL_USE_NAND || STM32_USE_FSMC_SRAM || STM32_USE_FSMC_SDRAM || \ + defined(__DOXYGEN__) /*===========================================================================*/ /* Driver local definitions. */ @@ -102,6 +103,17 @@ void fsmc_init(void) { #if STM32_USE_FSMC_PCCARD FSMCD1.pccard = (FSMC_PCCARD_TypeDef *)FSMC_Bank4_R_BASE; #endif + +#if (defined(STM32F427xx) || defined(STM32F437xx) || \ + defined(STM32F429xx) || defined(STM32F439xx)) + #if STM32_SDRAM_USE_FSMC_SDRAM1 + FSMCD1.sdram1 = (FSMC_SDRAM_TypeDef *)FSMC_Bank5_R_BASE; + #endif + + #if STM32_SDRAM_USE_FSMC_SDRAM2 + FSMCD1.sdram2 = (FSMC_SDRAM_TypeDef *)FSMC_Bank6_R_BASE; + #endif +#endif } } @@ -183,6 +195,6 @@ CH_IRQ_HANDLER(STM32_FSMC_HANDLER) { } #endif /* !STM32_NAND_USE_EXT_INT */ -#endif /* HAL_USE_FSMC || STM32_USE_FSMC_SRAM */ +#endif /* HAL_USE_FSMC || STM32_USE_FSMC_SRAM || STM32_USE_FSMC_SDRAM */ /** @} */ diff --git a/os/hal/ports/STM32/LLD/FSMCv1/fsmc.h b/os/hal/ports/STM32/LLD/FSMCv1/fsmc.h index 2b579a2..21c58bd 100644 --- a/os/hal/ports/STM32/LLD/FSMCv1/fsmc.h +++ b/os/hal/ports/STM32/LLD/FSMCv1/fsmc.h @@ -29,7 +29,7 @@ #ifndef _FSMC_H_ #define _FSMC_H_ -#if HAL_USE_NAND || STM32_USE_FSMC_SRAM || defined(__DOXYGEN__) +#if HAL_USE_NAND || STM32_USE_FSMC_SRAM || STM32_USE_FSMC_SDRAM || defined(__DOXYGEN__) /*===========================================================================*/ /* Driver constants. */ @@ -86,6 +86,11 @@ #define FSMC_Bank2_MAP_BASE ((uint32_t) 0x70000000) #define FSMC_Bank3_MAP_BASE ((uint32_t) 0x80000000) #define FSMC_Bank4_MAP_BASE ((uint32_t) 0x90000000) +#if (defined(STM32F427xx) || defined(STM32F437xx) || \ + defined(STM32F429xx) || defined(STM32F439xx)) + #define FSMC_Bank5_MAP_BASE ((uint32_t) 0xC0000000) + #define FSMC_Bank6_MAP_BASE ((uint32_t) 0xD0000000) +#endif /* * Subbunks of bank1 @@ -158,6 +163,15 @@ typedef struct { __IO uint32_t BWTR; /**< SRAM/NOR write timing registers */ } FSMC_SRAM_NOR_TypeDef; +#if (defined(STM32F427xx) || defined(STM32F437xx) || \ + defined(STM32F429xx) || defined(STM32F439xx)) + typedef struct { + __IO uint32_t SDCR; /**< SDRAM control register */ + uint32_t RESERVED0; /**< Reserved */ + __IO uint32_t SDTR; /**< SDRAM timing register */ + } FSMC_SDRAM_TypeDef; +#endif + /** * @brief PCR register */ @@ -280,6 +294,15 @@ struct FSMCDriver { #if STM32_USE_FSMC_PCCARD FSMC_PCCard_TypeDef *pccard; #endif +#if (defined(STM32F427xx) || defined(STM32F437xx) || \ + defined(STM32F429xx) || defined(STM32F439xx)) + #if STM32_SDRAM_USE_FSMC_SDRAM1 + FSMC_SDRAM_TypeDef *sdram1; + #endif + #if STM32_SDRAM_USE_FSMC_SDRAM2 + FSMC_SDRAM_TypeDef *sdram2; + #endif +#endif }; /*===========================================================================*/ @@ -304,7 +327,7 @@ extern "C" { } #endif -#endif /* HAL_USE_NAND || STM32_USE_FSMC_SRAM */ +#endif /* HAL_USE_NAND || STM32_USE_FSMC_SRAM || STM32_USE_FSMC_SDRAM */ #endif /* _FSMC_H_ */ diff --git a/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.c b/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.c index eca66ea..b738185 100644 --- a/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.c +++ b/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.c @@ -39,6 +39,17 @@ /* Driver local definitions. */ /*===========================================================================*/ +#define SDCR2_DONTCARE_BITS (FMC_SDClock_Period_Mask | \ + FMC_Read_Burst_Mask | \ + FMC_ReadPipe_Delay_Mask) + +#define SDTR2_DONTCARE_BITS (FMC_RowCycleDelay_Mask | FMC_RPDelay_Mask) + +/* + * FMC SDCRx write protection mask + */ +#define SDCR_WriteProtection_RESET ((uint32_t)0x00007DFF) + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ @@ -75,14 +86,14 @@ SDRAMDriver SDRAMD2; * * @notapi */ -static void fsmcSdramInitSequence(uint32_t CommandTarget) { +static void fsmc_sdram_init_sequence(uint32_t command_target) { uint32_t tmpreg; /* Step 3 -----------------------------------------------------------------*/ /* Wait until the SDRAM controller is ready */ while (FMC_Bank5_6->SDSR & FMC_SDSR_BUSY); /* Configure a clock configuration enable command */ FMC_Bank5_6->SDCMR = (uint32_t) FMC_Command_Mode_CLK_Enabled | - CommandTarget | + command_target | ((1 -1) << 5) | // FMC_AutoRefreshNumber = 1 (0 << 9); // FMC_ModeRegisterDefinition = 0 /* Step 4 -----------------------------------------------------------------*/ @@ -93,7 +104,7 @@ static void fsmcSdramInitSequence(uint32_t CommandTarget) { while (FMC_Bank5_6->SDSR & FMC_SDSR_BUSY); /* Configure a PALL (precharge all) command */ FMC_Bank5_6->SDCMR = (uint32_t) FMC_Command_Mode_PALL | - CommandTarget | + command_target | ((1 -1) << 5) | // FMC_AutoRefreshNumber = 1 (0 << 9); // FMC_ModeRegisterDefinition = 0 /* Step 6 -----------------------------------------------------------------*/ @@ -101,14 +112,14 @@ static void fsmcSdramInitSequence(uint32_t CommandTarget) { while (FMC_Bank5_6->SDSR & FMC_SDSR_BUSY); /* Configure a Auto-Refresh command: Send the first command */ FMC_Bank5_6->SDCMR = (uint32_t) FMC_Command_Mode_AutoRefresh | - CommandTarget | + command_target | ((4 -1) << 5) | // FMC_AutoRefreshNumber = 4 (0 << 9); // FMC_ModeRegisterDefinition = 0 /* Wait until the SDRAM controller is ready */ while (FMC_Bank5_6->SDSR & FMC_SDSR_BUSY); /* Configure a Auto-Refresh command: Send the second command*/ FMC_Bank5_6->SDCMR = (uint32_t) FMC_Command_Mode_AutoRefresh | - CommandTarget | + command_target | ((4 -1) << 5) | // FMC_AutoRefreshNumber = 4 (0 << 9); // FMC_ModeRegisterDefinition = 0 /* Step 7 -----------------------------------------------------------------*/ @@ -122,7 +133,7 @@ static void fsmcSdramInitSequence(uint32_t CommandTarget) { FMC_SDCMR_MRD_WRITEBURST_MODE_SINGLE; /* Send the command */ FMC_Bank5_6->SDCMR = (uint32_t) FMC_Command_Mode_LoadMode | - CommandTarget | + command_target | ((1 -1) << 5) | // FMC_AutoRefreshNumber = 1 (tmpreg << 9); /* Step 8 -----------------------------------------------------------------*/ @@ -152,8 +163,6 @@ static void fsmcSdramInitSequence(uint32_t CommandTarget) { /** * @brief Low level SDRAM driver initialization. - * - * @notapi */ void fsmcSdramInit(void) { @@ -168,7 +177,6 @@ void fsmcSdramInit(void) { SDRAMD2.sdram = FSMCD1.sdram2; SDRAMD2.state = SDRAM_STOP; #endif /* STM32_SDRAM_USE_FSMC_SDRAM2 */ - } /** @@ -176,13 +184,7 @@ void fsmcSdramInit(void) { * * @param[in] sdramp pointer to the @p SDRAMDriver object * @param[in] cfgp pointer to the @p SDRAMConfig object - * - * @notapi */ -#define SDCR2_DONTCARE_BITS (FMC_SDClock_Period_Mask | \ - FMC_Read_Burst_Mask | \ - FMC_ReadPipe_Delay_Mask) -#define SDTR2_DONTCARE_BITS (FMC_RowCycleDelay_Mask | FMC_RPDelay_Mask) void fsmcSdramStart(SDRAMDriver *sdramp, const SDRAMConfig *cfgp) { if (FSMCD1.state == FSMC_STOP) @@ -196,19 +198,19 @@ void fsmcSdramStart(SDRAMDriver *sdramp, const SDRAMConfig *cfgp) { if (sdramp->sdram == (FSMC_SDRAM_TypeDef *)FSMC_Bank5_R_BASE) { sdramp->sdram->SDCR = cfgp->sdcr; sdramp->sdram->SDTR = cfgp->sdtr; - fsmcSdramInitSequence(FMC_Command_Target_bank1); - } else { /* SDCR2 "don't care" bits configuration */ + fsmc_sdram_init_sequence(FMC_Command_Target_bank1); + } + else { /* SDCR2 "don't care" bits configuration */ ((FSMC_SDRAM_TypeDef *)FSMC_Bank5_R_BASE)->SDCR = cfgp->sdcr & SDCR2_DONTCARE_BITS; sdramp->sdram->SDCR = cfgp->sdcr; ((FSMC_SDRAM_TypeDef *)FSMC_Bank5_R_BASE)->SDTR = cfgp->sdtr & SDTR2_DONTCARE_BITS; sdramp->sdram->SDTR = cfgp->sdtr; - fsmcSdramInitSequence(FMC_Command_Target_bank2); + fsmc_sdram_init_sequence(FMC_Command_Target_bank2); } sdramp->state = SDRAM_READY; } - } /** @@ -225,7 +227,6 @@ void fsmcSdramStop(SDRAMDriver *sdramp) { } } - /** * @brief Wait until the SDRAM controller is ready. * @@ -237,25 +238,21 @@ void fsmcSdram_WaitReady(void) { } /** - * @brief Enables or disables write protection to the specified SDRAM Bank. - * @param SDRAM_Bank: Defines the FMC SDRAM bank. This parameter can be - * FMC_Bank1_SDRAM or FMC_Bank2_SDRAM. - * @param NewState: new state of the write protection flag. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -/* FMC SDCRx write protection Mask*/ -#define SDCR_WriteProtection_RESET ((uint32_t)0x00007DFF) -void fsmcSdram_WriteProtectionConfig(SDRAMDriver *sdramp, int State) { + * @brief Enables or disables write protection to the specified SDRAM Bank. + * @param SDRAM_Bank: Defines the FMC SDRAM bank. This parameter can be + * FMC_Bank1_SDRAM or FMC_Bank2_SDRAM. + * @param NewState: new state of the write protection flag. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void fsmcSdram_WriteProtectionConfig(SDRAMDriver *sdramp, int state) { - if (State) + if (state) sdramp->sdram->SDCR |= FMC_Write_Protection_Enable; else sdramp->sdram->SDCR &= SDCR_WriteProtection_RESET; - } - #endif /* STM32_USE_FSMC_SDRAM */ #endif /* STM32F427xx / STM32F429xx / STM32F437xx / STM32F439xx */ diff --git a/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.h b/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.h index 17fc28d..010fb58 100644 --- a/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.h +++ b/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.h @@ -40,9 +40,10 @@ /* Driver constants. */ /*===========================================================================*/ -/** @defgroup FMC_ColumnBits_Number - * @{ - */ +/** + * @defgroup FMC_ColumnBits_Number + * @{ + */ #define FMC_ColumnBits_Number_8b ((uint32_t)0x00000000) #define FMC_ColumnBits_Number_9b ((uint32_t)0x00000001) #define FMC_ColumnBits_Number_10b ((uint32_t)0x00000002) @@ -55,12 +56,13 @@ ((COLUMN) == FMC_ColumnBits_Number_11b)) /** - * @} - */ + * @} + */ -/** @defgroup FMC_RowBits_Number - * @{ - */ +/** + * @defgroup FMC_RowBits_Number + * @{ + */ #define FMC_RowBits_Number_11b ((uint32_t)0x00000000) #define FMC_RowBits_Number_12b ((uint32_t)0x00000004) #define FMC_RowBits_Number_13b ((uint32_t)0x00000008) @@ -71,12 +73,13 @@ ((ROW) == FMC_RowBits_Number_13b)) /** - * @} - */ + * @} + */ -/** @defgroup FMC_SDMemory_Data_Width - * @{ - */ +/** + * @defgroup FMC_SDMemory_Data_Width + * @{ + */ #define FMC_SDMemory_Width_8b ((uint32_t)0x00000000) #define FMC_SDMemory_Width_16b ((uint32_t)0x00000010) #define FMC_SDMemory_Width_32b ((uint32_t)0x00000020) @@ -87,12 +90,13 @@ ((WIDTH) == FMC_SDMemory_Width_32b)) /** - * @} - */ + * @} + */ -/** @defgroup FMC_InternalBank_Number - * @{ - */ +/** + * @defgroup FMC_InternalBank_Number + * @{ + */ #define FMC_InternalBank_Number_2 ((uint32_t)0x00000000) #define FMC_InternalBank_Number_4 ((uint32_t)0x00000040) @@ -101,13 +105,14 @@ ((NUMBER) == FMC_InternalBank_Number_4)) /** - * @} - */ + * @} + */ -/** @defgroup FMC_CAS_Latency - * @{ - */ +/** + * @defgroup FMC_CAS_Latency + * @{ + */ #define FMC_CAS_Latency_1 ((uint32_t)0x00000080) #define FMC_CAS_Latency_2 ((uint32_t)0x00000100) #define FMC_CAS_Latency_3 ((uint32_t)0x00000180) @@ -118,12 +123,13 @@ ((LATENCY) == FMC_CAS_Latency_3)) /** - * @} - */ + * @} + */ -/** @defgroup FMC_Write_Protection - * @{ - */ +/** + * @defgroup FMC_Write_Protection + * @{ + */ #define FMC_Write_Protection_Disable ((uint32_t)0x00000000) #define FMC_Write_Protection_Enable ((uint32_t)0x00000200) @@ -132,13 +138,14 @@ ((WRITE) == FMC_Write_Protection_Enable)) /** - * @} - */ + * @} + */ -/** @defgroup FMC_SDClock_Period - * @{ - */ +/** + * @defgroup FMC_SDClock_Period + * @{ + */ #define FMC_SDClock_Disable ((uint32_t)0x00000000) #define FMC_SDClock_Period_2 ((uint32_t)0x00000800) #define FMC_SDClock_Period_3 ((uint32_t)0x00000C00) @@ -150,12 +157,13 @@ ((PERIOD) == FMC_SDClock_Period_3)) /** - * @} - */ + * @} + */ -/** @defgroup FMC_Read_Burst - * @{ - */ +/** + * @defgroup FMC_Read_Burst + * @{ + */ #define FMC_Read_Burst_Disable ((uint32_t)0x00000000) #define FMC_Read_Burst_Enable ((uint32_t)0x00001000) #define FMC_Read_Burst_Mask ((uint32_t)0x00001000) @@ -165,12 +173,13 @@ ((RBURST) == FMC_Read_Burst_Enable)) /** - * @} - */ + * @} + */ -/** @defgroup FMC_ReadPipe_Delay - * @{ - */ +/** + * @defgroup FMC_ReadPipe_Delay + * @{ + */ #define FMC_ReadPipe_Delay_0 ((uint32_t)0x00000000) #define FMC_ReadPipe_Delay_1 ((uint32_t)0x00002000) #define FMC_ReadPipe_Delay_2 ((uint32_t)0x00004000) @@ -182,12 +191,13 @@ ((DELAY) == FMC_ReadPipe_Delay_2)) /** - * @} - */ + * @} + */ -/** @defgroup FMC_Command_Mode - * @{ - */ +/** + * @defgroup FMC_Command_Mode + * @{ + */ #define FMC_Command_Mode_normal ((uint32_t)0x00000000) #define FMC_Command_Mode_CLK_Enabled ((uint32_t)0x00000001) #define FMC_Command_Mode_PALL ((uint32_t)0x00000002) @@ -206,12 +216,13 @@ ((COMMAND) == FMC_Command_Mode_PowerDown)) /** - * @} - */ + * @} + */ -/** @defgroup FMC_Command_Target - * @{ - */ +/** + * @defgroup FMC_Command_Target + * @{ + */ #define FMC_Command_Target_bank2 ((uint32_t)0x00000008) #define FMC_Command_Target_bank1 ((uint32_t)0x00000010) #define FMC_Command_Target_bank1_2 ((uint32_t)0x00000018) @@ -222,31 +233,33 @@ ((TARGET) == FMC_Command_Target_bank1_2)) /** - * @} - */ + * @} + */ -/** @defgroup FMC_AutoRefresh_Number - * @{ - */ +/** + * @defgroup FMC_AutoRefresh_Number + * @{ + */ #define IS_FMC_AUTOREFRESH_NUMBER(NUMBER) (((NUMBER) > 0) && ((NUMBER) <= 16)) /** - * @} - */ + * @} + */ -/** @defgroup FMC_ModeRegister_Definition - * @{ - */ +/** + * @defgroup FMC_ModeRegister_Definition + * @{ + */ #define IS_FMC_MODE_REGISTER(CONTENT) ((CONTENT) <= 8191) /** - * @} - */ + * @} + */ /** - * @brief FMC SDRAM Mode definition register defines - */ + * @brief FMC SDRAM Mode definition register defines + */ #define FMC_SDCMR_MRD_BURST_LENGTH_1 ((uint16_t)0x0000) #define FMC_SDCMR_MRD_BURST_LENGTH_2 ((uint16_t)0x0001) #define FMC_SDCMR_MRD_BURST_LENGTH_4 ((uint16_t)0x0002) @@ -342,7 +355,7 @@ struct SDRAMDriver { /** * @brief Pointer to the FMC SDRAM registers block. */ - FSMC_SDRAM_TypeDef *sdram; + FSMC_SDRAM_TypeDef *sdram; }; /*===========================================================================*/ @@ -368,7 +381,7 @@ extern "C" { void fsmcSdramStart(SDRAMDriver *sdramp, const SDRAMConfig *cfgp); void fsmcSdramStop(SDRAMDriver *sdramp); void fsmcSdram_WaitReady(void); - void fsmcSdram_WriteProtectionConfig(SDRAMDriver *sdramp, int State); + void fsmcSdram_WriteProtectionConfig(SDRAMDriver *sdramp, int state); #ifdef __cplusplus } #endif diff --git a/os/hal/ports/STM32/STM32F4xx/platform.mk b/os/hal/ports/STM32/STM32F4xx/platform.mk index dc8f1c4..2ede59d 100644 --- a/os/hal/ports/STM32/STM32F4xx/platform.mk +++ b/os/hal/ports/STM32/STM32F4xx/platform.mk @@ -2,6 +2,7 @@ include ${CHIBIOS}/os/hal/ports/STM32/STM32F4xx/platform.mk PLATFORMSRC += ${CHIBIOS}/community/os/hal/ports/STM32/LLD/FSMCv1/fsmc.c \ ${CHIBIOS}/community/os/hal/ports/STM32/LLD/FSMCv1/nand_lld.c \ - ${CHIBIOS}/community/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sram.c + ${CHIBIOS}/community/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sram.c \ + ${CHIBIOS}/community/os/hal/src/fsmc_sdram.c PLATFORMINC += ${CHIBIOS}/community/os/hal/ports/STM32/LLD/FSMCv1 -- cgit v1.2.3 From e9f9ddaa12464a5706617814d2244b0937cdf9fc Mon Sep 17 00:00:00 2001 From: barthess Date: Fri, 24 Oct 2014 21:46:17 +0300 Subject: FSMC. SDRAM architecture reworked. Needs review. --- os/hal/ports/STM32/LLD/FSMCv1/fsmc.c | 6 +- os/hal/ports/STM32/LLD/FSMCv1/fsmc.h | 31 +++-- os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.c | 200 +++++++++++++---------------- os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.h | 122 ++---------------- 4 files changed, 119 insertions(+), 240 deletions(-) (limited to 'os/hal/ports') diff --git a/os/hal/ports/STM32/LLD/FSMCv1/fsmc.c b/os/hal/ports/STM32/LLD/FSMCv1/fsmc.c index 65f3baf..6cadfb1 100644 --- a/os/hal/ports/STM32/LLD/FSMCv1/fsmc.c +++ b/os/hal/ports/STM32/LLD/FSMCv1/fsmc.c @@ -107,11 +107,7 @@ void fsmc_init(void) { #if (defined(STM32F427xx) || defined(STM32F437xx) || \ defined(STM32F429xx) || defined(STM32F439xx)) #if STM32_SDRAM_USE_FSMC_SDRAM1 - FSMCD1.sdram1 = (FSMC_SDRAM_TypeDef *)FSMC_Bank5_R_BASE; - #endif - - #if STM32_SDRAM_USE_FSMC_SDRAM2 - FSMCD1.sdram2 = (FSMC_SDRAM_TypeDef *)FSMC_Bank6_R_BASE; + FSMCD1.sdram = (FSMC_SDRAM_TypeDef *)FSMC_Bank5_6_R_BASE; #endif #endif } diff --git a/os/hal/ports/STM32/LLD/FSMCv1/fsmc.h b/os/hal/ports/STM32/LLD/FSMCv1/fsmc.h index 21c58bd..4ca6e58 100644 --- a/os/hal/ports/STM32/LLD/FSMCv1/fsmc.h +++ b/os/hal/ports/STM32/LLD/FSMCv1/fsmc.h @@ -56,10 +56,7 @@ #define FSMC_Bank4_R_BASE (FMC_R_BASE + 0x00A0) #endif #if !defined(FSMC_Bank5_R_BASE) - #define FSMC_Bank5_R_BASE (FMC_R_BASE + 0x0140) - #endif - #if !defined(FSMC_Bank_R_BASE) - #define FSMC_Bank6_R_BASE (FMC_R_BASE + 0x0144) + #define FSMC_Bank5_6_R_BASE (FMC_R_BASE + 0x0140) #endif #else #if !defined(FSMC_Bank1_R_BASE) @@ -165,11 +162,20 @@ typedef struct { #if (defined(STM32F427xx) || defined(STM32F437xx) || \ defined(STM32F429xx) || defined(STM32F439xx)) - typedef struct { - __IO uint32_t SDCR; /**< SDRAM control register */ - uint32_t RESERVED0; /**< Reserved */ - __IO uint32_t SDTR; /**< SDRAM timing register */ - } FSMC_SDRAM_TypeDef; + +typedef struct { + __IO uint32_t SDCR; /**< SDRAM control register */ + uint32_t RESERVED; /**< Reserved */ + __IO uint32_t SDTR; /**< SDRAM timing register */ +} FSMC_SDRAM_BANK_TypeDef; + +typedef struct { + FSMC_SDRAM_BANK_TypeDef banks[2]; /**< Banks mapping */ + __IO uint32_t SDCMR; /**< SDRAM comand mode register */ + __IO uint32_t SDRTR; /**< SDRAM refresh timer register */ + __IO uint32_t SDSR; /**< SDRAM status register */ +} FSMC_SDRAM_TypeDef; + #endif /** @@ -296,11 +302,8 @@ struct FSMCDriver { #endif #if (defined(STM32F427xx) || defined(STM32F437xx) || \ defined(STM32F429xx) || defined(STM32F439xx)) - #if STM32_SDRAM_USE_FSMC_SDRAM1 - FSMC_SDRAM_TypeDef *sdram1; - #endif - #if STM32_SDRAM_USE_FSMC_SDRAM2 - FSMC_SDRAM_TypeDef *sdram2; + #if (STM32_SDRAM_USE_FSMC_SDRAM1 || STM32_SDRAM_USE_FSMC_SDRAM1) + FSMC_SDRAM_TypeDef *sdram; #endif #endif }; diff --git a/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.c b/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.c index b738185..6ac6966 100644 --- a/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.c +++ b/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.c @@ -54,18 +54,9 @@ /* Driver exported variables. */ /*===========================================================================*/ /** - * @brief SDRAM1 driver identifier. + * @brief SDRAM driver identifier. */ -#if STM32_SDRAM_USE_FSMC_SDRAM1 || defined(__DOXYGEN__) -SDRAMDriver SDRAMD1; -#endif - -/** - * @brief SDRAM2 driver identifier. - */ -#if STM32_SDRAM_USE_FSMC_SDRAM2 || defined(__DOXYGEN__) -SDRAMDriver SDRAMD2; -#endif +SDRAMDriver SDRAMD; /*===========================================================================*/ /* Driver local types. */ @@ -79,6 +70,16 @@ SDRAMDriver SDRAMD2; /* Driver local functions. */ /*===========================================================================*/ +/** + * @brief Wait until the SDRAM controller is ready. + * + * @notapi + */ +static void _sdram_wait_ready(void) { + /* Wait until the SDRAM controller is ready */ + while (SDRAMD.sdram->SDSR & FMC_SDSR_BUSY); +} + /** * @brief Executes the SDRAM memory initialization sequence. * @@ -86,71 +87,74 @@ SDRAMDriver SDRAMD2; * * @notapi */ -static void fsmc_sdram_init_sequence(uint32_t command_target) { - uint32_t tmpreg; - /* Step 3 -----------------------------------------------------------------*/ - /* Wait until the SDRAM controller is ready */ - while (FMC_Bank5_6->SDSR & FMC_SDSR_BUSY); - /* Configure a clock configuration enable command */ - FMC_Bank5_6->SDCMR = (uint32_t) FMC_Command_Mode_CLK_Enabled | - command_target | - ((1 -1) << 5) | // FMC_AutoRefreshNumber = 1 - (0 << 9); // FMC_ModeRegisterDefinition = 0 - /* Step 4 -----------------------------------------------------------------*/ - /* Insert 10 ms delay */ +static void _sdram_init_sequence(void) { + + uint32_t tmp = 0; + uint32_t command_target = 0; + +#if STM32_SDRAM_USE_FSMC_SDRAM1 + command_target |= FMC_SDCMR_CTB1; +#endif +#if STM32_SDRAM_USE_FSMC_SDRAM2 + command_target |= FMC_SDCMR_CTB2; +#endif + + /* Step 3: Configure a clock configuration enable command.*/ + _sdram_wait_ready(); + SDRAMD.sdram->SDCMR = (uint32_t) FMC_Command_Mode_CLK_Enabled | + command_target | + ((1 -1) << 5) | // FMC_AutoRefreshNumber = 1 + (0 << 9); // FMC_ModeRegisterDefinition = 0 + + /* Step 4: Insert 10 ms delay.*/ chSysPolledDelayX(MS2ST(10)); - /* Step 5 -----------------------------------------------------------------*/ - /* Wait until the SDRAM controller is ready */ - while (FMC_Bank5_6->SDSR & FMC_SDSR_BUSY); - /* Configure a PALL (precharge all) command */ - FMC_Bank5_6->SDCMR = (uint32_t) FMC_Command_Mode_PALL | - command_target | - ((1 -1) << 5) | // FMC_AutoRefreshNumber = 1 - (0 << 9); // FMC_ModeRegisterDefinition = 0 - /* Step 6 -----------------------------------------------------------------*/ - /* Wait until the SDRAM controller is ready */ - while (FMC_Bank5_6->SDSR & FMC_SDSR_BUSY); - /* Configure a Auto-Refresh command: Send the first command */ - FMC_Bank5_6->SDCMR = (uint32_t) FMC_Command_Mode_AutoRefresh | - command_target | - ((4 -1) << 5) | // FMC_AutoRefreshNumber = 4 - (0 << 9); // FMC_ModeRegisterDefinition = 0 - /* Wait until the SDRAM controller is ready */ - while (FMC_Bank5_6->SDSR & FMC_SDSR_BUSY); - /* Configure a Auto-Refresh command: Send the second command*/ - FMC_Bank5_6->SDCMR = (uint32_t) FMC_Command_Mode_AutoRefresh | - command_target | - ((4 -1) << 5) | // FMC_AutoRefreshNumber = 4 - (0 << 9); // FMC_ModeRegisterDefinition = 0 - /* Step 7 -----------------------------------------------------------------*/ - /* Wait until the SDRAM controller is ready */ - while (FMC_Bank5_6->SDSR & FMC_SDSR_BUSY); - /* Program the external memory mode register */ - tmpreg = FMC_SDCMR_MRD_BURST_LENGTH_2 | - FMC_SDCMR_MRD_BURST_TYPE_SEQUENTIAL | - FMC_SDCMR_MRD_CAS_LATENCY_3 | - FMC_SDCMR_MRD_OPERATING_MODE_STANDARD | - FMC_SDCMR_MRD_WRITEBURST_MODE_SINGLE; - /* Send the command */ - FMC_Bank5_6->SDCMR = (uint32_t) FMC_Command_Mode_LoadMode | - command_target | - ((1 -1) << 5) | // FMC_AutoRefreshNumber = 1 - (tmpreg << 9); - /* Step 8 -----------------------------------------------------------------*/ - /* Wait until the SDRAM controller is ready */ - while (FMC_Bank5_6->SDSR & FMC_SDSR_BUSY); + + /* Step 5: Configure a PALL (precharge all) command.*/ + _sdram_wait_ready(); + SDRAMD.sdram->SDCMR = (uint32_t) FMC_Command_Mode_PALL | + command_target | + ((1 -1) << 5) | // FMC_AutoRefreshNumber = 1 + (0 << 9); // FMC_ModeRegisterDefinition = 0 + + /* Step 6.1: Configure a Auto-Refresh command: send the first command.*/ + _sdram_wait_ready(); + SDRAMD.sdram->SDCMR = (uint32_t) FMC_Command_Mode_AutoRefresh | + command_target | + ((4 -1) << 5) | // FMC_AutoRefreshNumber = 4 + (0 << 9); // FMC_ModeRegisterDefinition = 0 + + /* Step 6.2: Send the second command.*/ + SDRAMD.sdram->SDCMR = (uint32_t) FMC_Command_Mode_AutoRefresh | + command_target | + ((4 -1) << 5) | // FMC_AutoRefreshNumber = 4 + (0 << 9); // FMC_ModeRegisterDefinition = 0 + + /* Step 7: Program the external memory mode register.*/ + _sdram_wait_ready(); + tmp = FMC_SDCMR_MRD_BURST_LENGTH_2 | + FMC_SDCMR_MRD_BURST_TYPE_SEQUENTIAL | + FMC_SDCMR_MRD_CAS_LATENCY_3 | + FMC_SDCMR_MRD_OPERATING_MODE_STANDARD | + FMC_SDCMR_MRD_WRITEBURST_MODE_SINGLE; + SDRAMD.sdram->SDCMR = (uint32_t) FMC_Command_Mode_LoadMode | + command_target | + ((1 -1) << 5) | // FMC_AutoRefreshNumber = 1 + (tmp << 9); + + /* Step 8: Set clock.*/ + _sdram_wait_ready(); // 64ms/4096=15.625us #if (STM32_SYSCLK == 180000000) //15.625us*90MHz=1406-20=1386 - FMC_Bank5_6->SDRTR=1386<<1; + SDRAMD.sdram->SDRTR=1386<<1; #elif (STM32_SYSCLK == 168000000) //15.625us*84MHz=1312-20=1292 - FMC_Bank5_6->SDRTR=1292<<1; + SDRAMD.sdram->SDRTR=1292<<1; #else #error No refresh timings for this clock #endif - /* Wait until the SDRAM controller is ready */ - while (FMC_Bank5_6->SDSR & FMC_SDSR_BUSY); + + _sdram_wait_ready(); } /*===========================================================================*/ @@ -168,15 +172,8 @@ void fsmcSdramInit(void) { fsmc_init(); -#if STM32_SDRAM_USE_FSMC_SDRAM1 - SDRAMD1.sdram = FSMCD1.sdram1; - SDRAMD1.state = SDRAM_STOP; -#endif /* STM32_SDRAM_USE_FSMC_SDRAM1 */ - -#if STM32_SDRAM_USE_FSMC_SDRAM2 - SDRAMD2.sdram = FSMCD1.sdram2; - SDRAMD2.state = SDRAM_STOP; -#endif /* STM32_SDRAM_USE_FSMC_SDRAM2 */ + SDRAMD.sdram = FSMCD1.sdram; + SDRAMD.state = SDRAM_STOP; } /** @@ -191,24 +188,19 @@ void fsmcSdramStart(SDRAMDriver *sdramp, const SDRAMConfig *cfgp) { fsmc_start(&FSMCD1); osalDbgAssert((sdramp->state == SDRAM_STOP) || (sdramp->state == SDRAM_READY), - "invalid state"); + "SDRAM. Invalid state."); if (sdramp->state == SDRAM_STOP) { - // Executes the SDRAM memory initialization sequence. - if (sdramp->sdram == (FSMC_SDRAM_TypeDef *)FSMC_Bank5_R_BASE) { - sdramp->sdram->SDCR = cfgp->sdcr; - sdramp->sdram->SDTR = cfgp->sdtr; - fsmc_sdram_init_sequence(FMC_Command_Target_bank1); - } - else { /* SDCR2 "don't care" bits configuration */ - ((FSMC_SDRAM_TypeDef *)FSMC_Bank5_R_BASE)->SDCR = - cfgp->sdcr & SDCR2_DONTCARE_BITS; - sdramp->sdram->SDCR = cfgp->sdcr; - ((FSMC_SDRAM_TypeDef *)FSMC_Bank5_R_BASE)->SDTR = - cfgp->sdtr & SDTR2_DONTCARE_BITS; - sdramp->sdram->SDTR = cfgp->sdtr; - fsmc_sdram_init_sequence(FMC_Command_Target_bank2); - } +#if STM32_SDRAM_USE_FSMC_SDRAM1 + sdramp->sdram->banks[0].SDCR = cfgp->sdcr1; + sdramp->sdram->banks[0].SDTR = cfgp->sdtr1; +#endif +#if STM32_SDRAM_USE_FSMC_SDRAM2 + sdramp->sdram->banks[1].SDCR = cfgp->sdcr2; + sdramp->sdram->banks[1].SDTR = cfgp->sdtr2; +#endif + _sdram_init_sequence(); + sdramp->state = SDRAM_READY; } } @@ -227,16 +219,6 @@ void fsmcSdramStop(SDRAMDriver *sdramp) { } } -/** - * @brief Wait until the SDRAM controller is ready. - * - * @notapi - */ -void fsmcSdram_WaitReady(void) { - /* Wait until the SDRAM controller is ready */ - while (FMC_Bank5_6->SDSR & FMC_SDSR_BUSY); -} - /** * @brief Enables or disables write protection to the specified SDRAM Bank. * @param SDRAM_Bank: Defines the FMC SDRAM bank. This parameter can be @@ -245,13 +227,13 @@ void fsmcSdram_WaitReady(void) { * This parameter can be: ENABLE or DISABLE. * @retval None */ -void fsmcSdram_WriteProtectionConfig(SDRAMDriver *sdramp, int state) { - - if (state) - sdramp->sdram->SDCR |= FMC_Write_Protection_Enable; - else - sdramp->sdram->SDCR &= SDCR_WriteProtection_RESET; -} +//void fsmcSdram_WriteProtectionConfig(SDRAMDriver *sdramp, int state) { +// +// if (state) +// sdramp->sdram->SDCR |= FMC_Write_Protection_Enable; +// else +// sdramp->sdram->SDCR &= SDCR_WriteProtection_RESET; +//} #endif /* STM32_USE_FSMC_SDRAM */ diff --git a/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.h b/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.h index 010fb58..0cb6fef 100644 --- a/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.h +++ b/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.h @@ -48,13 +48,6 @@ #define FMC_ColumnBits_Number_9b ((uint32_t)0x00000001) #define FMC_ColumnBits_Number_10b ((uint32_t)0x00000002) #define FMC_ColumnBits_Number_11b ((uint32_t)0x00000003) - -#define IS_FMC_COLUMNBITS_NUMBER(COLUMN) \ - (((COLUMN) == FMC_ColumnBits_Number_8b) || \ - ((COLUMN) == FMC_ColumnBits_Number_9b) || \ - ((COLUMN) == FMC_ColumnBits_Number_10b) || \ - ((COLUMN) == FMC_ColumnBits_Number_11b)) - /** * @} */ @@ -66,12 +59,6 @@ #define FMC_RowBits_Number_11b ((uint32_t)0x00000000) #define FMC_RowBits_Number_12b ((uint32_t)0x00000004) #define FMC_RowBits_Number_13b ((uint32_t)0x00000008) - -#define IS_FMC_ROWBITS_NUMBER(ROW) \ - (((ROW) == FMC_RowBits_Number_11b) || \ - ((ROW) == FMC_RowBits_Number_12b) || \ - ((ROW) == FMC_RowBits_Number_13b)) - /** * @} */ @@ -83,12 +70,6 @@ #define FMC_SDMemory_Width_8b ((uint32_t)0x00000000) #define FMC_SDMemory_Width_16b ((uint32_t)0x00000010) #define FMC_SDMemory_Width_32b ((uint32_t)0x00000020) - -#define IS_FMC_SDMEMORY_WIDTH(WIDTH) \ - (((WIDTH) == FMC_SDMemory_Width_8b) || \ - ((WIDTH) == FMC_SDMemory_Width_16b) || \ - ((WIDTH) == FMC_SDMemory_Width_32b)) - /** * @} */ @@ -99,11 +80,6 @@ */ #define FMC_InternalBank_Number_2 ((uint32_t)0x00000000) #define FMC_InternalBank_Number_4 ((uint32_t)0x00000040) - -#define IS_FMC_INTERNALBANK_NUMBER(NUMBER) \ - (((NUMBER) == FMC_InternalBank_Number_2) || \ - ((NUMBER) == FMC_InternalBank_Number_4)) - /** * @} */ @@ -116,12 +92,6 @@ #define FMC_CAS_Latency_1 ((uint32_t)0x00000080) #define FMC_CAS_Latency_2 ((uint32_t)0x00000100) #define FMC_CAS_Latency_3 ((uint32_t)0x00000180) - -#define IS_FMC_CAS_LATENCY(LATENCY) \ - (((LATENCY) == FMC_CAS_Latency_1) || \ - ((LATENCY) == FMC_CAS_Latency_2) || \ - ((LATENCY) == FMC_CAS_Latency_3)) - /** * @} */ @@ -132,11 +102,6 @@ */ #define FMC_Write_Protection_Disable ((uint32_t)0x00000000) #define FMC_Write_Protection_Enable ((uint32_t)0x00000200) - -#define IS_FMC_WRITE_PROTECTION(WRITE) \ - (((WRITE) == FMC_Write_Protection_Disable) || \ - ((WRITE) == FMC_Write_Protection_Enable)) - /** * @} */ @@ -150,12 +115,6 @@ #define FMC_SDClock_Period_2 ((uint32_t)0x00000800) #define FMC_SDClock_Period_3 ((uint32_t)0x00000C00) #define FMC_SDClock_Period_Mask ((uint32_t)0x00000C00) - -#define IS_FMC_SDCLOCK_PERIOD(PERIOD) \ - (((PERIOD) == FMC_SDClock_Disable) || \ - ((PERIOD) == FMC_SDClock_Period_2) || \ - ((PERIOD) == FMC_SDClock_Period_3)) - /** * @} */ @@ -167,11 +126,6 @@ #define FMC_Read_Burst_Disable ((uint32_t)0x00000000) #define FMC_Read_Burst_Enable ((uint32_t)0x00001000) #define FMC_Read_Burst_Mask ((uint32_t)0x00001000) - -#define IS_FMC_READ_BURST(RBURST) \ - (((RBURST) == FMC_Read_Burst_Disable) || \ - ((RBURST) == FMC_Read_Burst_Enable)) - /** * @} */ @@ -184,12 +138,6 @@ #define FMC_ReadPipe_Delay_1 ((uint32_t)0x00002000) #define FMC_ReadPipe_Delay_2 ((uint32_t)0x00004000) #define FMC_ReadPipe_Delay_Mask ((uint32_t)0x00006000) - -#define IS_FMC_READPIPE_DELAY(DELAY) \ - (((DELAY) == FMC_ReadPipe_Delay_0) || \ - ((DELAY) == FMC_ReadPipe_Delay_1) || \ - ((DELAY) == FMC_ReadPipe_Delay_2)) - /** * @} */ @@ -205,57 +153,9 @@ #define FMC_Command_Mode_LoadMode ((uint32_t)0x00000004) #define FMC_Command_Mode_Selfrefresh ((uint32_t)0x00000005) #define FMC_Command_Mode_PowerDown ((uint32_t)0x00000006) - -#define IS_FMC_COMMAND_MODE(COMMAND) \ - (((COMMAND) == FMC_Command_Mode_normal) || \ - ((COMMAND) == FMC_Command_Mode_CLK_Enabled) || \ - ((COMMAND) == FMC_Command_Mode_PALL) || \ - ((COMMAND) == FMC_Command_Mode_AutoRefresh) || \ - ((COMMAND) == FMC_Command_Mode_LoadMode) || \ - ((COMMAND) == FMC_Command_Mode_Selfrefresh) || \ - ((COMMAND) == FMC_Command_Mode_PowerDown)) - -/** - * @} - */ - -/** - * @defgroup FMC_Command_Target - * @{ - */ -#define FMC_Command_Target_bank2 ((uint32_t)0x00000008) -#define FMC_Command_Target_bank1 ((uint32_t)0x00000010) -#define FMC_Command_Target_bank1_2 ((uint32_t)0x00000018) - -#define IS_FMC_COMMAND_TARGET(TARGET) \ - (((TARGET) == FMC_Command_Target_bank1) || \ - ((TARGET) == FMC_Command_Target_bank2) || \ - ((TARGET) == FMC_Command_Target_bank1_2)) - /** * @} */ - -/** - * @defgroup FMC_AutoRefresh_Number - * @{ - */ -#define IS_FMC_AUTOREFRESH_NUMBER(NUMBER) (((NUMBER) > 0) && ((NUMBER) <= 16)) - -/** - * @} - */ - -/** - * @defgroup FMC_ModeRegister_Definition - * @{ - */ -#define IS_FMC_MODE_REGISTER(CONTENT) ((CONTENT) <= 8191) - -/** - * @} - */ - /** * @brief FMC SDRAM Mode definition register defines @@ -340,8 +240,14 @@ typedef struct SDRAMDriver SDRAMDriver; * @note It could be empty on some architectures. */ typedef struct { - uint32_t sdcr; - uint32_t sdtr; +#if STM32_SDRAM_USE_FSMC_SDRAM1 + uint32_t sdcr1; + uint32_t sdtr1; +#endif +#if STM32_SDRAM_USE_FSMC_SDRAM2 + uint32_t sdcr2; + uint32_t sdtr2; +#endif } SDRAMConfig; /** @@ -349,7 +255,7 @@ typedef struct { */ struct SDRAMDriver { /** - * @brief Driver state. + * @brief Driver state. */ sdramstate_t state; /** @@ -366,13 +272,7 @@ struct SDRAMDriver { /* External declarations. */ /*===========================================================================*/ -#if STM32_SDRAM_USE_FSMC_SDRAM1 && !defined(__DOXYGEN__) -extern SDRAMDriver SDRAMD1; -#endif - -#if STM32_SDRAM_USE_FSMC_SDRAM2 && !defined(__DOXYGEN__) -extern SDRAMDriver SDRAMD2; -#endif +extern SDRAMDriver SDRAMD; #ifdef __cplusplus extern "C" { @@ -380,8 +280,6 @@ extern "C" { void fsmcSdramInit(void); void fsmcSdramStart(SDRAMDriver *sdramp, const SDRAMConfig *cfgp); void fsmcSdramStop(SDRAMDriver *sdramp); - void fsmcSdram_WaitReady(void); - void fsmcSdram_WriteProtectionConfig(SDRAMDriver *sdramp, int state); #ifdef __cplusplus } #endif -- cgit v1.2.3 From b47ddce74d284f5b1b6a1e67fcf81febf43f62cf Mon Sep 17 00:00:00 2001 From: barthess Date: Sat, 25 Oct 2014 15:26:29 +0300 Subject: FSMC. SDRAM driver cleanup. Needs review. --- os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.c | 106 ++++++------------ os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.h | 167 ++++------------------------- 2 files changed, 55 insertions(+), 218 deletions(-) (limited to 'os/hal/ports') diff --git a/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.c b/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.c index 6ac6966..e0515cf 100644 --- a/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.c +++ b/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.c @@ -39,16 +39,16 @@ /* Driver local definitions. */ /*===========================================================================*/ -#define SDCR2_DONTCARE_BITS (FMC_SDClock_Period_Mask | \ - FMC_Read_Burst_Mask | \ - FMC_ReadPipe_Delay_Mask) - -#define SDTR2_DONTCARE_BITS (FMC_RowCycleDelay_Mask | FMC_RPDelay_Mask) - -/* - * FMC SDCRx write protection mask +/** + * FMC_Command_Mode */ -#define SDCR_WriteProtection_RESET ((uint32_t)0x00007DFF) +#define FMC_Command_Mode_normal ((uint32_t)0x00000000) +#define FMC_Command_Mode_CLK_Enabled ((uint32_t)0x00000001) +#define FMC_Command_Mode_PALL ((uint32_t)0x00000002) +#define FMC_Command_Mode_AutoRefresh ((uint32_t)0x00000003) +#define FMC_Command_Mode_LoadMode ((uint32_t)0x00000004) +#define FMC_Command_Mode_Selfrefresh ((uint32_t)0x00000005) +#define FMC_Command_Mode_PowerDown ((uint32_t)0x00000006) /*===========================================================================*/ /* Driver exported variables. */ @@ -83,13 +83,12 @@ static void _sdram_wait_ready(void) { /** * @brief Executes the SDRAM memory initialization sequence. * - * @param[in] sdramp pointer to the @p SDRAMDriver object + * @param[in] cfgp pointer to the @p SDRAMConfig object * * @notapi */ -static void _sdram_init_sequence(void) { +static void _sdram_init_sequence(const SDRAMConfig *cfgp) { - uint32_t tmp = 0; uint32_t command_target = 0; #if STM32_SDRAM_USE_FSMC_SDRAM1 @@ -101,58 +100,32 @@ static void _sdram_init_sequence(void) { /* Step 3: Configure a clock configuration enable command.*/ _sdram_wait_ready(); - SDRAMD.sdram->SDCMR = (uint32_t) FMC_Command_Mode_CLK_Enabled | - command_target | - ((1 -1) << 5) | // FMC_AutoRefreshNumber = 1 - (0 << 9); // FMC_ModeRegisterDefinition = 0 + SDRAMD.sdram->SDCMR = FMC_Command_Mode_CLK_Enabled | command_target; - /* Step 4: Insert 10 ms delay.*/ - chSysPolledDelayX(MS2ST(10)); + /* Step 4: Insert 1 ms delay (tipically 100uS).*/ + osalThreadSleepMilliseconds(1); /* Step 5: Configure a PALL (precharge all) command.*/ _sdram_wait_ready(); - SDRAMD.sdram->SDCMR = (uint32_t) FMC_Command_Mode_PALL | - command_target | - ((1 -1) << 5) | // FMC_AutoRefreshNumber = 1 - (0 << 9); // FMC_ModeRegisterDefinition = 0 + SDRAMD.sdram->SDCMR = FMC_Command_Mode_PALL | command_target; /* Step 6.1: Configure a Auto-Refresh command: send the first command.*/ _sdram_wait_ready(); - SDRAMD.sdram->SDCMR = (uint32_t) FMC_Command_Mode_AutoRefresh | - command_target | - ((4 -1) << 5) | // FMC_AutoRefreshNumber = 4 - (0 << 9); // FMC_ModeRegisterDefinition = 0 + SDRAMD.sdram->SDCMR = FMC_Command_Mode_AutoRefresh | command_target | + (cfgp->sdcmr & FMC_SDCMR_NRFS); /* Step 6.2: Send the second command.*/ - SDRAMD.sdram->SDCMR = (uint32_t) FMC_Command_Mode_AutoRefresh | - command_target | - ((4 -1) << 5) | // FMC_AutoRefreshNumber = 4 - (0 << 9); // FMC_ModeRegisterDefinition = 0 + SDRAMD.sdram->SDCMR = FMC_Command_Mode_AutoRefresh | command_target | + (cfgp->sdcmr & FMC_SDCMR_NRFS); /* Step 7: Program the external memory mode register.*/ _sdram_wait_ready(); - tmp = FMC_SDCMR_MRD_BURST_LENGTH_2 | - FMC_SDCMR_MRD_BURST_TYPE_SEQUENTIAL | - FMC_SDCMR_MRD_CAS_LATENCY_3 | - FMC_SDCMR_MRD_OPERATING_MODE_STANDARD | - FMC_SDCMR_MRD_WRITEBURST_MODE_SINGLE; - SDRAMD.sdram->SDCMR = (uint32_t) FMC_Command_Mode_LoadMode | - command_target | - ((1 -1) << 5) | // FMC_AutoRefreshNumber = 1 - (tmp << 9); + SDRAMD.sdram->SDCMR = FMC_Command_Mode_LoadMode | command_target | + (cfgp->sdcmr & FMC_SDCMR_MRD); /* Step 8: Set clock.*/ _sdram_wait_ready(); - // 64ms/4096=15.625us -#if (STM32_SYSCLK == 180000000) - //15.625us*90MHz=1406-20=1386 - SDRAMD.sdram->SDRTR=1386<<1; -#elif (STM32_SYSCLK == 168000000) - //15.625us*84MHz=1312-20=1292 - SDRAMD.sdram->SDRTR=1292<<1; -#else - #error No refresh timings for this clock -#endif + SDRAMD.sdram->SDRTR = cfgp->sdrtr; _sdram_wait_ready(); } @@ -191,15 +164,16 @@ void fsmcSdramStart(SDRAMDriver *sdramp, const SDRAMConfig *cfgp) { "SDRAM. Invalid state."); if (sdramp->state == SDRAM_STOP) { -#if STM32_SDRAM_USE_FSMC_SDRAM1 - sdramp->sdram->banks[0].SDCR = cfgp->sdcr1; - sdramp->sdram->banks[0].SDTR = cfgp->sdtr1; -#endif -#if STM32_SDRAM_USE_FSMC_SDRAM2 - sdramp->sdram->banks[1].SDCR = cfgp->sdcr2; - sdramp->sdram->banks[1].SDTR = cfgp->sdtr2; -#endif - _sdram_init_sequence(); + + /* Even if you need only bank2 you must properly set up SDCR and SDTR + regitsters for bank1 too. Both banks will be tuned equally assuming + connected memory ICs are equal.*/ + sdramp->sdram->banks[0].SDCR = cfgp->sdcr; + sdramp->sdram->banks[0].SDTR = cfgp->sdtr; + sdramp->sdram->banks[1].SDCR = cfgp->sdcr; + sdramp->sdram->banks[1].SDTR = cfgp->sdtr; + + _sdram_init_sequence(cfgp); sdramp->state = SDRAM_READY; } @@ -219,22 +193,6 @@ void fsmcSdramStop(SDRAMDriver *sdramp) { } } -/** - * @brief Enables or disables write protection to the specified SDRAM Bank. - * @param SDRAM_Bank: Defines the FMC SDRAM bank. This parameter can be - * FMC_Bank1_SDRAM or FMC_Bank2_SDRAM. - * @param NewState: new state of the write protection flag. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -//void fsmcSdram_WriteProtectionConfig(SDRAMDriver *sdramp, int state) { -// -// if (state) -// sdramp->sdram->SDCR |= FMC_Write_Protection_Enable; -// else -// sdramp->sdram->SDCR &= SDCR_WriteProtection_RESET; -//} - #endif /* STM32_USE_FSMC_SDRAM */ #endif /* STM32F427xx / STM32F429xx / STM32F437xx / STM32F439xx */ diff --git a/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.h b/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.h index 0cb6fef..940679a 100644 --- a/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.h +++ b/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.h @@ -40,142 +40,6 @@ /* Driver constants. */ /*===========================================================================*/ -/** - * @defgroup FMC_ColumnBits_Number - * @{ - */ -#define FMC_ColumnBits_Number_8b ((uint32_t)0x00000000) -#define FMC_ColumnBits_Number_9b ((uint32_t)0x00000001) -#define FMC_ColumnBits_Number_10b ((uint32_t)0x00000002) -#define FMC_ColumnBits_Number_11b ((uint32_t)0x00000003) -/** - * @} - */ - -/** - * @defgroup FMC_RowBits_Number - * @{ - */ -#define FMC_RowBits_Number_11b ((uint32_t)0x00000000) -#define FMC_RowBits_Number_12b ((uint32_t)0x00000004) -#define FMC_RowBits_Number_13b ((uint32_t)0x00000008) -/** - * @} - */ - -/** - * @defgroup FMC_SDMemory_Data_Width - * @{ - */ -#define FMC_SDMemory_Width_8b ((uint32_t)0x00000000) -#define FMC_SDMemory_Width_16b ((uint32_t)0x00000010) -#define FMC_SDMemory_Width_32b ((uint32_t)0x00000020) -/** - * @} - */ - -/** - * @defgroup FMC_InternalBank_Number - * @{ - */ -#define FMC_InternalBank_Number_2 ((uint32_t)0x00000000) -#define FMC_InternalBank_Number_4 ((uint32_t)0x00000040) -/** - * @} - */ - - -/** - * @defgroup FMC_CAS_Latency - * @{ - */ -#define FMC_CAS_Latency_1 ((uint32_t)0x00000080) -#define FMC_CAS_Latency_2 ((uint32_t)0x00000100) -#define FMC_CAS_Latency_3 ((uint32_t)0x00000180) -/** - * @} - */ - -/** - * @defgroup FMC_Write_Protection - * @{ - */ -#define FMC_Write_Protection_Disable ((uint32_t)0x00000000) -#define FMC_Write_Protection_Enable ((uint32_t)0x00000200) -/** - * @} - */ - - -/** - * @defgroup FMC_SDClock_Period - * @{ - */ -#define FMC_SDClock_Disable ((uint32_t)0x00000000) -#define FMC_SDClock_Period_2 ((uint32_t)0x00000800) -#define FMC_SDClock_Period_3 ((uint32_t)0x00000C00) -#define FMC_SDClock_Period_Mask ((uint32_t)0x00000C00) -/** - * @} - */ - -/** - * @defgroup FMC_Read_Burst - * @{ - */ -#define FMC_Read_Burst_Disable ((uint32_t)0x00000000) -#define FMC_Read_Burst_Enable ((uint32_t)0x00001000) -#define FMC_Read_Burst_Mask ((uint32_t)0x00001000) -/** - * @} - */ - -/** - * @defgroup FMC_ReadPipe_Delay - * @{ - */ -#define FMC_ReadPipe_Delay_0 ((uint32_t)0x00000000) -#define FMC_ReadPipe_Delay_1 ((uint32_t)0x00002000) -#define FMC_ReadPipe_Delay_2 ((uint32_t)0x00004000) -#define FMC_ReadPipe_Delay_Mask ((uint32_t)0x00006000) -/** - * @} - */ - -/** - * @defgroup FMC_Command_Mode - * @{ - */ -#define FMC_Command_Mode_normal ((uint32_t)0x00000000) -#define FMC_Command_Mode_CLK_Enabled ((uint32_t)0x00000001) -#define FMC_Command_Mode_PALL ((uint32_t)0x00000002) -#define FMC_Command_Mode_AutoRefresh ((uint32_t)0x00000003) -#define FMC_Command_Mode_LoadMode ((uint32_t)0x00000004) -#define FMC_Command_Mode_Selfrefresh ((uint32_t)0x00000005) -#define FMC_Command_Mode_PowerDown ((uint32_t)0x00000006) -/** - * @} - */ - -/** - * @brief FMC SDRAM Mode definition register defines - */ -#define FMC_SDCMR_MRD_BURST_LENGTH_1 ((uint16_t)0x0000) -#define FMC_SDCMR_MRD_BURST_LENGTH_2 ((uint16_t)0x0001) -#define FMC_SDCMR_MRD_BURST_LENGTH_4 ((uint16_t)0x0002) -#define FMC_SDCMR_MRD_BURST_LENGTH_8 ((uint16_t)0x0004) -#define FMC_SDCMR_MRD_BURST_TYPE_SEQUENTIAL ((uint16_t)0x0000) -#define FMC_SDCMR_MRD_BURST_TYPE_INTERLEAVED ((uint16_t)0x0008) -#define FMC_SDCMR_MRD_CAS_LATENCY_2 ((uint16_t)0x0020) -#define FMC_SDCMR_MRD_CAS_LATENCY_3 ((uint16_t)0x0030) -#define FMC_SDCMR_MRD_OPERATING_MODE_STANDARD ((uint16_t)0x0000) -#define FMC_SDCMR_MRD_WRITEBURST_MODE_PROGRAMMED ((uint16_t)0x0000) -#define FMC_SDCMR_MRD_WRITEBURST_MODE_SINGLE ((uint16_t)0x0200) - - -#define FMC_RowCycleDelay_Mask ((uint16_t)0x0000000F << 12) -#define FMC_RPDelay_Mask ((uint16_t)0x0000000F << 20) - /*===========================================================================*/ /* Driver pre-compile time settings. */ /*===========================================================================*/ @@ -240,14 +104,29 @@ typedef struct SDRAMDriver SDRAMDriver; * @note It could be empty on some architectures. */ typedef struct { -#if STM32_SDRAM_USE_FSMC_SDRAM1 - uint32_t sdcr1; - uint32_t sdtr1; -#endif -#if STM32_SDRAM_USE_FSMC_SDRAM2 - uint32_t sdcr2; - uint32_t sdtr2; -#endif + /** + * @brief SDRAM control register. + * @note Its value will be used for both banks. + */ + uint32_t sdcr; + + /** + * @brief SDRAM timing register. + * @note Its value will be used for both banks. + */ + uint32_t sdtr; + + /** + * @brief SDRAM command mode register. + * @note Only its MRD and NRFS bits will be used. + */ + uint32_t sdcmr; + + /** + * @brief SDRAM refresh timer register. + * @note Only its COUNT bits will be used. + */ + uint32_t sdrtr; } SDRAMConfig; /** -- cgit v1.2.3 From 3af04b9ee56ae5f46efa0b1cdf5d76fb438b3463 Mon Sep 17 00:00:00 2001 From: barthess Date: Sat, 25 Oct 2014 15:39:21 +0300 Subject: FSMC. SDRAM. Improved stop function --- os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.c | 34 +++++++++++++++++++----------- 1 file changed, 22 insertions(+), 12 deletions(-) (limited to 'os/hal/ports') diff --git a/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.c b/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.c index e0515cf..d2c4f78 100644 --- a/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.c +++ b/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.c @@ -42,13 +42,13 @@ /** * FMC_Command_Mode */ -#define FMC_Command_Mode_normal ((uint32_t)0x00000000) -#define FMC_Command_Mode_CLK_Enabled ((uint32_t)0x00000001) -#define FMC_Command_Mode_PALL ((uint32_t)0x00000002) -#define FMC_Command_Mode_AutoRefresh ((uint32_t)0x00000003) -#define FMC_Command_Mode_LoadMode ((uint32_t)0x00000004) -#define FMC_Command_Mode_Selfrefresh ((uint32_t)0x00000005) -#define FMC_Command_Mode_PowerDown ((uint32_t)0x00000006) +#define FMCCM_NORMAL ((uint32_t)0x00000000) +#define FMCCM_CLK_ENABLED ((uint32_t)0x00000001) +#define FMCCM_PALL ((uint32_t)0x00000002) +#define FMCCM_AUTO_REFRESH ((uint32_t)0x00000003) +#define FMCCM_LOAD_MODE ((uint32_t)0x00000004) +#define FMCCM_SELFREFRESH ((uint32_t)0x00000005) +#define FMCCM_POWER_DOWN ((uint32_t)0x00000006) /*===========================================================================*/ /* Driver exported variables. */ @@ -100,27 +100,27 @@ static void _sdram_init_sequence(const SDRAMConfig *cfgp) { /* Step 3: Configure a clock configuration enable command.*/ _sdram_wait_ready(); - SDRAMD.sdram->SDCMR = FMC_Command_Mode_CLK_Enabled | command_target; + SDRAMD.sdram->SDCMR = FMCCM_CLK_ENABLED | command_target; /* Step 4: Insert 1 ms delay (tipically 100uS).*/ osalThreadSleepMilliseconds(1); /* Step 5: Configure a PALL (precharge all) command.*/ _sdram_wait_ready(); - SDRAMD.sdram->SDCMR = FMC_Command_Mode_PALL | command_target; + SDRAMD.sdram->SDCMR = FMCCM_PALL | command_target; /* Step 6.1: Configure a Auto-Refresh command: send the first command.*/ _sdram_wait_ready(); - SDRAMD.sdram->SDCMR = FMC_Command_Mode_AutoRefresh | command_target | + SDRAMD.sdram->SDCMR = FMCCM_AUTO_REFRESH | command_target | (cfgp->sdcmr & FMC_SDCMR_NRFS); /* Step 6.2: Send the second command.*/ - SDRAMD.sdram->SDCMR = FMC_Command_Mode_AutoRefresh | command_target | + SDRAMD.sdram->SDCMR = FMCCM_AUTO_REFRESH | command_target | (cfgp->sdcmr & FMC_SDCMR_NRFS); /* Step 7: Program the external memory mode register.*/ _sdram_wait_ready(); - SDRAMD.sdram->SDCMR = FMC_Command_Mode_LoadMode | command_target | + SDRAMD.sdram->SDCMR = FMCCM_LOAD_MODE | command_target | (cfgp->sdcmr & FMC_SDCMR_MRD); /* Step 8: Set clock.*/ @@ -188,7 +188,17 @@ void fsmcSdramStart(SDRAMDriver *sdramp, const SDRAMConfig *cfgp) { */ void fsmcSdramStop(SDRAMDriver *sdramp) { + uint32_t command_target = 0; + +#if STM32_SDRAM_USE_FSMC_SDRAM1 + command_target |= FMC_SDCMR_CTB1; +#endif +#if STM32_SDRAM_USE_FSMC_SDRAM2 + command_target |= FMC_SDCMR_CTB2; +#endif + if (sdramp->state == SDRAM_READY) { + SDRAMD.sdram->SDCMR = FMCCM_POWER_DOWN | command_target; sdramp->state = SDRAM_STOP; } } -- cgit v1.2.3 From e87406722421e216deb91fa32e08e36b3dd03c91 Mon Sep 17 00:00:00 2001 From: barthess Date: Sat, 25 Oct 2014 15:46:31 +0300 Subject: FSMC. SDRAM. Fixed delay code --- os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'os/hal/ports') diff --git a/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.c b/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.c index d2c4f78..25da179 100644 --- a/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.c +++ b/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.c @@ -102,8 +102,8 @@ static void _sdram_init_sequence(const SDRAMConfig *cfgp) { _sdram_wait_ready(); SDRAMD.sdram->SDCMR = FMCCM_CLK_ENABLED | command_target; - /* Step 4: Insert 1 ms delay (tipically 100uS).*/ - osalThreadSleepMilliseconds(1); + /* Step 4: Insert delay (tipically 100uS).*/ + osalSysPolledDelayX(US2RTC(STM32_SYSCLK, 100)); /* Step 5: Configure a PALL (precharge all) command.*/ _sdram_wait_ready(); -- cgit v1.2.3 From 1c50a03cfd17090f39004849c79e1e6ce8874e05 Mon Sep 17 00:00:00 2001 From: barthess Date: Sat, 25 Oct 2014 15:54:24 +0300 Subject: FSMC. SDRAM. Added safety mask for SDRTR register --- os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'os/hal/ports') diff --git a/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.c b/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.c index 25da179..e635323 100644 --- a/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.c +++ b/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.c @@ -125,7 +125,7 @@ static void _sdram_init_sequence(const SDRAMConfig *cfgp) { /* Step 8: Set clock.*/ _sdram_wait_ready(); - SDRAMD.sdram->SDRTR = cfgp->sdrtr; + SDRAMD.sdram->SDRTR = cfgp->sdrtr & FMC_SDRTR_COUNT; _sdram_wait_ready(); } -- cgit v1.2.3 From 1f97428d5d6736c050d546a12837b19c48cfc99d Mon Sep 17 00:00:00 2001 From: barthess Date: Fri, 31 Oct 2014 02:51:00 +0300 Subject: FSMC. SDRAM. Fixed some typos --- os/hal/ports/STM32/LLD/FSMCv1/fsmc.c | 2 +- os/hal/ports/STM32/LLD/FSMCv1/fsmc.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'os/hal/ports') diff --git a/os/hal/ports/STM32/LLD/FSMCv1/fsmc.c b/os/hal/ports/STM32/LLD/FSMCv1/fsmc.c index 6cadfb1..274bc62 100644 --- a/os/hal/ports/STM32/LLD/FSMCv1/fsmc.c +++ b/os/hal/ports/STM32/LLD/FSMCv1/fsmc.c @@ -106,7 +106,7 @@ void fsmc_init(void) { #if (defined(STM32F427xx) || defined(STM32F437xx) || \ defined(STM32F429xx) || defined(STM32F439xx)) - #if STM32_SDRAM_USE_FSMC_SDRAM1 + #if STM32_USE_FSMC_SDRAM FSMCD1.sdram = (FSMC_SDRAM_TypeDef *)FSMC_Bank5_6_R_BASE; #endif #endif diff --git a/os/hal/ports/STM32/LLD/FSMCv1/fsmc.h b/os/hal/ports/STM32/LLD/FSMCv1/fsmc.h index 4ca6e58..6ddd566 100644 --- a/os/hal/ports/STM32/LLD/FSMCv1/fsmc.h +++ b/os/hal/ports/STM32/LLD/FSMCv1/fsmc.h @@ -302,7 +302,7 @@ struct FSMCDriver { #endif #if (defined(STM32F427xx) || defined(STM32F437xx) || \ defined(STM32F429xx) || defined(STM32F439xx)) - #if (STM32_SDRAM_USE_FSMC_SDRAM1 || STM32_SDRAM_USE_FSMC_SDRAM1) + #if STM32_USE_FSMC_SDRAM FSMC_SDRAM_TypeDef *sdram; #endif #endif -- cgit v1.2.3 From ed62d9e4d42bde4b929be2523ad94c1a7c8d2827 Mon Sep 17 00:00:00 2001 From: barthess Date: Fri, 31 Oct 2014 03:28:04 +0300 Subject: FSMC. SDRAM. Fixed bug with registers' memory layout --- os/hal/ports/STM32/LLD/FSMCv1/fsmc.h | 11 ++++------- os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.c | 11 ++++++----- 2 files changed, 10 insertions(+), 12 deletions(-) (limited to 'os/hal/ports') diff --git a/os/hal/ports/STM32/LLD/FSMCv1/fsmc.h b/os/hal/ports/STM32/LLD/FSMCv1/fsmc.h index 6ddd566..9ac64f7 100644 --- a/os/hal/ports/STM32/LLD/FSMCv1/fsmc.h +++ b/os/hal/ports/STM32/LLD/FSMCv1/fsmc.h @@ -164,13 +164,10 @@ typedef struct { defined(STM32F429xx) || defined(STM32F439xx)) typedef struct { - __IO uint32_t SDCR; /**< SDRAM control register */ - uint32_t RESERVED; /**< Reserved */ - __IO uint32_t SDTR; /**< SDRAM timing register */ -} FSMC_SDRAM_BANK_TypeDef; - -typedef struct { - FSMC_SDRAM_BANK_TypeDef banks[2]; /**< Banks mapping */ + __IO uint32_t SDCR1; /**< SDRAM control register (bank 1) */ + __IO uint32_t SDCR2; /**< SDRAM control register (bank 2) */ + __IO uint32_t SDTR1; /**< SDRAM timing register (bank 1) */ + __IO uint32_t SDTR2; /**< SDRAM timing register (bank 2) */ __IO uint32_t SDCMR; /**< SDRAM comand mode register */ __IO uint32_t SDRTR; /**< SDRAM refresh timer register */ __IO uint32_t SDSR; /**< SDRAM status register */ diff --git a/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.c b/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.c index e635323..ed415eb 100644 --- a/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.c +++ b/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sdram.c @@ -103,7 +103,7 @@ static void _sdram_init_sequence(const SDRAMConfig *cfgp) { SDRAMD.sdram->SDCMR = FMCCM_CLK_ENABLED | command_target; /* Step 4: Insert delay (tipically 100uS).*/ - osalSysPolledDelayX(US2RTC(STM32_SYSCLK, 100)); + osalThreadSleepMilliseconds(100); /* Step 5: Configure a PALL (precharge all) command.*/ _sdram_wait_ready(); @@ -115,6 +115,7 @@ static void _sdram_init_sequence(const SDRAMConfig *cfgp) { (cfgp->sdcmr & FMC_SDCMR_NRFS); /* Step 6.2: Send the second command.*/ + _sdram_wait_ready(); SDRAMD.sdram->SDCMR = FMCCM_AUTO_REFRESH | command_target | (cfgp->sdcmr & FMC_SDCMR_NRFS); @@ -168,10 +169,10 @@ void fsmcSdramStart(SDRAMDriver *sdramp, const SDRAMConfig *cfgp) { /* Even if you need only bank2 you must properly set up SDCR and SDTR regitsters for bank1 too. Both banks will be tuned equally assuming connected memory ICs are equal.*/ - sdramp->sdram->banks[0].SDCR = cfgp->sdcr; - sdramp->sdram->banks[0].SDTR = cfgp->sdtr; - sdramp->sdram->banks[1].SDCR = cfgp->sdcr; - sdramp->sdram->banks[1].SDTR = cfgp->sdtr; + sdramp->sdram->SDCR1 = cfgp->sdcr; + sdramp->sdram->SDTR1 = cfgp->sdtr; + sdramp->sdram->SDCR2 = cfgp->sdcr; + sdramp->sdram->SDTR2 = cfgp->sdtr; _sdram_init_sequence(cfgp); -- cgit v1.2.3