SAMS70 TCM setup

Go To Last Post
21 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm looking to setup some critical functions to run in ITCM and have my stack and heap in DTCM. All of the application notes only give pieces of the linker script and there isn't a TCM example that I can find in Atmel Studio.

 

Because of the Project needs I need to use the ITCM 64K, DTCM 64K, SRAM 256K configuration. I'd like to know how to put specific source files into the ITCM.

 

Could somebody point me to a complete example linker file?

This topic has a solution.
Last Edited: Thu. Jan 19, 2017 - 03:53 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

For anybody wanting a complete example of using the ITCM and DTCM of the SAME70/SAMS70/SAMV71 devices there is a complete example available in the SAMV71-XULT GNU Software Package 1.5 zip file (not install file) on this page:

http://www.atmel.com/tools/samv7...

 

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello,

 

Here is my working example of ITCM and DTCM usage on a SAME70.

 

I use ITCM for the vector table and a lot of fast Code, like FreeRTOS, math routines and Interrupts.

The DTCM is used for all data, there is an additional Segment for 'slow' data pointing to the remainig System Memory.

 

The configuration is 128KByte for ITCM, DTCM and System RAM on a SAME70N21.

 

Hope it helps,

Martin Cibulski

 

 

 

The linker script with modifications:

 

/**

* \file

*

* Copyright (c) 2015 Atmel Corporation. All rights reserved.

*

* \asf_license_start

*

* \page License

*

* Redistribution and use in source and binary forms, with or without

* modification, are permitted provided that the following conditions are met:

*

* 1. Redistributions of source code must retain the above copyright notice,

* this list of conditions and the following disclaimer.

*

* 2. Redistributions in binary form must reproduce the above copyright notice,

* this list of conditions and the following disclaimer in the documentation

* and/or other materials provided with the distribution.

*

* 3. The name of Atmel may not be used to endorse or promote products derived

* from this software without specific prior written permission.

*

* 4. This software may only be redistributed and used in connection with an

* Atmel microcontroller product.

*

* 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

* EXPRESSLY AND SPECIFICALLY 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.

*

* \asf_license_stop

*

*/

/*------------------------------------------------------------------------------

* Linker script for running in internal FLASH on the ATSAME70Q21

*----------------------------------------------------------------------------*/

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")

OUTPUT_ARCH(arm)

SEARCH_DIR(.)

/* Memory Spaces Definitions */

MEMORY

{

itcm_vectors (rx) : ORIGIN = 0x00000000, LENGTH = 0x00000400 /* Vector table at beginning of ITCM */

itcm (rx) : ORIGIN = 0x00000400, LENGTH = 0x0001FC00 /* Fast code in ITCM */

rom (rx) : ORIGIN = 0x00400000, LENGTH = 0x00200000 /* Remaining Code in Flash Memory */

dtcm (rw) : ORIGIN = 0x20000000, LENGTH = 0x00020000 /* Fast data/bss in DTCM */

ram (rwx) : ORIGIN = 0x20400000, LENGTH = 0x00020000 /* Remaining data/bss in System RAM */

}

/* The stack size used by the application. NOTE: you need to adjust according to your application. */

STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : 0x2000;

__ram_end__ = ORIGIN(ram) + LENGTH(ram) - 4;

/* The heapsize used by the application. NOTE: you need to adjust according to your application. */

HEAP_SIZE = DEFINED(HEAP_SIZE) ? HEAP_SIZE : 0x200;

/* Section Definitions */

SECTIONS

{

.fast_vectors (NOLOAD) :

{

. = ALIGN(4);

_srelocate_vectors = .;

} > itcm_vectors

.fast_code : AT (_etext)

{

. = ALIGN(4);

_s_fast_code = .;

_s_fast_code_from = LOADADDR(.fast_code);

*lib_a*.o (.text.*)

*list.o (.text.*)

*queue.o (.text.*)

*tasks.o (.text.*)

*timers.o (.text.*)

*my_timer.o (.text.*)

*test.o (.text.*)

*(.ramfunc);

_e_fast_code = .;

_e_fast_code_from = LOADADDR(.fast_code) + SIZEOF(.fast_code);

} > itcm

.text :

{

. = ALIGN(4);

_sfixed = .;

KEEP(*(.vectors .vectors.*))

*(.text .text.* .gnu.linkonce.t.*)

*(.glue_7t) *(.glue_7)

*(.rodata .rodata* .gnu.linkonce.r.*)

*(.ARM.extab* .gnu.linkonce.armextab.*)

/* Support C constructors, and C destructors in both user code

and the C library. This also provides support for C++ code. */

. = ALIGN(4);

KEEP(*(.init))

. = ALIGN(4);

__preinit_array_start = .;

KEEP (*(.preinit_array))

__preinit_array_end = .;

. = ALIGN(4);

__init_array_start = .;

KEEP (*(SORT(.init_array.*)))

KEEP (*(.init_array))

__init_array_end = .;

. = ALIGN(0x4);

KEEP (*crtbegin.o(.ctors))

KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))

KEEP (*(SORT(.ctors.*)))

KEEP (*crtend.o(.ctors))

. = ALIGN(4);

KEEP(*(.fini))

. = ALIGN(4);

__fini_array_start = .;

KEEP (*(.fini_array))

KEEP (*(SORT(.fini_array.*)))

__fini_array_end = .;

KEEP (*crtbegin.o(.dtors))

KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))

KEEP (*(SORT(.dtors.*)))

KEEP (*crtend.o(.dtors))

. = ALIGN(4);

_efixed = .; /* End of text section */

} > rom

/* .ARM.exidx is sorted, so has to go in its own output section. */

PROVIDE_HIDDEN (__exidx_start = .);

.ARM.exidx :

{

*(.ARM.exidx* .gnu.linkonce.armexidx.*)

} > rom

PROVIDE_HIDDEN (__exidx_end = .);

. = ALIGN(4);

_etext = .;

/* Slow data segment listed first */

/* Only a few modules are listed here */

/* Uses system memory */

.data : AT (_etext + SIZEOF(.fast_code))

{

. = ALIGN(4);

_s_data = .;

_s_data_from = LOADADDR(.data);

. = ALIGN(4);

_e_data = .;

_e_data_from = LOADADDR(.data) + SIZEOF(.data);

} > ram

/* Slow BSS segment listed first */

/* Only a few modules are listed here */

/* Uses system memory */

.bss (NOLOAD) :

{

. = ALIGN(4);

_s_bss = . ;

_s_zero = .;

. = ALIGN(4);

_e_bss = . ;

_e_zero = .;

} > dtcm

/* Fast data segment takes all remaining */

/* modules, uses the TCM */

.fast_data : AT (_etext + SIZEOF(.fast_code) + SIZEOF(.data))

{

. = ALIGN(4);

_s_fast_data = .;

_s_fast_data_from = LOADADDR(.fast_data);

*(.data .data.*);

. = ALIGN(4);

_e_fast_data = .;

_e_fast_from = LOADADDR(.fast_data) + SIZEOF(.fast_data);

} > dtcm

/* Fast BSS segment takes all remaining */

/* modules, uses the TCM */

.fast_bss (NOLOAD) :

{

. = ALIGN(4);

_s_fast_bss = . ;

_s_fast_zero = .;

*(.bss .bss.*)

*(COMMON)

. = ALIGN(4);

_e_fast_bss = . ;

_e_fast_zero = .;

} > dtcm

/* stack section */

.stack (NOLOAD):

{

. = ALIGN(8);

_s_stack = .;

. = . + STACK_SIZE;

. = ALIGN(8);

_e_stack = .;

} > dtcm

/* heap section */

.heap (NOLOAD):

{

. = ALIGN(8);

_s_heap = .;

. = . + HEAP_SIZE;

. = ALIGN(8);

_e_heap = .;

} > dtcm

. = ALIGN(4);

_end = . ;

_ram_end_ = ORIGIN(ram) + LENGTH(ram) -1 ;

}

 

 

The Startup Code:

 

/**
 * \file
 *
 * Copyright (c) 2015 Atmel Corporation. All rights reserved.
 *
 * \asf_license_start
 *
 * \page License
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * 3. The name of Atmel may not be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * 4. This software may only be redistributed and used in connection with an
 *    Atmel microcontroller product.
 *
 * 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
 * EXPRESSLY AND SPECIFICALLY 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.
 *
 * \asf_license_stop
 *
 */
/*
 * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
 */

#include "same70.h"

#if __FPU_USED /* CMSIS defined value to indicate usage of FPU */
#include "fpu.h"
#endif

extern uint32_t _s_fast_code_from;
extern uint32_t _e_fast_code_from;
extern uint32_t _s_fast_code;
extern uint32_t _e_fast_code;

extern uint32_t _s_data;
extern uint32_t _e_data;
extern uint32_t _s_data_from;
extern uint32_t _e_data_from;

extern uint32_t _s_fast_data;
extern uint32_t _e_fast_data;
extern uint32_t _s_fast_data_from;
extern uint32_t _e_fast_data_from;

extern uint32_t _s_bss;
extern uint32_t _e_bss;

extern uint32_t _s_fast_bss;
extern uint32_t _e_fast_bss;

extern uint32_t _s_stack;
extern uint32_t _e_stack;

/** \cond DOXYGEN_SHOULD_SKIP_THIS */
int main(void);
/** \endcond */

void __libc_init_array(void);

/* Default empty handler */
void Dummy_Handler(void);

/* Cortex-M7 core handlers */
void NMI_Handler        ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
//void HardFault_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void MemManage_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void BusFault_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void UsageFault_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void SVC_Handler        ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void DebugMon_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void PendSV_Handler     ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void SysTick_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

/* Peripherals handlers */
void SUPC_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void RSTC_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void RTC_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void RTT_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void WDT_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void PMC_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void EFC_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void UART0_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void UART1_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void PIOA_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void PIOB_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
#ifdef _SAME70_PIOC_INSTANCE_
void PIOC_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
#endif /* _SAME70_PIOC_INSTANCE_ */
void USART0_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void USART1_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void USART2_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void PIOD_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
#ifdef _SAME70_PIOE_INSTANCE_
void PIOE_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
#endif /* _SAME70_PIOE_INSTANCE_ */
#ifdef _SAME70_HSMCI_INSTANCE_
void HSMCI_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
#endif /* _SAME70_HSMCI_INSTANCE_ */
void TWIHS0_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void TWIHS1_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void SPI0_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void SSC_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void TC0_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void TC1_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void TC2_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
#ifdef _SAME70_TC1_INSTANCE_
void TC3_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
#endif /* _SAME70_TC1_INSTANCE_ */
#ifdef _SAME70_TC1_INSTANCE_
void TC4_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
#endif /* _SAME70_TC1_INSTANCE_ */
#ifdef _SAME70_TC1_INSTANCE_
void TC5_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
#endif /* _SAME70_TC1_INSTANCE_ */
void AFEC0_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
#ifdef _SAME70_DACC_INSTANCE_
void DACC_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
#endif /* _SAME70_DACC_INSTANCE_ */
void PWM0_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void ICM_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void ACC_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void USBHS_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void MCAN0_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void MCAN1_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void GMAC_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void AFEC1_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
#ifdef _SAME70_TWIHS2_INSTANCE_
void TWIHS2_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
#endif /* _SAME70_TWIHS2_INSTANCE_ */
void SPI1_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void QSPI_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void UART2_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void UART3_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void UART4_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
#ifdef _SAME70_TC2_INSTANCE_
void TC6_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
#endif /* _SAME70_TC2_INSTANCE_ */
#ifdef _SAME70_TC2_INSTANCE_
void TC7_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
#endif /* _SAME70_TC2_INSTANCE_ */
#ifdef _SAME70_TC2_INSTANCE_
void TC8_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
#endif /* _SAME70_TC2_INSTANCE_ */
void TC9_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void TC10_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void TC11_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void AES_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void TRNG_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void XDMAC_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void ISI_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void PWM1_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
#ifdef _SAME70_SDRAMC_INSTANCE_
void SDRAMC_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
#endif /* _SAME70_SDRAMC_INSTANCE_ */
void RSWDT_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

