Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cpu/stm32/periph: add FMC/FSMC support for STM32 #19843

Merged
merged 13 commits into from
Jul 27, 2023

Conversation

gschorcht
Copy link
Contributor

@gschorcht gschorcht commented Jul 22, 2023

Contribution description

The PR provides a driver for STM32 FMC/FSMC peripherals. It supports:

  • NOR Flashes,
  • PSRAMs/SRAMs,
  • SDRAMs, and
  • Display Controllers with MCU 8-/16-bit parallel interface.

NAND Flashes are not yet supported.

To use the FMC/FSMC, the periph_fmc module has to be enabled. To keep required data structures and resulting code as small as possible, a couple of pseudomodules are defined that have to be used in addition to the periph_fmc module to enable supported features. These are:

Module Feature
periph_fmc_nor_sram enable NOR Flash and PSRAM/SRAM support
periph_fmc_sdram enable SDRAM support
periph_fmc_16bit enable 16-bit support
periph_fmc_32bit enable 32-bit support

The board has then to define

  • the corresponding features according to the connected external device,
  • the peripheral configuration of the FMC/FSMC of type fmc_conf_t,
  • the configuration of the FMC banks which describe the connected external devices.

The PR includes the support for

  • stm32f429i-disc1 with 8 MByte SDRAM
  • stm32f746g-disco with 16 MByte SDRAM
  • stm32l496g-disco with 1 MByte SRAM
  • stm32f723e-disco with 1 MByte SRAM.

To use the RAM connected to the FMC as heap, the board defines FMC_RAM_ADDR and FMC_RAM_LEN. For that purpose:

  • the linker symbols _fmc_ram_addr and _fmc_ram_len are set,
  • a memory region fcmram is added in linker script for the FMC RAM based on these _fcm_ram_* linker symbols
  • a section for the FMC RAM is defined in this memory region that defines the heap by setting _sheap3 and _eheap3 and
  • the number of heaps is set to 4 to use _sheap3 and _eheap3 even though _sheap1 and _eheap1 (the backup RAM) and _sheap2 and _eheap2 (SRAM4) are not present.

Once the drivers/st77xx and drivers/lcd changes are merged, the display for boards like
the stm32l496g-disco and stm32f723e-disco can also use the FMC peripheral.

NOTE: The PR includes the fix in PR #19842 for now (commit 560fea1).

Testing procedure

  1. Use one of the boards above and flash tests/driver/stm32_fmc, for example:

    BOARD=stm32f429i-disc1 make -j8 -C tests/drivers/stm32_fmc flash test
    

    The test should succeed.

    NOTE: There is still a problem with stm32f746g-disco. It crashes with a hard-fault on accessing the upper 8 MByte of the 16 MByte.

  2. Use the board above and flash tests/sys/malloc, for example:

    USEMODULE=periph_fmc_sdram CFLAGS='-DCHUNK_SIZE=4096 -DDEBUG_ASSERT_VERBOSE' \
    BOARD=stm32f429i-disc1 make -j8 -C tests/sys/malloc
    

    The FMC RAM should be used for malloc. On stm32f746g-disco for example

    ...
    Allocated 4096 Bytes at 0x2002d7c8, total 184672
    Allocated 4096 Bytes at 0x2002e7e0, total 188776
    Allocated 4096 Bytes at 0xd0000008, total 192880
    Allocated 4096 Bytes at 0xd0001010, total 196984
    Allocated 4096 Bytes at 0xd0002018, total 201088
    ...
    Allocated 4096 Bytes at 0xd07fd6d0, total 8544520
    Allocated 4096 Bytes at 0xd07fe6e8, total 8548624
    Allocations count: 2083
    

Issues/PRs references

Depends on PR #19842

