Using the Cache as RAM

The cache can be disabled temporarily or permanently and used as RAM in stead. When the cache is disabled, the device runs at reduced speed. This increases the device power consumption. If you want to use the cache as cache and temporarily disable it for extra RAM at runtime, jump ahead to the Dynamic GPRAM section. If you want to configure the cache to be used as RAM from the outset, see the Configure the Cache as GPRAM section.

Configure the Cache as GPRAM

If your application needs more memory, or if you need more space in SRAM, the cache can be re-purposed as RAM. This will allow the linker to store parts of the compiled application in this section of the RAM. This section will be referred to as the general purpose RAM (GPRAM). This will cause the program to run at a slightly reduced speed, and it will increase the device power consumption in sleep. This is because the GPRAM, contrary to a cache, will have to be powered even when the device is sleeping. The current consumption in standby mode with and without cache retained is listed in the CC13x0 datasheet.

With the cache re-purposed as RAM, the program will run at a slightly decreased speed. This will cause the device to spend more time when active, which again will give a higher power consumption. How this will affect the device power consumption will depend on application. For some applications the added power consumption will be very small, but for processing intensive application it will be slightly higher. Please verify your application current consumption by using the method described in the Measuring CC13xx and CC26xx current consumption (SWRA478).

In order to enable using the cache as RAM, two things need to be done. Firstly, the program must be told to retain the cache/GPRAM when it’s being used. Secondly, the linker must be told to allocate the memory region used as cache to GPRAM, and what parts of code to store in the GPRAM. This is done in the linker command/configuration file. The syntax for the linker command/configuration file is slightly different in CCS and IAR. To read more about the CCS linker command file, see the article Linker Command File Primer. To read more about the IAR linker, see IAR C/C++ Development Guide.

If you want to use the cache as RAM in a project, follow these steps:

Note

The steps will be different for CCS users and IAR users. The steps will also differ depending on what example project your project is based on. For the example projects found in the EasyLink folder, only step 1-5 will be required.

1. In the ccfg file, (called ccfg.c), include the following before #include <startup_files/ccfg.c>:

#ifdef CACHE_AS_RAM
  #define SET_CCFG_SIZE_AND_DIS_FLAGS_DIS_GPRAM  0x0 /* Enable GPRAM */
#endif //CACHE_AS_RAM

#include <startup_files/ccfg.c>
  1. In main(), add the following code:
Listing 29. Retain cache in sleep.
#ifdef CACHE_AS_RAM
// retain cache during standby
Power_setConstraint(PowerCC26XX_SB_VIMS_CACHE_RETAIN);
Power_setConstraint(PowerCC26XX_NEED_FLASH_IN_IDLE);
#else
// Enable iCache pre-fetching
VIMSConfigure(VIMS_BASE, TRUE, TRUE);
// Enable cache
VIMSModeSet(VIMS_BASE, VIMS_MODE_ENABLED);
#endif //CACHE_AS_RAM

Important

Please make sure your program is not using VIMS while using cache as RAM.

In the same file, include the following files:

/* Power Driver */
#include <ti/drivers/Power.h>
#include <ti/drivers/power/PowerCC26XX.h>
/* Header files required to enable instruction fetch cache */
#include <ti/devices/cc26x0r2/inc/hw_memmap.h>
#include <ti/devices/cc26x0r2/driverlib/vims.h>
  1. Go to the compiler predefines and add CACHE_AS_RAM.

Add the following to the override list:

// Override list for the fast synth settings:
// Overrides for CMD_RADIO_SETUP
uint32_t pOverrides[] =
{
 ...
 ...
 ...
#ifdef CACHE_AS_RAM
    0x00018063,
#endif //CACHE_AS_RAM
    0xFFFFFFFF,
}

Important

The override list is terminated with 0xFFFFFFFF, so you need to make sure to apply the override 0x00018063 before 0xFFFFFFFF.

4. The GPRAM memory area must be defined in the linker command file. This syntax is different for the CCS and IAR linker. IAR specific instructions will follow the CCS specific instructions.