/* Exception Table */
__attribute__ ((section(".vectors")))
const DeviceVectors exception_table = {

        /* Configure Initial Stack Pointer, using linker-generated symbols */
        .pvStack = (void*) (&_e_stack),

        .pfnReset_Handler      = (void*) Reset_Handler,
        .pfnNMI_Handler        = (void*) NMI_Handler,
        .pfnHardFault_Handler  = (void*) HardFault_Handler,
        .pfnMemManage_Handler  = (void*) MemManage_Handler,
        .pfnBusFault_Handler   = (void*) BusFault_Handler,
        .pfnUsageFault_Handler = (void*) UsageFault_Handler,
        .pfnReserved1_Handler  = (void*) (0UL),          /* Reserved */
        .pfnReserved2_Handler  = (void*) (0UL),          /* Reserved */
        .pfnReserved3_Handler  = (void*) (0UL),          /* Reserved */
        .pfnReserved4_Handler  = (void*) (0UL),          /* Reserved */
        .pfnSVC_Handler        = (void*) SVC_Handler,
        .pfnDebugMon_Handler   = (void*) DebugMon_Handler,
        .pfnReserved5_Handler  = (void*) (0UL),          /* Reserved */
        .pfnPendSV_Handler     = (void*) PendSV_Handler,
        .pfnSysTick_Handler    = (void*) SysTick_Handler,

        /* Configurable interrupts */
        .pfnSUPC_Handler   = (void*) SUPC_Handler,   /* 0  Supply Controller */
        .pfnRSTC_Handler   = (void*) RSTC_Handler,   /* 1  Reset Controller */
        .pfnRTC_Handler    = (void*) RTC_Handler,    /* 2  Real Time Clock */
        .pfnRTT_Handler    = (void*) RTT_Handler,    /* 3  Real Time Timer */
        .pfnWDT_Handler    = (void*) WDT_Handler,    /* 4  Watchdog Timer */
        .pfnPMC_Handler    = (void*) PMC_Handler,    /* 5  Power Management Controller */
        .pfnEFC_Handler    = (void*) EFC_Handler,    /* 6  Enhanced Embedded Flash Controller */
        .pfnUART0_Handler  = (void*) UART0_Handler,  /* 7  UART 0 */
        .pfnUART1_Handler  = (void*) UART1_Handler,  /* 8  UART 1 */
        .pvReserved9       = (void*) (0UL),          /* 9  Reserved */
        .pfnPIOA_Handler   = (void*) PIOA_Handler,   /* 10 Parallel I/O Controller A */
        .pfnPIOB_Handler   = (void*) PIOB_Handler,   /* 11 Parallel I/O Controller B */
#ifdef _SAME70_PIOC_INSTANCE_
        .pfnPIOC_Handler   = (void*) PIOC_Handler,   /* 12 Parallel I/O Controller C */
#else
        .pvReserved12      = (void*) (0UL),          /* 12 Reserved */
#endif /* _SAME70_PIOC_INSTANCE_ */
        .pfnUSART0_Handler = (void*) USART0_Handler, /* 13 USART 0 */
        .pfnUSART1_Handler = (void*) USART1_Handler, /* 14 USART 1 */
        .pfnUSART2_Handler = (void*) USART2_Handler, /* 15 USART 2 */
        .pfnPIOD_Handler   = (void*) PIOD_Handler,   /* 16 Parallel I/O Controller D */
#ifdef _SAME70_PIOE_INSTANCE_
        .pfnPIOE_Handler   = (void*) PIOE_Handler,   /* 17 Parallel I/O Controller E */
#else
        .pvReserved17      = (void*) (0UL),          /* 17 Reserved */
#endif /* _SAME70_PIOE_INSTANCE_ */
#ifdef _SAME70_HSMCI_INSTANCE_
        .pfnHSMCI_Handler  = (void*) HSMCI_Handler,  /* 18 Multimedia Card Interface */
#else
        .pvReserved18      = (void*) (0UL),          /* 18 Reserved */
#endif /* _SAME70_HSMCI_INSTANCE_ */
        .pfnTWIHS0_Handler = (void*) TWIHS0_Handler, /* 19 Two Wire Interface 0 HS */
        .pfnTWIHS1_Handler = (void*) TWIHS1_Handler, /* 20 Two Wire Interface 1 HS */
        .pfnSPI0_Handler   = (void*) SPI0_Handler,   /* 21 Serial Peripheral Interface 0 */
        .pfnSSC_Handler    = (void*) SSC_Handler,    /* 22 Synchronous Serial Controller */
        .pfnTC0_Handler    = (void*) TC0_Handler,    /* 23 Timer/Counter 0 */
        .pfnTC1_Handler    = (void*) TC1_Handler,    /* 24 Timer/Counter 1 */
        .pfnTC2_Handler    = (void*) TC2_Handler,    /* 25 Timer/Counter 2 */
#ifdef _SAME70_TC1_INSTANCE_
        .pfnTC3_Handler    = (void*) TC3_Handler,    /* 26 Timer/Counter 3 */
#else
        .pvReserved26      = (void*) (0UL),          /* 26 Reserved */
#endif /* _SAME70_TC1_INSTANCE_ */
#ifdef _SAME70_TC1_INSTANCE_
        .pfnTC4_Handler    = (void*) TC4_Handler,    /* 27 Timer/Counter 4 */
#else
        .pvReserved27      = (void*) (0UL),          /* 27 Reserved */
#endif /* _SAME70_TC1_INSTANCE_ */
#ifdef _SAME70_TC1_INSTANCE_
        .pfnTC5_Handler    = (void*) TC5_Handler,    /* 28 Timer/Counter 5 */
#else
        .pvReserved28      = (void*) (0UL),          /* 28 Reserved */
#endif /* _SAME70_TC1_INSTANCE_ */
        .pfnAFEC0_Handler  = (void*) AFEC0_Handler,  /* 29 Analog Front End 0 */
#ifdef _SAME70_DACC_INSTANCE_
        .pfnDACC_Handler   = (void*) DACC_Handler,   /* 30 Digital To Analog Converter */
#else
        .pvReserved30      = (void*) (0UL),          /* 30 Reserved */
#endif /* _SAME70_DACC_INSTANCE_ */
        .pfnPWM0_Handler   = (void*) PWM0_Handler,   /* 31 Pulse Width Modulation 0 */
        .pfnICM_Handler    = (void*) ICM_Handler,    /* 32 Integrity Check Monitor */
        .pfnACC_Handler    = (void*) ACC_Handler,    /* 33 Analog Comparator */
        .pfnUSBHS_Handler  = (void*) USBHS_Handler,  /* 34 USB Host / Device Controller */
        .pfnMCAN0_Handler  = (void*) MCAN0_Handler,  /* 35 MCAN Controller 0 */
        .pvReserved36      = (void*) (0UL),          /* 36 Reserved */
        .pfnMCAN1_Handler  = (void*) MCAN1_Handler,  /* 37 MCAN Controller 1 */
        .pvReserved38      = (void*) (0UL),          /* 38 Reserved */
        .pfnGMAC_Handler   = (void*) GMAC_Handler,   /* 39 Ethernet MAC */
        .pfnAFEC1_Handler  = (void*) AFEC1_Handler,  /* 40 Analog Front End 1 */
#ifdef _SAME70_TWIHS2_INSTANCE_
        .pfnTWIHS2_Handler = (void*) TWIHS2_Handler, /* 41 Two Wire Interface 2 HS */
#else
        .pvReserved41      = (void*) (0UL),          /* 41 Reserved */
#endif /* _SAME70_TWIHS2_INSTANCE_ */
        .pfnSPI1_Handler   = (void*) SPI1_Handler,   /* 42 Serial Peripheral Interface 1 */
        .pfnQSPI_Handler   = (void*) QSPI_Handler,   /* 43 Quad I/O Serial Peripheral Interface */
        .pfnUART2_Handler  = (void*) UART2_Handler,  /* 44 UART 2 */
        .pfnUART3_Handler  = (void*) UART3_Handler,  /* 45 UART 3 */
        .pfnUART4_Handler  = (void*) UART4_Handler,  /* 46 UART 4 */
#ifdef _SAME70_TC2_INSTANCE_
        .pfnTC6_Handler    = (void*) TC6_Handler,    /* 47 Timer/Counter 6 */
#else
        .pvReserved47      = (void*) (0UL),          /* 47 Reserved */
#endif /* _SAME70_TC2_INSTANCE_ */
#ifdef _SAME70_TC2_INSTANCE_
        .pfnTC7_Handler    = (void*) TC7_Handler,    /* 48 Timer/Counter 7 */
#else
        .pvReserved48      = (void*) (0UL),          /* 48 Reserved */
#endif /* _SAME70_TC2_INSTANCE_ */
#ifdef _SAME70_TC2_INSTANCE_
        .pfnTC8_Handler    = (void*) TC8_Handler,    /* 49 Timer/Counter 8 */
#else
        .pvReserved49      = (void*) (0UL),          /* 49 Reserved */
#endif /* _SAME70_TC2_INSTANCE_ */
        .pfnTC9_Handler    = (void*) TC9_Handler,    /* 50 Timer/Counter 9 */
        .pfnTC10_Handler   = (void*) TC10_Handler,   /* 51 Timer/Counter 10 */
        .pfnTC11_Handler   = (void*) TC11_Handler,   /* 52 Timer/Counter 11 */
        .pvReserved53      = (void*) (0UL),          /* 53 Reserved */
        .pvReserved54      = (void*) (0UL),          /* 54 Reserved */
        .pvReserved55      = (void*) (0UL),          /* 55 Reserved */
        .pfnAES_Handler    = (void*) AES_Handler,    /* 56 AES */
        .pfnTRNG_Handler   = (void*) TRNG_Handler,   /* 57 True Random Generator */
        .pfnXDMAC_Handler  = (void*) XDMAC_Handler,  /* 58 DMA */
        .pfnISI_Handler    = (void*) ISI_Handler,    /* 59 Camera Interface */
        .pfnPWM1_Handler   = (void*) PWM1_Handler,   /* 60 Pulse Width Modulation 1 */
        .pvReserved61      = (void*) (0UL),          /* 61 Reserved */
#ifdef _SAME70_SDRAMC_INSTANCE_
        .pfnSDRAMC_Handler = (void*) SDRAMC_Handler, /* 62 SDRAM Controller */
#else
        .pvReserved62      = (void*) (0UL),          /* 62 Reserved */
#endif /* _SAME70_SDRAMC_INSTANCE_ */
        .pfnRSWDT_Handler  = (void*) RSWDT_Handler   /* 63 Reinforced Secure Watchdog Timer */
};

/**
 * \brief This is the code that gets called on processor reset.
 * To initialize the device, and call the main() routine.
 */
