Knight KE / Mbed OS Game_Master
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers mbed_application.c Source File

mbed_application.c

00001 /* mbed Microcontroller Library
00002  * Copyright (c) 2017-2017 ARM Limited
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 #include <stdlib.h>
00018 #include <stdarg.h>
00019 #include "device.h"
00020 #include "platform/mbed_application.h"
00021 
00022 #if MBED_APPLICATION_SUPPORT
00023 
00024 static void powerdown_nvic(void);
00025 static void powerdown_scb(uint32_t vtor);
00026 static void start_new_application(void *sp, void *pc);
00027 
00028 void mbed_start_application(uintptr_t address)
00029 {
00030     void *sp;
00031     void *pc;
00032 
00033     // Interrupts are re-enabled in start_new_application
00034     __disable_irq();
00035 
00036     SysTick->CTRL = 0x00000000;
00037     powerdown_nvic();
00038     powerdown_scb(address);
00039 
00040     sp = *((void**)address + 0);
00041     pc = *((void**)address + 1);
00042     start_new_application(sp, pc);
00043 }
00044 
00045 static void powerdown_nvic()
00046 {
00047     int isr_groups_32;
00048     int i;
00049     int j;
00050 
00051 #if defined(__CORTEX_M23)
00052     // M23 doesn't support ICTR and supports up to 240 external interrupts.
00053     isr_groups_32 = 8;
00054 #else
00055     isr_groups_32 = ((SCnSCB->ICTR & SCnSCB_ICTR_INTLINESNUM_Msk) >> SCnSCB_ICTR_INTLINESNUM_Pos) + 1;
00056 #endif
00057     for (i = 0; i < isr_groups_32; i++) {
00058         NVIC->ICER[i] = 0xFFFFFFFF;
00059         NVIC->ICPR[i] = 0xFFFFFFFF;
00060         for (j = 0; j < 8; j++) {
00061 #if defined(__CORTEX_M23)
00062             NVIC->IPR[i * 8 + j] = 0x00000000;
00063 #else
00064             NVIC->IP[i * 8 + j] = 0x00000000;
00065 #endif
00066         }
00067     }
00068 }
00069 
00070 static void powerdown_scb(uint32_t vtor)
00071 {
00072     int i;
00073 
00074     // SCB->CPUID   - Read only CPU ID register
00075     SCB->ICSR = SCB_ICSR_PENDSVCLR_Msk | SCB_ICSR_PENDSTCLR_Msk;
00076     SCB->VTOR = vtor;
00077     SCB->AIRCR = 0x05FA | 0x0000;
00078     SCB->SCR = 0x00000000;
00079     // SCB->CCR     - Implementation defined value
00080 #if defined(__CORTEX_M23)
00081     for (i = 0; i < 2; i++) {
00082         SCB->SHPR[i] = 0x00;
00083     }
00084 #else
00085     for (i = 0; i < 12; i++) {
00086 #if defined(__CORTEX_M7)
00087         SCB->SHPR[i] = 0x00;
00088 #else
00089         SCB->SHP[i] = 0x00;
00090 #endif
00091     }
00092 #endif
00093     SCB->SHCSR = 0x00000000;
00094 #if defined(__CORTEX_M23)
00095 #else
00096     SCB->CFSR = 0xFFFFFFFF;
00097     SCB->HFSR = SCB_HFSR_DEBUGEVT_Msk | SCB_HFSR_FORCED_Msk | SCB_HFSR_VECTTBL_Msk;
00098     SCB->DFSR = SCB_DFSR_EXTERNAL_Msk | SCB_DFSR_VCATCH_Msk |
00099                 SCB_DFSR_DWTTRAP_Msk | SCB_DFSR_BKPT_Msk | SCB_DFSR_HALTED_Msk;
00100 #endif
00101     // SCB->MMFAR   - Implementation defined value
00102     // SCB->BFAR    - Implementation defined value
00103     // SCB->AFSR    - Implementation defined value
00104     // SCB->PFR     - Read only processor feature register
00105     // SCB->DFR     - Read only debug feature registers
00106     // SCB->ADR     - Read only auxiliary feature registers
00107     // SCB->MMFR    - Read only memory model feature registers
00108     // SCB->ISAR    - Read only instruction set attribute registers
00109     // SCB->CPACR   - Implementation defined value
00110 }
00111 
00112 #if defined (__CC_ARM)
00113 
00114 __asm static void start_new_application(void *sp, void *pc)
00115 {
00116     MOV R2, #0
00117     MSR CONTROL, R2         // Switch to main stack
00118     MOV SP, R0
00119     MSR PRIMASK, R2         // Enable interrupts
00120     BX R1
00121 }
00122 
00123 #elif defined (__GNUC__) || defined (__ICCARM__)
00124 
00125 void start_new_application(void *sp, void *pc)
00126 {
00127     __asm volatile (
00128         "movw   r2, #0      \n" // Fail to compile "mov r2, #0" with ARMC6. Replace with MOVW.
00129                                 // We needn't "movt r2, #0" immediately following because MOVW
00130                                 // will zero-extend the 16-bit immediate.
00131         "msr    control, r2 \n" // Switch to main stack
00132         "mov    sp, %0      \n"
00133         "msr    primask, r2 \n" // Enable interrupts
00134         "bx     %1          \n"
00135         :
00136         : "l" (sp), "l" (pc)
00137         : "r2", "cc", "memory"
00138     );
00139 }
00140 
00141 #else
00142 
00143 #error "Unsupported toolchain"
00144 
00145 #endif
00146 
00147 #endif /* MBED_APPLICATION_SUPPORT */