Set write permission for 'write without response' characteristics.

Fork of nRF51822 by Nordic Semiconductor

Committer:
Rohit Grover
Date:
Tue Nov 04 10:42:27 2014 +0000
Revision:
69:61da91a52bd6
Parent:
66:b3680699d9a4
Release 0.2.2
=============

Features
~~~~~~~~

- Add API Gap::getAddress() to fetch MAC address.
- Add inline assembly for some bootloader specific files to be compiled with arm-gcc.

Bugfixes
~~~~~~~~

none

Compatibility
~~~~~~~~~~~~~

Works with 0.2.0 of BLE_API.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Rohit Grover 66:b3680699d9a4 1 /* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved.
Rohit Grover 66:b3680699d9a4 2 *
Rohit Grover 66:b3680699d9a4 3 * The information contained herein is property of Nordic Semiconductor ASA.
Rohit Grover 66:b3680699d9a4 4 * Terms and conditions of usage are described in detail in NORDIC
Rohit Grover 66:b3680699d9a4 5 * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
Rohit Grover 66:b3680699d9a4 6 *
Rohit Grover 66:b3680699d9a4 7 * Licensees are granted free, non-transferable use of the information. NO
Rohit Grover 66:b3680699d9a4 8 * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
Rohit Grover 66:b3680699d9a4 9 * the file.
Rohit Grover 66:b3680699d9a4 10 *
Rohit Grover 66:b3680699d9a4 11 */
Rohit Grover 66:b3680699d9a4 12
Rohit Grover 66:b3680699d9a4 13 #include "bootloader_util.h"
Rohit Grover 66:b3680699d9a4 14 #include <stdint.h>
Rohit Grover 66:b3680699d9a4 15
Rohit Grover 66:b3680699d9a4 16
Rohit Grover 66:b3680699d9a4 17 /**
Rohit Grover 66:b3680699d9a4 18 * @brief Function for aborting current handler mode and jump to to other application/bootloader.
Rohit Grover 66:b3680699d9a4 19 *
Rohit Grover 69:61da91a52bd6 20 * @details This function will use the address provided (reset handler) to be executed after
Rohit Grover 69:61da91a52bd6 21 * handler mode is exited. It creates an initial stack to ensure correct reset behavior
Rohit Grover 66:b3680699d9a4 22 * when the reset handler is executed.
Rohit Grover 66:b3680699d9a4 23 *
Rohit Grover 66:b3680699d9a4 24 * @param[in] reset_handler Address of the reset handler to be executed when handler mode exits.
Rohit Grover 66:b3680699d9a4 25 *
Rohit Grover 69:61da91a52bd6 26 * @note This function must never be called directly from 'C' but is intended only to be used from
Rohit Grover 69:61da91a52bd6 27 * \ref bootloader_util_reset. This function will never return but issue a reset into
Rohit Grover 66:b3680699d9a4 28 * provided address.
Rohit Grover 66:b3680699d9a4 29 */
Rohit Grover 69:61da91a52bd6 30 #ifdef TOOLCHAIN_ARM
Rohit Grover 66:b3680699d9a4 31 __asm void isr_abort(uint32_t reset_handler)
Rohit Grover 66:b3680699d9a4 32 {
Rohit Grover 66:b3680699d9a4 33 xPSR_RESET EQU 0x21000000 ; Default value of xPSR after System Reset.
Rohit Grover 66:b3680699d9a4 34 EXC_RETURN_CMD EQU 0xFFFFFFF9 ; EXC_RETURN for ARM Cortex. When loaded to PC the current interrupt service routine (handler mode) willl exit and the stack will be popped. Execution will continue in thread mode.
Rohit Grover 66:b3680699d9a4 35
Rohit Grover 66:b3680699d9a4 36 LDR R4,=MASK_ONES ; Fill with ones before jumping to reset handling. We be popped as R12 when exiting ISR (Cleaning up the registers).
Rohit Grover 66:b3680699d9a4 37 LDR R5,=MASK_ONES ; Fill with ones before jumping to reset handling. We be popped as LR when exiting ISR. Ensures no return to application.
Rohit Grover 66:b3680699d9a4 38 MOV R6, R0 ; Move address of reset handler to R6. Will be popped as PC when exiting ISR. Ensures the reset handler will be executed when exist ISR.
Rohit Grover 66:b3680699d9a4 39 LDR R7,=xPSR_RESET ; Move reset value of xPSR to R7. Will be popped as xPSR when exiting ISR.
Rohit Grover 66:b3680699d9a4 40 PUSH {r4-r7} ; Push everything to new stack to allow interrupt handler to fetch it on exiting the ISR.
Rohit Grover 69:61da91a52bd6 41
Rohit Grover 66:b3680699d9a4 42 LDR R4,=MASK_ZEROS ; Fill with zeros before jumping to reset handling. We be popped as R0 when exiting ISR (Cleaning up of the registers).
Rohit Grover 66:b3680699d9a4 43 LDR R5,=MASK_ZEROS ; Fill with zeros before jumping to reset handling. We be popped as R1 when exiting ISR (Cleaning up of the registers).
Rohit Grover 66:b3680699d9a4 44 LDR R6,=MASK_ZEROS ; Fill with zeros before jumping to reset handling. We be popped as R2 when exiting ISR (Cleaning up of the registers).
Rohit Grover 66:b3680699d9a4 45 LDR R7,=MASK_ZEROS ; Fill with zeros before jumping to reset handling. We be popped as R3 when exiting ISR (Cleaning up of the registers).
Rohit Grover 66:b3680699d9a4 46 PUSH {r4-r7} ; Push zeros (R4-R7) to stack to prepare for exiting the interrupt routine.
Rohit Grover 69:61da91a52bd6 47
Rohit Grover 66:b3680699d9a4 48 LDR R0,=EXC_RETURN_CMD ; Load the execution return command into register.
Rohit Grover 66:b3680699d9a4 49 BX R0 ; No return - Handler mode will be exited. Stack will be popped and execution will continue in reset handler initializing other application.
Rohit Grover 66:b3680699d9a4 50 ALIGN
Rohit Grover 66:b3680699d9a4 51 }
Rohit Grover 69:61da91a52bd6 52 #elif defined(TOOLCHAIN_GCC)
Rohit Grover 69:61da91a52bd6 53 void isr_abort(uint32_t reset_handler)
Rohit Grover 69:61da91a52bd6 54 {
Rohit Grover 69:61da91a52bd6 55 asm(
Rohit Grover 69:61da91a52bd6 56 ".equ xPSR_RESET, 0x21000000 \n\t" /* Default value of xPSR after System Reset. */
Rohit Grover 69:61da91a52bd6 57 ".equ EXC_RETURN_CMD, 0xFFFFFFF9\n\t" /* EXC_RETURN for ARM Cortex. When loaded to PC the current interrupt
Rohit Grover 69:61da91a52bd6 58 * service routine (handler mode) willl exit and the stack will be
Rohit Grover 69:61da91a52bd6 59 * popped. Execution will continue in thread mode. */
Rohit Grover 66:b3680699d9a4 60
Rohit Grover 69:61da91a52bd6 61 "LDR R4,=MASK_ONES \n\t" /* Fill with ones before jumping to reset handling. We be popped as R12 when exiting ISR (Cleaning up the registers). */
Rohit Grover 69:61da91a52bd6 62 "LDR R5,=MASK_ONES \n\t" /* Fill with ones before jumping to reset handling. We be popped as LR when exiting ISR. Ensures no return to application. */
Rohit Grover 69:61da91a52bd6 63 "MOV R6, R0 \n\t" /* Move address of reset handler to R6. Will be popped as PC when exiting ISR. Ensures the reset handler will be executed when exist ISR. */
Rohit Grover 69:61da91a52bd6 64 "LDR R7,=xPSR_RESET\n\t" /* Move reset value of xPSR to R7. Will be popped as xPSR when exiting ISR. */
Rohit Grover 69:61da91a52bd6 65 "PUSH {r4-r7} \n\t" /* Push everything to new stack to allow interrupt handler to fetch it on exiting the ISR. */
Rohit Grover 69:61da91a52bd6 66
Rohit Grover 69:61da91a52bd6 67 "LDR R4,=MASK_ZEROS\n\t" /* Fill with zeros before jumping to reset handling. We be popped as R0 when exiting ISR (Cleaning up of the registers). */
Rohit Grover 69:61da91a52bd6 68 "LDR R5,=MASK_ZEROS\n\t" /* Fill with zeros before jumping to reset handling. We be popped as R1 when exiting ISR (Cleaning up of the registers). */
Rohit Grover 69:61da91a52bd6 69 "LDR R6,=MASK_ZEROS\n\t" /* Fill with zeros before jumping to reset handling. We be popped as R2 when exiting ISR (Cleaning up of the registers). */
Rohit Grover 69:61da91a52bd6 70 "LDR R7,=MASK_ZEROS\n\t" /* Fill with zeros before jumping to reset handling. We be popped as R3 when exiting ISR (Cleaning up of the registers). */
Rohit Grover 69:61da91a52bd6 71 "PUSH {r4-r7} \n\t" /* Push zeros (R4-R7) to stack to prepare for exiting the interrupt routine. */
Rohit Grover 69:61da91a52bd6 72
Rohit Grover 69:61da91a52bd6 73 "LDR R0,=EXC_RETURN_CMD\n\t" /* Load the execution return command into register. */
Rohit Grover 69:61da91a52bd6 74 "BX R0 \n\t" /* No return - Handler mode will be exited. Stack will be popped and execution will continue in reset handler initializing other application. */
Rohit Grover 69:61da91a52bd6 75 );
Rohit Grover 69:61da91a52bd6 76 }
Rohit Grover 69:61da91a52bd6 77 #endif /* TOOLCHAIN_ARM */
Rohit Grover 66:b3680699d9a4 78
Rohit Grover 66:b3680699d9a4 79 /**
Rohit Grover 66:b3680699d9a4 80 * @brief Function for aborting current application/bootloader jump to to other app/bootloader.
Rohit Grover 66:b3680699d9a4 81 *
Rohit Grover 69:61da91a52bd6 82 * @details This function will use the address provided to swap the stack pointer and then load
Rohit Grover 69:61da91a52bd6 83 * the address of the reset handler to be executed. It will check current system mode
Rohit Grover 66:b3680699d9a4 84 * (thread/handler) and if in thread mode it will reset into other application.
Rohit Grover 69:61da91a52bd6 85 * If in handler mode \ref isr_abort will be executed to ensure correct exit of handler
Rohit Grover 66:b3680699d9a4 86 * mode and jump into reset handler of other application.
Rohit Grover 66:b3680699d9a4 87 *
Rohit Grover 69:61da91a52bd6 88 * @param[in] start_addr Start address of other application. This address must point to the
Rohit Grover 66:b3680699d9a4 89 initial stack pointer of the application.
Rohit Grover 66:b3680699d9a4 90 *
Rohit Grover 66:b3680699d9a4 91 * @note This function will never return but issue a reset into provided application.
Rohit Grover 66:b3680699d9a4 92 */
Rohit Grover 69:61da91a52bd6 93 #ifdef TOOLCHAIN_ARM
Rohit Grover 66:b3680699d9a4 94 __asm static void bootloader_util_reset(uint32_t start_addr)
Rohit Grover 66:b3680699d9a4 95 {
Rohit Grover 66:b3680699d9a4 96 MASK_ONES EQU 0xFFFFFFFF ; Ones, to be loaded into register as default value before reset.
Rohit Grover 66:b3680699d9a4 97 MASK_ZEROS EQU 0x00000000 ; Zeros, to be loaded into register as default value before reset.
Rohit Grover 66:b3680699d9a4 98
Rohit Grover 66:b3680699d9a4 99 LDR R1, [R0] ; Get App initial MSP for bootloader.
Rohit Grover 66:b3680699d9a4 100 MSR MSP, R1 ; Set the main stack pointer to the applications MSP.
Rohit Grover 66:b3680699d9a4 101 LDR R0,[R0, #0x04] ; Load Reset handler into register 0.
Rohit Grover 69:61da91a52bd6 102
Rohit Grover 66:b3680699d9a4 103 LDR R2, =MASK_ZEROS ; Load zeros to R2
Rohit Grover 69:61da91a52bd6 104 MRS R3, IPSR ; Load IPSR to R3 to check for handler or thread mode
Rohit Grover 66:b3680699d9a4 105 CMP R2, R3 ; Compare, if 0 then we are in thread mode and can continue to reset handler of bootloader
Rohit Grover 66:b3680699d9a4 106 BNE isr_abort ; If not zero we need to exit current ISR and jump to reset handler of bootloader
Rohit Grover 66:b3680699d9a4 107
Rohit Grover 66:b3680699d9a4 108 LDR R4, =MASK_ONES ; Load ones to R4 to be placed in Link Register.
Rohit Grover 66:b3680699d9a4 109 MOV LR, R4 ; Clear the link register and set to ones to ensure no return.
Rohit Grover 66:b3680699d9a4 110 BX R0 ; Branch to reset handler of bootloader
Rohit Grover 66:b3680699d9a4 111 ALIGN
Rohit Grover 66:b3680699d9a4 112 }
Rohit Grover 69:61da91a52bd6 113 #elif defined(TOOLCHAIN_GCC)
Rohit Grover 69:61da91a52bd6 114 static void bootloader_util_reset(uint32_t start_addr)
Rohit Grover 69:61da91a52bd6 115 {
Rohit Grover 69:61da91a52bd6 116 asm(
Rohit Grover 69:61da91a52bd6 117 ".equ MASK_ONES, 0xFFFFFFFF\n\t" /* Ones, to be loaded into register as default value before reset. */
Rohit Grover 69:61da91a52bd6 118 ".equ MASK_ZEROS, 0x00000000\n\t" /* Zeros, to be loaded into register as default value before reset. */
Rohit Grover 66:b3680699d9a4 119
Rohit Grover 69:61da91a52bd6 120 "LDR r1, [r0] \n\t" /* Get App initial MSP for bootloader. */
Rohit Grover 69:61da91a52bd6 121 "MSR MSP, r1 \n\t" /* Set the main stack pointer to the applications MSP. */
Rohit Grover 69:61da91a52bd6 122 "LDR r0,[r0, #0x04] \n\t" /* Load Reset handler into register 0. */
Rohit Grover 69:61da91a52bd6 123
Rohit Grover 69:61da91a52bd6 124 "LDR r2, =MASK_ZEROS\n\t" /* Load zeros to R2 */
Rohit Grover 69:61da91a52bd6 125 "MRS r3, IPSR \n\t" /* Load IPSR to R3 to check for handler or thread mode */
Rohit Grover 69:61da91a52bd6 126 "CMP r2, r3 \n\t" /* Compare, if 0 then we are in thread mode and can continue to reset handler of bootloader */
Rohit Grover 69:61da91a52bd6 127 "BNE isr_abort \n\t" /* If not zero we need to exit current ISR and jump to reset handler of bootloader */
Rohit Grover 69:61da91a52bd6 128
Rohit Grover 69:61da91a52bd6 129 "LDR r4, =MASK_ONES \n\t" /* Load ones to R4 to be placed in Link Register. */
Rohit Grover 69:61da91a52bd6 130 "MOV LR, r4 \n\t" /* Clear the link register and set to ones to ensure no return. */
Rohit Grover 69:61da91a52bd6 131 "BX r0 \n\t" /* Branch to reset handler of bootloader */
Rohit Grover 69:61da91a52bd6 132 : /* output operands */
Rohit Grover 69:61da91a52bd6 133 : /* input operands */
Rohit Grover 69:61da91a52bd6 134 : "r0", "r1", "r2", "r3", "r4" /* clobber list */
Rohit Grover 69:61da91a52bd6 135 );
Rohit Grover 69:61da91a52bd6 136 }
Rohit Grover 69:61da91a52bd6 137 #endif /* TOOLCHAIN_ARM */
Rohit Grover 66:b3680699d9a4 138
Rohit Grover 66:b3680699d9a4 139 void bootloader_util_app_start(uint32_t start_addr)
Rohit Grover 66:b3680699d9a4 140 {
Rohit Grover 66:b3680699d9a4 141 bootloader_util_reset(start_addr);
Rohit Grover 66:b3680699d9a4 142 }