emlib/src/em_emu.c
void EMU_RamPowerDown(uint32_t start, uint32_t end)
{
  uint32_t mask = 0;

  if (end == 0) {
    end = SRAM_BASE + SRAM_SIZE;
  }

  // Check to see if something in RAM0 can be powered down
  if (end > RAM0_END) {
#if defined(_SILICON_LABS_GECKO_INTERNAL_SDID_84) // EFM32xG12 and EFR32xG12
    // Block 0 is 16 kB and cannot be powered off
    mask |= ADDRESS_NOT_IN_BLOCK(start, 0x20004000) << 0; // Block 1, 16 kB
    mask |= ADDRESS_NOT_IN_BLOCK(start, 0x20008000) << 1; // Block 2, 16 kB
    mask |= ADDRESS_NOT_IN_BLOCK(start, 0x2000C000) << 2; // Block 3, 16 kB
    mask |= ADDRESS_NOT_IN_BLOCK(start, 0x20010000) << 3; // Block 4, 64 kB
#elif defined(_SILICON_LABS_GECKO_INTERNAL_SDID_80) // EFM32xG1 and EFR32xG1
    // Block 0 is 4 kB and cannot be powered off
    mask |= ADDRESS_NOT_IN_BLOCK(start, 0x20001000) << 0; // Block 1, 4 kB
    mask |= ADDRESS_NOT_IN_BLOCK(start, 0x20002000) << 1; // Block 2, 8 kB
    mask |= ADDRESS_NOT_IN_BLOCK(start, 0x20004000) << 2; // Block 3, 8 kB
    mask |= ADDRESS_NOT_IN_BLOCK(start, 0x20006000) << 3; // Block 4, 7 kB
#elif defined(RAM0_BLOCKS)
    // These platforms have equally sized RAM blocks
    for (int i = 1; i < RAM0_BLOCKS; i++) {
      mask |= ADDRESS_NOT_IN_BLOCK(start, RAM_MEM_BASE + (i * RAM0_BLOCK_SIZE)) << (i - 1);
    }
#endif
  }

  // Power down the selected blocks
#if defined(_EMU_MEMCTRL_MASK)
  EMU->MEMCTRL = EMU->MEMCTRL   | mask;
#elif defined(_EMU_RAM0CTRL_MASK)
  EMU->RAM0CTRL = EMU->RAM0CTRL | mask;
#else
  // These devices are unable to power down RAM blocks
  (void) mask;
  (void) start;
#endif

#if defined(RAM1_MEM_END)
  mask = 0;
  if (end > RAM1_MEM_END) {
    for (int i = 0; i < RAM1_BLOCKS; i++) {
      mask |= ADDRESS_NOT_IN_BLOCK(start, RAM1_MEM_BASE + (i * RAM1_BLOCK_SIZE)) << i;
    }
  }
  EMU->RAM1CTRL |= mask;
#endif

#if defined(RAM2_MEM_END)
  mask = 0;
  if (end > RAM2_MEM_END) {
    for (int i = 0; i < RAM2_BLOCKS; i++) {
      mask |= ADDRESS_NOT_IN_BLOCK(start, RAM2_MEM_BASE + (i * RAM2_BLOCK_SIZE)) << i;
    }
  }
  EMU->RAM2CTRL |= mask;
#endif
}
/***************************************************************************/
/**
 * @brief
 *   Power down RAM memory blocks.
 *
 * @details
 *   This function will power down all the RAM blocks that are within a given
 *   range. The RAM block layout is different between device families, so this
 *   function can be used in a generic way to power down a RAM memory region
 *   which is known to be unused.
 *
 *   This function will only power down blocks which are completely enclosed
 *   by the memory range given by [start, end).
 *
 *   Here is an example of how to power down all RAM blocks except the first
 *   one. The first RAM block is special in that it cannot be powered down
 *   by the hardware. The size of this first RAM block is device specific
 *   see the reference manual to find the RAM block sizes.
 *
 * @code
 *   EMU_RamPowerDown(SRAM_BASE, SRAM_BASE + SRAM_SIZE);
 * @endcode
 *
 * @note
 *   Only a POR reset can power up the specified memory block(s) after powerdown.
 *
 * @param[in] start
 *   The start address of the RAM region to power down. This address is
 *   inclusive.
 *
 * @param[in] end
 *   The end address of the RAM region to power down. This address is
 *   exclusive. If this parameter is 0, then all RAM blocks contained in the
 *   region from start to the upper RAM address will be powered down.
 ******************************************************************************/
