2 * This file is part of Cleanflight and Betaflight.
4 * Cleanflight and Betaflight are free software. You can redistribute
5 * this software and/or modify this software under the terms of the
6 * GNU General Public License as published by the Free Software
7 * Foundation, either version 3 of the License, or (at your option)
10 * Cleanflight and Betaflight are distributed in the hope that they
11 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
12 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 * See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this software.
18 * If not, see <http://www.gnu.org/licenses/>.
22 * An implementation of persistent data storage utilizing RTC backup data register.
23 * Retains values written across software resets and boot loader activities.
29 #include "drivers/persistent.h"
30 #include "drivers/system.h"
32 #define PERSISTENT_OBJECT_MAGIC_VALUE (('B' << 24)|('e' << 16)|('f' << 8)|('1' << 0))
36 uint32_t persistentObjectRead(persistentObjectId_e id
)
38 RTC_HandleTypeDef rtcHandle
= { .Instance
= RTC
};
40 uint32_t value
= HAL_RTCEx_BKUPRead(&rtcHandle
, id
);
45 void persistentObjectWrite(persistentObjectId_e id
, uint32_t value
)
47 RTC_HandleTypeDef rtcHandle
= { .Instance
= RTC
};
49 HAL_RTCEx_BKUPWrite(&rtcHandle
, id
, value
);
51 #ifdef USE_SPRACING_PERSISTENT_RTC_WORKAROUND
52 // Also write the persistent location used by the bootloader to support DFU etc.
53 if (id
== PERSISTENT_OBJECT_RESET_REASON
) {
54 // SPRACING firmware sometimes enters DFU mode when MSC mode is requested
55 if (value
== RESET_MSC_REQUEST
) {
58 HAL_RTCEx_BKUPWrite(&rtcHandle
, PERSISTENT_OBJECT_RESET_REASON_FWONLY
, value
);
63 void persistentObjectRTCEnable(void)
66 // G4 library V1.0.0 __HAL_RTC_WRITEPROTECTION_ENABLE/DISABLE macro does not use handle parameter
67 RTC_HandleTypeDef rtcHandle
= { .Instance
= RTC
};
71 __HAL_RCC_PWR_CLK_ENABLE(); // Enable Access to PWR
74 HAL_PWR_EnableBkUpAccess(); // Disable backup domain protection
77 /* Enable RTC APB clock */
78 __HAL_RCC_RTCAPB_CLK_ENABLE();
80 /* Peripheral clock enable */
81 __HAL_RCC_RTC_ENABLE();
83 #else // !STM32G4, F7 and H7 case
85 #if defined(__HAL_RCC_RTC_CLK_ENABLE)
86 // For those MCUs with RTCAPBEN bit in RCC clock enable register, turn it on.
87 __HAL_RCC_RTC_CLK_ENABLE(); // Enable RTC module
92 // We don't need a clock source for RTC itself. Skip it.
94 __HAL_RTC_WRITEPROTECTION_ENABLE(&rtcHandle
); // Reset sequence
95 __HAL_RTC_WRITEPROTECTION_DISABLE(&rtcHandle
); // Apply sequence
99 uint32_t persistentObjectRead(persistentObjectId_e id
)
101 uint32_t value
= RTC_ReadBackupRegister(id
);
106 void persistentObjectWrite(persistentObjectId_e id
, uint32_t value
)
108 RTC_WriteBackupRegister(id
, value
);
111 void persistentObjectRTCEnable(void)
113 RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR
, ENABLE
); // Enable Access to PWR
114 PWR_BackupAccessCmd(ENABLE
); // Disable backup domain protection
116 // We don't need a clock source for RTC itself. Skip it.
118 RTC_WriteProtectionCmd(ENABLE
); // Reset sequence
119 RTC_WriteProtectionCmd(DISABLE
); // Apply sequence
123 void persistentObjectInit(void)
125 // Configure and enable RTC for backup register access
127 persistentObjectRTCEnable();
129 // XXX Magic value checking may be sufficient
131 uint32_t wasSoftReset
;
134 wasSoftReset
= RCC
->RSR
& RCC_RSR_SFTRSTF
;
136 wasSoftReset
= RCC
->CSR
& RCC_CSR_SFTRSTF
;
139 if (!wasSoftReset
|| (persistentObjectRead(PERSISTENT_OBJECT_MAGIC
) != PERSISTENT_OBJECT_MAGIC_VALUE
)) {
140 for (int i
= 1; i
< PERSISTENT_OBJECT_COUNT
; i
++) {
141 persistentObjectWrite(i
, 0);
143 persistentObjectWrite(PERSISTENT_OBJECT_MAGIC
, PERSISTENT_OBJECT_MAGIC_VALUE
);