void Reset_Handler(void)
{
        uint32_t *pSrc;
        uint32_t *pSrcEnd;
        uint32_t *pDest;
        uint32_t *pDestEnd;

  // Configure TCM with maximum Size
  // 128 KByte Data
  // 128 KByte Program (currently not used)
  //
//#ifdef CONF_USE_DTCM
  EFC->EEFC_FCR = (EEFC_FCR_FKEY_PASSWD | EEFC_FCR_FCMD_GGPB);
  //EFC->EEFC_FCR = (EEFC_FCR_FCMD_GGPB);
  uint32_t ulEEFC_bits = EFC->EEFC_FRR;

  if ((ulEEFC_bits & 0x180) != 0x180)
  {
   EFC->EEFC_FCR = (EEFC_FCR_FKEY_PASSWD | EEFC_FCR_FCMD_SGPB | EEFC_FCR_FARG(7));
   EFC->EEFC_FCR = (EEFC_FCR_FKEY_PASSWD | EEFC_FCR_FCMD_SGPB | EEFC_FCR_FARG(8));

   // Trigger Reset
   RSTC->RSTC_CR = RSTC_CR_PROCRST;
  }

  // Enable DTCM and ITCM
  //
  __DSB();
  __ISB();
  SCB->ITCMCR = (SCB_DTCMCR_EN_Msk | SCB_DTCMCR_RMW_Msk | SCB_DTCMCR_RETEN_Msk);
  SCB->DTCMCR = (SCB_DTCMCR_EN_Msk | SCB_DTCMCR_RMW_Msk | SCB_DTCMCR_RETEN_Msk);
  __DSB();
  __ISB();
//#endif

        // Copy Vector Table to beginning of ITCM (Address 0)
        //
        pSrc  = (uint32_t*)&exception_table;
        pDest  = (uint32_t*)0;
        pDestEnd = (uint32_t*)sizeof (DeviceVectors);

     for (; pDest < pDestEnd;)
  {
      *pDest++ = *pSrc++;
     }

        // Copy fast Code from Flash into ITCM
        //
        pSrc  = &_s_fast_code_from;
        pSrcEnd  = &_e_fast_code_from;
        pDest  = &_s_fast_code;
        pDestEnd = &_e_fast_code;

     for (; pDest < pDestEnd;)
  {
      *pDest++ = *pSrc++;
     }

        // Copy data segments into DTCM and System RAM
  //
  pSrc  = &_s_data_from;
  pSrcEnd  = &_e_data_from;
        pDest  = &_s_data;
        pDestEnd = &_e_data;

     while (pDest < pDestEnd)
  {
      *pDest++ = *pSrc++;
     }

  pSrc  = &_s_fast_data_from;
  pSrcEnd  = &_e_fast_data_from;
        pDest  = &_s_fast_data;
        pDestEnd = &_e_fast_data;

     while (pDest < pDestEnd)
  {
      *pDest++ = *pSrc++;
     }

        // Clear the zero segments in DTCM and System RAM
  //
        pDest  = &_s_bss;
  pDestEnd = &_e_bss;
        while (pDest < pDestEnd)
  {
                *pDest++ = 0;
        }

        pDest  = &_s_fast_bss;
        pDestEnd = &_e_fast_bss;
        while (pDest < pDestEnd)
        {
         *pDest++ = 0;
        }

        // Set the vector table base address
  // to the copied table in ITCM (Address 0)
  //
        pSrc = (uint32_t *) 0;
        SCB->VTOR = ((uint32_t) pSrc & SCB_VTOR_TBLOFF_Msk);

#if __FPU_USED
 fpu_enable();
#endif

        /* Initialize the C library */
        __libc_init_array();

        /* Branch to main function */
        main();

        /* Infinite loop */
        while (1);
}

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You are awesome, thank you! Your code is much easier to follow than what was in the softpack 1.5 example. Got it up and running immediately.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Just a quick word of warning for everyone, my application requires optimization to be set to O3. For whatever reason, the reset handler above would hang (with the program counter going off in the weeds) when it would try copy the vector table from flash to ITCM address 0. I couldn't figure out why, so I simply added an optimization attribute above the reset handler to keep it at 'O0'.

 

__attribute__ ((optimize("O0")))

void Reset_Handler(void)

{

 

...

}

 

Thank you again for posting this martin.c, it's been a huge help and time saver.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

I found a few additional issues I thought worthwhile to present:

 

In the Reset_Handler() example above, specifically in the code to set GPNVM bits 8 & 7 to 1 and issue a reset, the line that issues the reset needs updated to include passing in the password key. The micro won't actually reset without it.

//Trigger Reset

RSTC->RSTC_CR = RSTC_CR_KEY_PASSWD | RSTC_CR_PROCRST;

 

In addition, for our application, we have designed in the capabilities to allow for remote updates to the firmware. This is done using variants of the Atmel Applets used on the SAM E70 Xplained board. This code runs out of System SRAM and Flash and requires TCM to be disabled. Therefore, when the loading is complete, it jumps into the reset handler and hangs. This is due to the example code above running everything out of TCM, including the stack. When reset_handler() tries to push to the stack, it tries to write to DTCM that is disabled at the time.

 

Therefore, I came up with a solution to create a "startup stack" of 256 bytes that lives in System SRAM. I also created a new "runtime stack" segment in the linker. Then, reset_handler() will always run out of the System SRAM startup stack. When code execution gets to the end of reset handler, it updates the system stack pointer with the address of the runtime stack in DTCM. It then jumps into main() and continues program execution using the stack in DTCM.

 

I've provided my updates to the linker and startup.c files below. Hopefully this will provide some help to those of you trying to get this up and running.

 

 

Linker:

 

/**

* \file

*

* Copyright (c) 2015 Atmel Corporation. All rights reserved.

*

* \asf_license_start

*

* \page License

*

* Redistribution and use in source and binary forms, with or without

* modification, are permitted provided that the following conditions are met:

*

* 1. Redistributions of source code must retain the above copyright notice,

* this list of conditions and the following disclaimer.

*

* 2. Redistributions in binary form must reproduce the above copyright notice,

* this list of conditions and the following disclaimer in the documentation

* and/or other materials provided with the distribution.

*

* 3. The name of Atmel may not be used to endorse or promote products derived

* from this software without specific prior written permission.

*

* 4. This software may only be redistributed and used in connection with an

* Atmel microcontroller product.

*

* 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

* EXPRESSLY AND SPECIFICALLY 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.

*

* \asf_license_stop

*

*/

/*------------------------------------------------------------------------------

* Linker script for running in internal FLASH on the ATSAME70Q21

*----------------------------------------------------------------------------*/

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")

OUTPUT_ARCH(arm)

SEARCH_DIR(.)

/* Memory Spaces Definitions */

MEMORY

{

itcm_vectors (rx) : ORIGIN = 0x00000000, LENGTH = 0x00000400 /* Vector table at beginning of ITCM */

itcm (rx) : ORIGIN = 0x00000400, LENGTH = 0x0001FC00 /* Fast code in ITCM */

rom (rx) : ORIGIN = 0x00400000, LENGTH = 0x00200000 /* Remaining Code in Flash Memory */

dtcm (rw) : ORIGIN = 0x20000000, LENGTH = 0x00020000 /* Fast data/bss in DTCM */

ram (rwx) : ORIGIN = 0x20400000, LENGTH = 0x00020000 /* Remaining data/bss in System RAM */

}

/* The stack size used by the application. NOTE: you need to adjust according to your application. */

STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : 0x100;

DTCM_STACK_SIZE = DEFINED(DTCM_STACK_SIZE) ? DTCM_STACK_SIZE : 0x2000;

__ram_end__ = ORIGIN(ram) + LENGTH(ram) - 4;

/* The heapsize used by the application. NOTE: you need to adjust according to your application. */

HEAP_SIZE = DEFINED(HEAP_SIZE) ? HEAP_SIZE : 0x1000;

/* Section Definitions */

SECTIONS

{

.fast_vectors (NOLOAD) :

{

. = ALIGN(4);

_srelocate_vectors = .;

} > itcm_vectors

 

.fast_code : AT (_etext)

{

. = ALIGN(4);

_s_fast_code = .;

_s_fast_code_from = LOADADDR(.fast_code);

*(.itcm_functions);

_e_fast_code = .;

_e_fast_code_from = LOADADDR(.fast_code) + SIZEOF(.fast_code);

} > itcm

 

.text :

{

. = ALIGN(4);

_sfixed = .;

KEEP(*(.vectors .vectors.*))

*(.text .text.* .gnu.linkonce.t.*)

*(.glue_7t) *(.glue_7)

*(.rodata .rodata* .gnu.linkonce.r.*)

*(.ARM.extab* .gnu.linkonce.armextab.*)

/* Support C constructors, and C destructors in both user code

and the C library. This also provides support for C++ code. */

. = ALIGN(4);

KEEP(*(.init))

. = ALIGN(4);

__preinit_array_start = .;

KEEP (*(.preinit_array))

__preinit_array_end = .;

. = ALIGN(4);

__init_array_start = .;

KEEP (*(SORT(.init_array.*)))

KEEP (*(.init_array))

__init_array_end = .;

. = ALIGN(0x4);

KEEP (*crtbegin.o(.ctors))

KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))

KEEP (*(SORT(.ctors.*)))

KEEP (*crtend.o(.ctors))

. = ALIGN(4);

KEEP(*(.fini))

. = ALIGN(4);

__fini_array_start = .;

KEEP (*(.fini_array))

KEEP (*(SORT(.fini_array.*)))

__fini_array_end = .;

KEEP (*crtbegin.o(.dtors))

KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))

KEEP (*(SORT(.dtors.*)))

KEEP (*crtend.o(.dtors))

. = ALIGN(4);

_efixed = .; /* End of text section */

} > rom

 

/* .ARM.exidx is sorted, so has to go in its own output section. */

PROVIDE_HIDDEN (__exidx_start = .);

.ARM.exidx :

{

*(.ARM.exidx* .gnu.linkonce.armexidx.*)

} > rom

PROVIDE_HIDDEN (__exidx_end = .);

. = ALIGN(4);

_etext = .;

 

/* Slow data segment listed first */

/* Only a few modules are listed here */

/* Uses system memory */

.data : AT (_etext + SIZEOF(.fast_code))

{

. = ALIGN(4);

_s_data = .;

_s_data_from = LOADADDR(.data);

. = ALIGN(4);

_e_data = .;

_e_data_from = LOADADDR(.data) + SIZEOF(.data);

} > ram

 

/* Slow BSS segment listed first */

/* Only a few modules are listed here */

/* Uses system memory */

.bss (NOLOAD) :

{

. = ALIGN(4);

_s_bss = . ;

_s_zero = .;

. = ALIGN(4);

_e_bss = . ;

_e_zero = .;

} > dtcm

 

/* Fast data segment takes all remaining */

/* modules, uses the TCM */

.fast_data : AT (_etext + SIZEOF(.fast_code) + SIZEOF(.data))

{

. = ALIGN(4);

_s_fast_data = .;

_s_fast_data_from = LOADADDR(.fast_data);

*(.data .data.*);

. = ALIGN(4);

_e_fast_data = .;

_e_fast_data_from = LOADADDR(.fast_data) + SIZEOF(.fast_data);

} > dtcm

 

/* Fast BSS segment takes all remaining */

/* modules, uses the TCM */

.fast_bss (NOLOAD) :

{

. = ALIGN(4);

_s_fast_bss = . ;

_s_fast_zero = .;

*(.bss .bss.*)

*(COMMON)

. = ALIGN(4);

_e_fast_bss = . ;

_e_fast_zero = .;

} > dtcm

 

/* heap section - needs to be listed before stack since heap grows up in address space*/

.heap (NOLOAD):

{

. = ALIGN(8);

_s_heap = .;

. = . + HEAP_SIZE;

. = ALIGN(8);

_e_heap = .;

} > dtcm

/* startup stack section. Stack needed just for reset_handler, just to get us through operation where we check TCM bits in GPNVM */

.stack (NOLOAD):

{

. = ALIGN(8);

_s_stack = .;

. = . + STACK_SIZE;

. = ALIGN(8);

_e_stack = .;

} > ram

 

.runtime_stack (NOLOAD):

{

. = ALIGN(8);

_s_runtime_stack = .;

. = . + DTCM_STACK_SIZE;

. = ALIGN(8);

_e_runtime_stack = .;

} > dtcm

. = ALIGN(4);

_end = . ;

_ram_end_ = ORIGIN(ram) + LENGTH(ram) -1 ;

}

 

 

 

 

Startup_same70q21.c

 

/*
  * \file
  *
  * Copyright (c) 2015 Atmel Corporation. All rights reserved.
  *
  * \asf_license_start
  *
  * \page License
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
  *
  * 1. Redistributions of source code must retain the above copyright notice,
  *    this list of conditions and the following disclaimer.
  *
  * 2. Redistributions in binary form must reproduce the above copyright notice,
  *    this list of conditions and the following disclaimer in the documentation
  *    and/or other materials provided with the distribution.
  *
  * 3. The name of Atmel may not be used to endorse or promote products derived
  *    from this software without specific prior written permission.
  *
  * 4. This software may only be redistributed and used in connection with an
  *    Atmel microcontroller product.
  *
  * 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
  * EXPRESSLY AND SPECIFICALLY 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.
  *
  * \asf_license_stop
  *
  */
 /*
  * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
  */

#include "same70q21.h"

