2 * This file is part of Cleanflight.
4 * Cleanflight is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * Cleanflight is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
24 #include "build/build_config.h"
26 #include "drivers/light_led.h"
27 #include "drivers/persistent.h"
28 #include "drivers/sound_beeper.h"
29 #include "drivers/system.h"
30 #include "drivers/time.h"
32 #if defined(STM32F3) || defined(STM32F4) || defined(STM32F7) || defined(STM32H7)
33 // See "RM CoreSight Architecture Specification"
34 // B2.3.10 "LSR and LAR, Software Lock Status Register and Software Lock Access Register"
35 // "E1.2.11 LAR, Lock Access Register"
36 #define DWT_LAR_UNLOCK_VALUE 0xC5ACCE55
39 // cached value of RCC->CSR
40 uint32_t cachedRccCsrValue
;
42 void cycleCounterInit(void)
44 extern uint32_t usTicks
; // From drivers/time.h
46 #if defined(USE_HAL_DRIVER)
47 // We assume that SystemCoreClock is already set to a correct value by init code
48 usTicks
= SystemCoreClock
/ 1000000;
50 RCC_ClocksTypeDef clocks
;
51 RCC_GetClocksFreq(&clocks
);
52 usTicks
= clocks
.SYSCLK_Frequency
/ 1000000;
55 // Enable DWT for precision time measurement
56 CoreDebug
->DEMCR
|= CoreDebug_DEMCR_TRCENA_Msk
;
58 #if defined(STM32F7) || defined(STM32H7)
59 DWT
->LAR
= DWT_LAR_UNLOCK_VALUE
;
60 #elif defined(STM32F3) || defined(STM32F4)
61 volatile uint32_t *DWTLAR
= (uint32_t *)(DWT_BASE
+ 0x0FB0);
62 *(DWTLAR
) = DWT_LAR_UNLOCK_VALUE
;
66 DWT
->CTRL
|= DWT_CTRL_CYCCNTENA_Msk
;
69 static inline void systemDisableAllIRQs(void)
71 // We access CMSIS NVIC registers directly here
72 for (int x
= 0; x
< 8; x
++) {
73 // Mask all IRQs controlled by a ICERx
74 NVIC
->ICER
[x
] = 0xFFFFFFFF;
75 // Clear all pending IRQs controlled by a ICPRx
76 NVIC
->ICPR
[x
] = 0xFFFFFFFF;
80 void systemReset(void)
83 systemDisableAllIRQs();
87 void systemResetRequest(uint32_t requestId
)
89 persistentObjectWrite(PERSISTENT_OBJECT_RESET_REASON
, requestId
);
93 void systemResetToBootloader(void)
95 systemResetRequest(RESET_BOOTLOADER_REQUEST_ROM
);
98 typedef void resetHandler_t(void);
100 typedef struct isrVector_s
{
102 resetHandler_t
*resetHandler
;
106 void checkForBootLoaderRequest(void)
108 uint32_t bootloaderRequest
= persistentObjectRead(PERSISTENT_OBJECT_RESET_REASON
);
110 if (bootloaderRequest
!= RESET_BOOTLOADER_REQUEST_ROM
) {
113 persistentObjectWrite(PERSISTENT_OBJECT_RESET_REASON
, RESET_NONE
);
115 volatile isrVector_t
*bootloaderVector
= (isrVector_t
*)systemBootloaderAddress();
116 __set_MSP(bootloaderVector
->stackEnd
);
117 bootloaderVector
->resetHandler();
121 #define SHORT_FLASH_DURATION 50
122 #define CODE_FLASH_DURATION 250
124 void failureMode(failureMode_e mode
)
129 int codeRepeatsRemaining
= 10;
130 int codeFlashesRemaining
;
131 int shortFlashesRemaining
;
133 while (codeRepeatsRemaining
--) {
136 shortFlashesRemaining
= 5;
137 codeFlashesRemaining
= mode
+ 1;
138 uint8_t flashDuration
= SHORT_FLASH_DURATION
;
140 while (shortFlashesRemaining
|| codeFlashesRemaining
) {
144 delay(flashDuration
);
149 delay(flashDuration
);
151 if (shortFlashesRemaining
) {
152 shortFlashesRemaining
--;
153 if (shortFlashesRemaining
== 0) {
155 flashDuration
= CODE_FLASH_DURATION
;
158 codeFlashesRemaining
--;
167 systemResetToBootloader();
172 void initialiseMemorySections(void)
175 /* Load functions into ITCM RAM */
176 extern uint8_t tcm_code_start
;
177 extern uint8_t tcm_code_end
;
178 extern uint8_t tcm_code
;
179 memcpy(&tcm_code_start
, &tcm_code
, (size_t) (&tcm_code_end
- &tcm_code_start
));