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(STM32F4) || defined(STM32F7) || defined(STM32H7)||defined(AT32F43x)
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
47 //crm_clocks_freq_type clocks;
48 //crm_clocks_freq_get(&clocks);
49 //usTicks = clocks.sclk_freq / 1000000;
50 usTicks
= SystemCoreClock
/ 1000000;
52 #if defined(USE_HAL_DRIVER)
53 // We assume that SystemCoreClock is already set to a correct value by init code
54 usTicks
= SystemCoreClock
/ 1000000;
56 RCC_ClocksTypeDef clocks
;
57 RCC_GetClocksFreq(&clocks
);
58 usTicks
= clocks
.SYSCLK_Frequency
/ 1000000;
62 // Enable DWT for precision time measurement
63 CoreDebug
->DEMCR
|= CoreDebug_DEMCR_TRCENA_Msk
;
65 #if defined(STM32F7) || defined(STM32H7)
66 DWT
->LAR
= DWT_LAR_UNLOCK_VALUE
;
67 #elif defined(AT32F43x)
68 ITM
->LAR
= DWT_LAR_UNLOCK_VALUE
;
69 #elif defined(STM32F4)
70 volatile uint32_t *DWTLAR
= (uint32_t *)(DWT_BASE
+ 0x0FB0);
71 *(DWTLAR
) = DWT_LAR_UNLOCK_VALUE
;
75 DWT
->CTRL
|= DWT_CTRL_CYCCNTENA_Msk
;
78 static inline void systemDisableAllIRQs(void)
80 // We access CMSIS NVIC registers directly here
81 for (int x
= 0; x
< 8; x
++) {
82 // Mask all IRQs controlled by a ICERx
83 NVIC
->ICER
[x
] = 0xFFFFFFFF;
84 // Clear all pending IRQs controlled by a ICPRx
85 NVIC
->ICPR
[x
] = 0xFFFFFFFF;
89 void systemReset(void)
92 systemDisableAllIRQs();
96 void systemResetRequest(uint32_t requestId
)
98 persistentObjectWrite(PERSISTENT_OBJECT_RESET_REASON
, requestId
);
102 void systemResetToBootloader(void)
104 systemResetRequest(RESET_BOOTLOADER_REQUEST_ROM
);
107 typedef void resetHandler_t(void);
109 typedef struct isrVector_s
{
111 resetHandler_t
*resetHandler
;
115 void checkForBootLoaderRequest(void)
117 uint32_t bootloaderRequest
= persistentObjectRead(PERSISTENT_OBJECT_RESET_REASON
);
119 if (bootloaderRequest
!= RESET_BOOTLOADER_REQUEST_ROM
) {
122 persistentObjectWrite(PERSISTENT_OBJECT_RESET_REASON
, RESET_NONE
);
124 volatile isrVector_t
*bootloaderVector
= (isrVector_t
*)systemBootloaderAddress();
125 __set_MSP(bootloaderVector
->stackEnd
);
126 bootloaderVector
->resetHandler();
132 #define SHORT_FLASH_DURATION 50
133 #define CODE_FLASH_DURATION 250
135 void failureMode(failureMode_e mode
)
140 int codeRepeatsRemaining
= 10;
141 int codeFlashesRemaining
;
142 int shortFlashesRemaining
;
144 while (codeRepeatsRemaining
--) {
147 shortFlashesRemaining
= 5;
148 codeFlashesRemaining
= mode
+ 1;
149 uint8_t flashDuration
= SHORT_FLASH_DURATION
;
151 while (shortFlashesRemaining
|| codeFlashesRemaining
) {
155 delay(flashDuration
);
160 delay(flashDuration
);
162 if (shortFlashesRemaining
) {
163 shortFlashesRemaining
--;
164 if (shortFlashesRemaining
== 0) {
166 flashDuration
= CODE_FLASH_DURATION
;
169 codeFlashesRemaining
--;
178 systemResetToBootloader();
182 // Tightly-Coupled Memory for instruction AT32 not enabled, can optimize preloading
183 void initialiseMemorySections(void)
186 /* Load functions into ITCM RAM */
187 extern uint8_t tcm_code_start
;
188 extern uint8_t tcm_code_end
;
189 extern uint8_t tcm_code
;
190 memcpy(&tcm_code_start
, &tcm_code
, (size_t) (&tcm_code_end
- &tcm_code_start
));