extern uint32_t _s_fast_code_from;
extern uint32_t _e_fast_code_from;
extern uint32_t _s_fast_code;
extern uint32_t _e_fast_code;

extern uint32_t _s_data;
extern uint32_t _e_data;
extern uint32_t _s_data_from;
extern uint32_t _e_data_from;

extern uint32_t _s_fast_data;
extern uint32_t _e_fast_data;
extern uint32_t _s_fast_data_from;
extern uint32_t _e_fast_data_from;

extern uint32_t _s_bss;
extern uint32_t _e_bss;

extern uint32_t _s_fast_bss;
extern uint32_t _e_fast_bss;

extern uint32_t _s_stack;
extern uint32_t _e_stack;

extern uint32_t _e_runtime_stack;

/** \cond DOXYGEN_SHOULD_SKIP_THIS */
 int main(void);
 /** \endcond */

void __libc_init_array(void);

/* Default empty handler */
 void Dummy_Handler(void);

/* Cortex-M7 core handlers */
 void NMI_Handler        ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void HardFault_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void MemManage_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void BusFault_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void UsageFault_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void SVC_Handler        ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void DebugMon_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void PendSV_Handler     ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void SysTick_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

/* Peripherals handlers */
 void SUPC_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void RSTC_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void RTC_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void RTT_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void WDT_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void PMC_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void EFC_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void UART0_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void UART1_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void PIOA_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void PIOB_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void PIOC_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void USART0_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void USART1_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void USART2_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void PIOD_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void PIOE_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void HSMCI_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void TWIHS0_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void TWIHS1_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void SPI0_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void SSC_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void TC0_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void TC1_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void TC2_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void TC3_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void TC4_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void TC5_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void AFEC0_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void DACC_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void PWM0_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void ICM_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void ACC_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void USBHS_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void MCAN0_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void MCAN1_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void GMAC_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void AFEC1_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void TWIHS2_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void SPI1_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void QSPI_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void UART2_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void UART3_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void UART4_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void TC6_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void TC7_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void TC8_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void TC9_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void TC10_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void TC11_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void AES_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void TRNG_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void XDMAC_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void ISI_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void PWM1_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void SDRAMC_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
 void RSWDT_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

/* Exception Table */
 __attribute__ ((section(".vectors")))
 const DeviceVectors exception_table = {

 /* Configure Initial Stack Pointer, using linker-generated symbols */
 .pvStack = (void*) (&_e_stack),

 .pfnReset_Handler      = (void*) Reset_Handler,
 .pfnNMI_Handler        = (void*) NMI_Handler,
 .pfnHardFault_Handler  = (void*) HardFault_Handler,
 .pfnMemManage_Handler  = (void*) MemManage_Handler,
 .pfnBusFault_Handler   = (void*) BusFault_Handler,
 .pfnUsageFault_Handler = (void*) UsageFault_Handler,
 .pfnReserved1_Handler  = (void*) (0UL),          /* Reserved */
 .pfnReserved2_Handler  = (void*) (0UL),          /* Reserved */
 .pfnReserved3_Handler  = (void*) (0UL),          /* Reserved */
 .pfnReserved4_Handler  = (void*) (0UL),          /* Reserved */
 .pfnSVC_Handler        = (void*) SVC_Handler,
 .pfnDebugMon_Handler   = (void*) DebugMon_Handler,
 .pfnReserved5_Handler  = (void*) (0UL),          /* Reserved */
 .pfnPendSV_Handler     = (void*) PendSV_Handler,
 .pfnSysTick_Handler    = (void*) SysTick_Handler,

 /* Configurable interrupts */
 .pfnSUPC_Handler   = (void*) SUPC_Handler,   /* 0  Supply Controller */
 .pfnRSTC_Handler   = (void*) RSTC_Handler,   /* 1  Reset Controller */
 .pfnRTC_Handler    = (void*) RTC_Handler,    /* 2  Real Time Clock */
 .pfnRTT_Handler    = (void*) RTT_Handler,    /* 3  Real Time Timer */
 .pfnWDT_Handler    = (void*) WDT_Handler,    /* 4  Watchdog Timer */
 .pfnPMC_Handler    = (void*) PMC_Handler,    /* 5  Power Management Controller */
 .pfnEFC_Handler    = (void*) EFC_Handler,    /* 6  Enhanced Embedded Flash Controller */
 .pfnUART0_Handler  = (void*) UART0_Handler,  /* 7  UART 0 */
 .pfnUART1_Handler  = (void*) UART1_Handler,  /* 8  UART 1 */
 .pvReserved9       = (void*) (0UL),          /* 9  Reserved */
 .pfnPIOA_Handler   = (void*) PIOA_Handler,   /* 10 Parallel I/O Controller A */
 .pfnPIOB_Handler   = (void*) PIOB_Handler,   /* 11 Parallel I/O Controller B */
 .pfnPIOC_Handler   = (void*) PIOC_Handler,   /* 12 Parallel I/O Controller C */
 .pfnUSART0_Handler = (void*) USART0_Handler, /* 13 USART 0 */
 .pfnUSART1_Handler = (void*) USART1_Handler, /* 14 USART 1 */
 .pfnUSART2_Handler = (void*) USART2_Handler, /* 15 USART 2 */
 .pfnPIOD_Handler   = (void*) PIOD_Handler,   /* 16 Parallel I/O Controller D */
 .pfnPIOE_Handler   = (void*) PIOE_Handler,   /* 17 Parallel I/O Controller E */
 .pfnHSMCI_Handler  = (void*) HSMCI_Handler,  /* 18 Multimedia Card Interface */
 .pfnTWIHS0_Handler = (void*) TWIHS0_Handler, /* 19 Two Wire Interface 0 HS */
 .pfnTWIHS1_Handler = (void*) TWIHS1_Handler, /* 20 Two Wire Interface 1 HS */
 .pfnSPI0_Handler   = (void*) SPI0_Handler,   /* 21 Serial Peripheral Interface 0 */
 .pfnSSC_Handler    = (void*) SSC_Handler,    /* 22 Synchronous Serial Controller */
 .pfnTC0_Handler    = (void*) TC0_Handler,    /* 23 Timer/Counter 0 */
 .pfnTC1_Handler    = (void*) TC1_Handler,    /* 24 Timer/Counter 1 */
 .pfnTC2_Handler    = (void*) TC2_Handler,    /* 25 Timer/Counter 2 */
 .pfnTC3_Handler    = (void*) TC3_Handler,    /* 26 Timer/Counter 3 */
 .pfnTC4_Handler    = (void*) TC4_Handler,    /* 27 Timer/Counter 4 */
 .pfnTC5_Handler    = (void*) TC5_Handler,    /* 28 Timer/Counter 5 */
 .pfnAFEC0_Handler  = (void*) AFEC0_Handler,  /* 29 Analog Front End 0 */
 .pfnDACC_Handler   = (void*) DACC_Handler,   /* 30 Digital To Analog Converter */
 .pfnPWM0_Handler   = (void*) PWM0_Handler,   /* 31 Pulse Width Modulation 0 */
 .pfnICM_Handler    = (void*) ICM_Handler,    /* 32 Integrity Check Monitor */
 .pfnACC_Handler    = (void*) ACC_Handler,    /* 33 Analog Comparator */
 .pfnUSBHS_Handler  = (void*) USBHS_Handler,  /* 34 USB Host / Device Controller */
 .pfnMCAN0_Handler  = (void*) MCAN0_Handler,  /* 35 MCAN Controller 0 */
 .pvReserved36      = (void*) (0UL),          /* 36 Reserved */
 .pfnMCAN1_Handler  = (void*) MCAN1_Handler,  /* 37 MCAN Controller 1 */
 .pvReserved38      = (void*) (0UL),          /* 38 Reserved */
 .pfnGMAC_Handler   = (void*) GMAC_Handler,   /* 39 Ethernet MAC */
 .pfnAFEC1_Handler  = (void*) AFEC1_Handler,  /* 40 Analog Front End 1 */
 .pfnTWIHS2_Handler = (void*) TWIHS2_Handler, /* 41 Two Wire Interface 2 HS */
 .pfnSPI1_Handler   = (void*) SPI1_Handler,   /* 42 Serial Peripheral Interface 1 */
 .pfnQSPI_Handler   = (void*) QSPI_Handler,   /* 43 Quad I/O Serial Peripheral Interface */
 .pfnUART2_Handler  = (void*) UART2_Handler,  /* 44 UART 2 */
 .pfnUART3_Handler  = (void*) UART3_Handler,  /* 45 UART 3 */
 .pfnUART4_Handler  = (void*) UART4_Handler,  /* 46 UART 4 */
 .pfnTC6_Handler    = (void*) TC6_Handler,    /* 47 Timer/Counter 6 */
 .pfnTC7_Handler    = (void*) TC7_Handler,    /* 48 Timer/Counter 7 */
 .pfnTC8_Handler    = (void*) TC8_Handler,    /* 49 Timer/Counter 8 */
 .pfnTC9_Handler    = (void*) TC9_Handler,    /* 50 Timer/Counter 9 */
 .pfnTC10_Handler   = (void*) TC10_Handler,   /* 51 Timer/Counter 10 */
 .pfnTC11_Handler   = (void*) TC11_Handler,   /* 52 Timer/Counter 11 */
 .pvReserved53      = (void*) (0UL),          /* 53 Reserved */
 .pvReserved54      = (void*) (0UL),          /* 54 Reserved */
 .pvReserved55      = (void*) (0UL),          /* 55 Reserved */
 .pfnAES_Handler    = (void*) AES_Handler,    /* 56 AES */
 .pfnTRNG_Handler   = (void*) TRNG_Handler,   /* 57 True Random Generator */
 .pfnXDMAC_Handler  = (void*) XDMAC_Handler,  /* 58 DMA */
 .pfnISI_Handler    = (void*) ISI_Handler,    /* 59 Camera Interface */
 .pfnPWM1_Handler   = (void*) PWM1_Handler,   /* 60 Pulse Width Modulation 1 */
 .pvReserved61      = (void*) (0UL),          /* 61 Reserved */
 .pfnSDRAMC_Handler = (void*) SDRAMC_Handler, /* 62 SDRAM Controller */
 .pfnRSWDT_Handler  = (void*) RSWDT_Handler   /* 63 Reinforced Secure Watchdog Timer */
 };

/**
  * \brief This is the code that gets called on processor reset.
  * To initialize the device, and call the main() routine.

  *  With the compiler optimization set to O3, this Reset_Handler
  *   funciton would hang when it gets to the section of code where it copies the vector
  *   table to beginning of ITCM (Address 0)
  */
 __attribute__ ((optimize("O0")))