In CCS, the linker command file ends with .cmd (e.g. cc26xx_app.cmd).

Listing 30. Under Memory Sizes, add defines for GPRAM start and length.
  /*******************************************************************************
   * Memory Sizes
   */
  #define FLASH_BASE   0x00000000
  #define GPRAM_BASE   0x11000000
  #define RAM_BASE     0x20000000
  #define ROM_BASE     0x10000000

  #if defined(CC26X0ROM) || defined(CC26X0FLASH)
  #define FLASH_SIZE 0x00020000
  #define GPRAM_SIZE 0x00002000
  #define RAM_SIZE   0x00005000
  #define ROM_SIZE   0x0001C000
  #endif /* CC26X0ROM || CC26X0FLASH */
Listing 31. Add GPRAM under Memory Definitions.
  /*******************************************************************************
   * GPRAM
   */

  #ifdef CACHE_AS_RAM
    #define GPRAM_START GPRAM_BASE
    #define GPRAM_END   (GPRAM_START + GPRAM_SIZE - 1)
  #endif /* CACHE_AS_RAM */
Listing 32. In MEMORY{}, allocate room for GPRAM.
    #ifdef CACHE_AS_RAM
      GPRAM(RWX) : origin = GPRAM_START, length = GPRAM_SIZE
    #endif /* CACHE_AS_RAM */
Listing 33. In SECTIONS{}, move .bss from SRAM to GPRAM.
  GROUP > SRAM
  {
    .data
    #ifndef CACHE_AS_RAM
    .bss
    #endif /* CACHE_AS_RAM */
    .vtable
    .vtable_ram
    vtable_ram
    .sysmem
    .nonretenvar

  } LOAD_END(heapStart)

  .stack            :   >  SRAM (HIGH) LOAD_START(heapEnd)

  #ifdef CACHE_AS_RAM
  .bss :
  {
    *(.bss)
  } > GPRAM
  #endif /* CACHE_AS_RAM */

Rebuild your application. This will move .bss from SRAM to GPRAM and place the auto-heap size start after. Other objects can also be moved. See Using the AUX RAM as RAM for an example of this.

. In IAR, the linker configuration file ends with .icf (e.g. cc26xx_app.icf).

Listing 34. Add defines for GPRAM start and length under Memory Definitions.
  //////////////////////////////////////////////////////////////////////////////
  // GPRAM
  //
  if ( isdefinedsymbol(CACHE_AS_RAM) )
  {
    define symbol GPRAM_START           = 0x11000000;
    define symbol GPRAM_SIZE            = 0x2000;
    define symbol GPRAM_END             = GPRAM_START + GPRAM_SIZE;
  }
Listing 35. Under Memory Regions, allocate room for GPRAM.
  if ( isdefinedsymbol(CACHE_AS_RAM) )
  {
    define region GPRAM               = mem:[from GPRAM_START to GPRAM_END];
  }
Listing 36. Under Memory Placement, move .bss from SRAM to GPRAM.
  if ( isdefinedsymbol(CACHE_AS_RAM) )
  {
    // GPRAM
    define block GPDATA { section .bss };
    place in GPRAM { block GPDATA } except { object ll.o };
  }

Rebuild your application. This will move .bss from SRAM to GPRAM. Other objects can also be moved. See Using the AUX RAM as RAM for an example of this.

Dynamic GPRAM

In this mode, the cache will be used as RAM only when we need it. At all other times, the cache will operate as normal. When the cache is disabled and the memory is used as RAM, the current consumption will increase as described in the Configure the Cache as GPRAM section. When the cache is not configured as RAM but runs as usual, the power consumption is not increased.

An example use-case is a device that sometimes receives or sends a data stream with a high throughput. When the device is not streaming, it can use the cache as usual. When the device receives the signal to start streaming, the device disables the cache and uses the GPRAM to store a buffer for the stream. When the device receives the command to stop streaming, the memory is freed and the cache is re-enabled.