takashi kadono / Mbed OS Nucleo_446

Dependencies:   ssd1331

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 #if defined(__CORTEX_A9)
00025 
00026 static void powerdown_gic(void);
00027 
00028 void mbed_start_application(uintptr_t address)
00029 {
00030     __disable_irq();
00031     powerdown_gic();
00032     __enable_irq();
00033     ((void(*)())address)();
00034 }
00035 
00036 static void powerdown_gic()
00037 {
00038     int i;
00039     int j;
00040 
00041     for (i = 0; i < 32; i++) {
00042         GICDistributor->ICENABLER[i] = 0xFFFFFFFF;
00043         GICDistributor->ICPENDR[i] = 0xFFFFFFFF;
00044         if (i < 4) {
00045             GICDistributor->CPENDSGIR[i] = 0xFFFFFFFF;
00046         }
00047         for (j = 0; j < 8; j++) {
00048             GICDistributor->IPRIORITYR[i*8+j] = 0x00000000;
00049         }
00050     }
00051 }
00052 
00053 #else
00054 
00055 static void powerdown_nvic(void);
00056 static void powerdown_scb(uint32_t vtor);
00057 static void start_new_application(void *sp, void *pc);
00058 
00059 void mbed_start_application(uintptr_t address)
00060 {
00061     void *sp;
00062     void *pc;
00063 
00064     // Interrupts are re-enabled in start_new_application
00065     __disable_irq();
00066 
00067     SysTick->CTRL = 0x00000000;
00068     powerdown_nvic();
00069     powerdown_scb(address);
00070 
00071     sp = *((void **)address + 0);
00072     pc = *((void **)address + 1);
00073     start_new_application(sp, pc);
00074 }
00075 
00076 static void powerdown_nvic()
00077 {
00078     int isr_groups_32;
00079     int i;
00080     int j;
00081 
00082 #if defined(__CORTEX_M23)
00083     // M23 doesn't support ICTR and supports up to 240 external interrupts.
00084     isr_groups_32 = 8;
00085 #else
00086     isr_groups_32 = ((SCnSCB->ICTR & SCnSCB_ICTR_INTLINESNUM_Msk) >> SCnSCB_ICTR_INTLINESNUM_Pos) + 1;
00087 #endif
00088     for (i = 0; i < isr_groups_32; i++) {
00089         NVIC->ICER[i] = 0xFFFFFFFF;
00090         NVIC->ICPR[i] = 0xFFFFFFFF;
00091         for (j = 0; j < 8; j++) {
00092 #if defined(__CORTEX_M23)
00093             NVIC->IPR[i * 8 + j] = 0x00000000;
00094 #else
00095             NVIC->IP[i * 8 + j] = 0x00000000;
00096 #endif
00097         }
00098     }
00099 }
00100 
00101 static void powerdown_scb(uint32_t vtor)
00102 {
00103     int i;
00104 
00105     // SCB->CPUID   - Read only CPU ID register
00106     SCB->ICSR = SCB_ICSR_PENDSVCLR_Msk | SCB_ICSR_PENDSTCLR_Msk;
00107     SCB->VTOR = vtor;
00108     SCB->AIRCR = 0x05FA | 0x0000;
00109     SCB->SCR = 0x00000000;
00110     // SCB->CCR     - Implementation defined value
00111 #if defined(__CORTEX_M23)
00112     for (i = 0; i < 2; i++) {
00113         SCB->SHPR[i] = 0x00;
00114     }
00115 #else
00116     for (i = 0; i < 12; i++) {
00117 #if defined(__CORTEX_M7)
00118         SCB->SHPR[i] = 0x00;
00119 #else
00120         SCB->SHP[i] = 0x00;
00121 #endif
00122     }
00123 #endif
00124     SCB->SHCSR = 0x00000000;
00125 #if defined(__CORTEX_M23)
00126 #else
00127     SCB->CFSR = 0xFFFFFFFF;
00128     SCB->HFSR = SCB_HFSR_DEBUGEVT_Msk | SCB_HFSR_FORCED_Msk | SCB_HFSR_VECTTBL_Msk;
00129     SCB->DFSR = SCB_DFSR_EXTERNAL_Msk | SCB_DFSR_VCATCH_Msk |
00130                 SCB_DFSR_DWTTRAP_Msk | SCB_DFSR_BKPT_Msk | SCB_DFSR_HALTED_Msk;
00131 #endif
00132     // SCB->MMFAR   - Implementation defined value
00133     // SCB->BFAR    - Implementation defined value
00134     // SCB->AFSR    - Implementation defined value
00135     // SCB->PFR     - Read only processor feature register
00136     // SCB->DFR     - Read only debug feature registers
00137     // SCB->ADR     - Read only auxiliary feature registers
00138     // SCB->MMFR    - Read only memory model feature registers
00139     // SCB->ISAR    - Read only instruction set attribute registers
00140     // SCB->CPACR   - Implementation defined value
00141 }
00142 
00143 #if defined (__CC_ARM)
00144 
00145 __asm static void start_new_application(void *sp, void *pc)
00146 {
00147     MOV R2, #0
00148     MSR CONTROL, R2         // Switch to main stack
00149     MOV SP, R0
00150     MSR PRIMASK, R2         // Enable interrupts
00151     BX R1
00152 }
00153 
00154 #elif defined (__GNUC__) || defined (__ICCARM__)
00155 
00156 void start_new_application(void *sp, void *pc)
00157 {
00158     __asm volatile(
00159         "movw   r2, #0      \n" // Fail to compile "mov r2, #0" with ARMC6. Replace with MOVW.
00160         // We needn't "movt r2, #0" immediately following because MOVW
00161         // will zero-extend the 16-bit immediate.
00162         "msr    control, r2 \n" // Switch to main stack
00163         "mov    sp, %0      \n"
00164         "msr    primask, r2 \n" // Enable interrupts
00165         "bx     %1          \n"
00166         :
00167         : "l"(sp), "l"(pc)
00168         : "r2", "cc", "memory"
00169     );
00170 }
00171 
00172 #else
00173 
00174 #error "Unsupported toolchain"
00175 
00176 #endif
00177 
00178 #endif
00179 
00180 #endif /* MBED_APPLICATION_SUPPORT */