/*************************************************************************** * Copyright (c) 2024 Microsoft Corporation * * This program and the accompanying materials are made available under the * terms of the MIT License which is available at * https://opensource.org/licenses/MIT. * * SPDX-License-Identifier: MIT **************************************************************************/ /**************************************************************************/ /**************************************************************************/ /** */ /** ThreadX Component */ /** */ /** Initialize */ /** */ /**************************************************************************/ /**************************************************************************/ SYSTEM_CLOCK = 6000000 SYSTICK_CYCLES = ((SYSTEM_CLOCK / 100) -1) .text .align 4 /**************************************************************************/ /* */ /* FUNCTION RELEASE */ /* */ /* _tx_initialize_low_level Cortex-M7/GHS */ /* 6.1 */ /* AUTHOR */ /* */ /* William E. Lamie, Microsoft Corporation */ /* */ /* DESCRIPTION */ /* */ /* This function is responsible for any low-level processor */ /* initialization, including setting up interrupt vectors, setting */ /* up a periodic timer interrupt source, saving the system stack */ /* pointer for use in ISR processing later, and finding the first */ /* available RAM memory address for tx_application_define. */ /* */ /* INPUT */ /* */ /* None */ /* */ /* OUTPUT */ /* */ /* None */ /* */ /* CALLS */ /* */ /* None */ /* */ /* CALLED BY */ /* */ /* _tx_initialize_kernel_enter ThreadX entry function */ /* */ /* RELEASE HISTORY */ /* */ /* DATE NAME DESCRIPTION */ /* */ /* 09-30-2020 William E. Lamie Initial Version 6.1 */ /* */ /**************************************************************************/ /* VOID _tx_initialize_low_level(VOID) { */ .globl _tx_initialize_low_level _tx_initialize_low_level: /* Disable interrupts. */ CPSID i ; Disable interrupts /* Save the system stack pointer. */ /* _tx_thread_system_stack_ptr = (VOID_PTR) (sp); */ LDR r1,=_tx_thread_system_stack_ptr ; Pickup address of system stack ptr STR sp, [r1] ; Save system stack /* Save the first available memory address. */ /* _tx_initialize_unused_memory = (VOID_PTR) __ghsbegin_free_mem; */ LDR r0,=__ghsbegin_free_mem ; Pickup free memory address LDR r2,=_tx_initialize_unused_memory ; Pickup unused memory ptr address STR r0, [r2] ; Save first free memory address /* Enable the cycle count register. */ LDR r0, =0xE0001000 ; Build address of DWT register LDR r1, [r0] ; Pickup the current value ORR r1, r1, 1 ; Set the CYCCNTENA bit STR r1, [r0] ; Enable the cycle count register /* Setup Vector Table Offset Register. */ MOV r0, 0xE000E000 ; Build address of NVIC registers LDR r1, =__vectors ; Pickup address of vector table STR r1, [r0, 0xD08] ; Set vector table address /* Configure SysTick for 100Hz clock, or 16384 cycles if no reference. */ LDR r1, =SYSTICK_CYCLES STR r1, [r0, 0x14] ; Setup SysTick Reload Value MOV r1, 0x7 ; Build SysTick Control Enable Value STR r1, [r0, 0x10] ; Setup SysTick Control /* Configure handler priorities. */ LDR r1, =0x00000000 ; Rsrv, UsgF, BusF, MemM STR r1, [r0, 0xD18] ; Setup System Handlers 4-7 Priority Registers LDR r1, =0xFF000000 ; SVCl, Rsrv, Rsrv, Rsrv STR r1, [r0, 0xD1C] ; Setup System Handlers 8-11 Priority Registers ; Note: SVC must be lowest priority, which is 0xFF LDR r1, =0x40FF0000 ; SysT, PnSV, Rsrv, DbgM STR r1, [r0, 0xD20] ; Setup System Handlers 12-15 Priority Registers ; Note: PnSV must be lowest priority, which is 0xFF #ifdef __VFP__ LDR r0, =0xE000EF34 ; Pickup FPCCR LDR r1, [r0] ; LDR r2, =0x3FFFFFFF ; Build mask to clear ASPEN and LSPEN AND r1, r1, r2 ; Clear the ASPEN and LSPEN bits STR r1, [r0] ; Update FPCCR #endif /* Return to caller. */ BX lr ; Return to caller .type _tx_initialize_low_level,$function .size _tx_initialize_low_level,.-_tx_initialize_low_level /* } */ /* Define shells for each of the interrupt vectors. */ .globl __tx_BadHandler __tx_BadHandler: B __tx_BadHandler .type __tx_BadHandler,$function .size __tx_BadHandler,.-__tx_BadHandler .globl __tx_IntHandler __tx_IntHandler: PUSH {lr} BL _tx_thread_context_save #ifdef TX_ENABLE_EVENT_LOGGING MOV r0, 0 ; Build interrupt code BL _tx_el_interrupt ; Call interrupt event logging #endif ; /* Do interrupt handler work here */ ; /* .... */ #ifdef TX_ENABLE_EVENT_LOGGING MOV r0, 0 ; Build interrupt code BL _tx_el_interrupt_end ; Call interrupt event logging #endif B _tx_thread_context_restore .type __tx_IntHandler,$function .size __tx_IntHandler,.-__tx_IntHandler .globl __tx_SysTickHandler __tx_SysTickHandler: PUSH {lr} BL _tx_thread_context_save #ifdef TX_ENABLE_EVENT_LOGGING MOV r0, 15 ; Build interrupt code BL _tx_el_interrupt ; Call interrupt event logging #endif BL _tx_timer_interrupt #ifdef TX_ENABLE_EVENT_LOGGING MOV r0, 15 ; Build interrupt code BL _tx_el_interrupt_end ; Call interrupt event logging #endif B _tx_thread_context_restore .type __tx_SysTickHandler,$function .size __tx_SysTickHandler,.-__tx_SysTickHandler .globl __tx_NMIHandler __tx_NMIHandler: B __tx_NMIHandler .type __tx_NMIHandler,$function .size __tx_NMIHandler,.-__tx_NMIHandler .globl __tx_DBGHandler __tx_DBGHandler: B __tx_DBGHandler .type __tx_DBGHandler,$function .size __tx_DBGHandler,.-__tx_DBGHandler .globl __tx_SVCallHandler __tx_SVCallHandler: B __tx_SVCallHandler .type __tx_SVCallHandler,$function .size __tx_SVCallHandler,.-__tx_SVCallHandler /* Reference build options and version ID to ensure they come in. */ BUILD_OPTIONS: .data.w _tx_build_options VERSION_ID: .data.w _tx_version_id