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

stm32h7: support SDRAM via FMC peripherial #459

Merged
merged 2 commits into from
Mar 25, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions arch/arm/src/common/up_arch.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,12 @@
# define getreg32(a) (*(volatile uint32_t *)(a))
# define putreg32(v,a) (*(volatile uint32_t *)(a) = (v))

/* Non-atomic, but more effective modification of registers */

# define modreg8(v,m,a) putreg8((getreg8(a) & ~(m)) | ((v) & (m)), a)
# define modreg16(v,m,a) putreg16((getreg16(a) & ~(m)) | ((v) & (m)), a)
# define modreg32(v,m,a) putreg32((getreg32(a) & ~(m)) | ((v) & (m)), a)

Copy link
Contributor

Choose a reason for hiding this comment

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

Remove these. They are not used any where. This is just noice.

/****************************************************************************
* Public Function Prototypes
****************************************************************************/
Expand Down
18 changes: 7 additions & 11 deletions arch/arm/src/stm32h7/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -281,9 +281,13 @@ config STM32H7_ETHMAC
select ARCH_HAVE_PHY

config STM32H7_FMC
bool "FMC"
default n
depends on STM32H7_HAVE_FMC
bool "FMC"
default n
depends on STM32H7_HAVE_FMC
---help---
Enable Flexible Memory Controller.
To correctly configure FMC for your hardware, you will have to define
a number of macros in your board.h file. See stm32_fmc.c for directions.

config STM32H7_OTGFS
bool "OTG FS"
Expand Down Expand Up @@ -1179,14 +1183,6 @@ endif # STM32H7_RTC_LSECLOCK

endmenu # RTC Configuration

config STM32H7_EXTERNAL_RAM
bool "External RAM on FMC"
default n
depends on STM32H7_FMC
select ARCH_HAVE_HEAP2
---help---
In addition to internal SDRAM, external RAM may be available through the FMC.

menu "QuadSPI Configuration"
depends on STM32H7_QUADSPI

Expand Down
710 changes: 365 additions & 345 deletions arch/arm/src/stm32h7/hardware/stm32_fmc.h

Large diffs are not rendered by default.

1,272 changes: 638 additions & 634 deletions arch/arm/src/stm32h7/hardware/stm32h7x3xx_rcc.h

Large diffs are not rendered by default.

222 changes: 116 additions & 106 deletions arch/arm/src/stm32h7/stm32_allocateheap.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,33 +60,57 @@
#include "hardware/stm32_memorymap.h"
#include "stm32_mpuinit.h"
#include "stm32_dtcm.h"
#include "stm32_fmc.h"

/****************************************************************************
* Pre-processor Definitions
****************************************************************************/

/* Internal SRAM is available in all members of the STM32 family. The
* following definitions must be provided to specify the size and
* location of internal(system) SRAM:
/* At startup the kernel will invoke up_addregion() so that platform code
* may register available memories for use as part of system heap.
* The global configuration option CONFIG_MM_REGIONS defines the maximal
* number of non-contiguous memory ranges that may be registered with the
* system heap. You must make sure it is large enough to hold all memory
* regions you intend to use.
*
* In addition to internal SRAM, external RAM may also be available through
* the FMC. In order to use FMC RAM, the following additional things need
* to be present in the NuttX configuration file:
* The following memory types can be used for heap on STM32H7 platform:
*
* CONFIG_STM32H7_FMC=y : Enables the FMC
* CONFIG_STM32H7_FMC_S[D]RAM=y : SRAM and/or SDRAM is available via the FMC.
* Either of these autoselects
* CONFIG_ARCH_HAVE_HEAP2 which is what we
* are interested in here.
* CONFIG_HEAP2_BASE : The base address of the external RAM in
* the FMC address space
* CONFIG_HEAP2_SIZE : The size of the external RAM in the FMC
* address space
* CONFIG_MM_REGIONS : Must be set to a large enough value to
* include the FMC external RAM (as determined
* by the rules provided below)
* - AXI SRAM is a 512kb memory area. This will be automatically registered
* with the system heap in up_allocate_heap, all the other memory
* regions will be registered in up_addregion().
* So, CONFIG_MM_REGIONS must be at least 1 to use AXI SRAM.
*
* CONFIG_STM32H7_DTCMEXCLUDE : Set to exclude the DTCM from heap
* - Internal SRAM is available in all members of the STM32 family.
* This is always registered with system heap.
* There are two contiguous regions of internal SRAM:
* SRAM1+SRAM2+SRAM3 and SRAM4 at a separate address.
* So, add 2 more to CONFIG_MM_REGIONS.
*
* - Tightly Coupled Memory (TCM RAM), we can use Data TCM (DTCM) for system
* heap. Note that DTCM has a number of limitations, for example DMA
* transfers to/from DTCM are limited.
* Define CONFIG_STM32H7_DTCMEXCLUDE to exclude the DTCM from heap.
* +1 to CONFIG_MM_REGIONS if you want to use DTCM.
*
* - External SDRAM can be connected to the FMC peripherial. Initialization
* of FMC is done as up_addregion() will invoke stm32_fmc_init().
* Please read the comment in stm32_fmc.c how to initialize FMC
* correctly.
*
* Then, up to two regions of SDRAM may be registered with the heap:
*
* - BOARD_SDRAM1_SIZE, if defined, declares the size of SDRAM
* at address STM32_FMC_BANK5. +1 to CONFIG_MM_REGIONS.
* - BOARD_SDRAM2_SIZE, if defined, declares the size of SDRAM
* at address STM32_FMC_BANK6. +1 to CONFIG_MM_REGIONS.
*
* - Additionaly, you may use the following options to add one more region
* of memory to system heap:
*
* - CONFIG_ARCH_HAVE_HEAP2=y
* - CONFIG_HEAP2_BASE=base address of memory area.
* - CONFIG_HEAP2_SIZE=size of memory area.
* - +1 to CONFIG_MM_REGIONS
*/

