From 4085ae3ddfbbf10c8ccbd3dccd43452c40a1fe40 Mon Sep 17 00:00:00 2001 From: Yuval Adam Date: Fri, 13 Mar 2015 12:24:52 +0200 Subject: Add bootloader, nfclib and sensorlib --- boot_loader/bl_startup_rvmdk.S | 653 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 653 insertions(+) create mode 100644 boot_loader/bl_startup_rvmdk.S (limited to 'boot_loader/bl_startup_rvmdk.S') diff --git a/boot_loader/bl_startup_rvmdk.S b/boot_loader/bl_startup_rvmdk.S new file mode 100644 index 0000000..435c325 --- /dev/null +++ b/boot_loader/bl_startup_rvmdk.S @@ -0,0 +1,653 @@ +;****************************************************************************** +; +; bl_startup_rvmdk.S - Startup code for RV-MDK. +; +; Copyright (c) 2007-2014 Texas Instruments Incorporated. All rights reserved. +; Software License Agreement +; +; Texas Instruments (TI) is supplying this software for use solely and +; exclusively on TI's microcontroller products. The software is owned by +; TI and/or its suppliers, and is protected under applicable copyright +; laws. You may not combine this software with "viral" open-source +; software in order to form a larger program. +; +; THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. +; NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +; NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +; A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY +; CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +; DAMAGES, FOR ANY REASON WHATSOEVER. +; +; This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package. +; +;****************************************************************************** + + include bl_config.inc + +;****************************************************************************** +; +; A couple of defines that would normally be obtained from the appropriate C +; header file, but must be manually provided here since the Keil compiler does +; not have a mechanism for passing assembly source through the C preprocessor. +; +;****************************************************************************** +SYSCTL_RESC equ 0x400fe05c +SYSCTL_RESC_MOSCFAIL equ 0x00010000 +NVIC_VTABLE equ 0xe000ed08 + +;****************************************************************************** +; +; Put the assembler into the correct configuration. +; +;****************************************************************************** + thumb + require8 + preserve8 + +;****************************************************************************** +; +; The stack gets placed into the zero-init section. +; +;****************************************************************************** + area ||.bss||, noinit, align=2 + +;****************************************************************************** +; +; Allocate storage for the stack. +; +;****************************************************************************** +g_pulStack + space _STACK_SIZE * 4 + +;****************************************************************************** +; +; This portion of the file goes into the reset section. +; +;****************************************************************************** + area RESET, code, readonly, align=3 + +;****************************************************************************** +; +; The minimal vector table for a Cortex-M3 processor. +; +;****************************************************************************** + export __Vectors +__Vectors + dcd g_pulStack + (_STACK_SIZE * 4) ; Offset 00: Initial stack pointer + dcd Reset_Handler ; Offset 04: Reset handler + dcd NmiSR ; Offset 08: NMI handler + dcd FaultISR ; Offset 0C: Hard fault handler + dcd IntDefaultHandler ; Offset 10: MPU fault handler + dcd IntDefaultHandler ; Offset 14: Bus fault handler + dcd IntDefaultHandler ; Offset 18: Usage fault handler + dcd 0 ; Offset 1C: Reserved + dcd 0 ; Offset 20: Reserved + dcd 0 ; Offset 24: Reserved + dcd 0 ; Offset 28: Reserved + dcd UpdateHandler ; Offset 2C: SVCall handler + dcd IntDefaultHandler ; Offset 30: Debug monitor handler + dcd 0 ; Offset 34: Reserved + dcd IntDefaultHandler ; Offset 38: PendSV handler + if :def:_ENET_ENABLE_UPDATE + import SysTickIntHandler + dcd SysTickIntHandler ; Offset 3C: SysTick handler + else + dcd IntDefaultHandler ; Offset 3C: SysTick handler + endif + if :def:_UART_ENABLE_UPDATE :land: :def:_UART_AUTOBAUD + import GPIOIntHandler + dcd GPIOIntHandler ; Offset 40: GPIO port A handler + else + dcd IntDefaultHandler ; Offset 40: GPIO port A handler + endif + if :def:_USB_ENABLE_UPDATE :lor: \ + (_APP_START_ADDRESS != _VTABLE_START_ADDRESS) + dcd IntDefaultHandler ; Offset 44: GPIO Port B + dcd IntDefaultHandler ; Offset 48: GPIO Port C + dcd IntDefaultHandler ; Offset 4C: GPIO Port D + dcd IntDefaultHandler ; Offset 50: GPIO Port E + dcd IntDefaultHandler ; Offset 54: UART0 Rx and Tx + dcd IntDefaultHandler ; Offset 58: UART1 Rx and Tx + dcd IntDefaultHandler ; Offset 5C: SSI0 Rx and Tx + dcd IntDefaultHandler ; Offset 60: I2C0 Master and Slave + dcd IntDefaultHandler ; Offset 64: PWM Fault + dcd IntDefaultHandler ; Offset 68: PWM Generator 0 + dcd IntDefaultHandler ; Offset 6C: PWM Generator 1 + dcd IntDefaultHandler ; Offset 70: PWM Generator 2 + dcd IntDefaultHandler ; Offset 74: Quadrature Encoder 0 + dcd IntDefaultHandler ; Offset 78: ADC Sequence 0 + dcd IntDefaultHandler ; Offset 7C: ADC Sequence 1 + dcd IntDefaultHandler ; Offset 80: ADC Sequence 2 + dcd IntDefaultHandler ; Offset 84: ADC Sequence 3 + dcd IntDefaultHandler ; Offset 88: Watchdog timer + dcd IntDefaultHandler ; Offset 8C: Timer 0 subtimer A + dcd IntDefaultHandler ; Offset 90: Timer 0 subtimer B + dcd IntDefaultHandler ; Offset 94: Timer 1 subtimer A + dcd IntDefaultHandler ; Offset 98: Timer 1 subtimer B + dcd IntDefaultHandler ; Offset 9C: Timer 2 subtimer A + dcd IntDefaultHandler ; Offset A0: Timer 2 subtimer B + dcd IntDefaultHandler ; Offset A4: Analog Comparator 0 + dcd IntDefaultHandler ; Offset A8: Analog Comparator 1 + dcd IntDefaultHandler ; Offset AC: Analog Comparator 2 + dcd IntDefaultHandler ; Offset B0: System Control + dcd IntDefaultHandler ; Offset B4: FLASH Control + endif + if :def:_USB_ENABLE_UPDATE :lor: \ + (_APP_START_ADDRESS != _VTABLE_START_ADDRESS) + dcd IntDefaultHandler ; Offset B8: GPIO Port F + dcd IntDefaultHandler ; Offset BC: GPIO Port G + dcd IntDefaultHandler ; Offset C0: GPIO Port H + dcd IntDefaultHandler ; Offset C4: UART2 Rx and Tx + dcd IntDefaultHandler ; Offset C8: SSI1 Rx and Tx + dcd IntDefaultHandler ; Offset CC: Timer 3 subtimer A + dcd IntDefaultHandler ; Offset D0: Timer 3 subtimer B + dcd IntDefaultHandler ; Offset D4: I2C1 Master and Slave + dcd IntDefaultHandler ; Offset D8: Quadrature Encoder 1 + dcd IntDefaultHandler ; Offset DC: CAN0 + dcd IntDefaultHandler ; Offset E0: CAN1 + dcd IntDefaultHandler ; Offset E4: CAN2 + dcd IntDefaultHandler ; Offset E8: Ethernet + dcd IntDefaultHandler ; Offset EC: Hibernation module + if :def: _USB_ENABLE_UPDATE + import USB0DeviceIntHandler + dcd USB0DeviceIntHandler ; Offset F0: USB 0 Controller + else + dcd IntDefaultHandler ; Offset F0: USB 0 Controller + endif + endif + +;****************************************************************************** +; +; Initialize the processor by copying the boot loader from flash to SRAM, zero +; filling the .bss section, and moving the vector table to the beginning of +; SRAM. The return address is modified to point to the SRAM copy of the boot +; loader instead of the flash copy, resulting in a branch to the copy now in +; SRAM. +; +;****************************************************************************** + export ProcessorInit +ProcessorInit + ; + ; Copy the code image from flash to SRAM. + ; + movs r0, #0x0000 + movs r1, #0x0000 + movt r1, #0x2000 + import ||Image$$SRAM$$ZI$$Base|| + ldr r2, =||Image$$SRAM$$ZI$$Base|| +copy_loop + ldr r3, [r0], #4 + str r3, [r1], #4 + cmp r1, r2 + blt copy_loop + + ; + ; Zero fill the .bss section. + ; + movs r0, #0x0000 + import ||Image$$SRAM$$ZI$$Limit|| + ldr r2, =||Image$$SRAM$$ZI$$Limit|| +zero_loop + str r0, [r1], #4 + cmp r1, r2 + blt zero_loop + + ; + ; Set the vector table pointer to the beginning of SRAM. + ; + movw r0, #(NVIC_VTABLE & 0xffff) + movt r0, #(NVIC_VTABLE >> 16) + movs r1, #0x0000 + movt r1, #0x2000 + str r1, [r0] + + ; + ; Return to the caller. + ; + bx lr + +;****************************************************************************** +; +; The reset handler, which gets called when the processor starts. +; +;****************************************************************************** + export Reset_Handler +Reset_Handler + + ; + ; Enable the floating-point unit. This must be done here in case any + ; later C functions use floating point. Note that some toolchains will + ; use the FPU registers for general workspace even if no explicit floating + ; point data types are in use. + ; + movw r0, #0xED88 + movt r0, #0xE000 + ldr r1, [r0] + orr r1, #0x00F00000 + str r1, [r0] + + ; + ; Initialize the processor. + ; + bl ProcessorInit + + ; + ; Branch to the SRAM copy of the reset handler. + ; + ldr pc, =Reset_Handler_In_SRAM + +;****************************************************************************** +; +; The NMI handler. +; +;****************************************************************************** +NmiSR + if :def:_ENABLE_MOSCFAIL_HANDLER + ; + ; Grab the fault frame from the stack (the stack will be cleared by the + ; processor initialization that follows). + ; + ldm sp, {r4-r11} + mov r12, lr + + ; + ; Initialize the processor. + ; + bl ProcessorInit + + ; + ; Branch to the SRAM copy of the NMI handler. + ; + ldr pc, =NmiSR_In_SRAM + else + ; + ; Loop forever since there is nothing that we can do about a NMI. + ; + b . + endif + +;****************************************************************************** +; +; The hard fault handler. +; +;****************************************************************************** +FaultISR + ; + ; Loop forever since there is nothing that we can do about a hard fault. + ; + b . + +;****************************************************************************** +; +; The update handler, which gets called when the application would like to +; start an update. +; +;****************************************************************************** +UpdateHandler + ; + ; Initialize the processor. + ; + bl ProcessorInit + + ; + ; Branch to the SRAM copy of the update handler. + ; + ldr pc, =UpdateHandler_In_SRAM + +;****************************************************************************** +; +; This portion of the file goes into the text section. +; +;****************************************************************************** + align 4 + area ||.text||, code, readonly, align=2 + +Reset_Handler_In_SRAM + ; + ; Call the user-supplied low level hardware initialization function + ; if provided. + ; + if :def:_BL_HW_INIT_FN_HOOK + import $_BL_HW_INIT_FN_HOOK + bl $_BL_HW_INIT_FN_HOOK + endif + + ; + ; See if an update should be performed. + ; + import CheckForceUpdate + bl CheckForceUpdate + cbz r0, CallApplication + + ; + ; Configure the microcontroller. + ; +EnterBootLoader + if :def:_ENET_ENABLE_UPDATE + import ConfigureEnet + bl ConfigureEnet + elif :def:_CAN_ENABLE_UPDATE + import ConfigureCAN + bl ConfigureCAN + elif :def:_USB_ENABLE_UPDATE + import ConfigureUSB + bl ConfigureUSB + else + import ConfigureDevice + bl ConfigureDevice + endif + + ; + ; Call the user-supplied initialization function if provided. + ; + if :def:_BL_INIT_FN_HOOK + import $_BL_INIT_FN_HOOK + bl $_BL_INIT_FN_HOOK + endif + + ; + ; Branch to the update handler. + ; + if :def:_ENET_ENABLE_UPDATE + import UpdateBOOTP + b UpdateBOOTP + elif :def:_CAN_ENABLE_UPDATE + import UpdaterCAN + b UpdaterCAN + elif :def:_USB_ENABLE_UPDATE + import UpdaterUSB + b UpdaterUSB + else + import Updater + b Updater + endif + + ; + ; This is a second symbol to allow starting the application from the boot + ; loader the linker may not like the perceived jump. + ; + export StartApplication +StartApplication + ; + ; Call the application via the reset handler in its vector table. Load the + ; address of the application vector table. + ; +CallApplication + ; + ; Copy the application's vector table to the target address if necessary. + ; Note that incorrect boot loader configuration could cause this to + ; corrupt the code! Setting VTABLE_START_ADDRESS to 0x20000000 (the start + ; of SRAM) is safe since this will use the same memory that the boot loader + ; already uses for its vector table. Great care will have to be taken if + ; other addresses are to be used. + ; + if (_APP_START_ADDRESS != _VTABLE_START_ADDRESS) + movw r0, #(_VTABLE_START_ADDRESS & 0xffff) + if (_VTABLE_START_ADDRESS > 0xffff) + movt r0, #(_VTABLE_START_ADDRESS >> 16) + endif + movw r1, #(_APP_START_ADDRESS & 0xffff) + if (_APP_START_ADDRESS > 0xffff) + movt r1, #(_APP_START_ADDRESS >> 16) + endif + + ; + ; Calculate the end address of the vector table assuming that it has the + ; maximum possible number of vectors. We don't know how many the app has + ; populated so this is the safest approach though it may copy some non + ; vector data if the app table is smaller than the maximum. + ; + movw r2, #(70 * 4) + adds r2, r2, r0 +VectorCopyLoop + ldr r3, [r1], #4 + str r3, [r0], #4 + cmp r0, r2 + blt VectorCopyLoop + endif + + ; + ; Set the vector table address to the beginning of the application. + ; + movw r0, #(_VTABLE_START_ADDRESS & 0xffff) + if (_VTABLE_START_ADDRESS > 0xffff) + movt r0, #(_VTABLE_START_ADDRESS >> 16) + endif + movw r1, #(NVIC_VTABLE & 0xffff) + movt r1, #(NVIC_VTABLE >> 16) + str r0, [r1] + + ; + ; Load the stack pointer from the application's vector table. + ; + if (_APP_START_ADDRESS != _VTABLE_START_ADDRESS) + movw r0, #(_APP_START_ADDRESS & 0xffff) + if (_APP_START_ADDRESS > 0xffff) + movt r0, #(_APP_START_ADDRESS >> 16) + endif + endif + ldr sp, [r0] + + ; + ; Load the initial PC from the application's vector table and branch to + ; the application's entry point. + ; + ldr r0, [r0, #4] + bx r0 + +;****************************************************************************** +; +; The update handler, which gets called when the application would like to +; start an update. +; +;****************************************************************************** +UpdateHandler_In_SRAM + ; + ; Load the stack pointer from the vector table. + ; + movs r0, #0x0000 + ldr sp, [r0] + + ; + ; Call the user-supplied low level hardware initialization function + ; if provided. + ; + if :def:_BL_HW_INIT_FN_HOOK + bl $_BL_HW_INIT_FN_HOOK + endif + + ; + ; Call the user-supplied re-initialization function if provided. + ; + if :def:_BL_REINIT_FN_HOOK + import $_BL_REINIT_FN_HOOK + bl $_BL_REINIT_FN_HOOK + endif + + ; + ; Branch to the update handler. + ; + if :def:_ENET_ENABLE_UPDATE + b UpdateBOOTP + elif :def:_CAN_ENABLE_UPDATE + import AppUpdaterCAN + b AppUpdaterCAN + elif :def:_USB_ENABLE_UPDATE + import AppUpdaterUSB + b AppUpdaterUSB + else + b Updater + endif + +;****************************************************************************** +; +; The NMI handler. +; +;****************************************************************************** + if :def:_ENABLE_MOSCFAIL_HANDLER +NmiSR_In_SRAM + ; + ; Restore the stack frame. + ; + mov lr, r12 + stm sp, {r4-r11} + + ; + ; Save the link register. + ; + mov r9, lr + + ; + ; Call the user-supplied low level hardware initialization function + ; if provided. + ; + if :def:_BL_HW_INIT_FN_HOOK + bl _BL_HW_INIT_FN_HOOK + endif + + ; + ; See if an update should be performed. + ; + bl CheckForceUpdate + cbz r0, EnterApplication + + ; + ; Clear the MOSCFAIL bit in RESC. + ; + movw r0, #(SYSCTL_RESC & 0xffff) + movt r0, #(SYSCTL_RESC >> 16) + ldr r1, [r0] + bic r1, r1, #SYSCTL_RESC_MOSCFAIL + str r1, [r0] + + ; + ; Fix up the PC on the stack so that the boot pin check is bypassed + ; (since it has already been performed). + ; + ldr r0, =EnterBootLoader + bic r0, #0x00000001 + str r0, [sp, #0x18] + + ; + ; Return from the NMI handler. This will then start execution of the + ; boot loader. + ; + bx r9 + + ; + ; Restore the link register. + ; +EnterApplication + mov lr, r9 + + ; + ; Copy the application's vector table to the target address if necessary. + ; Note that incorrect boot loader configuration could cause this to + ; corrupt the code! Setting VTABLE_START_ADDRESS to 0x20000000 (the start + ; of SRAM) is safe since this will use the same memory that the boot loader + ; already uses for its vector table. Great care will have to be taken if + ; other addresses are to be used. + ; + if (_APP_START_ADDRESS != _VTABLE_START_ADDRESS) + movw r0, #(_VTABLE_START_ADDRESS & 0xffff) + if (_VTABLE_START_ADDRESS > 0xffff) + movt r0, #(_VTABLE_START_ADDRESS >> 16) + endif + movw r1, #(_APP_START_ADDRESS & 0xffff) + if (_APP_START_ADDRESS > 0xffff) + movt r1, #(_APP_START_ADDRESS >> 16) + endif + + ; + ; Calculate the end address of the vector table assuming that it has the + ; maximum possible number of vectors. We don't know how many the app has + ; populated so this is the safest approach though it may copy some non + ; vector data if the app table is smaller than the maximum. + ; + movw r2, #(70 * 4) + adds r2, r2, r0 +VectorCopyLoop2 + ldr r3, [r1], #4 + str r3, [r0], #4 + cmp r0, r2 + blt VectorCopyLoop2 + endif + + ; + ; Set the application's vector table start address. Typically this is the + ; application start address but in some cases an application may relocate + ; this so we can't assume that these two addresses are equal. + ; + movw r0, #(_VTABLE_START_ADDRESS & 0xffff) + if (_VTABLE_START_ADDRESS > 0xffff) + movt r0, #(_VTABLE_START_ADDRESS >> 16) + endif + movw r1, #(NVIC_VTABLE & 0xffff) + movt r1, #(NVIC_VTABLE >> 16) + str r0, [r1] + + ; + ; Remove the NMI stack frame from the boot loader's stack. + ; + ldmia sp, {r4-r11} + + ; + ; Get the application's stack pointer. + ; + if (_APP_START_ADDRESS != _VTABLE_START_ADDRESS) + movw r0, #(_APP_START_ADDRESS & 0xffff) + if (_APP_START_ADDRESS > 0xffff) + movt r0, #(_APP_START_ADDRESS >> 16) + endif + endif + ldr sp, [r0, #0x00] + + ; + ; Fix up the NMI stack frame's return address to be the reset handler of + ; the application. + ; + ldr r10, [r0, #0x04] + bic r10, #0x00000001 + + ; + ; Store the NMI stack frame onto the application's stack. + ; + stmdb sp!, {r4-r11} + + ; + ; Branch to the application's NMI handler. + ; + ldr r0, [r0, #0x08] + bx r0 + endif + +;****************************************************************************** +; +; The default interrupt handler. +; +;****************************************************************************** +IntDefaultHandler + ; + ; Loop forever since there is nothing that we can do about an unexpected + ; interrupt. + ; + b . + +;****************************************************************************** +; +; Provides a small delay. The loop below takes 3 cycles/loop. +; +;****************************************************************************** + export Delay +Delay + subs r0, #1 + bne Delay + bx lr + +;****************************************************************************** +; +; This is the end of the file. +; +;****************************************************************************** + align 4 + end -- cgit v1.3.1