@brief
Power down RAM memory blocks.

@details
This function will power down all the RAM blocks that are within a given
range. The RAM block layout is different between device families, so this
function can be used in a generic way to power down a RAM memory region
which is known to be unused.

This function will only power down blocks which are completely enclosed
by the memory range given by [start, end).

Here is an example of how to power down all RAM blocks except the first
one. The first RAM block is special in that it cannot be powered down
by the hardware. The size of this first RAM block is device specific
see the reference manual to find the RAM block sizes.



@note
Only a POR reset can power up the specified memory block(s) after powerdown.

@param[in] start
The start address of the RAM region to power down. This address is
inclusive.

@param[in] end
The end address of the RAM region to power down. This address is
exclusive. If this parameter is 0, then all RAM blocks contained in the
region from start to the upper RAM address will be powered down.
@brief Power down RAM memory blocks . @details This function will power down all the RAM blocks that are within a given range . The RAM block layout is different between device families so this function can be used in a generic way to power down a RAM memory region which is known to be unused . This function will only power down blocks which are completely enclosed by the memory range given by [ start end ) . Here is an example of how to power down all RAM blocks except the first one . The first RAM block is special in that it cannot be powered down by the hardware . The size of this first RAM block is device specific see the reference manual to find the RAM block sizes . @note Only a POR reset can power up the specified memory block ( s ) after powerdown . @param [ in ] start The start address of the RAM region to power down . This address is inclusive . @param [ in ] end The end address of the RAM region to power down . This address is exclusive . If this parameter is 0 then all RAM blocks contained in the region from start to the upper RAM address will be powered down .
void EMU_RamPowerDown(uint32_t start, uint32_t end)
{
  uint32_t mask = 0;
  if (end == 0) {
    end = SRAM_BASE + SRAM_SIZE;
  }
  if (end > RAM0_END) {
#if defined(_SILICON_LABS_GECKO_INTERNAL_SDID_84) 
    mask |= ADDRESS_NOT_IN_BLOCK(start, 0x20004000) << 0; 
    mask |= ADDRESS_NOT_IN_BLOCK(start, 0x20008000) << 1; 
    mask |= ADDRESS_NOT_IN_BLOCK(start, 0x2000C000) << 2; 
    mask |= ADDRESS_NOT_IN_BLOCK(start, 0x20010000) << 3; 
#elif defined(_SILICON_LABS_GECKO_INTERNAL_SDID_80) 
    mask |= ADDRESS_NOT_IN_BLOCK(start, 0x20001000) << 0; 
    mask |= ADDRESS_NOT_IN_BLOCK(start, 0x20002000) << 1; 
    mask |= ADDRESS_NOT_IN_BLOCK(start, 0x20004000) << 2; 
    mask |= ADDRESS_NOT_IN_BLOCK(start, 0x20006000) << 3; 
#elif defined(RAM0_BLOCKS)
    for (int i = 1; i < RAM0_BLOCKS; i++) {
      mask |= ADDRESS_NOT_IN_BLOCK(start, RAM_MEM_BASE + (i * RAM0_BLOCK_SIZE)) << (i - 1);
    }
#endif
  }
#if defined(_EMU_MEMCTRL_MASK)
  EMU->MEMCTRL = EMU->MEMCTRL   | mask;
#elif defined(_EMU_RAM0CTRL_MASK)
  EMU->RAM0CTRL = EMU->RAM0CTRL | mask;
#else
  (void) mask;
  (void) start;
#endif
#if defined(RAM1_MEM_END)
  mask = 0;
  if (end > RAM1_MEM_END) {
    for (int i = 0; i < RAM1_BLOCKS; i++) {
      mask |= ADDRESS_NOT_IN_BLOCK(start, RAM1_MEM_BASE + (i * RAM1_BLOCK_SIZE)) << i;
    }
  }
  EMU->RAM1CTRL |= mask;
#endif
#if defined(RAM2_MEM_END)
  mask = 0;
  if (end > RAM2_MEM_END) {
    for (int i = 0; i < RAM2_BLOCKS; i++) {
      mask |= ADDRESS_NOT_IN_BLOCK(start, RAM2_MEM_BASE + (i * RAM2_BLOCK_SIZE)) << i;
    }
  }
  EMU->RAM2CTRL |= mask;
#endif
}
void EMU_RamPowerDown ( uint32_t start , uint32_t end ) { uint32_t mask = 0 ; if ( end == 0 ) { end = SRAM_BASE + SRAM_SIZE ; } if ( end > RAM0_END ) { #if defined ( _SILICON_LABS_GECKO_INTERNAL_SDID_84 ) mask |= ADDRESS_NOT_IN_BLOCK ( start , 0x20004000 ) << 0 ; mask |= ADDRESS_NOT_IN_BLOCK ( start , 0x20008000 ) << 1 ; mask |= ADDRESS_NOT_IN_BLOCK ( start , 0x2000C000 ) << 2 ; mask |= ADDRESS_NOT_IN_BLOCK ( start , 0x20010000 ) << 3 ; #elif defined ( _SILICON_LABS_GECKO_INTERNAL_SDID_80 ) mask |= ADDRESS_NOT_IN_BLOCK ( start , 0x20001000 ) << 0 ; mask |= ADDRESS_NOT_IN_BLOCK ( start , 0x20002000 ) << 1 ; mask |= ADDRESS_NOT_IN_BLOCK ( start , 0x20004000 ) << 2 ; mask |= ADDRESS_NOT_IN_BLOCK ( start , 0x20006000 ) << 3 ; #elif defined ( RAM0_BLOCKS ) for ( int i = 1 ; i < RAM0_BLOCKS ; i ++ ) { mask |= ADDRESS_NOT_IN_BLOCK ( start , RAM_MEM_BASE + ( i * RAM0_BLOCK_SIZE ) ) << ( i - 1 ) ; } #endif } #if defined ( _EMU_MEMCTRL_MASK ) EMU -> MEMCTRL = EMU -> MEMCTRL | mask ; #elif defined ( _EMU_RAM0CTRL_MASK ) EMU -> RAM0CTRL = EMU -> RAM0CTRL | mask ; #else ( void ) mask ; ( void ) start ; #endif #if defined ( RAM1_MEM_END ) mask = 0 ; if ( end > RAM1_MEM_END ) { for ( int i = 0 ; i < RAM1_BLOCKS ; i ++ ) { mask |= ADDRESS_NOT_IN_BLOCK ( start , RAM1_MEM_BASE + ( i * RAM1_BLOCK_SIZE ) ) << i ; } } EMU -> RAM1CTRL |= mask ; #endif #if defined ( RAM2_MEM_END ) mask = 0 ; if ( end > RAM2_MEM_END ) { for ( int i = 0 ; i < RAM2_BLOCKS ; i ++ ) { mask |= ADDRESS_NOT_IN_BLOCK ( start , RAM2_MEM_BASE + ( i * RAM2_BLOCK_SIZE ) ) << i ; } } EMU -> RAM2CTRL |= mask ; #endif }
@brief
   Power down RAM memory blocks.
@brief Power down RAM memory blocks .
// Check to see if something in RAM0 can be powered down
 // EFM32xG12 and EFR32xG12
 // Block 0 is 16 kB and cannot be powered off
 // Block 1, 16 kB
 // Block 2, 16 kB
 // Block 3, 16 kB
 // Block 4, 64 kB
 // EFM32xG1 and EFR32xG1
 // Block 0 is 4 kB and cannot be powered off
 // Block 1, 4 kB
 // Block 2, 8 kB
 // Block 3, 8 kB
 // Block 4, 7 kB
 // These platforms have equally sized RAM blocks
 // Power down the selected blocks
 // These devices are unable to power down RAM blocks
