diff options
Diffstat (limited to 'bsps/arm/atsam/contrib/libraries/libboard/source/board_lowlevel.c')
-rw-r--r-- | bsps/arm/atsam/contrib/libraries/libboard/source/board_lowlevel.c | 434 |
1 files changed, 434 insertions, 0 deletions
diff --git a/bsps/arm/atsam/contrib/libraries/libboard/source/board_lowlevel.c b/bsps/arm/atsam/contrib/libraries/libboard/source/board_lowlevel.c new file mode 100644 index 0000000000..cbdf41ba73 --- /dev/null +++ b/bsps/arm/atsam/contrib/libraries/libboard/source/board_lowlevel.c @@ -0,0 +1,434 @@ +/* ---------------------------------------------------------------------------- */ +/* Atmel Microcontroller Software Support */ +/* SAM Software Package License */ +/* ---------------------------------------------------------------------------- */ +/* Copyright (c) 2015, Atmel Corporation */ +/* */ +/* All rights reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or without */ +/* modification, are permitted provided that the following condition is met: */ +/* */ +/* - Redistributions of source code must retain the above copyright notice, */ +/* this list of conditions and the disclaimer below. */ +/* */ +/* Atmel's name may not be used to endorse or promote products derived from */ +/* this software without specific prior written permission. */ +/* */ +/* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR */ +/* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE */ +/* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, */ +/* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ +/* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */ +/* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF */ +/* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */ +/* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, */ +/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* ---------------------------------------------------------------------------- */ + +/** + * \file + * + * Provides the low-level initialization function that called on chip startup. + */ + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#ifndef __rtems__ +#include "board.h" +#else /* __rtems__ */ +#define MPU_HAS_NOCACHE_REGION +#include <chip.h> +#include <include/board_lowlevel.h> +#endif /* __rtems__ */ + + +#if defined(ENABLE_TCM) && defined(__GNUC__) + extern char _itcm_lma, _sitcm, _eitcm; +#endif + + +/*---------------------------------------------------------------------------- + * Exported functions + *----------------------------------------------------------------------------*/ +/* Default memory map + NO. Address range Memory region Memory type Shareable? Cache policy + 1 0x00000000- 0x1FFFFFFF Code Normal + 0x00000000- 0x003FFFFF ITCM + 0x00400000- 0x005FFFFF Internal flash Normal Not shareable WB + 2 0x20000000- 0x3FFFFFFF SRAM Normal + 0x20000000- 0x203FFFFF DTCM + 0x20400000- 0x2043FFFF First Partition Normal Not shareable WB + if MPU_HAS_NOCACHE_REGION is defined + 0x20440000- 0x2045EFFF Second Partition Normal Not shareable WB + 0x2045F000- 0x2045FFFF Nocache SRAM Normal Shareable + if MPU_HAS_NOCACHE_REGION is NOT defined + 0x20440000- 0x2045FFFF Second Partition Normal Not shareable WB + 3 0x40000000- 0x5FFFFFFF Peripheral Device Shareable + 4 0x60000000- 0x7FFFFFFF RAM + 0x60000000- 0x6FFFFFFF External EBI Strongly-ordered Shareable + 0x70000000- 0x7FFFFFFF SDRAM Normal Shareable WBWA + 5 0x80000000- 0x9FFFFFFF QSPI Strongly-ordered Shareable + 6 0xA0100000- 0xA01FFFFF USBHS RAM Device Shareable + 7 0xE0000000- 0xFFFFFFFF System - - + */ + +/** + * \brief Set up a memory region. + */ +void _SetupMemoryRegion(void) +{ + + uint32_t dwRegionBaseAddr; + uint32_t dwRegionAttr; + + memory_barrier(); + + /*************************************************** + ITCM memory region --- Normal + START_Addr:- 0x00000000UL + END_Addr:- 0x003FFFFFUL + ****************************************************/ + + dwRegionBaseAddr = + ITCM_START_ADDRESS | + MPU_REGION_VALID | + MPU_DEFAULT_ITCM_REGION; // 1 + +#ifdef __rtems__ + if (ITCM_END_ADDRESS + 1 != ITCM_START_ADDRESS) { +#endif /* __rtems__ */ + dwRegionAttr = + MPU_AP_PRIVILEGED_READ_WRITE | + MPU_CalMPURegionSize(ITCM_END_ADDRESS - ITCM_START_ADDRESS) | + MPU_REGION_ENABLE; +#ifdef __rtems__ + } else { + dwRegionAttr = MPU_REGION_DISABLE; + } +#endif /* __rtems__ */ + + MPU_SetRegion(dwRegionBaseAddr, dwRegionAttr); + + + /**************************************************** + Internal flash memory region --- Normal read-only + (update to Strongly ordered in write accesses) + START_Addr:- 0x00400000UL + END_Addr:- 0x005FFFFFUL + ******************************************************/ + + dwRegionBaseAddr = + IFLASH_START_ADDRESS | + MPU_REGION_VALID | + MPU_DEFAULT_IFLASH_REGION; //2 + + dwRegionAttr = + MPU_AP_READONLY | + INNER_NORMAL_WB_NWA_TYPE(NON_SHAREABLE) | + MPU_CalMPURegionSize(IFLASH_END_ADDRESS - IFLASH_START_ADDRESS) | + MPU_REGION_ENABLE; + + MPU_SetRegion(dwRegionBaseAddr, dwRegionAttr); + + /**************************************************** + DTCM memory region --- Normal + START_Addr:- 0x20000000L + END_Addr:- 0x203FFFFFUL + ******************************************************/ + + /* DTCM memory region */ + dwRegionBaseAddr = + DTCM_START_ADDRESS | + MPU_REGION_VALID | + MPU_DEFAULT_DTCM_REGION; //3 + +#ifdef __rtems__ + if (DTCM_END_ADDRESS + 1 != DTCM_START_ADDRESS) { +#endif /* __rtems__ */ + dwRegionAttr = + MPU_AP_PRIVILEGED_READ_WRITE | + INNER_NORMAL_NOCACHE_TYPE(NON_SHAREABLE) | + MPU_CalMPURegionSize(DTCM_END_ADDRESS - DTCM_START_ADDRESS) | + MPU_REGION_ENABLE; +#ifdef __rtems__ + } else { + dwRegionAttr = MPU_REGION_DISABLE; + } +#endif /* __rtems__ */ + + MPU_SetRegion(dwRegionBaseAddr, dwRegionAttr); + + + /**************************************************** + SRAM Cacheable memory region --- Normal + START_Addr:- 0x20400000UL + END_Addr:- 0x2043FFFFUL + ******************************************************/ + /* SRAM memory region */ + dwRegionBaseAddr = + SRAM_FIRST_START_ADDRESS | + MPU_REGION_VALID | + MPU_DEFAULT_SRAM_REGION_1; //4 + + dwRegionAttr = + MPU_AP_FULL_ACCESS | + INNER_NORMAL_WB_NWA_TYPE(NON_SHAREABLE) | + MPU_CalMPURegionSize(SRAM_FIRST_END_ADDRESS - SRAM_FIRST_START_ADDRESS) + | MPU_REGION_ENABLE; + + MPU_SetRegion(dwRegionBaseAddr, dwRegionAttr); + + + /**************************************************** + Internal SRAM second partition memory region --- Normal + START_Addr:- 0x20440000UL + END_Addr:- 0x2045FFFFUL + ******************************************************/ +#ifndef __rtems__ + /* SRAM memory region */ + dwRegionBaseAddr = + SRAM_SECOND_START_ADDRESS | + MPU_REGION_VALID | + MPU_DEFAULT_SRAM_REGION_2; //5 + + dwRegionAttr = + MPU_AP_FULL_ACCESS | + INNER_NORMAL_WB_NWA_TYPE(NON_SHAREABLE) | + MPU_CalMPURegionSize(SRAM_SECOND_END_ADDRESS - SRAM_SECOND_START_ADDRESS) | + MPU_REGION_ENABLE; + + MPU_SetRegion(dwRegionBaseAddr, dwRegionAttr); +#else /* __rtems__ */ + /* NOTE: The first SRAM region is increased so it covers the whole SRAM. If + * the SRAM is something odd (like 384k on the SAME70Q21), the next higher + * power of two will be used (in the example: 512k). That removes the need of + * the second SRAM region. There is currently no memory after the SRAM so that + * shouldn't be a problem. */ +#endif /* __rtems__ */ + +#ifdef MPU_HAS_NOCACHE_REGION + dwRegionBaseAddr = + SRAM_NOCACHE_START_ADDRESS | + MPU_REGION_VALID | + MPU_NOCACHE_SRAM_REGION; //11 + + dwRegionAttr = + MPU_AP_FULL_ACCESS | + INNER_OUTER_NORMAL_NOCACHE_TYPE(SHAREABLE) | + MPU_CalMPURegionSize(NOCACHE_SRAM_REGION_SIZE) | + MPU_REGION_ENABLE; + + MPU_SetRegion(dwRegionBaseAddr, dwRegionAttr); +#endif + + /**************************************************** + Peripheral memory region --- DEVICE Shareable + START_Addr:- 0x40000000UL + END_Addr:- 0x5FFFFFFFUL + ******************************************************/ + dwRegionBaseAddr = + PERIPHERALS_START_ADDRESS | + MPU_REGION_VALID | + MPU_PERIPHERALS_REGION; //6 + + dwRegionAttr = MPU_AP_FULL_ACCESS | + MPU_REGION_EXECUTE_NEVER | + SHAREABLE_DEVICE_TYPE | + MPU_CalMPURegionSize(PERIPHERALS_END_ADDRESS - PERIPHERALS_START_ADDRESS) + | MPU_REGION_ENABLE; + + MPU_SetRegion(dwRegionBaseAddr, dwRegionAttr); + +#ifdef __rtems__ + dwRegionBaseAddr = + SYSTEM_START_ADDRESS | + MPU_REGION_VALID | + MPU_SYSTEM_REGION; + + dwRegionAttr = MPU_AP_FULL_ACCESS | + MPU_REGION_EXECUTE_NEVER | + SHAREABLE_DEVICE_TYPE | + MPU_CalMPURegionSize(SYSTEM_END_ADDRESS - SYSTEM_START_ADDRESS) + | MPU_REGION_ENABLE; + + MPU_SetRegion(dwRegionBaseAddr, dwRegionAttr); +#endif /* __rtems__ */ + + /**************************************************** + External EBI memory memory region --- Strongly Ordered + START_Addr:- 0x60000000UL + END_Addr:- 0x6FFFFFFFUL + ******************************************************/ + dwRegionBaseAddr = + EXT_EBI_START_ADDRESS | + MPU_REGION_VALID | + MPU_EXT_EBI_REGION; + + dwRegionAttr = + MPU_AP_FULL_ACCESS | + /* External memory Must be defined with 'Device' or 'Strongly Ordered' + attribute for write accesses (AXI) */ + STRONGLY_ORDERED_SHAREABLE_TYPE | + MPU_CalMPURegionSize(EXT_EBI_END_ADDRESS - EXT_EBI_START_ADDRESS) | + MPU_REGION_ENABLE; + + MPU_SetRegion(dwRegionBaseAddr, dwRegionAttr); + + /**************************************************** + SDRAM Cacheable memory region --- Normal + START_Addr:- 0x70000000UL + END_Addr:- 0x7FFFFFFFUL + ******************************************************/ + dwRegionBaseAddr = + SDRAM_START_ADDRESS | + MPU_REGION_VALID | + MPU_DEFAULT_SDRAM_REGION; //7 + + dwRegionAttr = + MPU_AP_FULL_ACCESS | + INNER_NORMAL_WB_RWA_TYPE(SHAREABLE) | + MPU_CalMPURegionSize(SDRAM_END_ADDRESS - SDRAM_START_ADDRESS) | + MPU_REGION_ENABLE; + + MPU_SetRegion(dwRegionBaseAddr, dwRegionAttr); + + /**************************************************** + QSPI memory region --- Normal + START_Addr:- 0x80000000UL + END_Addr:- 0x9FFFFFFFUL + ******************************************************/ + dwRegionBaseAddr = + QSPI_START_ADDRESS | + MPU_REGION_VALID | + MPU_QSPIMEM_REGION; //8 + +#ifdef __rtems__ + if (QSPI_END_ADDRESS + 1 != QSPI_START_ADDRESS) { +#endif /* __rtems__ */ + dwRegionAttr = + MPU_AP_FULL_ACCESS | + INNER_NORMAL_WB_NWA_TYPE(SHAREABLE) | + MPU_CalMPURegionSize(QSPI_END_ADDRESS - QSPI_START_ADDRESS) | + MPU_REGION_ENABLE; +#ifdef __rtems__ + } else { + dwRegionAttr = MPU_REGION_DISABLE; + } +#endif /* __rtems__ */ + + MPU_SetRegion(dwRegionBaseAddr, dwRegionAttr); + + + /**************************************************** + USB RAM Memory region --- Device + START_Addr:- 0xA0100000UL + END_Addr:- 0xA01FFFFFUL + ******************************************************/ + dwRegionBaseAddr = + USBHSRAM_START_ADDRESS | + MPU_REGION_VALID | + MPU_USBHSRAM_REGION; //9 + + dwRegionAttr = + MPU_AP_FULL_ACCESS | + MPU_REGION_EXECUTE_NEVER | + SHAREABLE_DEVICE_TYPE | + MPU_CalMPURegionSize(USBHSRAM_END_ADDRESS - USBHSRAM_START_ADDRESS) | + MPU_REGION_ENABLE; + + MPU_SetRegion(dwRegionBaseAddr, dwRegionAttr); + + + /* Enable the memory management fault , Bus Fault, Usage Fault exception */ + SCB->SHCSR |= (SCB_SHCSR_MEMFAULTENA_Msk | SCB_SHCSR_BUSFAULTENA_Msk + | SCB_SHCSR_USGFAULTENA_Msk); + + /* Enable the MPU region */ +#ifndef __rtems__ + MPU_Enable(MPU_ENABLE | MPU_PRIVDEFENA); +#else /* __rtems__ */ + MPU_Enable(MPU_ENABLE); +#endif /* __rtems__ */ + + memory_sync(); +} + +#ifdef ENABLE_TCM + +#if defined (__ICCARM__) /* IAR Ewarm */ + #pragma section = "CSTACK" + #pragma section = "CSTACK_DTCM" + #define SRAM_STACK_BASE (__section_begin("CSTACK")) + #define DTCM_STACK_BASE (__section_begin("CSTACK_DTCM")) + #define SRAM_STACK_LIMIT (__section_end("CSTACK")) + #define DTCM_STACK_LIMIT (__section_end("CSTACK_DTCM")) +#elif defined (__CC_ARM) /* MDK */ + extern uint32_t Image$$ARM_LIB_STACK$$Base; + extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Limit; + extern uint32_t Image$$DTCM_STACK$$Base; + extern uint32_t Image$$DTCM_STACK$$ZI$$Limit; + #define SRAM_STACK_BASE (&Image$$ARM_LIB_STACK$$Base) + #define DTCM_STACK_BASE (&Image$$DTCM_STACK$$Base) + #define SRAM_STACK_LIMIT (&Image$$ARM_LIB_STACK$$ZI$$Limit) + #define DTCM_STACK_LIMIT (&Image$$DTCM_STACK$$ZI$$Limit) +#elif defined (__GNUC__) /* GCC */ + extern char _sdtcm_stack, _edtcm_stack, _sstack, _estack; + #define SRAM_STACK_BASE ((void *)(&_sstack)) + #define DTCM_STACK_BASE ((void *)(&_sdtcm_stack)) + #define SRAM_STACK_LIMIT ((void *)(&_estack)) + #define DTCM_STACK_LIMIT ((void *)(&_edtcm_stack)) +#endif + +/** \brief Change stack's location to DTCM + + The function changes the stack's location from SRAM to DTCM + */ +void TCM_StackInit(void); +void TCM_StackInit(void) +{ + uint32_t offset = (uint32_t)SRAM_STACK_LIMIT - (uint32_t)DTCM_STACK_LIMIT; + volatile char *dst = (volatile char *)DTCM_STACK_LIMIT; + volatile char *src = (volatile char *)SRAM_STACK_LIMIT; + + /* copy stack data from SRAM to DTCM */ + while (src > (volatile char *)SRAM_STACK_BASE) + *--dst = *--src; + + __set_MSP(__get_MSP() - offset); +} + +#endif + + +/** + * \brief Performs the low-level initialization of the chip. + */ +extern WEAK void LowLevelInit(void) +{ + + SystemInit(); +#ifndef MPU_EXAMPLE_FEATURE + _SetupMemoryRegion(); +#endif + +#if defined(FFT_DEMO) && (defined(__GNUC__) || defined(__CC_ARM)) + /* Enabling the FPU */ + SCB->CPACR |= 0x00F00000; + __DSB(); + __ISB(); +#endif + +#if defined(ENABLE_TCM) && defined(__GNUC__) + volatile char *dst = &_sitcm; + volatile char *src = &_itcm_lma; + + /* copy code_TCM from flash to ITCM */ + while (dst < &_eitcm) + *dst++ = *src++; + +#endif +} |