<libmaple/fsmc.h>
¶
Flexible Static Memory Controller (FSMC) support. The FSMC peripheral
is only available on some targets. Including this header on a target
without an FSMC will cause a compilation error. Check your target’s
documentation to determine if it’s available. You can also use
STM32_HAVE_FSMC from
<libmaple/stm32.h>
to determine whether your target has an FSMC at
build time.
All functionality documented here is portable.
Contents
Usage Note¶
FSMC support is fairly limited at this time. Current Leaflabs boards only use the FSMC to interface with external SRAM chips, so that’s what there’s the most support for (patches welcome!). Even for use with SRAM, you will still need to program some registers directly.
To use the FSMC with an SRAM chip, first call
fsmc_sram_init_gpios() to
configure its data, address, and control lines. Then, turn on the
FSMC clock (by calling rcc_clk_enable(RCC_FSMC)). You can then configure the relevant
fsmc_nor_psram_reg_map
BCR
register yourself for the SRAM chip you are using.
You can additionally use fsmc_nor_psram_set_datast() and fsmc_nor_psram_set_datast() to control read/write timing.
Functions¶
-
void
fsmc_sram_init_gpios
(void)¶ Configure FSMC GPIOs for use with SRAM.
-
static void
fsmc_nor_psram_set_datast
(fsmc_nor_psram_reg_map *regs, uint8 datast)¶ Set the DATAST bits in the given NOR/PSRAM register map’s chip-select timing register (FSMC_BTR).
- Parameters
regs
-NOR Flash/PSRAM register map whose chip-select timing register to set.
datast
-Value to use for DATAST bits.
-
static void
fsmc_nor_psram_set_addset
(fsmc_nor_psram_reg_map *regs, uint8 addset)¶ Set the ADDHLD bits in the given NOR/PSRAM register map’s chip select timing register (FSMC_BTRx).
- Parameters
regs
-NOR Flash/PSRAM register map whose chip-select timing register to set.
addset
-Value to use for ADDSET bits.
Register Maps¶
The general purpose register map type is fsmc_reg_map
; its base
pointer is FSMC_BASE
. The fsmc_nor_psram_reg_map
type is for
use configuring the registers for an individual NOR/PSRAM region
(FSMC_BCRx
, FSMC_BTRx
, and FSMC_BWTRx
); the relevant base
pointers are FSMC_NOR_PSRAM_REGION1
through
FSMC_NOR_PSRAM_REGION4
.
-
FSMC_BASE
¶ FSMC register map base pointer.
-
FSMC_NOR_PSRAM1_BASE
¶ FSMC NOR/PSRAM base pointer 1.
-
FSMC_NOR_PSRAM2_BASE
¶ FSMC NOR/PSRAM base pointer 2.
-
FSMC_NOR_PSRAM3_BASE
¶ FSMC NOR/PSRAM base pointer 3.
-
FSMC_NOR_PSRAM4_BASE
¶ FSMC NOR/PSRAM base pointer 4.
-
struct
fsmc_reg_map
¶ FSMC register map type.
-
struct
fsmc_nor_psram_reg_map
¶ FSMC NOR/PSRAM register map type.
Memory Bank Boundary Addresses¶
Reading and writing data on an external memory chip using FSMC is done by reading and writing from addresses in special memory-mapped sections of the address space called memory banks.
This is convenient, since it implies that the usual load and store
instructions used for I/O with the internal SRAM are also used to
perform bus transactions with the external memory chip. (Which means
you can use memcpy()
etc. on external memory.)
Pointers to the memory banks’ base addresses are given by the following macros.
-
FSMC_BANK1
¶ Void pointer to base address of FSMC memory bank 1 (NOR/PSRAM).
This bank is split into 4 regions. Each region supports interfacing with 1 NOR Flash, SRAM, or PSRAM chip. The base addresses of these regions are FSMC_NOR_PSRAM_REGIONx, for x = 1, 2, 3, 4.
-
FSMC_BANK2
¶ Void pointer to base address of FSMC memory bank 2 (NAND Flash).
-
FSMC_BANK3
¶ Void pointer to base address of FSMC memory bank 3 (NAND Flash).
-
FSMC_BANK4
¶ Void pointer to base address of FSMC memory bank 4 (PC card devices).
-
FSMC_NOR_PSRAM_REGION1
¶ Void pointer to base address of FSMC memory bank 1, region 1 (NOR/PSRAM).
-
FSMC_NOR_PSRAM_REGION2
¶ Void pointer to base address of FSMC memory bank 1, region 2 (NOR/PSRAM).
-
FSMC_NOR_PSRAM_REGION3
¶ Void pointer to base address of FSMC memory bank 1, region 3 (NOR/PSRAM).
-
FSMC_NOR_PSRAM_REGION4
¶ Void pointer to base address of FSMC memory bank 1, region 4 (NOR/PSRAM).
Register Bit Definitions¶
These are given as source code.
/* NOR/PSRAM chip-select control registers */
#define FSMC_BCR_CBURSTRW_BIT 19
#define FSMC_BCR_ASYNCWAIT_BIT 15
#define FSMC_BCR_EXTMOD_BIT 14
#define FSMC_BCR_WAITEN_BIT 13
#define FSMC_BCR_WREN_BIT 12
#define FSMC_BCR_WAITCFG_BIT 11
#define FSMC_BCR_WRAPMOD_BIT 10
#define FSMC_BCR_WAITPOL_BIT 9
#define FSMC_BCR_BURSTEN_BIT 8
#define FSMC_BCR_FACCEN_BIT 6
#define FSMC_BCR_MUXEN_BIT 1
#define FSMC_BCR_MBKEN_BIT 0
#define FSMC_BCR_CBURSTRW (1U << FSMC_BCR_CBURSTRW_BIT)
#define FSMC_BCR_ASYNCWAIT (1U << FSMC_BCR_ASYNCWAIT_BIT)
#define FSMC_BCR_EXTMOD (1U << FSMC_BCR_EXTMOD_BIT)
#define FSMC_BCR_WAITEN (1U << FSMC_BCR_WAITEN_BIT)
#define FSMC_BCR_WREN (1U << FSMC_BCR_WREN_BIT)
#define FSMC_BCR_WAITCFG (1U << FSMC_BCR_WAITCFG_BIT)
#define FSMC_BCR_WRAPMOD (1U << FSMC_BCR_WRAPMOD_BIT)
#define FSMC_BCR_WAITPOL (1U << FSMC_BCR_WAITPOL_BIT)
#define FSMC_BCR_BURSTEN (1U << FSMC_BCR_BURSTEN_BIT)
#define FSMC_BCR_FACCEN (1U << FSMC_BCR_FACCEN_BIT)
#define FSMC_BCR_MWID (0x3 << 4)
#define FSMC_BCR_MWID_8BITS (0x0 << 4)
#define FSMC_BCR_MWID_16BITS (0x1 << 4)
#define FSMC_BCR_MTYP (0x3 << 2)
#define FSMC_BCR_MTYP_SRAM (0x0 << 2)
#define FSMC_BCR_MTYP_PSRAM (0x1 << 2)
#define FSMC_BCR_MTYP_NOR_FLASH (0x2 << 2)
#define FSMC_BCR_MUXEN (1U << FSMC_BCR_MUXEN_BIT)
#define FSMC_BCR_MBKEN (1U << FSMC_BCR_MBKEN_BIT)
/* SRAM/NOR-Flash chip-select timing registers */
#define FSMC_BTR_ACCMOD (0x3 << 28)
#define FSMC_BTR_ACCMOD_A (0x0 << 28)
#define FSMC_BTR_ACCMOD_B (0x1 << 28)
#define FSMC_BTR_ACCMOD_C (0x2 << 28)
#define FSMC_BTR_ACCMOD_D (0x3 << 28)
#define FSMC_BTR_DATLAT (0xF << 24)
#define FSMC_BTR_CLKDIV (0xF << 20)
#define FSMC_BTR_BUSTURN (0xF << 16)
#define FSMC_BTR_DATAST (0xFF << 8)
#define FSMC_BTR_ADDHLD (0xF << 4)
#define FSMC_BTR_ADDSET 0xF
/* SRAM/NOR-Flash write timing registers */
#define FSMC_BWTR_ACCMOD (0x3 << 28)
#define FSMC_BWTR_ACCMOD_A (0x0 << 28)
#define FSMC_BWTR_ACCMOD_B (0x1 << 28)
#define FSMC_BWTR_ACCMOD_C (0x2 << 28)
#define FSMC_BWTR_ACCMOD_D (0x3 << 28)
#define FSMC_BWTR_DATLAT (0xF << 24)
#define FSMC_BWTR_CLKDIV (0xF << 20)
#define FSMC_BWTR_DATAST (0xFF << 8)
#define FSMC_BWTR_ADDHLD (0xF << 4)
#define FSMC_BWTR_ADDSET 0xF
/* NAND Flash/PC Card controller registers */
#define FSMC_PCR_ECCEN_BIT 6
#define FSMC_PCR_PTYP_BIT 3
#define FSMC_PCR_PBKEN_BIT 2
#define FSMC_PCR_PWAITEN_BIT 1
#define FSMC_PCR_ECCPS (0x7 << 17)
#define FSMC_PCR_ECCPS_256B (0x0 << 17)
#define FSMC_PCR_ECCPS_512B (0x1 << 17)
#define FSMC_PCR_ECCPS_1024B (0x2 << 17)
#define FSMC_PCR_ECCPS_2048B (0x3 << 17)
#define FSMC_PCR_ECCPS_4096B (0x4 << 17)
#define FSMC_PCR_ECCPS_8192B (0x5 << 17)
#define FSMC_PCR_TAR (0xF << 13)
#define FSMC_PCR_TCLR (0xF << 9)
#define FSMC_PCR_ECCEN (1U << FSMC_PCR_ECCEN_BIT)
#define FSMC_PCR_PWID (0x3 << 4)
#define FSMC_PCR_PWID_8BITS (0x0 << 4)
#define FSMC_PCR_PWID_16BITS (0x1 << 4)
#define FSMC_PCR_PTYP (1U << FSMC_PCR_PTYP_BIT)
#define FSMC_PCR_PTYP_PC_CF_PCMCIA (0x0 << FSMC_PCR_PTYP_BIT)
#define FSMC_PCR_PTYP_NAND (0x1 << FSMC_PCR_PTYP_BIT)
#define FSMC_PCR_PBKEN (1U << FSMC_PCR_PBKEN_BIT)
#define FSMC_PCR_PWAITEN (1U << FSMC_PCR_PWAITEN_BIT)
/* FIFO status and interrupt registers */
#define FSMC_SR_FEMPT_BIT 6
#define FSMC_SR_IFEN_BIT 5
#define FSMC_SR_ILEN_BIT 4
#define FSMC_SR_IREN_BIT 3
#define FSMC_SR_IFS_BIT 2
#define FSMC_SR_ILS_BIT 1
#define FSMC_SR_IRS_BIT 0
#define FSMC_SR_FEMPT (1U << FSMC_SR_FEMPT_BIT)
#define FSMC_SR_IFEN (1U << FSMC_SR_IFEN_BIT)
#define FSMC_SR_ILEN (1U << FSMC_SR_ILEN_BIT)
#define FSMC_SR_IREN (1U << FSMC_SR_IREN_BIT)
#define FSMC_SR_IFS (1U << FSMC_SR_IFS_BIT)
#define FSMC_SR_ILS (1U << FSMC_SR_ILS_BIT)
#define FSMC_SR_IRS (1U << FSMC_SR_IRS_BIT)
/* Common memory space timing registers */
#define FSMC_PMEM_MEMHIZ (0xFF << 24)
#define FSMC_PMEM_MEMHOLD (0xFF << 16)
#define FSMC_PMEM_MEMWAIT (0xFF << 8)
#define FSMC_PMEM_MEMSET 0xFF
/* Attribute memory space timing registers */
#define FSMC_PATT_ATTHIZ (0xFF << 24)
#define FSMC_PATT_ATTHOLD (0xFF << 16)
#define FSMC_PATT_ATTWAIT (0xFF << 8)
#define FSMC_PATT_ATTSET 0xFF
/* I/O space timing register 4 */
#define FSMC_PIO_IOHIZ (0xFF << 24)
#define FSMC_PIO_IOHOLD (0xFF << 16)
#define FSMC_PIO_IOWAIT (0xFF << 8)
#define FSMC_PIO_IOSET 0xF