void Reset_Handler(void)
{
 uint32_t *pSrc;
 uint32_t *pSrcEnd;
 uint32_t *pDest;
 uint32_t *pDestEnd;
 uint32_t ulEEFC_bits;
 uint32_t dtcm_stack_pointer_addr;

 // Configure TCM with maximum Size
 // 128 KByte Data
 // 128 KByte Program

 __DSB();
 __ISB();
 EFC->EEFC_FCR = (EEFC_FCR_FKEY_PASSWD | EEFC_FCR_FCMD_GGPB);
 __DSB();
 __ISB();
 
 while (!(EFC->EEFC_FSR & EEFC_FSR_FRDY));      //Wait until the status falls to 0 (EFFC command is complete)

 ulEEFC_bits = EFC->EEFC_FRR;

 if ((ulEEFC_bits & 0x180) != 0x180)
 {
  __DSB();
  __ISB();
  EFC->EEFC_FCR = (EEFC_FCR_FKEY_PASSWD | EEFC_FCR_FCMD_SGPB | EEFC_FCR_FARG(7));  //issue command to clear bit 7
  __DSB();
  __ISB();

  while(!(EFC->EEFC_FSR & EEFC_FSR_FRDY));     //Wait until the status falls to 0 (EFFC command is complete)

  __DSB();
  __ISB();
  EFC->EEFC_FCR = (EEFC_FCR_FKEY_PASSWD | EEFC_FCR_FCMD_SGPB | EEFC_FCR_FARG(8));  //issue command to clear bit 8
  __DSB();
  __ISB();

  while(!(EFC->EEFC_FSR & EEFC_FSR_FRDY));     //Wait until the status falls to 0 (EFFC command is complete)

  __DSB();
  __ISB();

  //Trigger Reset
  RSTC->RSTC_CR = RSTC_CR_KEY_PASSWD | RSTC_CR_PROCRST;

  __DSB();
  __ISB();
 }

 // Enable DTCM and ITCM
 __DSB();
 __ISB();
 SCB->ITCMCR = (SCB_DTCMCR_EN_Msk | SCB_DTCMCR_RMW_Msk | SCB_DTCMCR_RETEN_Msk);
 SCB->DTCMCR = (SCB_DTCMCR_EN_Msk | SCB_DTCMCR_RMW_Msk | SCB_DTCMCR_RETEN_Msk);
 __DSB();
 __ISB();

 // Copy Vector Table to beginning of ITCM (Address 0)
 pSrc  = (uint32_t*)&exception_table;
 pDest  = (uint32_t*)0;
 pDestEnd = (uint32_t*)sizeof (DeviceVectors);

 for (; pDest < pDestEnd;)
 {
  *pDest++ = *pSrc++;
 }

 // Copy fast Code from Flash into ITCM
 pSrc  = &_s_fast_code_from;
 pSrcEnd  = &_e_fast_code_from;
 pDest  = &_s_fast_code;
 pDestEnd = &_e_fast_code;

 for (; pDest < pDestEnd;)
 {
  *pDest++ = *pSrc++;
 }

 // Copy data segments into DTCM and System RAM
 pSrc  = &_s_data_from;
 pSrcEnd  = &_e_data_from;
 pDest  = &_s_data;
 pDestEnd = &_e_data;

 while (pDest < pDestEnd)
 {
  *pDest++ = *pSrc++;
 }

 pSrc  = &_s_fast_data_from;
 pSrcEnd  = &_e_fast_data_from;
 pDest  = &_s_fast_data;
 pDestEnd = &_e_fast_data;

 while (pDest < pDestEnd)
 {
  *pDest++ = *pSrc++;
 }

    // Clear the zero segments in DTCM and System RAM
 pDest  = &_s_bss;
 pDestEnd = &_e_bss;
 while (pDest < pDestEnd)
 {
  *pDest++ = 0;
 }

 pDest  = &_s_fast_bss;
 pDestEnd = &_e_fast_bss;
 while (pDest < pDestEnd)
 {
  *pDest++ = 0;
 }

 // Set the vector table base address
 // to the copied table in ITCM (Address 0)
 pSrc = (uint32_t *) 0;

 SCB->VTOR = ((uint32_t) pSrc & SCB_VTOR_TBLOFF_Msk);

 //Now that we're at the point in this routine where we don't need any stack variables,
 //update our stack pointer to the runtime stack pointer that lives in DTCM
 dtcm_stack_pointer_addr = (uint32_t)&_e_runtime_stack;

 //asm(code : output operand list : input operand list : clobber list);
 __ASM volatile ("mov.w r1, %0"::"r" (dtcm_stack_pointer_addr):"r1");    //write r1 with the address of DTCM where the beginning of the stack lives (per the linker)
 __ASM volatile("mov sp, r1");              //update the stack pointer with the stack address that lives in r1

 __DSB();
 __ISB();

 /* Initialize the C library */
 __libc_init_array(); 

 /* Branch to main function */
 main();

 /* Infinite loop */
 while (1);
 }

