3. Steps to achieve 32kB retention RAM

To use only the 32KB Block 4, the following changes are required:

3.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
Code 1 Copy the patch table in the new address
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

Code 2 Replace the patch_func
      void periph_init(void)
      {
          // 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();

         .....

      }

3.2. Change when the interrupts are enabled

  • File location: sdk/platform/arch/boot/rvds/system_ARMCM0.c
  • Function: SystemInit
Code 3 SystemInit
      void SystemInit (void)
      {
      ....

        ** //__enable_irq();**
      }

Note

From System Init. The vectors will not be available when this code is executed

3.3. Rebase the Hardfault and NMI Logs

  1. File location: sdk/platform/arch/main/nmi_handler.c

from:

#define STATUS_BASE (0x07FD0050)

to:

#define STATUS_BASE (0x07FC8050)
  1. File location: sdk/platform/arch/main/hardfault_handler.c

from:

#define STATUS_BASE (0x07FD0000)

to:

#define STATUS_BASE (0x07FC8000)

3.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
Code 4 Rebase 0x7FD0000 at 0x00 and enable interrupts
      int main(void)
      {
         sleep_mode_t sleep_mode;

         SetBits16(SYS_CTRL_REG, REMAP_ADR0, 3);
         __enable_irq();
         // initialize retention mode
         init_retention_mode();
         ....
      }

3.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. You can refer to Figure 6

  • Make a different area for the reset of the Handlers:

      .......
    
    __Vectors_Size         EQU     __Vectors_End - __Vectors
    
    
    ; Reset Handler
    ; DLG Create a Reset Handler area
                    AREA    RESET_HANDLER,CODE, READONLY
    
    Reset_Handler   PROC
                    EXPORT  Reset_Handler             [WEAK]
                    IMPORT  __main
                    IMPORT  SystemInit
    
                    LDR     R0, =SystemInit
                    BLX     R0
                    LDR     R0, =__main
                    BX      R0
                    ENDP
    
                    AREA    |.text|, CODE, READONLY
    
     ......
    
_images/figure5.jpg

Figure 6 How to Create a Reset Handler area

3.6. Make all the blocks (1,2,3) 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
#undef CFG_RETAIN_RAM_3_BLOCK
#endif

3.7. Create New Scatter file

The memory map is described in the scatterfile of the Keil project. The scatterfile used in a specific project may be found in the Linker Tab of the Project options window.

_images/figure7.jpg

Figure 7 Linker Tab of project options window

The Scatter file can be found at: sdk/common_project_files/scatterfiles/scatterfile_common.sct

  • Create a scatterfile, where :
    • The load area is at 0x7FC0000 and the execution area is 0x7FD0000 and assign it to the project.
    • Move the Reset Handler, the initial Stack Heap and system_ARMCM0
    • Change the length of the code accordingly (EXECUTION_SIZE_1)

You can refer to Figure 8

 ; 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))


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)
     }



   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
    }
}

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)
    }
}
_images/figure6.jpg

Figure 8 How to change the Scatter file for 32KB Memory