aboutsummaryrefslogtreecommitdiffstats
path: root/source/libmaple/api/fsmc.rst
blob: e2bf87a8ba24458f04a4c1acc2d0927023e97142 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
.. highlight:: c
.. _libmaple-fsmc:

``<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
:ref:`STM32_HAVE_FSMC <libmaple-stm32-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:: Contents
   :local:

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 (:ref:`patches welcome!
<libmaple-contributing>`). Even for use with SRAM, you will still need
to program some registers directly.

To use the FSMC with an SRAM chip, first call
:ref:`fsmc_sram_init_gpios() <libmaple-fsmc-fsmc_sram_init_gpios>` to
configure its data, address, and control lines.  Then, turn on the
FSMC clock (by calling :ref:`rcc_clk_enable(RCC_FSMC)
<libmaple-rcc-rcc_clk_enable>`). You can then configure the relevant
:ref:`fsmc_nor_psram_reg_map <libmaple-fsmc-fsmc_nor_psram_reg_map>`
``BCR`` register yourself for the SRAM chip you are using.

You can additionally use :ref:`fsmc_nor_psram_set_datast()
<libmaple-fsmc-fsmc_nor_psram_set_datast>` and
:ref:`fsmc_nor_psram_set_datast() <libmaple-fsmc-fsmc_nor_psram_set_datast>`
to control read/write timing.

Devices
-------

None at this time.

Functions
---------

.. _libmaple-fsmc-fsmc_sram_init_gpios:
.. doxygenfunction:: fsmc_sram_init_gpios
.. _libmaple-fsmc-fsmc_nor_psram_set_datast:
.. doxygenfunction:: fsmc_nor_psram_set_datast
.. _libmaple-fsmc-fsmc_nor_psram_set_addset:
.. doxygenfunction:: fsmc_nor_psram_set_addset

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``.

.. doxygendefine:: FSMC_BASE

.. doxygendefine:: FSMC_NOR_PSRAM1_BASE
.. doxygendefine:: FSMC_NOR_PSRAM2_BASE
.. doxygendefine:: FSMC_NOR_PSRAM3_BASE
.. doxygendefine:: FSMC_NOR_PSRAM4_BASE

.. doxygenstruct:: fsmc_reg_map
.. _libmaple-fsmc-fsmc_nor_psram_reg_map:
.. doxygenstruct:: fsmc_nor_psram_reg_map

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.

.. doxygendefine:: FSMC_BANK1
.. doxygendefine:: FSMC_BANK2
.. doxygendefine:: FSMC_BANK3
.. doxygendefine:: FSMC_BANK4

.. doxygendefine:: FSMC_NOR_PSRAM_REGION1
.. doxygendefine:: FSMC_NOR_PSRAM_REGION2
.. doxygendefine:: FSMC_NOR_PSRAM_REGION3
.. doxygendefine:: FSMC_NOR_PSRAM_REGION4

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