/**
* \brief Default interrupt handler for unused IRQs.
*/
void Dummy_Handler(void)
{
    while (1)
 {
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks agporsch. I was having trouble with release builds until I forced Reset_Handler() to get O0.

It makes me wonder what about the code is falling over because of this, though. I tried making more of the locals (like the loop variables) volatile, but that didn’t help.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello. There was a problem loading the data into DTCM.

 

linker script:

 

/*------------------------------------------------------------------------------
 *      Linker script for running in internal FLASH on the ATSAME70Q21
 *----------------------------------------------------------------------------*/

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
SEARCH_DIR(.)

/* Memory Spaces Definitions */
MEMORY
{
  itcm (rwx) : ORIGIN = 0x00000000, LENGTH = 0x00008000
  dtcm (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000
  rom (rx)  : ORIGIN = 0x00400000, LENGTH = 0x00200000
  ram (rwx) : ORIGIN = 0x20400000, LENGTH = 0x00060000
  sdram (rwxa) : ORIGIN = 0x70000000, LENGTH = 0x00200000
}

/* The stack size used by the application. NOTE: you need to adjust according to your application. */
STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : 0x2000;
__ram_end__ = ORIGIN(ram) + LENGTH(ram) - 4;

/*SDRAM*/
__sdram_end__ = ORIGIN(sdram) + LENGTH(sdram) - 4;

/* The heapsize used by the application. NOTE: you need to adjust according to your application. */
HEAP_SIZE = DEFINED(HEAP_SIZE) ? HEAP_SIZE : 0x1000;

/* Section Definitions */
SECTIONS
{
    .text :
    {
        . = ALIGN(4);
        _sfixed = .;
        KEEP(*(.vectors .vectors.*))
        *(.text .text.* .gnu.linkonce.t.*)
        *(.glue_7t) *(.glue_7)
        *(.rodata .rodata* .gnu.linkonce.r.*)
        *(.ARM.extab* .gnu.linkonce.armextab.*)

        /* Support C constructors, and C destructors in both user code
           and the C library. This also provides support for C++ code. */
        . = ALIGN(4);
        KEEP(*(.init))
        . = ALIGN(4);
        __preinit_array_start = .;
        KEEP (*(.preinit_array))
        __preinit_array_end = .;

        . = ALIGN(4);
        __init_array_start = .;
        KEEP (*(SORT(.init_array.*)))
        KEEP (*(.init_array))
        __init_array_end = .;

        . = ALIGN(0x4);
        KEEP (*crtbegin.o(.ctors))
        KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
        KEEP (*(SORT(.ctors.*)))
        KEEP (*crtend.o(.ctors))

        . = ALIGN(4);
        KEEP(*(.fini))

        . = ALIGN(4);
        __fini_array_start = .;
        KEEP (*(.fini_array))
        KEEP (*(SORT(.fini_array.*)))
        __fini_array_end = .;

        KEEP (*crtbegin.o(.dtors))
        KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
        KEEP (*(SORT(.dtors.*)))
        KEEP (*crtend.o(.dtors))

        . = ALIGN(4);
        _efixed = .;            /* End of text section */
    } > rom

    /* .ARM.exidx is sorted, so has to go in its own output section.  */
    PROVIDE_HIDDEN (__exidx_start = .);
    .ARM.exidx :
    {
      *(.ARM.exidx* .gnu.linkonce.armexidx.*)
    } > rom
    PROVIDE_HIDDEN (__exidx_end = .);

    . = ALIGN(4);
    _etext = .;

    .relocate : AT (_etext)
    {
        . = ALIGN(4);
        _srelocate = .;
        *(.ramfunc .ramfunc.*);
        *(.data .data.*);
        . = ALIGN(4);
        _erelocate = .;
    } > ram

    /* .bss section which is used for uninitialized data */
    .bss (NOLOAD) :
    {
        . = ALIGN(4);
        _sbss = . ;
        _szero = .;
        *(.bss .bss.*)
        *(COMMON)
        . = ALIGN(4);
        _ebss = . ;
        _ezero = .;
    } > ram

    /* stack section */
    .stack (NOLOAD):
    {
        . = ALIGN(8);
        _sstack = .;
        . = . + STACK_SIZE;
        . = ALIGN(8);
        _estack = .;
    } > ram

    /* heap section */
    .heap (NOLOAD):
    {
        . = ALIGN(8);
         _sheap = .;
        . = . + HEAP_SIZE;
        . = ALIGN(8);
        _eheap = .;
    } > ram

 .data_sdram ORIGIN(sdram) :
 {
  . = ALIGN(4);
  PROVIDE(_data_sdram = .);
  *(.data_sdram)
  . = ALIGN(8);
  PROVIDE(_edata_sdram = .);
 } >sdram

    . = ALIGN(4);
    _end = . ;
    _ram_end_ = ORIGIN(ram) + LENGTH(ram) -1 ;
 _sdram_end_ = ORIGIN(sdram) + LENGTH(sdram) -1 ;
}

SECTIONS
{
    _itcm_lma = _end;
    .code_TCM :
    AT ( _itcm_lma )
    {
        _sitcm = .; *(.code_TCM); _eitcm = .;
    } > itcm

    .data_TCM :
    {
        _sdtcm = .; *(.data_TCM); _edtcm = .;
    } > dtcm

    .DTCM_stack :
    {
        . = ALIGN(8);
        _sdtcm_stack = .;
        . += STACK_SIZE;
        _edtcm_stack = .;
    } > dtcm
}

location of variables:

 

__attribute__((__section__(".data_TCM")))  static float  Ia_buf[Sampls];
__attribute__((__section__(".data_TCM")))  static float  Ib_buf[Sampls];
__attribute__((__section__(".data_TCM")))  static float  Ic_buf[Sampls];
__attribute__((__section__(".data_TCM")))  static float  I0_buf[Sampls];
__attribute__((__section__(".data_TCM")))  static float  Ua_buf[Sampls];
__attribute__((__section__(".data_TCM")))  static float  Ub_buf[Sampls];
__attribute__((__section__(".data_TCM")))  static float  Uc_buf[Sampls];
__attribute__((__section__(".data_TCM")))  static float  U0_buf[Sampls];

What did I do wrong?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Should the section that copies the vector table to ITCM from SRAM

// Copy Vector Table to beginning of ITCM (Address 0)
pSrc  = (uint32_t*)&exception_table;
pDest  = (uint32_t*)0;
pDestEnd = (uint32_t*)sizeof(DeviceVectors);

for(; pDest < pDestEnd;)
{
    *pDest++ = *pSrc++;
}

actually be

// Copy Vector Table to beginning of ITCM (Address 0)
pSrc  = (uint32_t*)&exception_table;
pDest  = (uint32_t*)0;
pDestEnd = (uint32_t*)(sizeof(exception_table)/sizeof(DeviceVectors));

for(; pDest < pDestEnd;)
{
    *pDest++ = *pSrc++;
}

 

Is it better to store the vector table in instruction TCM (ITCM) than data TCM (DTCM)?

 

 

Last Edited: Fri. Dec 8, 2017 - 12:29 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I use the standard ASF functions (init.c)

#ifdef CONF_BOARD_ENABLE_TCM_AT_INIT
 /* TCM Configuration */
 EFC->EEFC_FCR = (EEFC_FCR_FKEY_PASSWD | EEFC_FCR_FCMD_CGPB 
     | EEFC_FCR_FARG(8));
 EFC->EEFC_FCR = (EEFC_FCR_FKEY_PASSWD | EEFC_FCR_FCMD_SGPB
     | EEFC_FCR_FARG(7));
 tcm_enable();
#if defined(__GNUC__)
 volatile char *dst = &_sitcm;
 volatile char *src = &_itcm_lma;
 /* copy code_TCM from flash to ITCM */
 while(dst < &_eitcm){
  *dst++ = *src++;
 }
#endif
#else
 /* TCM Configuration */
 EFC->EEFC_FCR = (EEFC_FCR_FKEY_PASSWD | EEFC_FCR_FCMD_CGPB 
     | EEFC_FCR_FARG(8));
 EFC->EEFC_FCR = (EEFC_FCR_FKEY_PASSWD | EEFC_FCR_FCMD_CGPB 
     | EEFC_FCR_FARG(7));
 
 tcm_disable();
#endif

I tried to run an example from xdk-asf-3.35.1 (sam_tcm). The result was the same - an error message.

Do I need to configure something in the ToolChain?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

0x20000000 to 0x20000938 in the error message is SRAM.  Does it successfully program the target?  What happens when a breakpoint is inserted at the first exectuable line in init.c?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

According to the documentation, the address range of DTCM 0x20000000 is 0x20400000.

http://www.atmel.com/Images/Atmel-42555-SMART-SAM-E70-TCM-Memory_Application%20Note_AT14971.pdf

 

The message occurs before the breakpoint.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Has anyone run the sample "sam_tcm" from xdk-asf-3.35.1?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

0x938 is 2,360 bytes.  Does this resembled any numbers from the summary at the end of compilation?  It seems like the programmer is trying to program SRAM/TCM instead of programming flash.  Do you know why that would be?  Is the correct linker file used?  Does the .map file show everything is correct?

Last Edited: Thu. Dec 21, 2017 - 04:43 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The linker from the example "sam_tcm" ( xdk-asf-3.35.1)

/**
 * \file
 *
 * Copyright (c) 2015 Atmel Corporation. All rights reserved.
 *
 * \asf_license_start
 *
 * \page License
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * 3. The name of Atmel may not be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * 4. This software may only be redistributed and used in connection with an
 *    Atmel microcontroller product.
 *
 * 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
 * EXPRESSLY AND SPECIFICALLY 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.
 *
 * \asf_license_stop
 *
 */

/*------------------------------------------------------------------------------
 *      Linker script for running in internal FLASH on the ATSAME70Q21
 *----------------------------------------------------------------------------*/

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
SEARCH_DIR(.)


/* Memory Spaces Definitions */
MEMORY
{
  itcm (rwx) : ORIGIN = 0x00000000, LENGTH = 0x00008000
  dtcm (rw) : ORIGIN = 0x20000000, LENGTH = 0x00008000
  rom (rx)  : ORIGIN = 0x00400000, LENGTH = 0x00200000
  ram (rwx) : ORIGIN = 0x20400000, LENGTH = 0x00060000
}

/* The stack size used by the application. NOTE: you need to adjust according to your application. */
STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : 0x2000;
__ram_end__ = ORIGIN(ram) + LENGTH(ram) - 4;

/* The heapsize used by the application. NOTE: you need to adjust according to your application. */
HEAP_SIZE = DEFINED(HEAP_SIZE) ? HEAP_SIZE : 0x1000;

/* Section Definitions */
SECTIONS
{
    .text :
    {
        . = ALIGN(4);
        _sfixed = .;
        KEEP(*(.vectors .vectors.*))
        *(.text .text.* .gnu.linkonce.t.*)
        *(.glue_7t) *(.glue_7)
        *(.rodata .rodata* .gnu.linkonce.r.*)
        *(.ARM.extab* .gnu.linkonce.armextab.*)

        /* Support C constructors, and C destructors in both user code
           and the C library. This also provides support for C++ code. */
        . = ALIGN(4);
        KEEP(*(.init))
        . = ALIGN(4);
        __preinit_array_start = .;
        KEEP (*(.preinit_array))
        __preinit_array_end = .;

        . = ALIGN(4);
        __init_array_start = .;
        KEEP (*(SORT(.init_array.*)))
        KEEP (*(.init_array))
        __init_array_end = .;

        . = ALIGN(0x4);
        KEEP (*crtbegin.o(.ctors))
        KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
        KEEP (*(SORT(.ctors.*)))
        KEEP (*crtend.o(.ctors))

        . = ALIGN(4);
        KEEP(*(.fini))

        . = ALIGN(4);
        __fini_array_start = .;
        KEEP (*(.fini_array))
        KEEP (*(SORT(.fini_array.*)))
        __fini_array_end = .;

        KEEP (*crtbegin.o(.dtors))
        KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
        KEEP (*(SORT(.dtors.*)))
        KEEP (*crtend.o(.dtors))

        . = ALIGN(4);
        _efixed = .;            /* End of text section */
    } > rom

    /* .ARM.exidx is sorted, so has to go in its own output section.  */
    PROVIDE_HIDDEN (__exidx_start = .);
    .ARM.exidx :
    {
      *(.ARM.exidx* .gnu.linkonce.armexidx.*)
    } > rom
    PROVIDE_HIDDEN (__exidx_end = .);

    . = ALIGN(4);
    _etext = .;

    .relocate : AT (_etext)
    {
        . = ALIGN(4);
        _srelocate = .;
        *(.ramfunc .ramfunc.*);
        *(.data .data.*);
        . = ALIGN(4);
        _erelocate = .;
    } > ram

    /* .bss section which is used for uninitialized data */
    .bss (NOLOAD) :
    {
        . = ALIGN(4);
        _sbss = . ;
        _szero = .;
        *(.bss .bss.*)
        *(COMMON)
        . = ALIGN(4);
        _ebss = . ;
        _ezero = .;
    } > ram

    /* stack section */
    .stack (NOLOAD):
    {
        . = ALIGN(8);
        _sstack = .;
        . = . + STACK_SIZE;
        . = ALIGN(8);
        _estack = .;
    } > ram

    /* heap section */
    .heap (NOLOAD):
    {
        . = ALIGN(8);
         _sheap = .;
        . = . + HEAP_SIZE;
        . = ALIGN(8);
        _eheap = .;
    } > ram

    . = ALIGN(4);
    _end = . ;
    _ram_end_ = ORIGIN(ram) + LENGTH(ram) -1 ;
}

SECTIONS
{
    _itcm_lma = _end;
    .code_TCM :
    AT ( _itcm_lma )
    {
        _sitcm = .; *(.code_TCM); _eitcm = .;
    } > itcm

    .data_TCM :
    {
        _sdtcm = .; *(.data_TCM); _edtcm = .;
    } > dtcm

    .DTCM_stack :
    {
        . = ALIGN(8);
        _sdtcm_stack = .;
        . += STACK_SIZE;
        _edtcm_stack = .;
    } > dtcm
}

map file

.code_TCM       0x00000000       0xcc load address 0x20407ab8
                0x00000000                _sitcm = .
 *(.code_TCM)
 .code_TCM      0x00000000       0xcc src/main.o
                0x000000cc                _eitcm = .

.eh_frame       0x000000cc        0x0 load address 0x20407b84
 .eh_frame      0x000000cc        0x0 c:/program files (x86)/atmel/studio/7.0/toolchain/arm/arm-gnu-toolchain/bin/../lib/gcc/arm-none-eabi/6.3.1/thumb/v7e-m/crtbegin.o

.data_TCM       0x20000000     0x4000
                0x20000000                _sdtcm = .
 *(.data_TCM)
 .data_TCM      0x20000000     0x4000 src/main.o
                0x20000000                tcm_srcbuff
                0x20001000                tcm_destbuff
                0x20004000                _edtcm = .

.jcr            0x20004000        0x0
 .jcr           0x20004000        0x0 c:/program files (x86)/atmel/studio/7.0/toolchain/arm/arm-gnu-toolchain/bin/../lib/gcc/arm-none-eabi/6.3.1/thumb/v7e-m/crtbegin.o

.igot.plt       0x20004000        0x0
 .igot.plt      0x20004000        0x0 c:/program files (x86)/atmel/studio/7.0/toolchain/arm/arm-gnu-toolchain/bin/../lib/gcc/arm-none-eabi/6.3.1/thumb/v7e-m/crtbegin.o

.DTCM_stack     0x20004000     0x2000
                0x20004000                . = ALIGN (0x8)
                0x20004000                _sdtcm_stack = .
                0x20006000                . = (. + STACK_SIZE)
 *fill*         0x20004000     0x2000 
                0x20006000                _edtcm_stack = .

When I try to load an example from xdk-asf-3.35.1 into the MCU, the following error occurs:

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I don't see anything strange in the .map.  It's trying to program the SRAM from some reason.  What does Tools->Device Programming look like?
 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for the help. GPNVM (8,7) bits were not set.

The example "sam_tcm" (xdk-asf-3.35.1) works.

In the example, a function located in DTCM is called once. In my program, the function located in DTCM is called cyclically.

For some reason after exiting the function, the program stops.

The function declaration in the header file.

 #ifdef CONF_BOARD_ENABLE_TCM_AT_INIT
 __attribute__((__section__(".code_TCM")))
 #endif
 void AI_Processing(void);

Implementation of the function.

#ifdef CONF_BOARD_ENABLE_TCM_AT_INIT
__attribute__((__section__(".code_TCM")))
#endif
void AI_Processing()
{
    //.......
    
    //.......   
}

What is the reason for this behavior?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I think pDestEnd should be divided by four because sizeof(uint32_t) is four times larger than uint32_t.  This is overwriting code in ITCM if I am correct because the loop is overflowing past the exception table where code is located and going into the code (!)

 // Copy Vector Table to beginning of ITCM (Address 0)
 pSrc  = (uint32_t*)&exception_table;
 pDest  = (uint32_t*)0;
 pDestEnd = (uint32_t*)sizeof (DeviceVectors);

 for (; pDest < pDestEnd;)
 {
  *pDest++ = *pSrc++;
 }
 

should be

 // Copy Vector Table to beginning of ITCM (Address 0)
 pSrc  = (uint32_t*)&exception_table;
 pDest  = (uint32_t*)0;
 pDestEnd = (uint32_t*)(sizeof (DeviceVectors)/4);

 for (; pDest < pDestEnd;)
 {
  *pDest++ = *pSrc++;
 }

 

I think the comments for setting the GPNVM bits for TCM should say set bit instead of clear bit. 

 if ((ulEEFC_bits & 0x180) != 0x180)
 {
  __DSB();
  __ISB();
  EFC->EEFC_FCR = (EEFC_FCR_FKEY_PASSWD | EEFC_FCR_FCMD_SGPB | EEFC_FCR_FARG(7));  //issue command to clear bit 7
  __DSB();
  __ISB();

  while(!(EFC->EEFC_FSR & EEFC_FSR_FRDY));     //Wait until the status falls to 0 (EFFC command is complete)

  __DSB();
  __ISB();
  EFC->EEFC_FCR = (EEFC_FCR_FKEY_PASSWD | EEFC_FCR_FCMD_SGPB | EEFC_FCR_FARG(8));  //issue command to clear bit 8
  __DSB();
  __ISB();

to

 

 if ((ulEEFC_bits & 0x180) != 0x180)
 {
  __DSB();
  __ISB();
  EFC->EEFC_FCR = (EEFC_FCR_FKEY_PASSWD | EEFC_FCR_FCMD_SGPB | EEFC_FCR_FARG(7));  //issue command to set bit 7
  __DSB();
  __ISB();

  while(!(EFC->EEFC_FSR & EEFC_FSR_FRDY));     //Wait until the status falls to 0 (EFFC command is complete)

  __DSB();
  __ISB();
  EFC->EEFC_FCR = (EEFC_FCR_FKEY_PASSWD | EEFC_FCR_FCMD_SGPB | EEFC_FCR_FARG(8));  //issue command to set bit 8
  __DSB();
  __ISB();

 

Another syntax option for relocating the stack pointer is __set_MSP(uint32_t MainStackPtrLimit).  (Main Stack Pointer)

 

//Now that we're at the point in this routine where we don't need any stack variables,
//update our stack pointer to the runtime stack pointer that lives in DTCM
dtcm_stack_pointer_addr = (uint32_t)&_e_runtime_stack;

//asm(code : output operand list : input operand list : clobber list);
__ASM volatile ("mov.w r1, %0"::"r" (dtcm_stack_pointer_addr):"r1");    //write r1 with the address of DTCM where the beginning of the stack lives (per the linker)
__ASM volatile("mov sp, r1");              //update the stack pointer with the stack address that lives in r1

__DSB();
__ISB();

to

#include "cmsis_gcc.h"

//Now that we're at the point in this routine where we don't need any stack variables,
//update our stack pointer to the runtime stack pointer that lives in DTCM
__set_MSP((uint32_t)&_e_runtime_stack);
__DSB();
__ISB();

Picking which one is just a preference.  Both are correct

 

Last Edited: Mon. Apr 9, 2018 - 08:26 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

sizeof(DeviceVectors) should be the size of the entire structure. In other words, it spans from 0 to (sizeof(DeviceVectors)) in memory. You're comparing the destination pointer to the end pointer to decide when to quit. It looks correct to me as written.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

nsayer wrote:

sizeof(DeviceVectors) should be the size of the entire structure. In other words, it spans from 0 to (sizeof(DeviceVectors)) in memory. You're comparing the destination pointer to the end pointer to decide when to quit. It looks correct to me as written.

 

I was wrong. The code is correct sorry.  You are correct.

 

Anyone using an Atmel Cortex-M7 device should check the const DeviceVectors exception_table in startup_samXX.c against the datasheet.  I confirmed with Atmel the list of peripherals in some startup_samXX.c does not match the datasheet (pg. 52 Section 10 - Product Mapping).  The const DeviceVectors exception_table in post 6 is an example.  The timer counters TCx between 23 to 28 and 47 to 52 do not match the datasheet at first glance and are incorrect.  I didn't check the full exception table. Others may be wrong besides the timer counters.   

Last Edited: Tue. Apr 10, 2018 - 12:45 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I've been investigating the TCM setup for my SAM V71 Xplained Ultra board since last week. I tried to follow the application note in http://www.microchip.com//wwwApp... and a thread in https://www.avrfreaks.net/commen.... But I cannot get it run.

The problem is the two buffers are located in the section "data_TCM" as I wanted (the value of add_tx and add_rx record the buffer address). But they don't have any value as shown in the debug mode, like this. They are not initialized and their value seems undefined.

/** The buffer for transmit and receive  */
 __attribute__((__section__(".data_TCM"))) uint8_t tx_buffer[BUFFER_SIZE];
 __attribute__((__section__(".data_TCM"))) uint8_t rx_buffer[BUFFER_SIZE];

 as a result, when I try to access the two buffers, the program is going to Dummy_Handler. Here are the linker script and startup.c. Any idea about this? I am new to the linker script and the memory remap things... Thanks in advance!

 

Linker script:

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")

OUTPUT_ARCH(arm)

SEARCH_DIR(.)

 

/* Memory Spaces Definitions */

MEMORY

{

  itcm (rwx) : ORIGIN = 0x00000000, LENGTH = 0x00020000

  rom (rx)  : ORIGIN = 0x00400000, LENGTH = 0x00200000

  dtcm (rw) : ORIGIN = 0x20000000, LENGTH = 0x00020000

  ram (rwx) : ORIGIN = 0x20400000, LENGTH = 0x00060000

}

 

/* The stack size used by the application. NOTE: you need to adjust according to your application. */

STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : 0x2000;

__ram_end__ = ORIGIN(ram) + LENGTH(ram) - 4;

 

/* The heapsize used by the application. NOTE: you need to adjust according to your application. */

HEAP_SIZE = DEFINED(HEAP_SIZE) ? HEAP_SIZE : 0x1000;

 

/* Section Definitions */

SECTIONS

{

    .text :

    {

        . = ALIGN(4);

        _sfixed = .;

        KEEP(*(.vectors .vectors.*))

        *(.text .text.* .gnu.linkonce.t.*)

        *(.glue_7t) *(.glue_7)

        *(.rodata .rodata* .gnu.linkonce.r.*)

        *(.ARM.extab* .gnu.linkonce.armextab.*)

 

        /* Support C constructors, and C destructors in both user code

           and the C library. This also provides support for C++ code. */

        . = ALIGN(4);

        KEEP(*(.init))

        . = ALIGN(4);

        __preinit_array_start = .;

        KEEP (*(.preinit_array))

        __preinit_array_end = .;

 

        . = ALIGN(4);

        __init_array_start = .;

        KEEP (*(SORT(.init_array.*)))

        KEEP (*(.init_array))

        __init_array_end = .;

 

        . = ALIGN(0x4);

        KEEP (*crtbegin.o(.ctors))

        KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))

        KEEP (*(SORT(.ctors.*)))

        KEEP (*crtend.o(.ctors))

 

        . = ALIGN(4);

        KEEP(*(.fini))

 

        . = ALIGN(4);

        __fini_array_start = .;

        KEEP (*(.fini_array))

        KEEP (*(SORT(.fini_array.*)))

        __fini_array_end = .;

 

        KEEP (*crtbegin.o(.dtors))

        KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))

        KEEP (*(SORT(.dtors.*)))

        KEEP (*crtend.o(.dtors))

 

        . = ALIGN(4);

        _efixed = .;            /* End of text section */

    } > rom

 

    /* .ARM.exidx is sorted, so has to go in its own output section.  */

    PROVIDE_HIDDEN (__exidx_start = .);

    .ARM.exidx :

    {

      *(.ARM.exidx* .gnu.linkonce.armexidx.*)

    } > rom

    PROVIDE_HIDDEN (__exidx_end = .);

 

    . = ALIGN(4);

    _etext = .;

 

    .relocate : AT (_etext)

    {

        . = ALIGN(4);

        _srelocate = .;

        *(.ramfunc .ramfunc.*);

        *(.data .data.*);

        . = ALIGN(4);

        _erelocate = .;

    } > ram

 

    /* .bss section which is used for uninitialized data */

    .bss (NOLOAD) :

    {

        . = ALIGN(4);

        _sbss = . ;

        _szero = .;

        *(.bss .bss.*)

        *(COMMON)

        . = ALIGN(4);

        _ebss = . ;

        _ezero = .;

    } > ram

 

    /* stack section */

    .stack (NOLOAD):

    {

        . = ALIGN(8);

        _sstack = .;

        . = . + STACK_SIZE;

        . = ALIGN(8);

        _estack = .;

    } > ram

 

    /* heap section */

    .heap (NOLOAD):

    {

        . = ALIGN(8);

         _sheap = .;

        . = . + HEAP_SIZE;

        . = ALIGN(8);

        _eheap = .;

    } > ram

 

    . = ALIGN(4);

    _end = . ;

    _ram_end_ = ORIGIN(ram) + LENGTH(ram) -1 ;

}

 

SECTIONS

{

    _itcm_lma = _etext + SIZEOF(.relocate);

    .code_TCM :

    AT ( _itcm_lma )

    {

        _sitcm = .; *(.code_TCM); _eitcm = .;

    } > itcm

 

_dtcm_lma = _itcm_lma + SIZEOF(.code_TCM);

    .data_TCM :

AT ( _dtcm_lma )

    {

        _sdtcm = .; *(.data_TCM); _edtcm = .;

    } > dtcm

_dtcm_stack_lma = _dtcm_lma + SIZEOF(.data_TCM);

    .DTCM_stack :

AT ( _dtcm_stack_lma )

    {

        . = ALIGN(8);

        _sdtcm_stack = .;

        . += STACK_SIZE;

        _edtcm_stack = .;

    } > dtcm

}

 

startup_samv71.c

/**

 * \file

 *

 * Copyright (c) 2015 Atmel Corporation. All rights reserved.

 *

 * \asf_license_start

 *

 * \page License

 *

 * Redistribution and use in source and binary forms, with or without

 * modification, are permitted provided that the following conditions are met:

 *

 * 1. Redistributions of source code must retain the above copyright notice,

 *    this list of conditions and the following disclaimer.

 *

 * 2. Redistributions in binary form must reproduce the above copyright notice,

 *    this list of conditions and the following disclaimer in the documentation

 *    and/or other materials provided with the distribution.

 *

 * 3. The name of Atmel may not be used to endorse or promote products derived

 *    from this software without specific prior written permission.

 *

 * 4. This software may only be redistributed and used in connection with an

 *    Atmel microcontroller product.

 *

 * 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

 * EXPRESSLY AND SPECIFICALLY 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.

 *

 * \asf_license_stop

 *

 */

/*

 * Support and FAQ: visit <a href="http://www.atmel.com/design-supp...">Atmel Support</a>

 */

 

#include "samv71.h"

 

#if __FPU_USED /* CMSIS defined value to indicate usage of FPU */

#include "fpu.h"

#endif

 

/* Initialize segments */

extern uint32_t _sfixed;

extern uint32_t _efixed;

extern uint32_t _etext;

extern uint32_t _srelocate;

extern uint32_t _erelocate;

extern uint32_t _szero;

extern uint32_t _ezero;

extern uint32_t _sstack;

extern uint32_t _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))