@github-actions github-actions bot added Platform: ARM Platform: This PR/issue effects ARM-based platforms Area: doc Area: Documentation Area: tests Area: tests and testing framework Area: build system Area: Build system Area: drivers Area: Device drivers Area: tools Area: Supplementary tools Area: boards Area: Board ports Area: cpu Area: CPU/MCU ports labels Jul 22, 2023
@gschorcht gschorcht added Type: new feature The issue requests / The PR implemements a new feature for RIOT CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR labels Jul 22, 2023
@gschorcht gschorcht force-pushed the cpu/stm32/periph_fmc branch from 571abcf to db198d1 Compare July 22, 2023 15:52
@riot-ci
Copy link

riot-ci commented Jul 22, 2023

Murdock results

✔️ PASSED

6fdc6ef tests/periph/fmc: improve test app

Success Failures Total Runtime
7907 0 7907 10m:37s

Artifacts

@gschorcht gschorcht requested a review from jia200x as a code owner July 23, 2023 16:53
@github-actions github-actions bot added the Area: Kconfig Area: Kconfig integration label Jul 23, 2023
@gschorcht gschorcht added the State: waiting for other PR State: The PR requires another PR to be merged first label Jul 24, 2023
@gschorcht gschorcht force-pushed the cpu/stm32/periph_fmc branch from aeac869 to 33c8ff9 Compare July 24, 2023 07:46
@aabadie
Copy link
Contributor

aabadie commented Jul 24, 2023

From the testing procedure:

BOARD=stm32f429i-disc1 make -j8 -C tests/drivers/stm32_fmc flash test

Should the test application rather go in tests/periph/fmc since it's designed as a peripheral driver?

@aabadie
Copy link
Contributor

aabadie commented Jul 24, 2023

BTW I tested the application on stm32f723e-disco and stm32f429i-disc1 and it works (e.g. I get a SUCCESS at the end)

@gschorcht
Copy link
Contributor Author

From the testing procedure:

BOARD=stm32f429i-disc1 make -j8 -C tests/drivers/stm32_fmc flash test

Should the test application rather go in tests/periph/fmc since it's designed as a peripheral driver?

I don't have a strong preference here. I was thinking about that but I couldn't finally decide it 🤔

Comment on lines 82 to 84
ifneq (,$(filter periph_fmc_%,$(USEMODULE)))
USEMODULE += periph_fmc
endif

ifneq (,$(filter periph_fmc,$(USEMODULE)))
FEATURES_OPTIONAL += periph_fmc_16bit
FEATURES_OPTIONAL += periph_fmc_nor_sram
FEATURES_OPTIONAL += periph_fmc_sdram
endif
Copy link
Contributor

