mirror of https://github.com/ARMmbed/mbed-os.git
M467: Support HyperRAM
1. For GCC, support multi-block .data/.bss initialization 2. HyperRAM is mapped to two regions: 0x0A000000 and 0x80000000 According to default system address map, 0x0A000000 is located at 'Code' region and 0x80000000 at 'RAM' region. With MPU enabled on Mbed OS, 'Code' region is write-never and 'RAM' region execute-never. 0x80000000 is chosen because 'RAM' regioin is naturally for HyperRAM. 3. Configurable multi-function pins for HBI 4. To locate code/data at external HyperRAM: - Specify __attribute__((section(".text.nu.exthyperram"))) for RO/.text/readonly section type Invoke mbed_mpu_manager_lock_ram_execution()/mbed_mpu_manager_unlock_ram_execution() to run HyperRAM code - Specify __attribute__((section(".data.nu.exthyperram"))) for RW/.data/readwrite section type - Specify __attribute__((section(".bss.nu.exthyperram"))) for ZI/.bss/zeroinit section type 5. Add readmepull/15337/head
parent
8da2e31336
commit
0494866f5f
|
@ -0,0 +1,67 @@
|
|||
# Nuvoton M460 series
|
||||
|
||||
## HyperRAM
|
||||
|
||||
HyperRAM, via Hyper Bus Interface Controller (HBI), is mapped to two regions: `0x0A00_0000`–`0x0BFF_FFFF` and `0x8000_0000`–`0x81FF_FFFF`, through which CPU can direct access.
|
||||
|
||||
### Enable HBI for HyperRAM
|
||||
|
||||
To enable HBI for HyperRAM, create one Mbed OS application configuration file named `mbed_app.json` under root directory of your sample program.
|
||||
The file should have the following content which will enable HBI and configure its multi-function pins:
|
||||
|
||||
**mbed_app.json**:
|
||||
|
||||
```json
|
||||
{
|
||||
......
|
||||
"target_overrides": {
|
||||
......
|
||||
"NUMAKER_IOT_M467": {
|
||||
"target.hbi-enable": true,
|
||||
"target.hbi-mfp-reg-list": "0x40000534, 0x4000057C, 0x40000590, 0x40000594",
|
||||
"target.hbi-mfp-reg-msk-list": "0xFFFFFF00, 0xFFFFFFFF, 0xFFFF0000, 0xFFFFFFFF",
|
||||
"target.hbi-mfp-reg-val-list": "0x10101000, 0x10101010, 0x10100000, 0x10101010"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Where:
|
||||
|
||||
- `hbi-mfp-reg-list`: Comma-separated list of relevant multi-function pin registers
|
||||
- `hbi-mfp-reg-msk-list`: Comma-separated list of relevant multi-function pin register masks
|
||||
- `hbi-mfp-reg-val-list`: Comma-separated list of relevant multi-function pin register values
|
||||
|
||||
> **_NOTE:_** Make sure your HyperRAM hardware is ready.
|
||||
|
||||
> **_NOTE:_** Change the multi-function pins to align with your hardware.
|
||||
|
||||
### Locate data at HyperRAM
|
||||
|
||||
In the port, the region `0x8000_0000`–`0x81FF_FFFF` is chosen for the goal because on Mbed OS, MPU is enabled and the region is configured to be write-able, which naturally fits HyperRAM.
|
||||
To get to the goal, data must place in specified sections:
|
||||
|
||||
**Locate initialized data**
|
||||
|
||||
Initialized data are just like `RW` sections for ARM, `.data` sectionis for GCC_ARM, and `readwrite` sections for IAR.
|
||||
To locate them at HyperRAM, place in specified sections named `.data.nu.hyperram`.
|
||||
|
||||
```c++
|
||||
__attribute__((section(".data.nu.hyperram")))
|
||||
uint32_t my_data = 100;
|
||||
```
|
||||
|
||||
**Locate zero-initialized data**
|
||||
|
||||
Zero-initialized data are just like `ZI` sections for ARM, `.bss` sections for GCC_ARM, and `zeroinit` sections for IAR.
|
||||
To locate them at HyperRAM, place in specified sections named`.bss.nu.hyperram`.
|
||||
|
||||
```c++
|
||||
__attribute__((section(".bss.nu.hyperram")))
|
||||
uint32_t my_bss;
|
||||
```
|
||||
|
||||
> **_NOTE:_** Don't mis-place in sections,
|
||||
or behavior is undefined because C runtime is not correctly initialized for these sections.
|
||||
|
||||
> **_NOTE:_** Check linker-generated .map file to make sure your data are actually located at HyperRAM.
|
|
@ -21,11 +21,19 @@
|
|||
#include "../M460_mem.h"
|
||||
|
||||
#if !defined(MBED_BOOT_STACK_SIZE)
|
||||
#define MBED_BOOT_STACK_SIZE 0x400
|
||||
#define MBED_BOOT_STACK_SIZE 0x400
|
||||
#endif
|
||||
|
||||
#define VECTOR_SIZE (4*(16 + 128))
|
||||
|
||||
#if !defined(NU_HYPERRAM_START)
|
||||
#define NU_HYPERRAM_START 0x80000000
|
||||
#endif
|
||||
|
||||
#if !defined(NU_HYPERRAM_SIZE)
|
||||
#define NU_HYPERRAM_SIZE 0x800000
|
||||
#endif
|
||||
|
||||
LR_IROM1 MBED_APP_START MBED_APP_SIZE {
|
||||
ER_IROM1 MBED_APP_START MBED_APP_SIZE { ; load address = execution address
|
||||
*(RESET, +First)
|
||||
|
@ -53,6 +61,12 @@ LR_IROM1 MBED_APP_START MBED_APP_SIZE {
|
|||
|
||||
ARM_LIB_HEAP AlignExpr(+0, 16) EMPTY (MBED_RAM_APP_START + MBED_RAM_APP_SIZE - AlignExpr(ImageLimit(RW_IRAM1), 16)) {
|
||||
}
|
||||
|
||||
NU_HYPERRAM NU_HYPERRAM_START NU_HYPERRAM_SIZE {
|
||||
*(.text.nu.hyperram)
|
||||
*(.data.nu.hyperram)
|
||||
*(.bss.nu.hyperram)
|
||||
}
|
||||
}
|
||||
|
||||
ScatterAssert(LoadLimit(LR_IROM1) <= (MBED_APP_START + MBED_APP_SIZE))
|
||||
|
|
|
@ -23,7 +23,15 @@
|
|||
#include "../M460_mem.h"
|
||||
|
||||
#if !defined(MBED_BOOT_STACK_SIZE)
|
||||
#define MBED_BOOT_STACK_SIZE 0x400
|
||||
#define MBED_BOOT_STACK_SIZE 0x400
|
||||
#endif
|
||||
|
||||
#if !defined(NU_HYPERRAM_START)
|
||||
#define NU_HYPERRAM_START 0x80000000
|
||||
#endif
|
||||
|
||||
#if !defined(NU_HYPERRAM_SIZE)
|
||||
#define NU_HYPERRAM_SIZE 0x800000
|
||||
#endif
|
||||
|
||||
M_CRASH_DATA_RAM_SIZE = 0x100;
|
||||
|
@ -34,6 +42,7 @@ MEMORY
|
|||
VECTORS (rx) : ORIGIN = MBED_APP_START, LENGTH = 0x00000400
|
||||
FLASH (rx) : ORIGIN = MBED_APP_START + 0x400, LENGTH = MBED_APP_SIZE - 0x00000400
|
||||
RAM_INTERN (rwx) : ORIGIN = MBED_RAM_APP_START, LENGTH = MBED_RAM_APP_SIZE
|
||||
HYPERRAM (rwx) : ORIGIN = NU_HYPERRAM_START, LENGTH = NU_HYPERRAM_SIZE
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -79,6 +88,52 @@ SECTIONS
|
|||
. = ALIGN(8);
|
||||
} > VECTORS
|
||||
|
||||
.copy.table : ALIGN(4)
|
||||
{
|
||||
__copy_table_start__ = .;
|
||||
|
||||
/* .data located at internal SRAM */
|
||||
LONG (LOADADDR(.data))
|
||||
LONG (ADDR(.data))
|
||||
LONG (SIZEOF(.data))
|
||||
|
||||
/* .text.nu.hyperram located at HyperRAM */
|
||||
LONG (LOADADDR(.text.nu.hyperram))
|
||||
LONG (ADDR(.text.nu.hyperram))
|
||||
LONG (SIZEOF(.text.nu.hyperram))
|
||||
|
||||
/* .data.nu.hyperram located at HyperRAM */
|
||||
LONG (LOADADDR(.data.nu.hyperram))
|
||||
LONG (ADDR(.data.nu.hyperram))
|
||||
LONG (SIZEOF(.data.nu.hyperram))
|
||||
|
||||
__copy_table_end__ = .;
|
||||
} > FLASH
|
||||
|
||||
.zero.table : ALIGN(4)
|
||||
{
|
||||
__zero_table_start__ = .;
|
||||
|
||||
/* .bss located at internal SRAM */
|
||||
LONG (ADDR(.bss))
|
||||
LONG (SIZEOF(.bss))
|
||||
|
||||
/* .bss.nu.hyperram located at HyperRAM */
|
||||
LONG (ADDR(.bss.nu.hyperram))
|
||||
LONG (SIZEOF(.bss.nu.hyperram))
|
||||
|
||||
__zero_table_end__ = .;
|
||||
} > FLASH
|
||||
|
||||
/* First match used, so place in front of .text */
|
||||
.text.nu.hyperram :
|
||||
{
|
||||
*(.text.nu.hyperram)
|
||||
} >HYPERRAM AT>FLASH
|
||||
|
||||
Image$$NU_HYPERRAM$$RO$$Base = ADDR(.text.nu.hyperram);
|
||||
Image$$NU_HYPERRAM$$RO$$Limit = ADDR(.text.nu.hyperram) + SIZEOF(.text.nu.hyperram);
|
||||
Image$$NU_HYPERRAM$$RO$$Length = SIZEOF(.text.nu.hyperram);
|
||||
|
||||
.text :
|
||||
{
|
||||
|
@ -156,7 +211,17 @@ SECTIONS
|
|||
. = ALIGN(8);
|
||||
__CRASH_DATA_RAM_END__ = .; /* Define a global symbol at data end */
|
||||
} > RAM_INTERN
|
||||
|
||||
|
||||
/* First match used, so place in front of .data */
|
||||
.data.nu.hyperram :
|
||||
{
|
||||
*(.data.nu.hyperram)
|
||||
} >HYPERRAM AT>FLASH
|
||||
|
||||
Image$$NU_HYPERRAM$$RW$$Base = ADDR(.data.nu.hyperram);
|
||||
Image$$NU_HYPERRAM$$RW$$Limit = ADDR(.data.nu.hyperram) + SIZEOF(.data.nu.hyperram);
|
||||
Image$$NU_HYPERRAM$$RW$$Length = SIZEOF(.data.nu.hyperram);
|
||||
|
||||
.data :
|
||||
{
|
||||
PROVIDE( __etext = LOADADDR(.data) );
|
||||
|
@ -205,6 +270,20 @@ SECTIONS
|
|||
__uninitialized_end = .;
|
||||
} > RAM_INTERN
|
||||
|
||||
/* First match used, so place in front of .bss */
|
||||
/* If a variable defined with __attribute__((section())) keyword the
|
||||
* variable is treated like an initialized variable. To not waste memory
|
||||
* NOLOAD attribute used here. The whole section is zero initialized by
|
||||
* adding section information to .zero.table */
|
||||
.bss.nu.hyperram (NOLOAD):
|
||||
{
|
||||
*(.bss.nu.hyperram)
|
||||
} > HYPERRAM
|
||||
|
||||
Image$$NU_HYPERRAM$$ZI$$Base = ADDR(.bss.nu.hyperram);
|
||||
Image$$NU_HYPERRAM$$ZI$$Limit = ADDR(.bss.nu.hyperram) + SIZEOF(.bss.nu.hyperram);
|
||||
Image$$NU_HYPERRAM$$ZI$$Length = SIZEOF(.bss.nu.hyperram);
|
||||
|
||||
.bss (NOLOAD):
|
||||
{
|
||||
__bss_start__ = .;
|
||||
|
@ -226,5 +305,4 @@ SECTIONS
|
|||
PROVIDE(__heap_size = SIZEOF(.heap));
|
||||
PROVIDE(__mbed_sbrk_start = ADDR(.heap));
|
||||
PROVIDE(__mbed_krbs_start = ADDR(.heap) + SIZEOF(.heap));
|
||||
|
||||
}
|
||||
|
|
|
@ -26,6 +26,14 @@ if (!isdefinedsymbol(MBED_BOOT_STACK_SIZE)) {
|
|||
define symbol MBED_BOOT_STACK_SIZE = 0x400;
|
||||
}
|
||||
|
||||
if (!isdefinedsymbol(NU_HYPERRAM_START)) {
|
||||
define symbol NU_HYPERRAM_START = 0x80000000;
|
||||
}
|
||||
|
||||
if (!isdefinedsymbol(NU_HYPERRAM_SIZE)) {
|
||||
define symbol NU_HYPERRAM_SIZE = 0x800000;
|
||||
}
|
||||
|
||||
/*-Specials-*/
|
||||
define symbol __ICFEDIT_intvec_start__ = MBED_APP_START;
|
||||
/*-Memory Regions-*/
|
||||
|
@ -35,6 +43,8 @@ define symbol __ICFEDIT_region_IRAM_start__ = MBED_RAM_APP_START;
|
|||
define symbol __ICFEDIT_region_IRAM_end__ = MBED_RAM_APP_START + MBED_RAM_APP_SIZE - 0x100 - 1;
|
||||
define symbol __region_CRASH_DATA_RAM_start__ = MBED_RAM_APP_START + MBED_RAM_APP_SIZE - 0x100;
|
||||
define symbol __region_CRASH_DATA_RAM_end__ = MBED_RAM_APP_START + MBED_RAM_APP_SIZE - 1;
|
||||
define symbol __ICFEDIT_region_HYPERRAM_start__ = NU_HYPERRAM_START;
|
||||
define symbol __ICFEDIT_region_HYPERRAM_end__ = NU_HYPERRAM_START + NU_HYPERRAM_SIZE - 1;
|
||||
/*-Sizes-*/
|
||||
define symbol __ICFEDIT_size_cstack__ = MBED_BOOT_STACK_SIZE;
|
||||
define symbol __ICFEDIT_size_intvec__ = (4 * (16 + 128));
|
||||
|
@ -46,23 +56,42 @@ define memory mem with size = 4G;
|
|||
define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
|
||||
define region IRAM_region = mem:[from __ICFEDIT_region_IRAM_start__ to __ICFEDIT_region_IRAM_end__];
|
||||
define region CRASH_DATA_RAM_region = mem:[from __region_CRASH_DATA_RAM_start__ to __region_CRASH_DATA_RAM_end__];
|
||||
define region HYPERRAM_region = mem:[from __ICFEDIT_region_HYPERRAM_start__ to __ICFEDIT_region_HYPERRAM_end__];
|
||||
|
||||
define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
|
||||
define block HEAP with expanding size, alignment = 8, minimum size = __ICFEDIT_size_heap__ { };
|
||||
/* NOTE: Vector table base requires to be aligned to the power of vector table size. Give a safe value here. */
|
||||
define block IRAMVEC with alignment = 1024, size = __ICFEDIT_size_intvec__ { };
|
||||
/* Place .text.nu.hyperram/.data.nu.hyperram/.bss.nu.hyperram together
|
||||
*
|
||||
* NOTE: Don't use wildcard like .text.nu.hyperram*. This can collide with .text.nu.hyperram*_init or
|
||||
* linker-generated initializer for .text.nu.hyperram*.
|
||||
* NOTE: Per test, 'section .data.nu.hyperram*' will cause linker-generated initializer (const)
|
||||
* also placed here, resulting in large gap, though it can get fixed with
|
||||
* 'readwrite section .data.nu.hyperram*'.
|
||||
* NOTE: With 'initialize by copy { section .text.nu.hyperram }', .text.nu.hyperram is still taken
|
||||
* as readonly (for initializer), resulting in large gap.
|
||||
* NOTE: With 'initialize manually { section .text.nu.hyperram }', .text.nu.hyperram becomes readwrite
|
||||
* .text.nu.hyperram_init is generated by linker to be readonly. We need to do the initialization
|
||||
* for .text.nu.hyperram manually.
|
||||
*/
|
||||
define block NU_HYPERRAM with alignment = 8 { section .text.nu.hyperram,
|
||||
section .data.nu.hyperram,
|
||||
section .bss.nu.hyperram };
|
||||
|
||||
/* Define Crash Data Symbols */
|
||||
define exported symbol __CRASH_DATA_RAM_START__ = __region_CRASH_DATA_RAM_start__;
|
||||
define exported symbol __CRASH_DATA_RAM_END__ = __region_CRASH_DATA_RAM_end__;
|
||||
|
||||
initialize by copy { readwrite };
|
||||
do not initialize { section .noinit };
|
||||
initialize by copy { readwrite };
|
||||
initialize manually { section .text.nu.hyperram };
|
||||
do not initialize { section .noinit };
|
||||
|
||||
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
|
||||
|
||||
place in ROM_region { readonly };
|
||||
place in ROM_region { readonly };
|
||||
place at start of IRAM_region { block CSTACK };
|
||||
place in IRAM_region { block IRAMVEC };
|
||||
place in IRAM_region { readwrite };
|
||||
place in IRAM_region { block HEAP };
|
||||
place in HYPERRAM_region { block NU_HYPERRAM };
|
||||
|
|
|
@ -16,6 +16,23 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#if defined(__GNUC__)
|
||||
|
||||
/* Get around error: conflicting type qualifiers for '__copy_table_start__'
|
||||
*
|
||||
* cmsis_gcc.h also imports the following symbols but with different type qualifier:
|
||||
*
|
||||
* __copy_table_start__
|
||||
* __copy_table_end__
|
||||
* __zero_table_start__
|
||||
* __zero_table_end__
|
||||
*
|
||||
* Define `__PROGRAM_START` to exclude __cmsis_start() in cmsis_gcc.h.
|
||||
*/
|
||||
#define __PROGRAM_START
|
||||
|
||||
#endif
|
||||
|
||||
#include "M460.h"
|
||||
|
||||
/* Suppress warning messages */
|
||||
|
@ -64,11 +81,10 @@ extern void __main(void);
|
|||
void __iar_program_start(void);
|
||||
#elif defined(__GNUC__)
|
||||
extern uint32_t __StackTop;
|
||||
extern uint32_t __etext;
|
||||
extern uint32_t __data_start__;
|
||||
extern uint32_t __data_end__;
|
||||
extern uint32_t __bss_start__;
|
||||
extern uint32_t __bss_end__;
|
||||
extern uint32_t __copy_table_start__;
|
||||
extern uint32_t __copy_table_end__;
|
||||
extern uint32_t __zero_table_start__;
|
||||
extern uint32_t __zero_table_end__;
|
||||
|
||||
#if defined(TOOLCHAIN_GCC_ARM)
|
||||
extern void _start(void);
|
||||
|
@ -466,31 +482,73 @@ void Reset_Handler_1(void)
|
|||
|
||||
void Reset_Handler_2(void)
|
||||
{
|
||||
|
||||
#if defined(__ARMCC_VERSION)
|
||||
__main();
|
||||
|
||||
#elif defined(__ICCARM__)
|
||||
__iar_program_start();
|
||||
|
||||
#elif defined(__GNUC__)
|
||||
uint32_t *src_ind = (uint32_t *) &__etext;
|
||||
uint32_t *dst_ind = (uint32_t *) &__data_start__;
|
||||
uint32_t *dst_end = (uint32_t *) &__data_end__;
|
||||
|
||||
/* Move .data section from ROM to RAM */
|
||||
if (src_ind != dst_ind) {
|
||||
for (; dst_ind < dst_end;) {
|
||||
*dst_ind ++ = *src_ind ++;
|
||||
/* With 'initialize manually { section .text.nu.hyperram }' in .icf, do the
|
||||
* initialization for .text.nu.hyperram manually.
|
||||
*
|
||||
* NOTE: C runtime not initialized yet, don't invoke memcpy() for safe. */
|
||||
{
|
||||
/* BSP not defined yet, define it */
|
||||
#pragma section=".text.nu.hyperram"
|
||||
#pragma section=".text.nu.hyperram_init"
|
||||
uint32_t *src_ind = (uint32_t *) __section_begin(".text.nu.hyperram_init");
|
||||
uint32_t *src_end = (uint32_t *) __section_end(".text.nu.hyperram_init");
|
||||
uint32_t *dst_ind = (uint32_t *) __section_begin(".text.nu.hyperram");
|
||||
if (src_ind != dst_ind) {
|
||||
for (; src_ind < src_end;) {
|
||||
*dst_ind ++ = *src_ind ++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize .bss section to zero */
|
||||
dst_ind = (uint32_t *) &__bss_start__;
|
||||
dst_end = (uint32_t *) &__bss_end__;
|
||||
if (dst_ind != dst_end) {
|
||||
for (; dst_ind < dst_end;) {
|
||||
*dst_ind ++ = 0;
|
||||
__iar_program_start();
|
||||
|
||||
#elif defined(__GNUC__)
|
||||
/* Move (multiple) .data section(s) from ROM to RAM */
|
||||
{
|
||||
/* Struct of copy table entry which must match linker script */
|
||||
typedef struct copy_table_entry_ {
|
||||
uint32_t src; // Address to copy from
|
||||
uint32_t dst; // Address to copy to
|
||||
uint32_t size; // Copy size in bytes
|
||||
} copy_table_entry;
|
||||
|
||||
copy_table_entry *copy_table_ind = (copy_table_entry *) &__copy_table_start__;
|
||||
copy_table_entry *copy_table_end = (copy_table_entry *) &__copy_table_end__;
|
||||
|
||||
for (; copy_table_ind != copy_table_end; copy_table_ind ++) {
|
||||
uint32_t *src_ind = (uint32_t *) copy_table_ind->src;
|
||||
uint32_t *src_end = (uint32_t *) (copy_table_ind->src + copy_table_ind->size);
|
||||
uint32_t *dst_ind = (uint32_t *) copy_table_ind->dst;
|
||||
if (src_ind != dst_ind) {
|
||||
for (; src_ind < src_end;) {
|
||||
*dst_ind ++ = *src_ind ++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize (multiple) .bss sections to zero */
|
||||
{
|
||||
/* Struct of zero table entry which must match linker script */
|
||||
typedef struct zero_table_entry_ {
|
||||
uint32_t start; // Address to start zero'ing
|
||||
uint32_t size; // Zero size in bytes
|
||||
} zero_table_entry;
|
||||
|
||||
zero_table_entry *zero_table_ind = (zero_table_entry *) &__zero_table_start__;
|
||||
zero_table_entry *zero_table_end = (zero_table_entry *) &__zero_table_end__;
|
||||
|
||||
for (; zero_table_ind != zero_table_end; zero_table_ind ++) {
|
||||
uint32_t *dst_ind = (uint32_t *) zero_table_ind->start;
|
||||
uint32_t *dst_end = (uint32_t *) (zero_table_ind->start + zero_table_ind->size);
|
||||
|
||||
for (; dst_ind < dst_end; ) {
|
||||
*dst_ind ++ = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -93,4 +93,98 @@ void SystemInit (void)
|
|||
/* Lock protected registers */
|
||||
SYS_LockReg();
|
||||
|
||||
#if defined(MBED_CONF_TARGET_HBI_ENABLE) && MBED_CONF_TARGET_HBI_ENABLE
|
||||
/* Initialize HBI for HyperRAM */
|
||||
void nu_hbi_init(void);
|
||||
nu_hbi_init();
|
||||
#else
|
||||
int32_t nu_hyperram_used(void);
|
||||
if (nu_hyperram_used()) {
|
||||
/* TODO: Report error: HyperRAM used but HBI not enabled */
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Detect whether or not HyperRAM is used
|
||||
*
|
||||
* NOTE: For Arm Compiler, Image$$region_name doesn't include ZI. To avoid
|
||||
* confusion, use Image$$region_name$$RO/Image$$region_name$$RW/
|
||||
* Image$$region_name$$ZI instead.
|
||||
* NOTE: Compiler e.g. Arm Compiler can optimize assuming (®ion_name$$Limit != ®ion_name$$Base) being true.
|
||||
* Change to (®ion_name$$Limit - ®ion_name$$Base) instead.
|
||||
* NOTE: Compiler e.g. GCC can optimize assuming ®ion_name$$Length being non-zero.
|
||||
* Change to (®ion_name$$Limit - ®ion_name$$Base) instead.
|
||||
*/
|
||||
#if defined(__ARMCC_VERSION) || defined(__GNUC__)
|
||||
extern uint32_t Image$$NU_HYPERRAM$$RO$$Base;
|
||||
extern uint32_t Image$$NU_HYPERRAM$$RO$$Limit;
|
||||
extern uint32_t Image$$NU_HYPERRAM$$RW$$Base;
|
||||
extern uint32_t Image$$NU_HYPERRAM$$RW$$Limit;
|
||||
extern uint32_t Image$$NU_HYPERRAM$$ZI$$Base;
|
||||
extern uint32_t Image$$NU_HYPERRAM$$ZI$$Limit;
|
||||
#define NU_HYPERRAM_USED \
|
||||
((((uint32_t) &Image$$NU_HYPERRAM$$RO$$Limit) - ((uint32_t) &Image$$NU_HYPERRAM$$RO$$Base)) || \
|
||||
(((uint32_t) &Image$$NU_HYPERRAM$$RW$$Limit) - ((uint32_t) &Image$$NU_HYPERRAM$$RW$$Base)) || \
|
||||
(((uint32_t) &Image$$NU_HYPERRAM$$ZI$$Limit) - ((uint32_t) &Image$$NU_HYPERRAM$$ZI$$Base)))
|
||||
#elif defined(__ICCARM__)
|
||||
extern uint32_t NU_HYPERRAM$$Base;
|
||||
extern uint32_t NU_HYPERRAM$$Limit;
|
||||
#define NU_HYPERRAM_USED \
|
||||
(!!(((uint32_t) &NU_HYPERRAM$$Limit) - ((uint32_t) &NU_HYPERRAM$$Base)))
|
||||
#endif
|
||||
|
||||
int32_t nu_hyperram_used(void)
|
||||
{
|
||||
return NU_HYPERRAM_USED;
|
||||
}
|
||||
|
||||
#if defined(MBED_CONF_TARGET_HBI_ENABLE) && MBED_CONF_TARGET_HBI_ENABLE
|
||||
|
||||
/* Simple array size macro without type check */
|
||||
#define _NU_ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0]))
|
||||
|
||||
void nu_hbi_init(void)
|
||||
{
|
||||
/* Configurable HBI multi-function pin
|
||||
*
|
||||
* NOTE: C runtime not initialized yet, locate at ROM region.
|
||||
*/
|
||||
static const uint32_t hbi_mfp_reg_arr[] = {
|
||||
MBED_CONF_TARGET_HBI_MFP_REG_LIST
|
||||
};
|
||||
static const uint32_t hbi_mfp_reg_msk_arr[] = {
|
||||
MBED_CONF_TARGET_HBI_MFP_REG_MSK_LIST
|
||||
};
|
||||
static const uint32_t hbi_mfp_reg_val_arr[] = {
|
||||
MBED_CONF_TARGET_HBI_MFP_REG_VAL_LIST
|
||||
};
|
||||
|
||||
/* Make sure consistent HBI multi-function pin configurations */
|
||||
_Static_assert(_NU_ARRAY_SIZE(hbi_mfp_reg_arr) == _NU_ARRAY_SIZE(hbi_mfp_reg_msk_arr),
|
||||
"Inconsistent HBI MFP register and mask list length");
|
||||
_Static_assert(_NU_ARRAY_SIZE(hbi_mfp_reg_arr) == _NU_ARRAY_SIZE(hbi_mfp_reg_val_arr),
|
||||
"Inconsistent HBI MFP register and value list length");
|
||||
|
||||
/* Unlock protected registers */
|
||||
SYS_UnlockReg();
|
||||
|
||||
/* Initialize HBI module */
|
||||
SYS_ResetModule(HBI_RST);
|
||||
|
||||
/* Enable HBI module clock */
|
||||
CLK_EnableModuleClock(HBI_MODULE);
|
||||
|
||||
/* Set HBI multi-function pins */
|
||||
const uint32_t *reg_pos = hbi_mfp_reg_arr;
|
||||
const uint32_t *reg_end = hbi_mfp_reg_arr + _NU_ARRAY_SIZE(hbi_mfp_reg_arr);
|
||||
const uint32_t *msk_pos = hbi_mfp_reg_msk_arr;
|
||||
const uint32_t *val_pos = hbi_mfp_reg_val_arr;
|
||||
for (; reg_pos != reg_end; reg_pos ++, msk_pos ++, val_pos ++) {
|
||||
M32(*reg_pos) = (M32(*reg_pos) & ~*msk_pos) | *val_pos;
|
||||
}
|
||||
|
||||
/* Lock protected registers */
|
||||
SYS_LockReg();
|
||||
}
|
||||
|
||||
#endif /* #if defined(MBED_CONF_TARGET_HBI_ENABLE) && MBED_CONF_TARGET_HBI_ENABLE */
|
||||
|
|
|
@ -7414,6 +7414,19 @@
|
|||
"gpio-irq-debounce-sample-rate": {
|
||||
"help": "Select GPIO IRQ debounce sample rate: GPIO_DBCTL_DBCLKSEL_1, GPIO_DBCTL_DBCLKSEL_2, GPIO_DBCTL_DBCLKSEL_4, ..., or GPIO_DBCTL_DBCLKSEL_32768",
|
||||
"value": "GPIO_DBCTL_DBCLKSEL_16"
|
||||
},
|
||||
"hbi-enable": {
|
||||
"help": "Enable HBI for HyperRAM",
|
||||
"options": [false, true]
|
||||
},
|
||||
"hbi-mfp-reg-list": {
|
||||
"help": "Comma separated multi-function pin register list to enable HBI for HyperRAM"
|
||||
},
|
||||
"hbi-mfp-reg-msk-list": {
|
||||
"help": "Comma separated multi-function pin register mask list to enable HBI for HyperRAM"
|
||||
},
|
||||
"hbi-mfp-reg-val-list": {
|
||||
"help": "Comma separated multi-function pin register value list to enable HBI for HyperRAM"
|
||||
}
|
||||
},
|
||||
"inherits": [
|
||||
|
@ -7501,7 +7514,11 @@
|
|||
"usb-uart": "UART_0",
|
||||
"usb-uart-tx": "PB_13",
|
||||
"usb-uart-rx": "PB_12",
|
||||
"network-default-interface-type": "WIFI"
|
||||
"network-default-interface-type": "WIFI",
|
||||
"hbi-enable": false,
|
||||
"hbi-mfp-reg-list": "0x40000534, 0x4000057C, 0x40000590, 0x40000594",
|
||||
"hbi-mfp-reg-msk-list": "0xFFFFFF00, 0xFFFFFFFF, 0xFFFF0000, 0xFFFFFFFF",
|
||||
"hbi-mfp-reg-val-list": "0x10101000, 0x10101010, 0x10100000, 0x10101010"
|
||||
}
|
||||
},
|
||||
"MCU_M480": {
|
||||
|
|
Loading…
Reference in New Issue