Merge remote-tracking branch 'upstream/master' into abo_RTH_sanity_fix
[inav.git] / src / main / drivers / system.c
blob8fcf1f5dc5304d22c08c7e3a40b78d3736c1b274
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(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
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(USE_HAL_DRIVER)
47 // We assume that SystemCoreClock is already set to a correct value by init code
48 usTicks = SystemCoreClock / 1000000;
49 #else
50 RCC_ClocksTypeDef clocks;
51 RCC_GetClocksFreq(&clocks);
52 usTicks = clocks.SYSCLK_Frequency / 1000000;
53 #endif
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;
63 #endif
65 DWT->CYCCNT = 0;
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)
82 __disable_irq();
83 systemDisableAllIRQs();
84 NVIC_SystemReset();
87 void systemResetRequest(uint32_t requestId)
89 persistentObjectWrite(PERSISTENT_OBJECT_RESET_REASON, requestId);
90 systemReset();
93 void systemResetToBootloader(void)
95 systemResetRequest(RESET_BOOTLOADER_REQUEST_ROM);
98 typedef void resetHandler_t(void);
100 typedef struct isrVector_s {
101 uint32_t stackEnd;
102 resetHandler_t *resetHandler;
103 } isrVector_t;
106 void checkForBootLoaderRequest(void)
108 uint32_t bootloaderRequest = persistentObjectRead(PERSISTENT_OBJECT_RESET_REASON);
110 if (bootloaderRequest != RESET_BOOTLOADER_REQUEST_ROM) {
111 return;
113 persistentObjectWrite(PERSISTENT_OBJECT_RESET_REASON, RESET_NONE);
115 volatile isrVector_t *bootloaderVector = (isrVector_t *)systemBootloaderAddress();
116 __set_MSP(bootloaderVector->stackEnd);
117 bootloaderVector->resetHandler();
118 while (1);
121 #define SHORT_FLASH_DURATION 50
122 #define CODE_FLASH_DURATION 250
124 void failureMode(failureMode_e mode)
126 #ifdef UNIT_TEST
127 (void)mode;
128 #else
129 int codeRepeatsRemaining = 10;
130 int codeFlashesRemaining;
131 int shortFlashesRemaining;
133 while (codeRepeatsRemaining--) {
134 LED1_ON;
135 LED0_OFF;
136 shortFlashesRemaining = 5;
137 codeFlashesRemaining = mode + 1;
138 uint8_t flashDuration = SHORT_FLASH_DURATION;
140 while (shortFlashesRemaining || codeFlashesRemaining) {
141 LED1_TOGGLE;
142 LED0_TOGGLE;
143 BEEP_ON;
144 delay(flashDuration);
146 LED1_TOGGLE;
147 LED0_TOGGLE;
148 BEEP_OFF;
149 delay(flashDuration);
151 if (shortFlashesRemaining) {
152 shortFlashesRemaining--;
153 if (shortFlashesRemaining == 0) {
154 delay(500);
155 flashDuration = CODE_FLASH_DURATION;
157 } else {
158 codeFlashesRemaining--;
161 delay(1000);
164 #ifdef DEBUG
165 systemReset();
166 #else
167 systemResetToBootloader();
168 #endif
169 #endif //UNIT_TEST
172 void initialiseMemorySections(void)
174 #ifdef USE_ITCM_RAM
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));
180 #endif