5. Steps to achieve 48kB retention RAM¶
To use only the 48KB Block 4 + Block 3, the following changes are required:
5.1. Copy the patch table in the new address¶
Create a patch function that copies the contents of 0x07C00C0 array which is 0x80 to 0x07FD00C0. There is a patch table there in the system library
- File location:
projects/target_apps/ble_examples/ble_app_barebone/src/platform/user_periph_setup.c
void my_patch_func(void)
{
patch_func();
// Function patches start at 0x07fc00c0
memcpy((uint32_t *)0x07fd00c0, (uint32_t *)0x07fc00c0, 80);
}
Replace the patch_func
call with the my_patch_func
called in the periph_init
function
void periph_init(void) // set i2c, spi, uart, uart2 serial clks
{
// Power up peripherals' power domain
SetBits16(PMU_CTRL_REG, PERIPH_SLEEP, 0);
while (!(GetWord16(SYS_STAT_REG) & PER_IS_UP)) ;
SetBits16(CLK_16M_REG, XTAL16_BIAS_SH_ENABLE, 1);
//rom patch
my_patch_func();
//Init pads
set_pad_functions();
.....
}
5.2. Change when the interrupts are enabled¶
- File location:
sdk/platform/arch/boot/rvds/system_ARMCM0.c
- Function: SystemInit
void SystemInit (void)
{
....
//__enable_irq();
}
Note
From System Init. The vectors will not be available when this code is executed
5.3. Rebase the Hardfault and NMI Logs¶
- File location:
sdk/platform/arch/main/nmi_handler.c
from:
#define STATUS_BASE (0x07FD0050)
to:
#define STATUS_BASE (0x07FC8050)
- File location:
sdk/platform/arch/main/hardfault_handler.c
from:
#define STATUS_BASE (0x07FD0000)
to:
#define STATUS_BASE (0x07FC8000)
5.4. Rebase 0x7FD0000 at 0x00 and enable interrupts¶
- File location:
sdk/platform/arch/main/arch_main.c
Add the REMAP function and the IRQ enable as the first commands of the main function
int main(void)
{
sleep_mode_t sleep_mode;
SetBits16(SYS_CTRL_REG, REMAP_ADR0, 3);
__enable_irq();
// initialize retention mode
init_retention_mode();
....
}
5.5. Rebase the interrupt vectors¶
- File location:
sdk/platform/arch/boot/rvds/boot_vectors.s
- Create a Reset Handler area and move the reset HANDLER and the code that is executed before the
main_func
in there. - Make a different area for the reset of the Handlers.
5.6. Make all the blocks (1,2) unretainable¶
File location: src/config/da1458x_config_advanced.h
#define CFG_CUSTOM_SCATTER_FILE
#ifdef CFG_CUSTOM_SCATTER_FILE
#undef CFG_RETAIN_RAM_1_BLOCK
#undef CFG_RETAIN_RAM_2_BLOCK
#define CFG_RETAIN_RAM_3_BLOCK
#endif
5.7. Create New Scatter file¶
The Scatter file can be found at: sdk/common_project_files/scatterfiles/scatterfile_common.sct
you can refer to Figure 7.
- Create a scatterfile where
- The load area is at 0x7fc0000 and there are 2 execution areas.
- The first one (EXECUTION_BASE_1) is 0x7fd0000 and there is where you should place the interrupt vector table
- The second one (EXECUTION_BASE_2) is at 0x7fCC000 and can host more data.
- Always execute the Reset Handler, the initial Stack Heap and the system_ARMCM0 from the initial 0x7fc0000
- Change the length of the code accordingly
You can refer to Figure 10
; Definition required by da1458x_scatter_config.h
#define ARM_SCATTERFILE
#include "da1458x_config_basic.h"
#include "da1458x_config_advanced.h"
#include "da1458x_scatter_config.h"
; Macro to align val on the multiple of 4 equal or nearest higher
#define ALIGN4_HI(val) (((val)+3) AND (~3))
#if !defined(CFG_RET_DATA_SIZE)
#error "CFG_RET_DATA_SIZE is not defined!"
#endif
#if !defined(CFG_RET_DATA_UNINIT_SIZE)
#error "CFG_RET_DATA_UNINIT_SIZE is not defined!"
#endif
#define RET_MEM_BASE_ADDR ALIGN4_HI((__SCT_BLE_BASE - (CFG_RET_DATA_UNINIT_SIZE + CFG_RET_DATA_SIZE + RET_HEAP_SIZE)))
#if defined(CFG_CODE_LOCATION_OTP) && defined(CFG_CODE_LOCATION_EXT)
#error "Only one of CFG_CODE_LOCATION_OTP and CFG_CODE_LOCATION_EXT must be defined!"
#elif defined(CFG_CODE_LOCATION_OTP)
#define CODE_LOCATION_OTP 1
#define CODE_LOCATION_EXT 0
#elif defined(CFG_CODE_LOCATION_EXT)
#define CODE_LOCATION_OTP 0
#define CODE_LOCATION_EXT 1
#else
#error "One of CFG_CODE_LOCATION_OTP and CFG_CODE_LOCATION_EXT must be defined!"
#endif
#if defined (CFG_TRNG)
#define TRNG_BUFFER_AREA_SZ CFG_TRNG
#else
#define TRNG_BUFFER_AREA_SZ 0
#endif
#if CODE_LOCATION_OTP
#define CODE_AREA_BASE (0x07fc0000 + 0xC0 + 80)
#define CODE_AREA_MAX_SIZE (0xF800 - (0xC0 + 80))
#elif CODE_LOCATION_EXT
#define CODE_AREA_BASE (0x07fc0000 + 0xC0 + 80 + TRNG_BUFFER_AREA_SZ)
#define CODE_AREA_MAX_SIZE (0x16800 - (0xC0 + 80 + TRNG_BUFFER_AREA_SZ))
#endif
#define LOAD_BASE 0x07fc0000
#define LOAD_SIZE (0x000)
#define EXECUTION_BASE_1 (0x07fd0000 + 0xC0 + 80+ TRNG_BUFFER_AREA_SZ)
#define EXECUTION_SIZE_1 (0x8000-(0xC0 + 80 + TRNG_BUFFER_AREA_SZ))
#define EXECUTION_BASE_2 (0x07fCC000)
#define EXECUTION_SIZE_2 (0x4000)
LR_IROM1 0x07fc0000 0xc0 { ;
ER_IROM1 0x07fd0000 0xc0 { ; load address = execution address
*.o (RESET, +First)
}
}
LR_IROM2 0x07fc00c0 80 { ; 20 patch function slots
ER_IROM2 0x07fd00c0 EMPTY 80 { ; load address = execution address
}
}
#if CODE_LOCATION_EXT
LR_TRNG_ZI (0x07fc0000 +0xC0+80) TRNG_BUFFER_AREA_SZ {
ER_TRNG_ZI (0x07fd0000 +0xC0+80) TRNG_BUFFER_AREA_SZ {
/* The TRNG buffer area must be located lower than the 64K boundary. */
.ANY(trng_buffer_area_zi)
}
}
#endif
LR_IROM3 CODE_AREA_BASE CODE_AREA_MAX_SIZE {
ER_IROM3 CODE_AREA_BASE EXECUTION_SIZE_1 {
*(InRoot$$Sections) ; All library sections that must be in a
; root region, for example, __main.o,
; __scatter*.o, __dc*.o, and * Region$$Table
boot_vectors.o (Reset_Handler, __user_initial_stackheap)
system_ARMCM0.o (+RO)
.ANY (+RO)
.ANY (+RW)
}
ER_IROM31 EXECUTION_BASE_1 EXECUTION_SIZE_1 {
boot_vectors.o (+RO)
.ANY (+RO)
.ANY (+RW)
}
; *********************************************************************************************
; * END OF OTP - ANYTHING BELOW THIS POINT IS NOT WRITTEN WHEN THE CODE IS BURNED TO THE OTP! *
; *********************************************************************************************
ER_PRODTEST AlignExpr(+0,8) UNINIT {
.ANY (prodtest_uninit)
}
#if CODE_LOCATION_OTP
ER_TRNG_ZI +0 {
/* The TRNG buffer area must be located lower than the 64K boundary. */
/* This execution region starts at most 2K before the 64K boundary. */
.ANY(trng_buffer_area_zi, +FIRST)
}
#endif
ER_ZI +0 {
.ANY (+ZI)
.ANY (STACK)
jump_table.o (heap_mem_area_not_ret) ; not retained HEAP
}
ER_IROM32 EXECUTION_BASE_2 EXECUTION_SIZE_2 {
.ANY (+RO)
.ANY (+RW)
}
}
LR_RETAINED_RAM0 RET_MEM_BASE_ADDR {
RET_DATA_UNINIT RET_MEM_BASE_ADDR UNINIT CFG_RET_DATA_UNINIT_SIZE {
.ANY (retention_mem_area_uninit) ; uninitialized application data
}
RET_DATA +0 CFG_RET_DATA_SIZE {
.ANY (retention_mem_area0) ; zero initialized SDK + application data
}
RET_HEAP +0 RET_HEAP_SIZE {
jump_table.o (heap_env_area)
jump_table.o (heap_db_area)
jump_table.o (heap_msg_area)
}
}