From b06722cd7fe596199c7ae18c1edc4bbe6356ff08 Mon Sep 17 00:00:00 2001 From: Gustavo Henrique Nihei Date: Tue, 23 Jun 2020 11:56:37 -0300 Subject: [PATCH] boards/arm/stm32/stm32f769i-disco: Add support for external SDRAM --- arch/arm/src/stm32f7/stm32_fmc.h | 595 +++++++++--------- .../stm32f746g-disco/src/stm32_extmem.c | 79 +-- .../arm/stm32f7/stm32f769i-disco/src/Makefile | 4 + .../stm32f7/stm32f769i-disco/src/stm32_boot.c | 6 +- .../stm32f769i-disco/src/stm32_extmem.c | 322 ++++++++++ .../stm32f769i-disco/src/stm32f769i-disco.h | 20 +- 6 files changed, 704 insertions(+), 322 deletions(-) create mode 100644 boards/arm/stm32f7/stm32f769i-disco/src/stm32_extmem.c diff --git a/arch/arm/src/stm32f7/stm32_fmc.h b/arch/arm/src/stm32f7/stm32_fmc.h index d162e665e5..ef9fd57885 100644 --- a/arch/arm/src/stm32f7/stm32_fmc.h +++ b/arch/arm/src/stm32f7/stm32_fmc.h @@ -1,4 +1,4 @@ -/************************************************************************************ +/***************************************************************************************************************************************************** * arch/arm/src/stm32f7/stm32_fmc.h * * Copyright (C) 2018 Gregory Nutt. All rights reserved. @@ -31,346 +31,381 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************************/ + *****************************************************************************************************************************************************/ #ifndef __ARCH_ARM_SRC_STM32F7_STM32_FMC_H #define __ARCH_ARM_SRC_STM32F7_STM32_FMC_H -/************************************************************************************ +/***************************************************************************************************************************************************** * Included Files - ************************************************************************************/ + *****************************************************************************************************************************************************/ #include #include "chip.h" -/************************************************************************************ +/***************************************************************************************************************************************************** * Pre-processor Definitions - ************************************************************************************/ + *****************************************************************************************************************************************************/ -/* Register Offsets *****************************************************************/ +/* Register Offsets **********************************************************************************************************************************/ -#define STM32_FMC_BCR_OFFSET(n) (8*((n)-1)) -#define STM32_FMC_BCR1_OFFSET 0x0000 /* SRAM/NOR-Flash chip-select control registers 1 */ -#define STM32_FMC_BCR2_OFFSET 0x0008 /* SRAM/NOR-Flash chip-select control registers 2 */ -#define STM32_FMC_BCR3_OFFSET 0x0010 /* SRAM/NOR-Flash chip-select control registers 3 */ -#define STM32_FMC_BCR4_OFFSET 0x0018 /* SRAM/NOR-Flash chip-select control registers 4 */ +#define STM32_FMC_BCR_OFFSET(n) (8*((n)-1)) +#define STM32_FMC_BCR1_OFFSET 0x0000 /* SRAM/NOR-Flash chip-select control registers 1 */ +#define STM32_FMC_BCR2_OFFSET 0x0008 /* SRAM/NOR-Flash chip-select control registers 2 */ +#define STM32_FMC_BCR3_OFFSET 0x0010 /* SRAM/NOR-Flash chip-select control registers 3 */ +#define STM32_FMC_BCR4_OFFSET 0x0018 /* SRAM/NOR-Flash chip-select control registers 4 */ -#define STM32_FMC_BTR_OFFSET(n) (8*((n)-1)+0x0004) -#define STM32_FMC_BTR1_OFFSET 0x0004 /* SRAM/NOR-Flash chip-select timing registers 1 */ -#define STM32_FMC_BTR2_OFFSET 0x000c /* SRAM/NOR-Flash chip-select timing registers 2 */ -#define STM32_FMC_BTR3_OFFSET 0x0014 /* SRAM/NOR-Flash chip-select timing registers 3 */ -#define STM32_FMC_BTR4_OFFSET 0x001c /* SRAM/NOR-Flash chip-select timing registers 4 */ +#define STM32_FMC_BTR_OFFSET(n) (8*((n)-1)+0x0004) +#define STM32_FMC_BTR1_OFFSET 0x0004 /* SRAM/NOR-Flash chip-select timing registers 1 */ +#define STM32_FMC_BTR2_OFFSET 0x000c /* SRAM/NOR-Flash chip-select timing registers 2 */ +#define STM32_FMC_BTR3_OFFSET 0x0014 /* SRAM/NOR-Flash chip-select timing registers 3 */ +#define STM32_FMC_BTR4_OFFSET 0x001c /* SRAM/NOR-Flash chip-select timing registers 4 */ -#define STM32_FMC_BWTR_OFFSET(n) (8*((n)-1)+0x0104) -#define STM32_FMC_BWTR1_OFFSET 0x0104 /* SRAM/NOR-Flash write timing registers 1 */ -#define STM32_FMC_BWTR2_OFFSET 0x010c /* SRAM/NOR-Flash write timing registers 2 */ -#define STM32_FMC_BWTR3_OFFSET 0x0114 /* SRAM/NOR-Flash write timing registers 3 */ -#define STM32_FMC_BWTR4_OFFSET 0x011c /* SRAM/NOR-Flash write timing registers 4 */ +#define STM32_FMC_BWTR_OFFSET(n) (8*((n)-1)+0x0104) +#define STM32_FMC_BWTR1_OFFSET 0x0104 /* SRAM/NOR-Flash write timing registers 1 */ +#define STM32_FMC_BWTR2_OFFSET 0x010c /* SRAM/NOR-Flash write timing registers 2 */ +#define STM32_FMC_BWTR3_OFFSET 0x0114 /* SRAM/NOR-Flash write timing registers 3 */ +#define STM32_FMC_BWTR4_OFFSET 0x011c /* SRAM/NOR-Flash write timing registers 4 */ -#define STM32_FMC_PCR_OFFSET(n) (0x0020*((n)-1)+0x0040) -#define STM32_FMC_PCR2_OFFSET 0x0060 /* NAND Flash/PC Card controller register 2 */ -#define STM32_FMC_PCR3_OFFSET 0x0080 /* NAND Flash/PC Card controller register 3 */ -#define STM32_FMC_PCR4_OFFSET 0x00a0 /* NAND Flash/PC Card controller register 4 */ +#define STM32_FMC_PCR_OFFSET 0x0080 /* NAND Flash control register */ -#define STM32_FMC_SR_OFFSET(n) (0x0020*((n)-1)+0x0044) -#define STM32_FMC_SR2_OFFSET 0x0064 /* NAND Flash/PC Card controller register 2 */ -#define STM32_FMC_SR3_OFFSET 0x0084 /* NAND Flash/PC Card controller register 3 */ -#define STM32_FMC_SR4_OFFSET 0x00a4 /* NAND Flash/PC Card controller register 4 */ +#define STM32_FMC_SR_OFFSET 0x0084 /* FIFO status and interrupt register */ -#define STM32_FMC_PMEM_OFFSET(n) (0x0020*((n)-1)+0x0048) -#define STM32_FMC_PMEM2_OFFSET 0x0068 /* Common memory space timing register 2 */ -#define STM32_FMC_PMEM3_OFFSET 0x0088 /* Common memory space timing register 3 */ -#define STM32_FMC_PMEM4_OFFSET 0x00a8 /* Common memory space timing register 4 */ +#define STM32_FMC_PMEM_OFFSET 0x0088 /* Common memory space timing register */ -#define STM32_FMC_PATT_OFFSET(n) (0x0020*((n)-1)+0x004c) -#define STM32_FMC_PATT2_OFFSET 0x006c /* Attribute memory space timing register 2 */ -#define STM32_FMC_PATT3_OFFSET 0x008c /* Attribute memory space timing register 3 */ -#define STM32_FMC_PATT4_OFFSET 0x00ac /* Attribute memory space timing register 4 */ +#define STM32_FMC_PATT_OFFSET 0x008c /* Attribute memory space timing register */ -#define STM32_PIO4_OFFSET 0x00b0 /* I/O space timing register 4 */ +#define STM32_FMC_ECCR_OFFSET 0x0094 /* ECC result register */ -#define STM32_FMC_ECCR_OFFSET(n) (0x0020*((n)-1)+0x003c) -#define STM32_FMC_ECCR2_OFFSET 0x0054 /* ECC result register 2 */ -#define STM32_FMC_ECCR3_OFFSET 0x0074 /* ECC result register 3 */ +#define STM32_FMC_SDCR_OFFSET(n) (4*((n)-1)+0x0140) +#define STM32_FMC_SDCR1_OFFSET 0x0140 /* SDRAM Control Register, Bank 1 */ +#define STM32_FMC_SDCR2_OFFSET 0x0144 /* SDRAM Control Register, Bank 1 */ -#define STM32_FMC_SDCR1_OFFSET 0x0140 /* SDRAM Control Register, Bank 0 */ -#define STM32_FMC_SDCR2_OFFSET 0x0144 /* SDRAM Control Register, Bank 1 */ +#define STM32_FMC_SDTR_OFFSET(n) (4*((n)-1)+0x0148) +#define STM32_FMC_SDTR1_OFFSET 0x0148 /* SDRAM Timing Register, Bank 0 */ +#define STM32_FMC_SDTR2_OFFSET 0x014c /* SDRAM Timing Register, Bank 1 */ -#define STM32_FMC_SDTR1_OFFSET 0x0148 /* SDRAM Timing Register, Bank 0 */ -#define STM32_FMC_SDTR2_OFFSET 0x014c /* SDRAM Timing Register, Bank 1 */ +#define STM32_FMC_SDCMR_OFFSET 0x0150 /* SDRAM Command mode register */ +#define STM32_FMC_SDRTR_OFFSET 0x0154 /* SDRAM Refresh Timing Register maybe */ +#define STM32_FMC_SDSR_OFFSET 0x0158 /* SDRAM Status Register */ -#define STM32_FMC_SDCMR_OFFSET 0x0150 /* SDRAM Config Memory register */ -#define STM32_FMC_SDRTR_OFFSET 0x0154 /* SDRAM Refresh Timing Register maybe */ -#define STM32_FMC_SDSR_OFFSET 0x0158 /* SDRAM Status Register */ +/* Register Addresses ********************************************************************************************************************************/ -/* Register Addresses ***************************************************************/ +#define STM32_FMC_BCR(n) (STM32_FMC_BASE+STM32_FMC_BCR_OFFSET(n)) +#define STM32_FMC_BCR1 (STM32_FMC_BASE+STM32_FMC_BCR1_OFFSET ) +#define STM32_FMC_BCR2 (STM32_FMC_BASE+STM32_FMC_BCR2_OFFSET ) +#define STM32_FMC_BCR3 (STM32_FMC_BASE+STM32_FMC_BCR3_OFFSET ) +#define STM32_FMC_BCR4 (STM32_FMC_BASE+STM32_FMC_BCR4_OFFSET ) -#define STM32_FMC_BCR(n) (STM32_FMC_BASE+STM32_FMC_BCR_OFFSET(n)) -#define STM32_FMC_BCR1 (STM32_FMC_BASE+STM32_FMC_BCR1_OFFSET ) -#define STM32_FMC_BCR2 (STM32_FMC_BASE+STM32_FMC_BCR2_OFFSET ) -#define STM32_FMC_BCR3 (STM32_FMC_BASE+STM32_FMC_BCR3_OFFSET ) -#define STM32_FMC_BCR4 (STM32_FMC_BASE+STM32_FMC_BCR4_OFFSET ) +#define STM32_FMC_BTR(n) (STM32_FMC_BASE+STM32_FMC_BTR_OFFSET(n)) +#define STM32_FMC_BTR1 (STM32_FMC_BASE+STM32_FMC_BTR1_OFFSET ) +#define STM32_FMC_BTR2 (STM32_FMC_BASE+STM32_FMC_BTR2_OFFSET ) +#define STM32_FMC_BTR3 (STM32_FMC_BASE+STM32_FMC_BTR3_OFFSET ) +#define STM32_FMC_BTR4 (STM32_FMC_BASE+STM32_FMC_BTR4_OFFSET ) -#define STM32_FMC_BTR(n) (STM32_FMC_BASE+STM32_FMC_BTR_OFFSET(n)) -#define STM32_FMC_BTR1 (STM32_FMC_BASE+STM32_FMC_BTR1_OFFSET ) -#define STM32_FMC_BTR2 (STM32_FMC_BASE+STM32_FMC_BTR2_OFFSET ) -#define STM32_FMC_BTR3 (STM32_FMC_BASE+STM32_FMC_BTR3_OFFSET ) -#define STM32_FMC_BTR4 (STM32_FMC_BASE+STM32_FMC_BTR4_OFFSET ) +#define STM32_FMC_BWTR(n) (STM32_FMC_BASE+STM32_FMC_BWTR_OFFSET(n)) +#define STM32_FMC_BWTR1 (STM32_FMC_BASE+STM32_FMC_BWTR1_OFFSET ) +#define STM32_FMC_BWTR2 (STM32_FMC_BASE+STM32_FMC_BWTR2_OFFSET ) +#define STM32_FMC_BWTR3 (STM32_FMC_BASE+STM32_FMC_BWTR3_OFFSET ) +#define STM32_FMC_BWTR4 (STM32_FMC_BASE+STM32_FMC_BWTR4_OFFSET ) -#define STM32_FMC_BWTR(n) (STM32_FMC_BASE+STM32_FMC_BWTR_OFFSET(n)) -#define STM32_FMC_BWTR1 (STM32_FMC_BASE+STM32_FMC_BWTR1_OFFSET ) -#define STM32_FMC_BWTR2 (STM32_FMC_BASE+STM32_FMC_BWTR2_OFFSET ) -#define STM32_FMC_BWTR3 (STM32_FMC_BASE+STM32_FMC_BWTR3_OFFSET ) -#define STM32_FMC_BWTR4 (STM32_FMC_BASE+STM32_FMC_BWTR4_OFFSET ) +#define STM32_FMC_PCR (STM32_FMC_BASE+STM32_FMC_PCR_OFFSET) -#define STM32_FMC_PCR(n) (STM32_FMC_BASE+STM32_FMC_PCR_OFFSET(n)) -#define STM32_FMC_PCR2 (STM32_FMC_BASE+STM32_FMC_PCR2_OFFSET ) -#define STM32_FMC_PCR3 (STM32_FMC_BASE+STM32_FMC_PCR3_OFFSET ) -#define STM32_FMC_PCR4 (STM32_FMC_BASE+STM32_FMC_PCR4_OFFSET ) +#define STM32_FMC_SR (STM32_FMC_BASE+STM32_FMC_SR_OFFSET) -#define STM32_FMC_SR(n) (STM32_FMC_BASE+STM32_FMC_SR_OFFSET(n)) -#define STM32_FMC_SR2 (STM32_FMC_BASE+STM32_FMC_SR2_OFFSET ) -#define STM32_FMC_SR3 (STM32_FMC_BASE+STM32_FMC_SR3_OFFSET ) -#define STM32_FMC_SR4 (STM32_FMC_BASE+STM32_FMC_SR4_OFFSET ) +#define STM32_FMC_PMEM (STM32_FMC_BASE+STM32_FMC_PMEM_OFFSET) -#define STM32_FMC_PMEM(n) (STM32_FMC_BASE+STM32_FMC_PMEM_OFFSET(n)) -#define STM32_FMC_PMEM2 (STM32_FMC_BASE+STM32_FMC_PMEM2_OFFSET ) -#define STM32_FMC_PMEM3 (STM32_FMC_BASE+STM32_FMC_PMEM3_OFFSET ) -#define STM32_FMC_PMEM4 (STM32_FMC_BASE+STM32_FMC_PMEM4_OFFSET ) +#define STM32_FMC_PATT (STM32_FMC_BASE+STM32_FMC_PATT_OFFSET) -#define STM32_FMC_PATT(n) (STM32_FMC_BASE+STM32_FMC_PATT_OFFSET(n)) -#define STM32_FMC_PATT2 (STM32_FMC_BASE+STM32_FMC_PATT2_OFFSET ) -#define STM32_FMC_PATT3 (STM32_FMC_BASE+STM32_FMC_PATT3_OFFSET ) -#define STM32_FMC_PATT4 (STM32_FMC_BASE+STM32_FMC_PATT4_OFFSET ) +#define STM32_FMC_ECCR (STM32_FMC_BASE+STM32_FMC_ECCR_OFFSET) -#define STM32_PIO4 (STM32_FMC_BASE+STM32_FMC_PIO4_OFFSET ) +#define STM32_FMC_SDCR1 (STM32_FMC_BASE+STM32_FMC_SDCR1_OFFSET) +#define STM32_FMC_SDCR2 (STM32_FMC_BASE+STM32_FMC_SDCR2_OFFSET) -#define STM32_FMC_ECCR(n) (STM32_FMC_BASE+STM32_FMC_ECCR_OFFSET(n)) -#define STM32_FMC_ECCR2 (STM32_FMC_BASE+STM32_FMC_ECCR2_OFFSET ) -#define STM32_FMC_ECCR3 (STM32_FMC_BASE+STM32_FMC_ECCR3_OFFSET ) +#define STM32_FMC_SDTR1 (STM32_FMC_BASE+STM32_FMC_SDTR1_OFFSET) +#define STM32_FMC_SDTR2 (STM32_FMC_BASE+STM32_FMC_SDTR2_OFFSET) -#define STM32_FMC_SDCR1 (STM32_FMC_BASE+STM32_FMC_SDCR1_OFFSET) -#define STM32_FMC_SDCR2 (STM32_FMC_BASE+STM32_FMC_SDCR2_OFFSET) +#define STM32_FMC_SDCMR (STM32_FMC_BASE+STM32_FMC_SDCMR_OFFSET) +#define STM32_FMC_SDRTR (STM32_FMC_BASE+STM32_FMC_SDRTR_OFFSET) +#define STM32_FMC_SDSR (STM32_FMC_BASE+STM32_FMC_SDSR_OFFSET) -#define STM32_FMC_SDTR1 (STM32_FMC_BASE+STM32_FMC_SDTR1_OFFSET) -#define STM32_FMC_SDTR2 (STM32_FMC_BASE+STM32_FMC_SDTR2_OFFSET) +/* Register Bitfield Definitions *********************************************************************************************************************/ -#define STM32_FMC_SDCMR (STM32_FMC_BASE+STM32_FMC_SDCMR_OFFSET) -#define STM32_FMC_SDRTR (STM32_FMC_BASE+STM32_FMC_SDRTR_OFFSET) -#define STM32_FMC_SDSR (STM32_FMC_BASE+STM32_FMC_SDSR_OFFSET) +#define FMC_BCR_MBKEN (1 << 0) /* Memory bank enable bit */ +#define FMC_BCR_MUXEN (1 << 1) /* Address/data multiplexing enable bit */ +#define FMC_BCR_MTYP_SHIFT (2) /* Memory type */ +#define FMC_BCR_MTYP_MASK (3 << FMC_BCR_MTYP_SHIFT) +# define FMC_BCR_SRAM (0 << FMC_BCR_MTYP_SHIFT) +# define FMC_BCR_ROM (0 << FMC_BCR_MTYP_SHIFT) +# define FMC_BCR_PSRAM (1 << FMC_BCR_MTYP_SHIFT) +# define FMC_BCR_CRAM (1 << FMC_BCR_MTYP_SHIFT) +# define FMC_BCR_NOR (2 << FMC_BCR_MTYP_SHIFT) +#define FMC_BCR_MWID_SHIFT (4) /* Memory data bus width */ +#define FMC_BCR_MWID_MASK (3 << FMC_BCR_MWID_SHIFT) +# define FMC_BCR_MWID8 (0 << FMC_BCR_MWID_SHIFT) +# define FMC_BCR_MWID16 (1 << FMC_BCR_MWID_SHIFT) +# define FMC_BCR_MWID32 (2 << FMC_BCR_MWID_SHIFT) +#define FMC_BCR_FACCEN (1 << 6) /* Flash access enable */ +#define FMC_BCR_BURSTEN (1 << 8) /* Burst enable bit */ +#define FMC_BCR_WAITPOL (1 << 9) /* Wait signal polarity bit */ +#define FMC_BCR_WAITCFG (1 << 11) /* Wait timing configuration */ +#define FMC_BCR_WREN (1 << 12) /* Write enable bit */ +#define FMC_BCR_WAITEN (1 << 13) /* Wait enable bit */ +#define FMC_BCR_EXTMOD (1 << 14) /* Extended mode enable */ +#define FMC_BCR_ASYNCWAIT (1 << 15) /* Wait signal during asynchronous transfers */ +#define FMC_BCR_CPSIZE_SHIFT (16) +#define FMC_BCR_CPSIZE_MASK (7 << FMC_BCR_CPSIZE_SHIFT) +# define FMC_BCR_CPSIZE0 (0 << FMC_BCR_CPSIZE_SHIFT) +# define FMC_BCR_CPSIZE128 (1 << FMC_BCR_CPSIZE_SHIFT) +# define FMC_BCR_CPSIZE256 (2 << FMC_BCR_CPSIZE_SHIFT) +# define FMC_BCR_CPSIZE1024 (3 << FMC_BCR_CPSIZE_SHIFT) +#define FMC_BCR_CBURSTRW (1 << 19) /* Write burst enable */ +#define FMC_BCR_CCLKEN (1 << 20) /* Continuous Clock Enable */ +#define FMC_BCR_WFDIS (1 << 21) /* Write FIFO Disable */ +#define FMC_BCR_BMAP_SHIFT (24) +#define FMC_BCR_BMAP_MASK (3 << FMC_BCR_BMAP_SHIFT) +# define FMC_BCR_BMAP0 (0 << FMC_BCR_BMAP_SHIFT) /* Default mapping */ +# define FMC_BCR_BMAP1 (1 << FMC_BCR_BMAP_SHIFT) /* NOR/PSRAM bank and SDRAM bank 1/bank2 are swapped */ +# define FMC_BCR_BMAP2 (2 << FMC_BCR_BMAP_SHIFT) /* SDRAM Bank2 remapped on FMC bank2 and still accessible at default mapping */ +#define FMC_BCR_FMCEN (1 << 31) /* FMC controller Enable */ -/* Register Bitfield Definitions ****************************************************/ +#define FMC_BCR_RSTVALUE(n) ((n == 0) ? 0x000030db : 0x000030d2) /* Reset value for BCR */ -#define FMC_BCR_MBKEN (1 << 0) /* Memory bank enable bit */ -#define FMC_BCR_MUXEN (1 << 1) /* Address/data multiplexing enable bit */ -#define FMC_BCR_MTYP_SHIFT (2) /* Memory type */ -#define FMC_BCR_MTYP_MASK (3 << FMC_BCR_MTYP_SHIFT) -# define FMC_BCR_SRAM (0 << FMC_BCR_MTYP_SHIFT) -# define FMC_BCR_ROM (0 << FMC_BCR_MTYP_SHIFT) -# define FMC_BCR_PSRAM (1 << FMC_BCR_MTYP_SHIFT) -# define FMC_BCR_CRAM (1 << FMC_BCR_MTYP_SHIFT) -# define FMC_BCR_NOR (2 << FMC_BCR_MTYP_SHIFT) -#define FMC_BCR_MWID_SHIFT (4) /* Memory data bus width */ -#define FMC_BCR_MWID_MASK (3 << FMC_BCR_MWID_SHIFT) -# define FMC_BCR_MWID8 (0 << FMC_BCR_MWID_SHIFT) -# define FMC_BCR_MWID16 (1 << FMC_BCR_MWID_SHIFT) -#define FMC_BCR_FACCEN (1 << 6) /* Flash access enable */ -#define FMC_BCR_BURSTEN (1 << 8) /* Burst enable bit */ -#define FMC_BCR_WAITPOL (1 << 9) /* Wait signal polarity bit */ -#define FMC_BCR_WRAPMOD (1 << 10) /* Wrapped burst mode support */ -#define FMC_BCR_WAITCFG (1 << 11) /* Wait timing configuration */ -#define FMC_BCR_WREN (1 << 12) /* Write enable bit */ -#define FMC_BCR_WAITEN (1 << 13) /* Wait enable bit */ -#define FMC_BCR_EXTMOD (1 << 14) /* Extended mode enable */ -#define FMC_BCR_ASYNCWAIT (1 << 15) /* Wait signal during asynchronous transfers */ -#define FMC_BCR_CBURSTRW (1 << 19) /* Write burst enable */ +#define FMC_BTR_ADDSET_SHIFT (0) /* Address setup phase duration */ +#define FMC_BTR_ADDSET_MASK (15 << FMC_BTR_ADDSET_SHIFT) +# define FMC_BTR_ADDSET(n) ((n-1) << FMC_BTR_ADDSET_SHIFT) /* (n)xHCLK n=1..16 */ +#define FMC_BTR_ADDHLD_SHIFT (4) /* Address-hold phase duration */ +#define FMC_BTR_ADDHLD_MASK (15 << FMC_BTR_ADDHLD_SHIFT) +# define FMC_BTR_ADDHLD(n) ((n-1) << FMC_BTR_ADDHLD_SHIFT) /* (n)xHCLK n=2..16*/ +#define FMC_BTR_DATAST_SHIFT (8) /* Data-phase duration */ +#define FMC_BTR_DATAST_MASK (255 << FMC_BTR_DATAST_SHIFT) +# define FMC_BTR_DATAST(n) ((n-1) << FMC_BTR_DATAST_SHIFT) /* (n)xHCLK n=2..256 */ +#define FMC_BTR_BUSTURN_SHIFT (16) /* Bus turnaround phase duration */ +#define FMC_BTR_BUSTURN_MASK (15 << FMC_BTR1_BUSTURN_SHIFT) +# define FMC_BTR_BUSTURN(n) ((n-1) << FMC_BTR_BUSTURN_SHIFT)/* (n)xHCLK n=1..16 */ +#define FMC_BTR_CLKDIV_SHIFT (20) /* Clock divide ratio */ +#define FMC_BTR_CLKDIV_MASK (15 << FMC_BTR_CLKDIV_SHIFT) +# define FMC_BTR_CLKDIV(n) ((n-1) << FMC_BTR_CLKDIV_SHIFT) /* (n)xHCLK n=2..16 */ +#define FMC_BTR_DATLAT_SHIFT (24) /* Data latency */ +#define FMC_BTR_DATLAT_MASK (15 << FMC_BTR_DATLAT_SHIFT) +# define FMC_BTR_DATLAT(n) ((n-2) << FMC_BTR_DATLAT_SHIFT) + /* (n)xHCLK n=2..17 */ +#define FMC_BTR_ACCMOD_SHIFT (28) /* Access mode */ +#define FMC_BTR_ACCMOD_MASK (3 << FMC_BTR_ACCMOD_SHIFT) +# define FMC_BTR_ACCMODA (0 << FMC_BTR_ACCMOD_SHIFT) +# define FMC_BTR_ACCMODB (1 << FMC_BTR_ACCMOD_SHIFT) +# define FMC_BTR_ACCMODC (2 << FMC_BTR_ACCMOD_SHIFT) +# define FMC_BTR_ACCMODD (3 << FMC_BTR_ACCMOD_SHIFT) -#define FMC_BCR_RSTVALUE 0x000003d2 +#define FMC_BTR_RSTVALUE 0xffffffff -#define FMC_BTR_ADDSET_SHIFT (0) /* Address setup phase duration */ -#define FMC_BTR_ADDSET_MASK (15 << FMC_BTR_ADDSET_SHIFT) -# define FMC_BTR_ADDSET(n) ((n-1) << FMC_BTR_ADDSET_SHIFT) /* (n)xHCLK n=1..16 */ -#define FMC_BTR_ADDHLD_SHIFT (4) /* Address-hold phase duration */ -#define FMC_BTR_ADDHLD_MASK (15 << FMC_BTR_ADDHLD_SHIFT) -# define FMC_BTR_ADDHLD(n) ((n-1) << FMC_BTR_ADDHLD_SHIFT) /* (n)xHCLK n=2..16*/ -#define FMC_BTR_DATAST_SHIFT (8) /* Data-phase duration */ -#define FMC_BTR_DATAST_MASK (255 << FMC_BTR_DATAST_SHIFT) -# define FMC_BTR_DATAST(n) ((n-1) << FMC_BTR_DATAST_SHIFT) /* (n)xHCLK n=2..256 */ -#define FMC_BTR_BUSTURN_SHIFT (16) /* Bus turnaround phase duration */ -#define FMC_BTR_BUSTURN_MASK (15 << FMC_BTR1_BUSTURN_SHIFT) -# define FMC_BTR_BUSTURN(n) ((n-1) << FMC_BTR_BUSTURN_SHIFT) /* (n)xHCLK n=1..16 */ -#define FMC_BTR_CLKDIV_SHIFT (20) /* Clock divide ratio */ -#define FMC_BTR_CLKDIV_MASK (15 << FMC_BTR_CLKDIV_SHIFT) -# define FMC_BTR_CLKDIV(n) ((n-1) << FMC_BTR_CLKDIV_SHIFT) /* (n)xHCLK n=2..16 */ -#define FMC_BTR_DATLAT_SHIFT (24) /* Data latency */ -#define FMC_BTR_DATLAT_MASK (15 << FMC_BTR_DATLAT_SHIFT) -# define FMC_BTR_DATLAT(n) ((n-2) << FMC_BTR_DATLAT_SHIFT) /* (n)xHCLK n=2..17 */ -#define FMC_BTR_ACCMOD_SHIFT (28) /* Access mode */ -#define FMC_BTR_ACCMOD_MASK (3 << FMC_BTR_ACCMOD_SHIFT) -# define FMC_BTR_ACCMODA (0 << FMC_BTR_ACCMOD_SHIFT) -# define FMC_BTR_ACCMODB (1 << FMC_BTR_ACCMOD_SHIFT) -# define FMC_BTR_ACCMODC (2 << FMC_BTR_ACCMOD_SHIFT) -# define FMC_BTR_ACCMODD (3 << FMC_BTR_ACCMOD_SHIFT) +#define FMC_BWTR_ADDSET_SHIFT (0) /* Address setup phase duration */ +#define FMC_BWTR_ADDSET_MASK (15 << FMC_BWTR_ADDSET_SHIFT) +# define FMC_BWTR_ADDSET(n) ((n-1) << FMC_BWTR_ADDSET_SHIFT)/* (n)xHCLK n=1..16 */ +#define FMC_BWTR_ADDHLD_SHIFT (4) /* Address-hold phase duration */ +#define FMC_BWTR_ADDHLD_MASK (15 << FMC_BWTR_ADDHLD_SHIFT) +# define FMC_BWTR_ADDHLD(n) ((n-1) << FMC_BWTR_ADDHLD_SHIFT)/* (n)xHCLK n=2..16 */ +#define FMC_BWTR_DATAST_SHIFT (8) /* Data-phase duration */ +#define FMC_BWTR_DATAST_MASK (255 << FMC_BWTR_DATAST_SHIFT) +# define FMC_BWTR_DATAST(n) ((n-1) << FMC_BWTR_DATAST_SHIFT)/* (n)xHCLK n=2..256 */ +#define FMC_BWTR_CLKDIV_SHIFT (20) /* Clock divide ratio */ +#define FMC_BWTR_CLKDIV_MASK (15 << FMC_BWTR_CLKDIV_SHIFT) +# define FMC_BWTR_CLKDIV(n) ((n-1) << FMC_BWTR_CLKDIV_SHIFT)/* (n)xHCLK n=2..16 */ +#define FMC_BWTR_DATLAT_SHIFT (24) /* Data latency */ +#define FMC_BWTR_DATLAT_MASK (15 << FMC_BWTR_DATLAT_SHIFT) +# define FMC_BWTR_DATLAT(n) ((n-2) << FMC_BWTR_DATLAT_SHIFT)/* (n)xHCLK n=2..17 */ +#define FMC_BWTR_ACCMOD_SHIFT (28) /* Access mode */ +#define FMC_BWTR_ACCMOD_MASK (3 << FMC_BWTR_ACCMOD_SHIFT) +# define FMC_BWTR_ACCMODA (0 << FMC_BWTR_ACCMOD_SHIFT) +# define FMC_BWTR_ACCMODB (1 << FMC_BWTR_ACCMOD_SHIFT) +# define FMC_BWTR_ACCMODC (2 << FMC_BWTR_ACCMOD_SHIFT) +# define FMC_BWTR_ACCMODD (3 << FMC_BWTR_ACCMOD_SHIFT) -#define FMC_BTR_RSTVALUE 0xffffffff +#define FMC_PCR_RSTVALUE (0x00000018) -#define FMC_BWTR_ADDSET_SHIFT (0) /* Address setup phase duration */ -#define FMC_BWTR_ADDSET_MASK (15 << FMC_BWTR_ADDSET_SHIFT) -# define FMC_BWTR_ADDSET(n) ((n-1) << FMC_BWTR_ADDSET_SHIFT) /* (n)xHCLK n=1..16 */ -#define FMC_BWTR_ADDHLD_SHIFT (4) /* Address-hold phase duration */ -#define FMC_BWTR_ADDHLD_MASK (15 << FMC_BWTR_ADDHLD_SHIFT) -# define FMC_BWTR_ADDHLD(n) ((n-1) << FMC_BWTR_ADDHLD_SHIFT) /* (n)xHCLK n=2..16*/ -#define FMC_BWTR_DATAST_SHIFT (8) /* Data-phase duration */ -#define FMC_BWTR_DATAST_MASK (255 << FMC_BWTR_DATAST_SHIFT) -# define FMC_BWTR_DATAST(n) ((n-1) << FMC_BWTR_DATAST_SHIFT) /* (n)xHCLK n=2..256 */ -#define FMC_BWTR_CLKDIV_SHIFT (20) /* Clock divide ratio */ -#define FMC_BWTR_CLKDIV_MASK (15 << FMC_BWTR_CLKDIV_SHIFT) -# define FMC_BWTR_CLKDIV(n) ((n-1) << FMC_BWTR_CLKDIV_SHIFT) /* (n)xHCLK n=2..16 */ -#define FMC_BWTR_DATLAT_SHIFT (24) /* Data latency */ -#define FMC_BWTR_DATLAT_MASK (15 << FMC_BWTR_DATLAT_SHIFT) -# define FMC_BWTR_DATLAT(n) ((n-2) << FMC_BWTR_DATLAT_SHIFT) /* (n)xHCLK n=2..17 */ -#define FMC_BWTR_ACCMOD_SHIFT (28) /* Access mode */ -#define FMC_BWTR_ACCMOD_MASK (3 << FMC_BWTR_ACCMOD_SHIFT) -# define FMC_BWTR_ACCMODA (0 << FMC_BWTR_ACCMOD_SHIFT) -# define FMC_BWTR_ACCMODB (1 << FMC_BWTR_ACCMOD_SHIFT) -# define FMC_BWTR_ACCMODC (2 << FMC_BWTR_ACCMOD_SHIFT) -# define FMC_BWTR_ACCMODD (3 << FMC_BTR_ACCMOD_SHIFT) +#define FMC_PCR_PWAITEN (1 << 1) /* Wait feature enable bit */ +#define FMC_PCR_PBKEN (1 << 2) /* PC Card/NAND Flash memory bank enable bit */ +#define FMC_PCR_PWID_SHIFT (4) /* NAND Flash databus width */ +#define FMC_PCR_PWID_MASK (3 << FMC_PCR_PWID_SHIFT) +# define FMC_PCR_PWID8 (0 << FMC_PCR_PWID_SHIFT) +# define FMC_PCR_PWID16 (1 << FMC_PCR_PWID_SHIFT) +#define FMC_PCR_ECCEN (1 << 6) /* ECC computation logic enable bit */ +#define FMC_PCR_TCLR_SHIFT (9) /* CLE to RE delay */ +#define FMC_PCR_TCLR_MASK (15 << FMC_PCR_TCLR_SHIFT) +# define FMC_PCR_TCLR(n) ((n-1) << FMC_PCR_TCLR_SHIFT) /* (n)xHCLK n=1..16 */ +#define FMC_PCR_TAR_SHIFT (13) /* ALE to RE delay */ +#define FMC_PCR_TAR_MASK (15 << FMC_PCR_TAR_MASK) +# define FMC_PCR_TAR(n) ((n-1) << FMC_PCR_TAR_SHIFT) /* (n)xHCLK n=1..16 */ +#define FMC_PCR_ECCPS_SHIFT (17) /* ECC page size */ +#define FMC_PCR_ECCPS_MASK (7 << FMC_PCR_ECCPS_SHIFT) +# define FMC_PCR_ECCPS256 (0 << FMC_PCR_ECCPS_SHIFT) /* 256 bytes */ +# define FMC_PCR_ECCPS512 (1 << FMC_PCR_ECCPS_SHIFT) /* 512 bytes */ +# define FMC_PCR_ECCPS1024 (2 << FMC_PCR_ECCPS_SHIFT) /* 1024 bytes */ +# define FMC_PCR_ECCPS2048 (3 << FMC_PCR_ECCPS_SHIFT) /* 2048 bytes */ +# define FMC_PCR_ECCPS4096 (4 << FMC_PCR_ECCPS_SHIFT) /* 8192 bytes */ +# define FMC_PCR_ECCPS8192 (5 << FMC_PCR_ECCPS_SHIFT) /* 1024 bytes */ -#define FMC_PCR_PWAITEN (1 << 1) /* Wait feature enable bit */ -#define FMC_PCR_PBKEN (1 << 2) /* PC Card/NAND Flash memory bank enable bit */ -#define FMC_PCR_PTYP (1 << 3) /* Memory type */ -#define FMC_PCR_PWID_SHIFT (4) /* NAND Flash databus width */ -#define FMC_PCR_PWID_MASK (3 << FMC_PCR_PWID_SHIFT) -# define FMC_PCR_PWID8 (0 << FMC_PCR_PWID_SHIFT) -# define FMC_PCR_PWID16 (1 << FMC_PCR_PWID_SHIFT) -#define FMC_PCR_ECCEN (1 << 6) /* ECC computation logic enable bit */ -#define FMC_PCR_TCLR_SHIFT (9) /* CLE to RE delay */ -#define FMC_PCR_TCLR_MASK (15 << FMC_PCR_TCLR_SHIFT) -# define FMC_PCR_TCLR(n) ((n-1) << FMC_PCR_TCLR_SHIFT) /* (n)xHCLK n=1..16 */ -#define FMC_PCR_TAR_SHIFT (13) /* ALE to RE delay */ -#define FMC_PCR_TAR_MASK (15 << FMC_PCR_TAR_MASK) -# define FMC_PCR_TAR(n) ((n-1) << FMC_PCR_TAR_SHIFT) /* (n)xHCLK n=1..16 */ -#define FMC_PCR_ECCPS_SHIFT (17) /* ECC page size */ -#define FMC_PCR_ECCPS_MASK (7 << FMC_PCR_ECCPS_SHIFT) -# define FMC_PCR_ECCPS256 (0 << FMC_PCR_ECCPS_SHIFT) /* 256 bytes */ -# define FMC_PCR_ECCPS512 (1 << FMC_PCR_ECCPS_SHIFT) /* 512 bytes */ -# define FMC_PCR_ECCPS1024 (2 << FMC_PCR_ECCPS_SHIFT) /* 1024 bytes */ -# define FMC_PCR_ECCPS2048 (3 << FMC_PCR_ECCPS_SHIFT) /* 2048 bytes */ -# define FMC_PCR_ECCPS4096 (4 << FMC_PCR_ECCPS_SHIFT) /* 8192 bytes */ -# define FMC_PCR_ECCPS8192 (5 << FMC_PCR_ECCPS_SHIFT) /* 1024 bytes */ +#define FMC_SR_IRS (1 << 0) /* Interrupt Rising Edge status */ +#define FMC_SR_ILS (1 << 1) /* Interrupt Level status */ +#define FMC_SR_IFS (1 << 2) /* Interrupt Falling Edge status */ +#define FMC_SR_IREN (1 << 3) /* Interrupt Rising Edge detection Enable bit */ +#define FMC_SR_ILEN (1 << 4) /* Interrupt Level detection Enable bit */ +#define FMC_SR_IFEN (1 << 5) /* Interrupt Falling Edge detection Enable bit */ +#define FMC_SR_FEMPT (1 << 6) /* FIFO empty */ -#define FMC_SR_IRS (1 << 0) /* Interrupt Rising Edge status */ -#define FMC_SR_ILS (1 << 1) /* Interrupt Level status */ -#define FMC_SR_IFS (1 << 2) /* Interrupt Falling Edge status */ -#define FMC_SR_IREN (1 << 3) /* Interrupt Rising Edge detection Enable bit */ -#define FMC_SR_ILEN (1 << 4) /* Interrupt Level detection Enable bit */ -#define FMC_SR_IFEN (1 << 5) /* Interrupt Falling Edge detection Enable bit */ -#define FMC_SR_FEMPT (1 << 6) /* FIFO empty */ +#define FMC_PMEM_RSTVALUE (0xfcfcfcfc) -#define FMC_PMEM_MEMSET_SHIFT (0) /* Common memory setup time */ -#define FMC_PMEM_MEMSET_MASK (255 << FMC_PMEM_MEMSET_SHIFT) -# define FMC_PMEM_MEMSET(n) ((n-1) << FMC_PMEM_MEMSET_SHIFT) /* (n)xHCLK n=1..256 */ -#define FMC_PMEM_MEMWAIT_SHIFT (8) /* Common memory wait time */ -#define FMC_PMEM_MEMWAIT_MASK (255 << FMC_PMEM_MEMWAIT_SHIFT) -# define FMC_PMEM_MEMWAIT(n) ((n-1) << FMC_PMEM_MEMWAIT_SHIFT) /* (n)xHCLK n=2..256 */ -#define FMC_PMEM_MEMHOLD_SHIFT (16) /* Common memoryhold time */ -#define FMC_PMEM_MEMHOLD_MASK (255 << FMC_PMEM_MEMHOLD_SHIFT) -# define FMC_PMEM_MEMHOLD(n) ((n) << FMC_PMEM_MEMHOLD_SHIFT) /* (n)xHCLK n=1..255 */ -#define FMC_PMEM_MEMHIZ_SHIFT (24) /* Common memory databus HiZ time */ -#define FMC_PMEM_MEMHIZ_MASK (255 << FMC_PMEM_MEMHIZ_SHIFT) -# define FMC_PMEM_MEMHIZ(n) ((n) << FMC_PMEM_MEMHIZ_SHIFT) /* (n)xHCLK n=0..255 */ +#define FMC_PMEM_MEMSET_SHIFT (0) /* Common memory setup time */ +#define FMC_PMEM_MEMSET_MASK (255 << FMC_PMEM_MEMSET_SHIFT) +# define FMC_PMEM_MEMSET(n) ((n-1) << FMC_PMEM_MEMSET_SHIFT)/* (n)xHCLK n=1..256 */ +#define FMC_PMEM_MEMWAIT_SHIFT (8) /* Common memory wait time */ +#define FMC_PMEM_MEMWAIT_MASK (255 << FMC_PMEM_MEMWAIT_SHIFT) +# define FMC_PMEM_MEMWAIT(n) ((n-1)< 0) { - regval = getreg32( STM32_FMC_SDSR ) & 0x00000020; + regval = getreg32(STM32_FMC_SDSR) & 0x00000020; } + putreg32(command, STM32_FMC_SDCMR); - timeout = 0xFFFF; - regval = getreg32( STM32_FMC_SDSR ) & 0x00000020; + timeout = 0xffff; + regval = getreg32(STM32_FMC_SDSR) & 0x00000020; while ((regval != 0) && timeout-- > 0) { - regval = getreg32( STM32_FMC_SDSR ) & 0x00000020; + regval = getreg32(STM32_FMC_SDSR) & 0x00000020; } } @@ -181,7 +184,7 @@ void stm32_enablefmc(void) /* Enable AHB clocking to the FMC */ - regval = getreg32( STM32_RCC_AHB3ENR); + regval = getreg32(STM32_RCC_AHB3ENR); regval |= RCC_AHB3ENR_FMCEN; putreg32(regval, STM32_RCC_AHB3ENR); @@ -192,29 +195,29 @@ void stm32_enablefmc(void) * All timings from the datasheet for Speedgrade -6A (=6ns) */ - putreg32(FMC_SDRAM_CR_RPIPE_0 | - FMC_SDRAM_CR_BURST_READ | - FMC_SDRAM_CR_SDCLK_2X | - FMC_SDRAM_CR_CASLAT_3 | - FMC_SDRAM_CR_BANKS_4 | - FMC_SDRAM_CR_WIDTH_16 | - FMC_SDRAM_CR_ROWBITS_12 | - FMC_SDRAM_CR_COLBITS_8, + putreg32(FMC_SDCR_RPIPE_0 | + FMC_SDCR_BURST_READ | + FMC_SDCR_SDCLK_2X | + FMC_SDCR_CASLAT_3 | + FMC_SDCR_BANKS_4 | + FMC_SDCR_WIDTH_16 | + FMC_SDCR_ROWBITS_12 | + FMC_SDCR_COLBITS_8, STM32_FMC_SDCR1); - putreg32((1 << FMC_SDRAM_TR_TRCD_SHIFT) | /* tRCD min = 18ns */ - (1 << FMC_SDRAM_TR_TRP_SHIFT) | /* tRP min = 18ns */ - (1 << FMC_SDRAM_TR_TWR_SHIFT) | /* tWR = 2CLK */ - (6 << FMC_SDRAM_TR_TRC_SHIFT) | /* tRC min = 64ns */ - (4 << FMC_SDRAM_TR_TRAS_SHIFT) | /* tRAS min = 46ns */ - (7 << FMC_SDRAM_TR_TXSR_SHIFT) | /* tXSR min = 74ns */ - (1 << FMC_SDRAM_TR_TMRD_SHIFT), /* tMRD = 2CLK */ + putreg32(FMC_SDTR_TRCD(2) | /* tRCD min = 18ns */ + FMC_SDTR_TRP(2) | /* tRP min = 18ns */ + FMC_SDTR_TWR(2) | /* tWR = 2CLK */ + FMC_SDTR_TRC(7) | /* tRC min = 64ns */ + FMC_SDTR_TRAS(5) | /* tRAS min = 46ns */ + FMC_SDTR_TXSR(8) | /* tXSR min = 74ns */ + FMC_SDTR_TMRD(2), /* tMRD = 2CLK */ STM32_FMC_SDTR1); /* SDRAM Initialization sequence */ stm32_sdramcommand(STM32_SDRAM_CLKEN); /* Clock enable command */ - for (count = 0; count < 10000; count++) ; /* Delay */ + for (count = 0; count < 10000; count++) ; /* Delay */ stm32_sdramcommand(STM32_SDRAM_PALL); /* Precharge ALL command */ stm32_sdramcommand(STM32_SDRAM_REFRESH); /* Auto refresh command */ stm32_sdramcommand(STM32_SDRAM_MODEREG); /* Mode Register program */ diff --git a/boards/arm/stm32f7/stm32f769i-disco/src/Makefile b/boards/arm/stm32f7/stm32f769i-disco/src/Makefile index 6c6ebed685..702e5478a9 100644 --- a/boards/arm/stm32f7/stm32f769i-disco/src/Makefile +++ b/boards/arm/stm32f7/stm32f769i-disco/src/Makefile @@ -63,4 +63,8 @@ ifeq ($(CONFIG_SPORADIC_INSTRUMENTATION),y) CSRCS += stm32_sporadic.c endif +ifeq ($(CONFIG_STM32F7_FMC),y) +CSRCS += stm32_extmem.c +endif + include $(TOPDIR)/boards/Board.mk diff --git a/boards/arm/stm32f7/stm32f769i-disco/src/stm32_boot.c b/boards/arm/stm32f7/stm32f769i-disco/src/stm32_boot.c index 43b9305d3c..501825135a 100644 --- a/boards/arm/stm32f7/stm32f769i-disco/src/stm32_boot.c +++ b/boards/arm/stm32f7/stm32f769i-disco/src/stm32_boot.c @@ -86,7 +86,7 @@ void stm32_boardinitialize(void) #ifdef CONFIG_SPORADIC_INSTRUMENTATION /* This configuration has been used for evaluating the NuttX sporadic scheduler. - * The following caqll initializes the sporadic scheduler monitor. + * The following call initializes the sporadic scheduler monitor. */ arch_sporadic_initialize(); @@ -97,6 +97,10 @@ void stm32_boardinitialize(void) board_autoled_initialize(); #endif + +#ifdef CONFIG_STM32F7_FMC + stm32_sdram_initialize(); +#endif } /**************************************************************************** diff --git a/boards/arm/stm32f7/stm32f769i-disco/src/stm32_extmem.c b/boards/arm/stm32f7/stm32f769i-disco/src/stm32_extmem.c new file mode 100644 index 0000000000..81b7728053 --- /dev/null +++ b/boards/arm/stm32f7/stm32f769i-disco/src/stm32_extmem.c @@ -0,0 +1,322 @@ +/**************************************************************************** + * boards/arm/stm32f7/stm32f769i-disco/src/stm32_extmem.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include + +#include "chip.h" +#include "arm_arch.h" + +#include "stm32_fmc.h" +#include "stm32_gpio.h" +#include "stm32_rcc.h" +#include "stm32f769i-disco.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef CONFIG_STM32F7_FMC +# warning "FMC is not enabled" +#endif + +#if STM32F7_NGPIO < 8 +# error "Required GPIO ports not enabled" +#endif + +#define STM32_FMC_NADDRCONFIGS 25 +#define STM32_FMC_NDATACONFIGS 32 + +#define STM32_SDRAM_CLKEN FMC_SDCMR_CTB1 | FMC_SDCMR_MODE_CLK_ENABLE +#define STM32_SDRAM_PALL FMC_SDCMR_CTB1 | FMC_SDCMR_MODE_PALL +#define STM32_SDRAM_REFRESH FMC_SDCMR_CTB1 | FMC_SDCMR_MODE_AUTO_REFRESH |\ + FMC_SDCMR_NRFS(8) +#define STM32_SDRAM_MODEREG FMC_SDCMR_CTB1 | FMC_SDCMR_MODE_LOAD_MODE |\ + FMC_SDCMR_MRD_BURST_LENGTH_1 | \ + FMC_SDCMR_MRD_BURST_TYPE_SEQUENTIAL |\ + FMC_SDCMR_MRD_CAS_LATENCY_3 |\ + FMC_SDCMR_MRD_OPERATING_MODE_STANDARD |\ + FMC_SDCMR_MRD_WRITEBURST_MODE_SINGLE + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* GPIO configurations common to most external memories */ + +static const uint32_t g_addressconfig[STM32_FMC_NADDRCONFIGS] = +{ + GPIO_FMC_A0, GPIO_FMC_A1, GPIO_FMC_A2, GPIO_FMC_A3, GPIO_FMC_A4, + GPIO_FMC_A5, GPIO_FMC_A6, GPIO_FMC_A7, GPIO_FMC_A8, GPIO_FMC_A9, + GPIO_FMC_A10, GPIO_FMC_A11, GPIO_FMC_A12, + + GPIO_FMC_NBL0, GPIO_FMC_NBL1, GPIO_FMC_NBL2, GPIO_FMC_NBL3, GPIO_FMC_BA0, + GPIO_FMC_BA1, GPIO_FMC_SDNWE_3, GPIO_FMC_SDNCAS, GPIO_FMC_SDNRAS, + GPIO_FMC_SDNE0_3, GPIO_FMC_SDCKE0_3, GPIO_FMC_SDCLK +}; + +static const uint32_t g_dataconfig[STM32_FMC_NDATACONFIGS] = +{ + GPIO_FMC_D0, GPIO_FMC_D1, GPIO_FMC_D2, GPIO_FMC_D3, GPIO_FMC_D4, + GPIO_FMC_D5, GPIO_FMC_D6, GPIO_FMC_D7, GPIO_FMC_D8, GPIO_FMC_D9, + GPIO_FMC_D10, GPIO_FMC_D11, GPIO_FMC_D12, GPIO_FMC_D13, GPIO_FMC_D14, + GPIO_FMC_D15, GPIO_FMC_D16, GPIO_FMC_D17, GPIO_FMC_D18, GPIO_FMC_D19, + GPIO_FMC_D20, GPIO_FMC_D21, GPIO_FMC_D22, GPIO_FMC_D23, GPIO_FMC_D24, + GPIO_FMC_D25, GPIO_FMC_D26, GPIO_FMC_D27, GPIO_FMC_D28, GPIO_FMC_D29, + GPIO_FMC_D30, GPIO_FMC_D31 +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_fmc_sdram_wait + * + * Description: + * Wait for the SDRAM controller to be ready. + * + ****************************************************************************/ + +static void stm32_fmc_sdram_wait(void) +{ + int timeout = 0xffff; + while (timeout > 0) + { + if ((getreg32(STM32_FMC_SDSR) & FMC_SDSR_BUSY) == 0) + { + break; + } + + timeout--; + } + + DEBUGASSERT(timeout > 0); +} + +/**************************************************************************** + * Name: stm32_fmc_enable + * + * Description: + * Enable clocking to the FMC. + * + ****************************************************************************/ + +static void stm32_fmc_enable(void) +{ + modifyreg32(STM32_RCC_AHB3ENR, 0, RCC_AHB3ENR_FMCEN); +} + +/**************************************************************************** + * Name: stm32_fmc_sdram_set_refresh_rate + * + * Description: + * Set the SDRAM refresh rate. + * + ****************************************************************************/ + +static void stm32_fmc_sdram_set_refresh_rate(int count) +{ + uint32_t val; + + DEBUGASSERT(count <= 0x1fff && count >= 0x29); + + stm32_fmc_sdram_wait(); + + val = getreg32(STM32_FMC_SDRTR); + val &= ~(0x1fff << 1); /* preserve non-count bits */ + val |= (count << 1); + putreg32(val, STM32_FMC_SDRTR); +} + +/**************************************************************************** + * Name: stm32_fmc_sdram_set_timing + * + * Description: + * Set the SDRAM timing parameters. + * + ****************************************************************************/ + +static void stm32_fmc_sdram_set_timing(int bank, uint32_t timing) +{ + uint32_t val; + uint32_t sdtr; + + DEBUGASSERT((bank == 1) || (bank == 2)); + DEBUGASSERT((timing & FMC_SDTR_RESERVED) == 0); + + sdtr = (bank == 1) ? STM32_FMC_SDTR1 : STM32_FMC_SDTR2; + val = getreg32(sdtr); + val &= FMC_SDTR_RESERVED; /* preserve reserved bits */ + val |= timing; + putreg32(val, sdtr); +} + +/**************************************************************************** + * Name: stm32_fmc_sdram_set_control + * + * Description: + * Set the SDRAM control parameters. + * + ****************************************************************************/ + +static void stm32_fmc_sdram_set_control(int bank, uint32_t ctrl) +{ + uint32_t val; + uint32_t sdcr; + + DEBUGASSERT((bank == 1) || (bank == 2)); + DEBUGASSERT((ctrl & FMC_SDCR_RESERVED) == 0); + + sdcr = (bank == 1) ? STM32_FMC_SDCR1 : STM32_FMC_SDCR2; + val = getreg32(sdcr); + val &= FMC_SDCR_RESERVED; /* preserve reserved bits */ + val |= ctrl; + putreg32(val, sdcr); +} + +/**************************************************************************** + * Name: stm32_fmc_sdram_command + * + * Description: + * Send a command to the SDRAM. + * + ****************************************************************************/ + +static void stm32_fmc_sdram_command(uint32_t cmd) +{ + uint32_t val; + + DEBUGASSERT((cmd & FMC_SDCMR_RESERVED) == 0); + + /* Wait for the controller to be ready */ + + stm32_fmc_sdram_wait(); + + val = getreg32(STM32_FMC_SDCMR); + val &= FMC_SDCMR_RESERVED; /* Preserve reserved bits */ + val |= cmd; + putreg32(val, STM32_FMC_SDCMR); +} + +/**************************************************************************** + * Name: stm32_extmemgpios + * + * Description: + * Initialize GPIOs for external memory usage. + * + ****************************************************************************/ + +static void stm32_extmemgpios(const uint32_t *gpios, int ngpios) +{ + int i; + + /* Configure GPIOs */ + + for (i = 0; i < ngpios; i++) + { + stm32_configgpio(gpios[i]); + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_sdram_initialize + * + * Description: + * Called from stm32_bringup to initialize external SDRAM access. + * + ****************************************************************************/ + +void stm32_sdram_initialize(void) +{ + uint32_t val; + volatile int count; + + /* Enable GPIOs as FMC / memory pins */ + + stm32_extmemgpios(g_addressconfig, STM32_FMC_NADDRCONFIGS); + stm32_extmemgpios(g_dataconfig, STM32_FMC_NDATACONFIGS); + + /* Enable AHB clocking to the FMC */ + + stm32_fmc_enable(); + + /* Configure and enable the SDRAM bank1 + * + * FMC clock = 216MHz/2 = 108MHz + * 108MHz = 9,26 ns + * All timings from the datasheet for Speedgrade -6A (=6ns) + */ + + val = FMC_SDCR_RPIPE_0 | /* rpipe = 0 hclk */ + FMC_SDCR_BURST_READ | /* enable burst read */ + FMC_SDCR_SDCLK_2X | /* sdclk = 2 hclk */ + FMC_SDCR_CASLAT_3 | /* cas latency = 3 cycles */ + FMC_SDCR_BANKS_4 | /* 4 internal banks */ + FMC_SDCR_WIDTH_32 | /* width = 32 bits */ + FMC_SDCR_ROWBITS_12 | /* numrows = 12 bits */ + FMC_SDCR_COLBITS_8; /* numcols = 8 bits */ + stm32_fmc_sdram_set_control(1, val); + + val = FMC_SDTR_TRCD(2) | /* tRCD min = 18ns */ + FMC_SDTR_TRP(2) | /* tRP min = 18ns */ + FMC_SDTR_TWR(3) | /* tWR = 3CLK */ + FMC_SDTR_TRC(7) | /* tRC min = 64ns */ + FMC_SDTR_TRAS(4) | /* tRAS min = 37ns */ + FMC_SDTR_TXSR(7) | /* tXSR min = 64ns */ + FMC_SDTR_TMRD(2); /* tMRD = 2CLK */ + stm32_fmc_sdram_set_timing(1, val); + + /* SDRAM Initialization sequence */ + + stm32_fmc_sdram_command(STM32_SDRAM_CLKEN); /* Clock enable command */ + + for (count = 0; count < 10000; count++); /* Delay */ + + stm32_fmc_sdram_command(STM32_SDRAM_PALL); /* Precharge ALL command */ + stm32_fmc_sdram_command(STM32_SDRAM_REFRESH); /* Auto refresh command */ + stm32_fmc_sdram_command(STM32_SDRAM_MODEREG); /* Mode Register program */ + + /* Set refresh count + * + * FMC_CLK = 108MHz + * Refresh_Rate = 64ms / 4096 rows = 15.63us + * Counter = (FMC_CLK * Refresh_Rate) - 20 + */ + + stm32_fmc_sdram_set_refresh_rate(1668); +} diff --git a/boards/arm/stm32f7/stm32f769i-disco/src/stm32f769i-disco.h b/boards/arm/stm32f7/stm32f769i-disco/src/stm32f769i-disco.h index 24dbbad274..f8e98176bd 100644 --- a/boards/arm/stm32f7/stm32f769i-disco/src/stm32f769i-disco.h +++ b/boards/arm/stm32f7/stm32f769i-disco/src/stm32f769i-disco.h @@ -74,9 +74,11 @@ #define GPIO_BTN_USER (GPIO_INPUT | GPIO_FLOAT | GPIO_EXTI | GPIO_PORTA | GPIO_PIN0) -/* Sporadic scheduler instrumentation. This configuration has been used for evaluating the NuttX - * sporadic scheduler. In this evaluation, two GPIO outputs are used. One indicating the priority - * (high or low) of the sporadic thread and one indicating where the thread is running or not. +/* Sporadic scheduler instrumentation. + * This configuration has been used for evaluating the NuttX sporadic scheduler. + * In this evaluation, two GPIO outputs are used. One indicating the priority + * (high or low) of the sporadic thread and one indicating where the thread is + * running or not. * * There is nothing special about the pin selections: * @@ -157,5 +159,17 @@ void weak_function stm32_spidev_initialize(void); void arch_sporadic_initialize(void); #endif +/**************************************************************************** + * Name: stm32_sdram_initialize + * + * Description: + * Called from stm32_bringup to initialize external SDRAM access. + * + ****************************************************************************/ + +#ifdef CONFIG_STM32F7_FMC +void stm32_sdram_initialize(void); +#endif + #endif /* __ASSEMBLY__ */ #endif /* __BOARDS_ARM_STM32F7_STM32F769I_DISCO_SRC_STM32F769I_DISCO_H */