@aabadie aabadie Jul 24, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like a circular dependency resolution (periph_fmc depends on periph_fmc_sdram/nor_sram/16bit and then if periph_fmc is used, include periph_fmc_sdram/nor_sram/16bit if possible.

Why not just:

Suggested change
ifneq (,$(filter periph_fmc_%,$(USEMODULE)))
USEMODULE += periph_fmc
endif
ifneq (,$(filter periph_fmc,$(USEMODULE)))
FEATURES_OPTIONAL += periph_fmc_16bit
FEATURES_OPTIONAL += periph_fmc_nor_sram
FEATURES_OPTIONAL += periph_fmc_sdram
endif
ifneq (,$(filter periph_fmc_%,$(USEMODULE)))
FEATURES_REQUIRED += periph_fmc
endif

here, and let the user include the specific implementation. e.g in the test application use:

FEATURES_OPTIONAL += periph_fmc_16bit
FEATURES_OPTIONAL += periph_fmc_nor_sram
FEATURES_OPTIONAL += periph_fmc_sdram

Copy link
Contributor Author

@gschorcht gschorcht Jul 24, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤔 good question. In this case, I'm really not sure how to do it right. Because FMC only works if all required modules are enabled my intention was that the user cannot decide which features are used. This is decided by the defined features for the board. It would not work if the user only enabled periph_fmc for example.

I think the situation for FMC is a bit different than for periph_uart_* or periph_spi_* where additional features are enabled but the peripheral already works with the base module.

Would it be an option just to remove the circular dependency?

Suggested change
ifneq (,$(filter periph_fmc_%,$(USEMODULE)))
USEMODULE += periph_fmc
endif
ifneq (,$(filter periph_fmc,$(USEMODULE)))
FEATURES_OPTIONAL += periph_fmc_16bit
FEATURES_OPTIONAL += periph_fmc_nor_sram
FEATURES_OPTIONAL += periph_fmc_sdram
endif
ifneq (,$(filter periph_fmc,$(USEMODULE)))
FEATURES_OPTIONAL += periph_fmc_16bit
FEATURES_OPTIONAL += periph_fmc_nor_sram
FEATURES_OPTIONAL += periph_fmc_sdram
endif

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alternatively we could add in board's Makefile.dep for SDRAM for example:

ifneq (,$(filter periph_fmc,$(USEMODULE)))
  FEATURES_REQUIRED += periph_fmc_16bit
  FEATURES_REQUIRED += periph_fmc_sdram
endif

But this would require to add required features in Makefile.features and in Makefile.dep.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just do like I proposed in https://github.com/RIOT-OS/RIOT/pull/19843/files/33c8ff931ee36c0762f0d8e46fe14c7480bc3221#diff-b85e38a85615fbf0712b3a1de6006c631efbdb025ed9d8fd96d8df28f49f7656. Since periph_fmc* are defined as features, only the boards that provide these features can build the application. Using FEATURES_REQUIRED += periph_fmc in cpu/stm32/Makefile.dep does the magic. And it is important to use FEATURES_REQUIRED instead of USEMODULE.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At least the features periph_fmc_16bit and periph_fmc_32bit must not be understood as optional additional functionalities, but as mandatory functionalities in case the FMC has to operate with 16 bits and 32 bits respectively.

The periph_sdram and periph_nor_sram features, on the other hand, could indeed be considered optional to control whether the SDRAM or the SRAM is used, e.g. when FMC is used for display but the SDRAM or the SRAM should not be used 🤔

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And later when FMC will be used for display stuff, we could add:

ifneq (,$(filter disp_dev,$(USEMODULE)))
    FEATURES_REQUIRED += periph_fmc_sdram
endif

in a board Makefile.dep if it should use the sdram fmc with its display.

Copy link
Contributor

@aabadie aabadie Jul 25, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At least the features periph_fmc_16bit and periph_fmc_32bit must not be understood as optional additional functionalities, but as mandatory functionalities in case the FMC has to operate with 16 bits and 32 bits respectively.

The periph_sdram and periph_nor_sram features, on the other hand, could indeed be considered optional to control whether the SDRAM or the SRAM is used, e.g. when FMC is used for display but the SDRAM or the SRAM should not be used thinking

Hmm, ok. So maybe in the application Makefile use:

FEATURES_REQUIRED += periph_fmc
FEATURES_OPTIONAL += periph_fmc_sram
FEATURES_OPTIONAL += periph_fmc_sdram

and in the board Makefile.dep:

ifneq (,$(filter periph_fmc,$(USEMODULE)))
    FEATURES_REQUIRED += periph_fmc_16bit  # or 32bit depending on what the board is providing
endif

What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, ok. So maybe in the application Makefile use:

FEATURES_REQUIRED += periph_fmc
FEATURES_OPTIONAL += periph_fmc_sram
FEATURES_OPTIONAL += periph_fmc_sdram

and in the board Makefile.dep:

ifneq (,$(filter periph_fmc,$(USEMODULE)))
    FEATURES_REQUIRED += periph_fmc_16bit  # or 32bit depending on what the board is providing
endif

What do you think?

This is exactly like I understand the dependencies. I will try it in that way.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I made the following changes:

  • The test application is now in tests/periph/fmc.
  • periph_fmc_sdram and periph_fmc_nor_sram are enabled by FEATURES_OPTIONAL in test application.
  • periph_fmc is still enabled with USEMODULE in the test application to be consistent with CONFIG_MODULE_PERIPH_FMC=y which requires feature periph_fmc so that only boards with this feature can be compiled.
  • periph_fmc_16bit is enabled by FEATURE_REQUIRED in board Makefile.dep.
  • MODULE_PERIPH_FMC_16BIT and MODULE_PERIPH_FMC_32BIT are now hidden in Kconfig and enabled by HAVE_PERIPH_FMC_16BIT and HAVE_PERIPH_FMC_32BIT.
  • RAM is enabled as heap in tests/sys/malloc if it is compiled with USEMODULE=periph_fmc_sdram or USEMODULE=periph_fmc_nor_sram. I'm not sure whether we should add FMC as FEATURES_OPTIONAL here.
  • If SDRAM or NOR/PSRAM/SRAM is configured in board's periph_conf.h but the corresponding feature is not enabeled it is not initialized. It doesn't trigger an assertion anymore but only prints now a warning that the corresponding feature is not enabeld.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • I'm not sure whether we should add FMC as FEATURES_OPTIONAL here.

I don't know either. It could maybe increase the testing time because the heap can be much larger, so more message to print.

  • periph_fmc is still enabled with USEMODULE in the test application to be consistent with CONFIG_MODULE_PERIPH_FMC=y which requires feature periph_fmc so that only boards with this feature can be compiled.

In the Makefile, it should still be included using "FEATURES_REQUIRED += ". The features is turned into a USEMODULE automatically by the build system somewhere else. But it's important to use FEATURES_REQUIRED here so the build system is able to know what boards is supported (and it's also used by Murdock to skip the build on boards that doesn't provide this feature, I think).

@aabadie
Copy link
Contributor

aabadie commented Jul 25, 2023

From the testing procedure:

BOARD=stm32f429i-disc1 make -j8 -C tests/drivers/stm32_fmc flash test

Should the test application rather go in tests/periph/fmc since it's designed as a peripheral driver?

I don't have a strong preference here. I was thinking about that but I couldn't finally decide it thinking

Then I'd say put the application in tests/periph/fmc. This will be consistent with the STM32 ltdc peripheral driver and FMC is a peripheral after all.

@gschorcht
Copy link
Contributor Author

Then I'd say put the application in tests/periph/fmc. This will be consistent with the STM32 ltdc peripheral driver and FMC is a peripheral after all.

I will move it. I was just a bit unsure since FMC is STM32 specific like LTDC. That's why I also placed all type declaration in cpu/periph/cpu_fmc.h and not in drivers/periph/fmc.h.

@bors
Copy link
Contributor

bors bot commented Jul 26, 2023

Build failed:

@gschorcht
Copy link
Contributor Author

gschorcht commented Jul 26, 2023

I found the problem with the stm32f723e-disco board. Only 18 of the 19 address lines are connected 🙈 Therefore, only 256K x 16 bits (512 kByte) of the 1 MByte PSRAM can be used. What for a nonsense. I don't understand why ST drop the half of the RAM just to save one GPIO.

Because A18 is pulled down, tests/sys/malloc was overwriting the memory @0x00000 once it reached address space @ 0x80000.

Now it is working as expected.

If the compilation in CI fail, I will provide the fix. Otherwise I will open a very small PR.

@gschorcht
Copy link
Contributor Author

In any case, this tells me that the test app needs to be improved. Although I tried to cross-fill the memory, I did not see this problem. Probably filling the memory linearly with its addresses should deteect such addressing problems.

@gschorcht
Copy link
Contributor Author

Hm, the compilation in Murdock succeeded but the merge was blocked by bors 🤔

@gschorcht gschorcht force-pushed the cpu/stm32/periph_fmc branch from a7129eb to 3eec3ae Compare July 26, 2023 21:25
To detect misconfigurations of addresses and sizes, the whole memory is filled word-wise with it's addresses. If the content doesn't match, it prints the address and the content.
f
@gschorcht gschorcht force-pushed the cpu/stm32/periph_fmc branch from 3eec3ae to 6fdc6ef Compare July 26, 2023 21:47
@gschorcht
Copy link
Contributor Author

I found the problem with the stm32f723e-disco board. Only 18 of the 19 address lines are connected see_no_evil Therefore, only 256K x 16 bits (512 kByte) of the 1 MByte PSRAM can be used. What for a nonsense. I don't understand why ST drop the half of the RAM just to save one GPIO.

Because A18 is pulled down, tests/sys/malloc was overwriting the memory @0x00000 once it reached address space @ 0x80000.

Now it is working as expected.

If the compilation in CI fail, I will provide the fix. Otherwise I will open a very small PR.

@aabadie I took the chance of the unsuccessful bors action to provide the fix for the stm32f723e-disco board. I squashed the fix directly. It includes the following changes:

* @note A18 of the PSRAM is not used. Therefore, only 256K x 16 bits
* (512 kByte) of the 1 MByte PSRAM can be used.
.size = KiB(512), /* Size in byte, 256K x 16 bit */

I also provide in commit 3eec3ae an improvement of the test app which now actually detects address or size misconfigurations. With the previous misconfiguration of the size for the stm32f723e-disco board I get now

fill complete memory of 1024 kByte, a . represents a 16 kByte block
................................................................
ready
check memory content, a + represents one 16 kByte block of matching data
ERROR: memory content did not match @0x60000000, should be 0x60000000 but was 0x60080000

where it becomes immediately clear that the write operation to 0x60080000 actually wrote to 0x60000000.

@aabadie
Copy link
Contributor

aabadie commented Jul 27, 2023

the compilation in Murdock succeeded but the merge was blocked by bors

This is because I manually restarted the failed job from Murdock UI but apparently that doesn't work with bors...

Copy link
Contributor

@aabadie aabadie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bors merge

bors bot added a commit that referenced this pull request Jul 27, 2023
19843: cpu/stm32/periph: add FMC/FSMC support for STM32 r=aabadie a=gschorcht

### Contribution description

The PR provides a driver for STM32 FMC/FSMC peripherals. It supports:
- NOR Flashes,
- PSRAMs/SRAMs,
- SDRAMs, and
- Display Controllers with MCU 8-/16-bit parallel interface.

NAND Flashes are not yet supported.

To use the FMC/FSMC, the `periph_fmc` module has to be enabled. To keep required data structures and resulting code as small as possible, a couple of pseudomodules are defined that have to be used in addition to the `periph_fmc` module to enable supported features. These are:
 
| Module | Feature |
|:-----------------------|:----------------------------------------|
| `periph_fmc_nor_sram`  | enable NOR Flash and PSRAM/SRAM support |
| `periph_fmc_sdram`     | enable SDRAM support                    |
| `periph_fmc_16bit`     | enable 16-bit support                   |
| `periph_fmc_32bit`     | enable 32-bit support                   |

The board has then to define
- the corresponding features according to the connected external device,
- the peripheral configuration of the FMC/FSMC of type `fmc_conf_t,`
- the configuration of the FMC banks which describe the connected external devices.

The PR includes the support for
- `stm32f429i-disc1` with 8 MByte SDRAM
- `stm32f746g-disco` with 16 MByte SDRAM
- `stm32l496g-disco` with 1 MByte SRAM
- `stm32f723e-disco` with 1 MByte SRAM.

To use the RAM connected to the FMC as heap, the board defines `FMC_RAM_ADDR` and ` FMC_RAM_LEN`. For that purpose:
- the linker symbols `_fmc_ram_addr` and `_fmc_ram_len` are set,
- a memory region `fcmram` is added in linker script for the FMC RAM based on these `_fcm_ram_*` linker symbols
- a section for the FMC RAM is defined in this memory region that defines the heap by setting `_sheap3` and `_eheap3` and
- the number of heaps is set to 4 to use `_sheap3` and `_eheap3` even though `_sheap1` and `_eheap1` (the backup RAM) and `_sheap2` and `_eheap2` (SRAM4) are not present.

Once the `drivers/st77xx` and `drivers/lcd` changes are merged, the display for boards like 
the `stm32l496g-disco` and `stm32f723e-disco` can also use the FMC peripheral.

~**NOTE**: The PR includes the fix in PR #19842 for now (commit 560fea1).~

### Testing procedure

1. Use one of the boards above and flash `tests/driver/stm32_fmc`, for example:
   ```
   BOARD=stm32f429i-disc1 make -j8 -C tests/drivers/stm32_fmc flash test
   ```
   The test should succeed.
   
   **NOTE**: There is still a problem with `stm32f746g-disco`. It crashes with a hard-fault on accessing the upper 8 MByte of the 16 MByte.
   
2. Use the board above and flash `tests/sys/malloc`, for example:
   ```
   USEMODULE=periph_fmc CFLAGS='-DCHUNK_SIZE=4096 -DDEBUG_ASSERT_VERBOSE' \
   BOARD=stm32f429i-disc1 make -j8 -C tests/sys/malloc
   ```
   The FMC RAM should be used for `malloc`. On `stm32f746g-disco` for example
   ```
   ...
   Allocated 4096 Bytes at 0x2002d7c8, total 184672
   Allocated 4096 Bytes at 0x2002e7e0, total 188776
   Allocated 4096 Bytes at 0xd0000008, total 192880
   Allocated 4096 Bytes at 0xd0001010, total 196984
   Allocated 4096 Bytes at 0xd0002018, total 201088
   ...
   Allocated 4096 Bytes at 0xd07fd6d0, total 8544520
   Allocated 4096 Bytes at 0xd07fe6e8, total 8548624
   Allocations count: 2083
   ```

### Issues/PRs references

~Depends on PR #19842~

Co-authored-by: Gunar Schorcht <gunar@schorcht.net>
@gschorcht
Copy link
Contributor Author

gschorcht commented Jul 27, 2023

@aabadie Do you have a stm32f469i-disco or stm32f769i-disco board at hand? These boards use SDRAM with 32-bit data bus width and it would be interesting to test FMC with one of them.

@aabadie
Copy link
Contributor

aabadie commented Jul 27, 2023

Do you have a stm32f469i-disco or stm32f769i-disco board at hand? These boards use 32-bit data bus width and it would be interesting to test FMC with one of them.

I only have stm32f429i-disc1 and stm32f723e-disco. @vincent-d added stm32f769i-disco in #7051 maybe he has one.

@gschorcht
Copy link
Contributor Author

Ok, I will provide the FMC config for the stm32f769i-disco board in a follow-up PR and will ask @vincent-d to try it on this board.

@bors
Copy link
Contributor

bors bot commented Jul 27, 2023

Build failed:

@aabadie
Copy link
Contributor

aabadie commented Jul 27, 2023

This is very annoying. It fails randomly 80% of the time and is unrelated.

bors merge

bors bot added a commit that referenced this pull request Jul 27, 2023
19843: cpu/stm32/periph: add FMC/FSMC support for STM32 r=aabadie a=gschorcht

### Contribution description

The PR provides a driver for STM32 FMC/FSMC peripherals. It supports:
- NOR Flashes,
- PSRAMs/SRAMs,
- SDRAMs, and
- Display Controllers with MCU 8-/16-bit parallel interface.

NAND Flashes are not yet supported.

To use the FMC/FSMC, the `periph_fmc` module has to be enabled. To keep required data structures and resulting code as small as possible, a couple of pseudomodules are defined that have to be used in addition to the `periph_fmc` module to enable supported features. These are:
 
| Module | Feature |
|:-----------------------|:----------------------------------------|
| `periph_fmc_nor_sram`  | enable NOR Flash and PSRAM/SRAM support |
| `periph_fmc_sdram`     | enable SDRAM support                    |
| `periph_fmc_16bit`     | enable 16-bit support                   |
| `periph_fmc_32bit`     | enable 32-bit support                   |

The board has then to define
- the corresponding features according to the connected external device,
- the peripheral configuration of the FMC/FSMC of type `fmc_conf_t,`
- the configuration of the FMC banks which describe the connected external devices.

The PR includes the support for
- `stm32f429i-disc1` with 8 MByte SDRAM
- `stm32f746g-disco` with 16 MByte SDRAM
- `stm32l496g-disco` with 1 MByte SRAM
- `stm32f723e-disco` with 1 MByte SRAM.

To use the RAM connected to the FMC as heap, the board defines `FMC_RAM_ADDR` and ` FMC_RAM_LEN`. For that purpose:
- the linker symbols `_fmc_ram_addr` and `_fmc_ram_len` are set,
- a memory region `fcmram` is added in linker script for the FMC RAM based on these `_fcm_ram_*` linker symbols
- a section for the FMC RAM is defined in this memory region that defines the heap by setting `_sheap3` and `_eheap3` and
- the number of heaps is set to 4 to use `_sheap3` and `_eheap3` even though `_sheap1` and `_eheap1` (the backup RAM) and `_sheap2` and `_eheap2` (SRAM4) are not present.

Once the `drivers/st77xx` and `drivers/lcd` changes are merged, the display for boards like 
the `stm32l496g-disco` and `stm32f723e-disco` can also use the FMC peripheral.

~**NOTE**: The PR includes the fix in PR #19842 for now (commit 560fea1).~

### Testing procedure

1. Use one of the boards above and flash `tests/driver/stm32_fmc`, for example:
   ```
   BOARD=stm32f429i-disc1 make -j8 -C tests/drivers/stm32_fmc flash test
   ```
   The test should succeed.
   
   **NOTE**: There is still a problem with `stm32f746g-disco`. It crashes with a hard-fault on accessing the upper 8 MByte of the 16 MByte.
   
2. Use the board above and flash `tests/sys/malloc`, for example:
   ```
   USEMODULE=periph_fmc CFLAGS='-DCHUNK_SIZE=4096 -DDEBUG_ASSERT_VERBOSE' \
   BOARD=stm32f429i-disc1 make -j8 -C tests/sys/malloc
   ```
   The FMC RAM should be used for `malloc`. On `stm32f746g-disco` for example
   ```
   ...
   Allocated 4096 Bytes at 0x2002d7c8, total 184672
   Allocated 4096 Bytes at 0x2002e7e0, total 188776
   Allocated 4096 Bytes at 0xd0000008, total 192880
   Allocated 4096 Bytes at 0xd0001010, total 196984
   Allocated 4096 Bytes at 0xd0002018, total 201088
   ...
   Allocated 4096 Bytes at 0xd07fd6d0, total 8544520
   Allocated 4096 Bytes at 0xd07fe6e8, total 8548624
   Allocations count: 2083
   ```

### Issues/PRs references

~Depends on PR #19842~

Co-authored-by: Gunar Schorcht <gunar@schorcht.net>
@aabadie
Copy link
Contributor

aabadie commented Jul 27, 2023

bors cancel

@bors
Copy link
Contributor

bors bot commented Jul 27, 2023

Canceled.

@aabadie
Copy link
Contributor

aabadie commented Jul 27, 2023

bors merge

@bors
Copy link
Contributor

bors bot commented Jul 27, 2023

Build succeeded!

The publicly hosted instance of bors-ng is deprecated and will go away soon.

If you want to self-host your own instance, instructions are here.
For more help, visit the forum.

If you want to switch to GitHub's built-in merge queue, visit their help page.

@bors bors bot merged commit c4a1802 into RIOT-OS:master Jul 27, 2023
@gschorcht
Copy link
Contributor Author

gschorcht commented Jul 27, 2023

@aabadie Many thanks for your review, your patience and your valuable advises. I really appriciate it 😄

@gschorcht gschorcht deleted the cpu/stm32/periph_fmc branch July 28, 2023 13:05
@MrKevinWeiss MrKevinWeiss added this to the Release 2023.10 milestone Nov 17, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: boards Area: Board ports Area: build system Area: Build system Area: cpu Area: CPU/MCU ports Area: doc Area: Documentation Area: drivers Area: Device drivers Area: Kconfig Area: Kconfig integration Area: tests Area: tests and testing framework Area: tools Area: Supplementary tools CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Platform: ARM Platform: This PR/issue effects ARM-based platforms Type: new feature The issue requests / The PR implemements a new feature for RIOT
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants