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_ccs.s | 645 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 645 insertions(+) create mode 100644 boot_loader/bl_startup_ccs.s (limited to 'boot_loader/bl_startup_ccs.s') diff --git a/boot_loader/bl_startup_ccs.s b/boot_loader/bl_startup_ccs.s new file mode 100644 index 0000000..8bfa96b --- /dev/null +++ b/boot_loader/bl_startup_ccs.s @@ -0,0 +1,645 @@ +;;***************************************************************************** +;; +;; bl_startup_ccs.s - Boot loader startup code for Code Composer Studio +;; +;; Copyright (c) 2009-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 the boot loader configuration options. +;; +;;***************************************************************************** + .cdecls C, NOLIST, WARN + %{ + #include "inc/hw_nvic.h" + #include "inc/hw_sysctl.h" + #include "bl_config.h" + %} + +;;***************************************************************************** +;; +;; Export symbols from this file that are used elsewhere +;; +;;***************************************************************************** + .global ResetISR, Delay, Vectors + +;;***************************************************************************** +;; +;; Create the stack and put it in a section +;; +;;***************************************************************************** + .global __stack +__stack:.usect ".stack", STACK_SIZE * 4, 8 + +;;***************************************************************************** +;; +;; Put the assembler into the correct configuration. +;; +;;***************************************************************************** + .thumb + +;;***************************************************************************** +;; +;; This portion of the file goes into interrupt vectors section +;; +;;***************************************************************************** + .sect ".intvecs" + +;;***************************************************************************** +;; +;; The minimal vector table for a Cortex-M3 processor. +;; +;;***************************************************************************** +Vectors: + .ref __STACK_TOP + .word __STACK_TOP ;; Offset 00: Initial stack pointer + .word ResetISR - 0x20000000 ;; Offset 04: Reset handler + .word NmiSR - 0x20000000 ;; Offset 08: NMI handler + .word FaultISR - 0x20000000 ;; Offset 0C: Hard fault handler + .word IntDefaultHandler ;; Offset 10: MPU fault handler + .word IntDefaultHandler ;; Offset 14: Bus fault handler + .word IntDefaultHandler ;; Offset 18: Usage fault handler + .word 0 ;; Offset 1C: Reserved + .word 0 ;; Offset 20: Reserved + .word 0 ;; Offset 24: Reserved + .word 0 ;; Offset 28: Reserved + .word UpdateHandler - 0x20000000 ;; Offset 2C: SVCall handler + .word IntDefaultHandler ;; Offset 30: Debug monitor handler + .word 0 ;; Offset 34: Reserved + .word IntDefaultHandler ;; Offset 38: PendSV handler + .if $$defined(ENET_ENABLE_UPDATE) + .ref SysTickIntHandler + .word SysTickIntHandler ;; Offset 3C: SysTick handler + .else + .word IntDefaultHandler ;; Offset 3C: SysTick handler + .endif + .if $$defined(UART_ENABLE_UPDATE) & $$defined(UART_AUTOBAUD) + .ref GPIOIntHandler + .word GPIOIntHandler ;; Offset 40: GPIO port A handler + .else + .word IntDefaultHandler ;; Offset 40: GPIO port A handler + .endif + .if ($$defined(USB_ENABLE_UPDATE) | (APP_START_ADDRESS != VTABLE_START_ADDRESS)) + .word IntDefaultHandler ;; Offset 44: GPIO Port B + .word IntDefaultHandler ;; Offset 48: GPIO Port C + .word IntDefaultHandler ;; Offset 4C: GPIO Port D + .word IntDefaultHandler ;; Offset 50: GPIO Port E + .word IntDefaultHandler ;; Offset 54: UART0 Rx and Tx + .word IntDefaultHandler ;; Offset 58: UART1 Rx and Tx + .word IntDefaultHandler ;; Offset 5C: SSI0 Rx and Tx + .word IntDefaultHandler ;; Offset 60: I2C0 Master and Slave + .word IntDefaultHandler ;; Offset 64: PWM Fault + .word IntDefaultHandler ;; Offset 68: PWM Generator 0 + .word IntDefaultHandler ;; Offset 6C: PWM Generator 1 + .word IntDefaultHandler ;; Offset 70: PWM Generator 2 + .word IntDefaultHandler ;; Offset 74: Quadrature Encoder 0 + .word IntDefaultHandler ;; Offset 78: ADC Sequence 0 + .word IntDefaultHandler ;; Offset 7C: ADC Sequence 1 + .word IntDefaultHandler ;; Offset 80: ADC Sequence 2 + .word IntDefaultHandler ;; Offset 84: ADC Sequence 3 + .word IntDefaultHandler ;; Offset 88: Watchdog timer + .word IntDefaultHandler ;; Offset 8C: Timer 0 subtimer A + .word IntDefaultHandler ;; Offset 90: Timer 0 subtimer B + .word IntDefaultHandler ;; Offset 94: Timer 1 subtimer A + .word IntDefaultHandler ;; Offset 98: Timer 1 subtimer B + .word IntDefaultHandler ;; Offset 9C: Timer 2 subtimer A + .word IntDefaultHandler ;; Offset A0: Timer 2 subtimer B + .word IntDefaultHandler ;; Offset A4: Analog Comparator 0 + .word IntDefaultHandler ;; Offset A8: Analog Comparator 1 + .word IntDefaultHandler ;; Offset AC: Analog Comparator 2 + .word IntDefaultHandler ;; Offset B0: System Control + .word IntDefaultHandler ;; Offset B4: FLASH Control + .endif + .if ($$defined(USB_ENABLE_UPDATE) | (APP_START_ADDRESS != VTABLE_START_ADDRESS)) + .word IntDefaultHandler ;; Offset B8: GPIO Port F + .word IntDefaultHandler ;; Offset BC: GPIO Port G + .word IntDefaultHandler ;; Offset C0: GPIO Port H + .word IntDefaultHandler ;; Offset C4: UART2 Rx and Tx + .word IntDefaultHandler ;; Offset C8: SSI1 Rx and Tx + .word IntDefaultHandler ;; Offset CC: Timer 3 subtimer A + .word IntDefaultHandler ;; Offset D0: Timer 3 subtimer B + .word IntDefaultHandler ;; Offset D4: I2C1 Master and Slave + .word IntDefaultHandler ;; Offset D8: Quadrature Encoder 1 + .word IntDefaultHandler ;; Offset DC: CAN0 + .word IntDefaultHandler ;; Offset E0: CAN1 + .word IntDefaultHandler ;; Offset E4: CAN2 + .word IntDefaultHandler ;; Offset E8: Ethernet + .word IntDefaultHandler ;; Offset EC: Hibernation module + .if $$defined(USB_ENABLE_UPDATE) + .ref USB0DeviceIntHandler + .word USB0DeviceIntHandler ;; Offset F0: USB 0 Controller + .else + .word IntDefaultHandler ;; Offset F0: USB 0 Controller + .endif + .endif + +;;***************************************************************************** +;; +;; This portion of the file goes into the text section. +;; +;;***************************************************************************** + .text + +;;***************************************************************************** +;; +;; 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. +;; +;;***************************************************************************** + .ref bss_run +bss_start .word bss_run + .ref __STACK_TOP +bss_end .word __STACK_TOP + + .thumbfunc ProcessorInit +ProcessorInit: .asmfunc + ;; + ;; Copy the code image from flash to SRAM. + ;; + movs r0, #0x0000 + movs r1, #0x0000 + movt r1, #0x2000 + ldr r2, bss_start +copy_loop: + ldr r3, [r0], #4 + str r3, [r1], #4 + cmp r1, r2 + blt copy_loop + + ;; + ;; Zero fill the .bss section. + ;; + movs r0, #0x0000 + ldr r2, bss_end +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] + + ;; + ;; Set the return address to the code just copied into SRAM. + ;; + orr lr, lr, #0x20000000 + + ;; + ;; Return to the caller. + ;; + bx lr + .endasmfunc + +;;***************************************************************************** +;; +;; The reset handler, which gets called when the processor starts. +;; +;;***************************************************************************** + .thumbfunc ResetISR +ResetISR: .asmfunc + ;; + ;; 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, r1, #0x00F00000 + str r1, [r0] + + ;; + ;; Initialize the processor. + ;; + bl ProcessorInit + + ;; + ;; Call the user-supplied low level hardware initialization function + ;; if provided. + ;; + .if $$defined(BL_HW_INIT_FN_HOOK) + .ref BL_HW_INIT_FN_HOOK + bl BL_HW_INIT_FN_HOOK + .endif + + ;; + ;; See if an update should be performed. + ;; + .ref CheckForceUpdate + bl CheckForceUpdate + cbz r0, CallApplication + + ;; + ;; Configure the microcontroller. + ;; + .thumbfunc EnterBootLoader +EnterBootLoader: + .if $$defined(ENET_ENABLE_UPDATE) + .ref ConfigureEnet + bl ConfigureEnet + .elseif $$defined(CAN_ENABLE_UPDATE) + .ref ConfigureCAN + bl ConfigureCAN + .elseif $$defined(USB_ENABLE_UPDATE) + .ref ConfigureUSB + bl ConfigureUSB + .else + .ref ConfigureDevice + bl ConfigureDevice + .endif + + ;; + ;; Call the user-supplied initialization function if provided. + ;; + .if $$defined(BL_INIT_FN_HOOK) + .ref BL_INIT_FN_HOOK + bl BL_INIT_FN_HOOK + .endif + + ;; + ;; Branch to the update handler. + ;; + .if $$defined(ENET_ENABLE_UPDATE) + .ref UpdateBOOTP + b UpdateBOOTP + .elseif $$defined(CAN_ENABLE_UPDATE) + .ref UpdaterCAN + b UpdaterCAN + .elseif $$defined(USB_ENABLE_UPDATE) + .ref UpdaterUSB + b UpdaterUSB + .else + .ref Updater + b Updater + .endif + .endasmfunc + + ;; + ;; This is a second symbol to allow starting the application from the boot + ;; loader the linker may not like the perceived jump. + ;; + .global StartApplication + .thumbfunc StartApplication +StartApplication: + ;; + ;; Call the application via the reset handler in its vector table. Load + ;; the address of the application vector table. + ;; + .thumbfunc CallApplication +CallApplication: .asmfunc + ;; + ;; 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 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] + + ;; + ;; 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 + .endasmfunc + +;;***************************************************************************** +;; +;; The update handler, which gets called when the application would like to +;; start an update. +;; +;;***************************************************************************** + .thumbfunc UpdateHandler +UpdateHandler: .asmfunc + ;; + ;; Initialize the processor. + ;; + bl ProcessorInit + + ;; + ;; 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 $$defined(BL_HW_INIT_FN_HOOK) + bl BL_HW_INIT_FN_HOOK + .endif + + ;; + ;; Call the user-supplied re-initialization function if provided. + ;; + .if $$defined(BL_REINIT_FN_HOOK) + .ref BL_REINIT_FN_HOOK + bl BL_REINIT_FN_HOOK + .endif + + ;; + ;; Branch to the update handler. + ;; + .if $$defined(ENET_ENABLE_UPDATE) + b UpdateBOOTP + .elseif $$defined(CAN_ENABLE_UPDATE) + .ref AppUpdaterCAN + b AppUpdaterCAN + .elseif $$defined(USB_ENABLE_UPDATE) + .ref AppUpdaterUSB + b AppUpdaterUSB + .else + b Updater + .endif + .endasmfunc + +;;***************************************************************************** +;; +;; The NMI handler. +;; +;;***************************************************************************** + .thumbfunc NmiSR +NmiSR: .asmfunc + .if $$defined(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 + + ;; + ;; 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 $$defined(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 + .else + ;; + ;; Loop forever since there is nothing that we can do about a NMI. + ;; + b NmiSR + .endif + .endasmfunc + +;;***************************************************************************** +;; +;; The hard fault handler. +;; +;;***************************************************************************** + .thumbfunc FaultISR +FaultISR: .asmfunc + ;; + ;; Loop forever since there is nothing that we can do about a hard fault. + ;; + b FaultISR + .endasmfunc + +;;***************************************************************************** +;; +;; The default interrupt handler. +;; +;;***************************************************************************** + .thumbfunc IntDefaultHandler +IntDefaultHandler: .asmfunc + ;; + ;; Loop forever since there is nothing that we can do about an unexpected + ;; interrupt. + ;; + b IntDefaultHandler + .endasmfunc + +;;***************************************************************************** +;; +;; Provides a small delay. The loop below takes 3 cycles/loop. +;; +;;***************************************************************************** +; .globl Delay + .thumbfunc Delay +Delay: .asmfunc + subs r0, #1 + bne Delay + bx lr + .endasmfunc + + .thumbfunc _c_int00 + .global _c_int00 +_c_int00: .asmfunc + b ResetISR + +;;***************************************************************************** +;; +;; This is the end of the file. +;; +;;***************************************************************************** + .end -- cgit v1.3.1