Blackbox device type 'file' (SITL) considered working when file handler is available
[inav.git] / src / main / drivers / system.c
blob18a569857e248a62d68f1757050aadbb0274336b
1 /*
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/>.
18 #include <stdbool.h>
19 #include <stdint.h>
20 #include <string.h>
22 #include "platform.h"
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
37 #endif
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(AT32F43x)
47 //crm_clocks_freq_type clocks;
48 //crm_clocks_freq_get(&clocks);
49 //usTicks = clocks.sclk_freq / 1000000;
50 usTicks = SystemCoreClock / 1000000;
51 #else
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;
55 #else
56 RCC_ClocksTypeDef clocks;
57 RCC_GetClocksFreq(&clocks);
58 usTicks = clocks.SYSCLK_Frequency / 1000000;
59 #endif
60 #endif
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;
72 #endif
74 DWT->CYCCNT = 0;
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)
91 __disable_irq();
92 systemDisableAllIRQs();
93 NVIC_SystemReset();
96 void systemResetRequest(uint32_t requestId)
98 persistentObjectWrite(PERSISTENT_OBJECT_RESET_REASON, requestId);
99 systemReset();
102 void systemResetToBootloader(void)
104 systemResetRequest(RESET_BOOTLOADER_REQUEST_ROM);
107 typedef void resetHandler_t(void);
109 typedef struct isrVector_s {
110 uint32_t stackEnd;
111 resetHandler_t *resetHandler;
112 } isrVector_t;
115 void checkForBootLoaderRequest(void)
117 uint32_t bootloaderRequest = persistentObjectRead(PERSISTENT_OBJECT_RESET_REASON);
119 if (bootloaderRequest != RESET_BOOTLOADER_REQUEST_ROM) {
120 return;
122 persistentObjectWrite(PERSISTENT_OBJECT_RESET_REASON, RESET_NONE);
124 volatile isrVector_t *bootloaderVector = (isrVector_t *)systemBootloaderAddress();
125 __set_MSP(bootloaderVector->stackEnd);
126 bootloaderVector->resetHandler();
129 while (1);
132 #define SHORT_FLASH_DURATION 50
133 #define CODE_FLASH_DURATION 250
135 void failureMode(failureMode_e mode)
137 #ifdef UNIT_TEST
138 (void)mode;
139 #else
140 int codeRepeatsRemaining = 10;
141 int codeFlashesRemaining;
142 int shortFlashesRemaining;
144 while (codeRepeatsRemaining--) {
145 LED1_ON;
146 LED0_OFF;
147 shortFlashesRemaining = 5;
148 codeFlashesRemaining = mode + 1;
149 uint8_t flashDuration = SHORT_FLASH_DURATION;
151 while (shortFlashesRemaining || codeFlashesRemaining) {
152 LED1_TOGGLE;
153 LED0_TOGGLE;
154 BEEP_ON;
155 delay(flashDuration);
157 LED1_TOGGLE;
158 LED0_TOGGLE;
159 BEEP_OFF;
160 delay(flashDuration);
162 if (shortFlashesRemaining) {
163 shortFlashesRemaining--;
164 if (shortFlashesRemaining == 0) {
165 delay(500);
166 flashDuration = CODE_FLASH_DURATION;
168 } else {
169 codeFlashesRemaining--;
172 delay(1000);
175 #ifdef DEBUG
176 systemReset();
177 #else
178 systemResetToBootloader();
179 #endif
180 #endif //UNIT_TEST
182 // Tightly-Coupled Memory for instruction AT32 not enabled, can optimize preloading
183 void initialiseMemorySections(void)
185 #ifdef USE_ITCM_RAM
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));
191 #endif