/* Set the start and end of the SRAMs */
Expand Down Expand Up @@ -114,28 +138,6 @@
# undef HAVE_DTCM
#endif

/* There are <x> possible heap configurations:
*
* Configuration 1. System SRAM (only)
* CONFIG_MM_REGIONS == 1
* Configuration 2. System SRAM and SRAM123
* CONFIG_MM_REGIONS == 2
* Configuration 3. System SRAM and SRAM123 and DTCM
* CONFIG_MM_REGIONS == 3
* HAVE_DTCM defined
* Configuration 4. System SRAM and SRAM123 and DTCM and SRAM4
* CONFIG_MM_REGIONS == 4
* HAVE_DTCM defined
* Configuration 5. System SRAM and SRAM123 and DTCM and SRAM4 and FMC RAM
* CONFIG_MM_REGIONS == 5
* HAVE_DTCM defined
*
* TODO ....
*
* Let's make sure that all definitions are consistent before doing
* anything else
*/

/****************************************************************************
* Private Functions
****************************************************************************/
Expand Down Expand Up @@ -204,7 +206,8 @@ void up_allocate_heap(FAR void **heap_start, size_t *heap_size)
* of CONFIG_MM_KERNEL_HEAPSIZE (subject to alignment).
*/

uintptr_t ubase = (uintptr_t)USERSPACE->us_bssend + CONFIG_MM_KERNEL_HEAPSIZE;
uintptr_t ubase = (uintptr_t)USERSPACE->us_bssend +
CONFIG_MM_KERNEL_HEAPSIZE;
size_t usize = SRAM123_END - ubase;
int log2;

Expand Down Expand Up @@ -246,6 +249,10 @@ void up_allocate_heap(FAR void **heap_start, size_t *heap_size)

up_heap_color(*heap_start, *heap_size);
#endif

/* Display memory ranges to help debugging */

minfo("%uKb of SRAM at %p\n", *heap_size / 1024, *heap_start);
}

/****************************************************************************
Expand All @@ -266,7 +273,8 @@ void up_allocate_kheap(FAR void **heap_start, size_t *heap_size)
* of CONFIG_MM_KERNEL_HEAPSIZE (subject to alignment).
*/

uintptr_t ubase = (uintptr_t)USERSPACE->us_bssend + CONFIG_MM_KERNEL_HEAPSIZE;
uintptr_t ubase = (uintptr_t)USERSPACE->us_bssend +
CONFIG_MM_KERNEL_HEAPSIZE;
size_t usize = SRAM123_END - ubase;
int log2;

Expand All @@ -293,89 +301,91 @@ void up_allocate_kheap(FAR void **heap_start, size_t *heap_size)
#endif

/****************************************************************************
* Name: up_addregion
* Name: addregion
*
* Description:
* Memory may be added in non-contiguous chunks. Additional chunks are
* added by calling this function.
* Make a range of memory available for allocation from system heap.
* If debug is disabled, compiler should optimize out the "desc" strings.
*
****************************************************************************/