/** \cond DOXYGEN_SHOULD_SKIP_THIS */

int main(void);

/** \endcond */

 

void __libc_init_array(void);

 

/* Default empty handler */

void Dummy_Handler(void);

 

/* Cortex-M7 core handlers */

void NMI_Handler        ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

void HardFault_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

void MemManage_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

void BusFault_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

void UsageFault_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

void SVC_Handler        ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

void DebugMon_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

void PendSV_Handler     ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

void SysTick_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

 

/* Peripherals handlers */

void SUPC_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

void RSTC_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

void RTC_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

void RTT_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

void WDT_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

void PMC_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

void EFC_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

void UART0_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

void UART1_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

void PIOA_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

void PIOB_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

#ifdef _SAMV71_PIOC_INSTANCE_

void PIOC_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

#endif /* _SAMV71_PIOC_INSTANCE_ */

void USART0_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

void USART1_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

void USART2_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

void PIOD_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

#ifdef _SAMV71_PIOE_INSTANCE_

void PIOE_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

#endif /* _SAMV71_PIOE_INSTANCE_ */

void HSMCI_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

void TWIHS0_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

void TWIHS1_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

void SPI0_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

void SSC_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

void TC0_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

void TC1_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

void TC2_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

#ifdef _SAMV71_TC1_INSTANCE_

void TC3_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

#endif /* _SAMV71_TC1_INSTANCE_ */

#ifdef _SAMV71_TC1_INSTANCE_

void TC4_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

#endif /* _SAMV71_TC1_INSTANCE_ */

#ifdef _SAMV71_TC1_INSTANCE_

void TC5_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

#endif /* _SAMV71_TC1_INSTANCE_ */

void AFEC0_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

#ifdef _SAMV71_DACC_INSTANCE_

void DACC_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

#endif /* _SAMV71_DACC_INSTANCE_ */

void PWM0_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

void ICM_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

void ACC_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

void USBHS_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

void MCAN0_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

void MCAN1_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

void GMAC_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

void AFEC1_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

#ifdef _SAMV71_TWIHS2_INSTANCE_

void TWIHS2_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

#endif /* _SAMV71_TWIHS2_INSTANCE_ */

void SPI1_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

void QSPI_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

void UART2_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

void UART3_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

void UART4_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

#ifdef _SAMV71_TC2_INSTANCE_

void TC6_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

#endif /* _SAMV71_TC2_INSTANCE_ */

#ifdef _SAMV71_TC2_INSTANCE_

void TC7_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

#endif /* _SAMV71_TC2_INSTANCE_ */

#ifdef _SAMV71_TC2_INSTANCE_

void TC8_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

#endif /* _SAMV71_TC2_INSTANCE_ */

void TC9_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

void TC10_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

void TC11_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

void MLB_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

void AES_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

void TRNG_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

void XDMAC_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

void ISI_Handler    ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

void PWM1_Handler   ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

#ifdef _SAMV71_SDRAMC_INSTANCE_

void SDRAMC_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

#endif /* _SAMV71_SDRAMC_INSTANCE_ */

void RSWDT_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

 

/* Exception Table */

__attribute__ ((section(".vectors")))

const DeviceVectors exception_table = {

 

        /* Configure Initial Stack Pointer, using linker-generated symbols */

        .pvStack = (void*) (&_estack),

 

        .pfnReset_Handler      = (void*) Reset_Handler,

        .pfnNMI_Handler        = (void*) NMI_Handler,

        .pfnHardFault_Handler  = (void*) HardFault_Handler,

        .pfnMemManage_Handler  = (void*) MemManage_Handler,

        .pfnBusFault_Handler   = (void*) BusFault_Handler,

        .pfnUsageFault_Handler = (void*) UsageFault_Handler,

        .pfnReserved1_Handler  = (void*) (0UL),          /* Reserved */

        .pfnReserved2_Handler  = (void*) (0UL),          /* Reserved */

        .pfnReserved3_Handler  = (void*) (0UL),          /* Reserved */

        .pfnReserved4_Handler  = (void*) (0UL),          /* Reserved */

        .pfnSVC_Handler        = (void*) SVC_Handler,

        .pfnDebugMon_Handler   = (void*) DebugMon_Handler,

        .pfnReserved5_Handler  = (void*) (0UL),          /* Reserved */

        .pfnPendSV_Handler     = (void*) PendSV_Handler,

        .pfnSysTick_Handler    = (void*) SysTick_Handler,

 

        /* Configurable interrupts */

        .pfnSUPC_Handler   = (void*) SUPC_Handler,   /* 0  Supply Controller */

        .pfnRSTC_Handler   = (void*) RSTC_Handler,   /* 1  Reset Controller */

        .pfnRTC_Handler    = (void*) RTC_Handler,    /* 2  Real Time Clock */

        .pfnRTT_Handler    = (void*) RTT_Handler,    /* 3  Real Time Timer */

        .pfnWDT_Handler    = (void*) WDT_Handler,    /* 4  Watchdog Timer */

        .pfnPMC_Handler    = (void*) PMC_Handler,    /* 5  Power Management Controller */

        .pfnEFC_Handler    = (void*) EFC_Handler,    /* 6  Enhanced Embedded Flash Controller */

        .pfnUART0_Handler  = (void*) UART0_Handler,  /* 7  UART 0 */

        .pfnUART1_Handler  = (void*) UART1_Handler,  /* 8  UART 1 */

        .pvReserved9       = (void*) (0UL),          /* 9  Reserved */

        .pfnPIOA_Handler   = (void*) PIOA_Handler,   /* 10 Parallel I/O Controller A */

        .pfnPIOB_Handler   = (void*) PIOB_Handler,   /* 11 Parallel I/O Controller B */

#ifdef _SAMV71_PIOC_INSTANCE_

        .pfnPIOC_Handler   = (void*) PIOC_Handler,   /* 12 Parallel I/O Controller C */

#else

        .pvReserved12      = (void*) (0UL),          /* 12 Reserved */

#endif /* _SAMV71_PIOC_INSTANCE_ */

        .pfnUSART0_Handler = (void*) USART0_Handler, /* 13 USART 0 */

        .pfnUSART1_Handler = (void*) USART1_Handler, /* 14 USART 1 */

        .pfnUSART2_Handler = (void*) USART2_Handler, /* 15 USART 2 */

        .pfnPIOD_Handler   = (void*) PIOD_Handler,   /* 16 Parallel I/O Controller D */

#ifdef _SAMV71_PIOE_INSTANCE_

        .pfnPIOE_Handler   = (void*) PIOE_Handler,   /* 17 Parallel I/O Controller E */

#else

        .pvReserved17      = (void*) (0UL),          /* 17 Reserved */

#endif /* _SAMV71_PIOE_INSTANCE_ */

        .pfnHSMCI_Handler  = (void*) HSMCI_Handler,  /* 18 Multimedia Card Interface */

        .pfnTWIHS0_Handler = (void*) TWIHS0_Handler, /* 19 Two Wire Interface 0 HS */

        .pfnTWIHS1_Handler = (void*) TWIHS1_Handler, /* 20 Two Wire Interface 1 HS */

        .pfnSPI0_Handler   = (void*) SPI0_Handler,   /* 21 Serial Peripheral Interface 0 */

        .pfnSSC_Handler    = (void*) SSC_Handler,    /* 22 Synchronous Serial Controller */

        .pfnTC0_Handler    = (void*) TC0_Handler,    /* 23 Timer/Counter 0 */

        .pfnTC1_Handler    = (void*) TC1_Handler,    /* 24 Timer/Counter 1 */

        .pfnTC2_Handler    = (void*) TC2_Handler,    /* 25 Timer/Counter 2 */

#ifdef _SAMV71_TC1_INSTANCE_

        .pfnTC3_Handler    = (void*) TC3_Handler,    /* 26 Timer/Counter 3 */

#else

        .pvReserved26      = (void*) (0UL),          /* 26 Reserved */

#endif /* _SAMV71_TC1_INSTANCE_ */

#ifdef _SAMV71_TC1_INSTANCE_

        .pfnTC4_Handler    = (void*) TC4_Handler,    /* 27 Timer/Counter 4 */

#else

        .pvReserved27      = (void*) (0UL),          /* 27 Reserved */

#endif /* _SAMV71_TC1_INSTANCE_ */

#ifdef _SAMV71_TC1_INSTANCE_

        .pfnTC5_Handler    = (void*) TC5_Handler,    /* 28 Timer/Counter 5 */

#else

        .pvReserved28      = (void*) (0UL),          /* 28 Reserved */

#endif /* _SAMV71_TC1_INSTANCE_ */

        .pfnAFEC0_Handler  = (void*) AFEC0_Handler,  /* 29 Analog Front End 0 */

#ifdef _SAMV71_DACC_INSTANCE_

        .pfnDACC_Handler   = (void*) DACC_Handler,   /* 30 Digital To Analog Converter */

#else

        .pvReserved30      = (void*) (0UL),          /* 30 Reserved */

#endif /* _SAMV71_DACC_INSTANCE_ */

        .pfnPWM0_Handler   = (void*) PWM0_Handler,   /* 31 Pulse Width Modulation 0 */

        .pfnICM_Handler    = (void*) ICM_Handler,    /* 32 Integrity Check Monitor */

        .pfnACC_Handler    = (void*) ACC_Handler,    /* 33 Analog Comparator */

        .pfnUSBHS_Handler  = (void*) USBHS_Handler,  /* 34 USB Host / Device Controller */

        .pfnMCAN0_Handler  = (void*) MCAN0_Handler,  /* 35 MCAN Controller 0 */

        .pvReserved36      = (void*) (0UL),          /* 36 Reserved */

        .pfnMCAN1_Handler  = (void*) MCAN1_Handler,  /* 37 MCAN Controller 1 */

        .pvReserved38      = (void*) (0UL),          /* 38 Reserved */

        .pfnGMAC_Handler   = (void*) GMAC_Handler,   /* 39 Ethernet MAC */

        .pfnAFEC1_Handler  = (void*) AFEC1_Handler,  /* 40 Analog Front End 1 */

#ifdef _SAMV71_TWIHS2_INSTANCE_

        .pfnTWIHS2_Handler = (void*) TWIHS2_Handler, /* 41 Two Wire Interface 2 HS */

#else

        .pvReserved41      = (void*) (0UL),          /* 41 Reserved */

#endif /* _SAMV71_TWIHS2_INSTANCE_ */

        .pfnSPI1_Handler   = (void*) SPI1_Handler,   /* 42 Serial Peripheral Interface 1 */

        .pfnQSPI_Handler   = (void*) QSPI_Handler,   /* 43 Quad I/O Serial Peripheral Interface */

        .pfnUART2_Handler  = (void*) UART2_Handler,  /* 44 UART 2 */

        .pfnUART3_Handler  = (void*) UART3_Handler,  /* 45 UART 3 */

        .pfnUART4_Handler  = (void*) UART4_Handler,  /* 46 UART 4 */

#ifdef _SAMV71_TC2_INSTANCE_

        .pfnTC6_Handler    = (void*) TC6_Handler,    /* 47 Timer/Counter 6 */

#else

        .pvReserved47      = (void*) (0UL),          /* 47 Reserved */

#endif /* _SAMV71_TC2_INSTANCE_ */

#ifdef _SAMV71_TC2_INSTANCE_

        .pfnTC7_Handler    = (void*) TC7_Handler,    /* 48 Timer/Counter 7 */

#else

        .pvReserved48      = (void*) (0UL),          /* 48 Reserved */

#endif /* _SAMV71_TC2_INSTANCE_ */

#ifdef _SAMV71_TC2_INSTANCE_

        .pfnTC8_Handler    = (void*) TC8_Handler,    /* 49 Timer/Counter 8 */

#else

        .pvReserved49      = (void*) (0UL),          /* 49 Reserved */

#endif /* _SAMV71_TC2_INSTANCE_ */

        .pfnTC9_Handler    = (void*) TC9_Handler,    /* 50 Timer/Counter 9 */

        .pfnTC10_Handler   = (void*) TC10_Handler,   /* 51 Timer/Counter 10 */

        .pfnTC11_Handler   = (void*) TC11_Handler,   /* 52 Timer/Counter 11 */

        .pfnMLB_Handler    = (void*) MLB_Handler,    /* 53 MediaLB */

        .pvReserved54      = (void*) (0UL),          /* 54 Reserved */

        .pvReserved55      = (void*) (0UL),          /* 55 Reserved */

        .pfnAES_Handler    = (void*) AES_Handler,    /* 56 AES */

        .pfnTRNG_Handler   = (void*) TRNG_Handler,   /* 57 True Random Generator */

        .pfnXDMAC_Handler  = (void*) XDMAC_Handler,  /* 58 DMA */

        .pfnISI_Handler    = (void*) ISI_Handler,    /* 59 Camera Interface */

        .pfnPWM1_Handler   = (void*) PWM1_Handler,   /* 60 Pulse Width Modulation 1 */

        .pvReserved61      = (void*) (0UL),          /* 61 Reserved */

#ifdef _SAMV71_SDRAMC_INSTANCE_

        .pfnSDRAMC_Handler = (void*) SDRAMC_Handler, /* 62 SDRAM Controller */

#else

        .pvReserved62      = (void*) (0UL),          /* 62 Reserved */

#endif /* _SAMV71_SDRAMC_INSTANCE_ */

        .pfnRSWDT_Handler  = (void*) RSWDT_Handler   /* 63 Reinforced Secure Watchdog Timer */

};

 

extern char _itcm_lma, _sitcm, _eitcm, _sdtcm, _dtcm_lma, _edtcm, _sdtcm_stack, _dtcm_stack_lma, _edtcm_stack;

/**

 * \brief This is the code that gets called on processor reset.

 * To initialize the device, and call the main() routine.

 */

void Reset_Handler(void)

{

SystemInit();

/*Configure TCM sizes to: 128 kB ITCM - 128 kB DTCM (set GPNVM7 and GPNVM8)*/

EFC->EEFC_FCR = (EEFC_FCR_FKEY_PASSWD | EEFC_FCR_FCMD_SGPB | EEFC_FCR_FARG(7));

EFC->EEFC_FCR = (EEFC_FCR_FKEY_PASSWD | EEFC_FCR_FCMD_SGPB | EEFC_FCR_FARG(8));

__DSB();

__ISB();

SCB->ITCMCR = (SCB_ITCMCR_EN_Msk | SCB_ITCMCR_RMW_Msk | SCB_ITCMCR_RETEN_Msk);

SCB->DTCMCR = (SCB_DTCMCR_EN_Msk | SCB_DTCMCR_RMW_Msk | SCB_DTCMCR_RETEN_Msk);

__DSB();

__ISB();

        uint32_t *pSrc, *pDest;

 

        /* Initialize the relocate segment */

        pSrc = &_etext;

        pDest = &_srelocate;

 

        if (pSrc != pDest) {

        for (; pDest < &_erelocate;) {

        *pDest++ = *pSrc++;

        }

        }

 

        /* Clear the zero segment */

        for (pDest = &_szero; pDest < &_ezero;) {

                *pDest++ = 0;

        }

 

        /* Set the vector table base address */

        pSrc = (uint32_t *) & _sfixed;

        SCB->VTOR = ((uint32_t) pSrc & SCB_VTOR_TBLOFF_Msk);

 

/* copy code_TCM from flash to ITCM */

volatile char *dst = NULL;

volatile char *src = NULL;

 

/* copy code_TCM from flash to ITCM */

dst = &_sitcm;

src = &_itcm_lma;

while (dst < &_eitcm)

*dst++ = *src++;

 

/* copy data_TCM from flash to DTCM */

dst = &_sdtcm;

src = &_dtcm_lma;

while (dst < &_edtcm)

*dst++ = *src++;

 

/* copy DTCM_stack from flash to DTCM */

dst = &_sdtcm_stack;

src = &_dtcm_stack_lma;

while (dst < &_edtcm_stack)

*dst++ = *src++;

#if __FPU_USED

fpu_enable();

#endif

 

        /* Initialize the C library */

        __libc_init_array();

 

        /* Branch to main function */

        main();

 

        /* Infinite loop */

        while (1);

}

 

/**

 * \brief Default interrupt handler for unused IRQs.

 */

void Dummy_Handler(void)

{

while (1) {

}

}