#if CONFIG_MM_REGIONS > 1
void up_addregion(void)
static void addregion (uintptr_t start, uint32_t size, const char *desc)
{
# if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP)

/* Allow user-mode access to the SRAM123 heap */

stm32_mpu_uheap((uintptr_t)SRAM123_START, SRAM123_END - SRAM123_START);

# endif

/* Colorize the heap for debug */

up_heap_color((FAR void *)SRAM123_START, SRAM123_END - SRAM123_START);

/* Add the SRAM123 user heap region. */

kumm_addregion((FAR void *)SRAM123_START, SRAM123_END - SRAM123_START);

# if CONFIG_MM_REGIONS > 2
# if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP)

/* Allow user-mode access to the SRAM4 user heap memory */

stm32_mpu_uheap((uintptr_t)SRAM4_START, SRAM4_END - SRAM4_START);
/* Display memory ranges to help debugging */

# endif
minfo("%uKb of %s at %p\n", size / 1024, desc, (FAR void *)start);

/* Colorize the heap for debug */

up_heap_color((FAR void *)SRAM4_START, SRAM4_END - SRAM4_START);

/* Add the external SRAM4 user heap region. */

kumm_addregion((FAR void *)SRAM4_START, SRAM4_END - SRAM4_START);
# endif

# if CONFIG_MM_REGIONS > 3
# ifdef HAVE_DTCM
# if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP)
#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP)

/* Allow user-mode access to the DTCM heap */
/* Allow user-mode access to the SRAM123 heap */

stm32_mpu_uheap((uintptr_t)DTCM_START, DTCM_END - DTCM_START);
stm32_mpu_uheap(start, size);

# endif
#endif

/* Colorize the heap for debug */

up_heap_color((FAR void *)DTCM_START, DTCM_END - DTCM_START);
up_heap_color((FAR void *)start, size);

/* Add the DTCM user heap region. */

kumm_addregion((FAR void *)DTCM_START, DTCM_END - DTCM_START);
# endif
# endif

# if CONFIG_MM_REGIONS > 4
# ifdef CONFIG_ARCH_HAVE_HEAP2
# if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP)
/* Add the SRAM123 user heap region. */

/* Allow user-mode access to the FMC RAM user heap memory */
kumm_addregion((FAR void *)start, size);
}

stm32_mpu_uheap((uintptr_t)CONFIG_HEAP2_BASE, CONFIG_HEAP2_SIZE);
/****************************************************************************
* Name: up_addregion
*
* Description:
* Memory may be added in non-contiguous chunks. Additional chunks are
* added by calling this function.
*
****************************************************************************/

# endif
void up_addregion(void)
{
addregion (SRAM123_START, SRAM123_END - SRAM123_START, "SRAM1,2,3");

unsigned mm_regions = 1;

if (mm_regions < CONFIG_MM_REGIONS)
{
addregion (SRAM4_START, SRAM4_END - SRAM4_START, "SRAM4");
mm_regions++;
}

#ifdef HAVE_DTCM
if (mm_regions < CONFIG_MM_REGIONS)
{
addregion (DTCM_START, DTCM_END - DTCM_START, "DTCM");
mm_regions++;
}
#endif

/* Colorize the heap for debug */
#ifdef CONFIG_STM32H7_FMC
stm32_fmc_init();
#endif

up_heap_color((FAR void *)CONFIG_HEAP2_BASE, CONFIG_HEAP2_SIZE);
#ifdef BOARD_SDRAM1_SIZE
if (mm_regions < CONFIG_MM_REGIONS)
{
addregion (STM32_FMC_BANK5, BOARD_SDRAM1_SIZE, "SDRAM1");
mm_regions++;
}
#endif

/* Add the external FMC RAM user heap region. */
#ifdef BOARD_SDRAM2_SIZE
if (mm_regions < CONFIG_MM_REGIONS)
{
addregion (STM32_FMC_BANK6, BOARD_SDRAM2_SIZE, "SDRAM2");
mm_regions++;
}
#endif

kumm_addregion((FAR void *)CONFIG_HEAP2_BASE, CONFIG_HEAP2_SIZE);
# endif
# endif
}
#ifdef CONFIG_ARCH_HAVE_HEAP2
if (mm_regions < CONFIG_MM_REGIONS)
{
addregion (CONFIG_HEAP2_BASE, CONFIG_HEAP2_SIZE, "HEAP2");
mm_regions++;
}
#endif
}