2 * This file is part of INAV.
4 * INAV 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 * INAV distributed in the hope that it
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 (('i' << 24)|('N' << 16)|('a' << 8)|('v' << 0))
36 uint32_t persistentObjectRead(persistentObjectId_e id
)
38 uint32_t value
= ertc_bpr_data_read((ertc_dt_type
)id
);
43 void persistentObjectWrite(persistentObjectId_e id
, uint32_t value
)
45 ertc_bpr_data_write((ertc_dt_type
)id
,value
);
48 void persistentObjectRTCEnable(void)
50 /* enable the pwc clock interface */
51 crm_periph_clock_enable(CRM_PWC_PERIPH_CLOCK
, TRUE
);
53 /* allow access to bpr domain */
54 pwc_battery_powered_domain_access(TRUE
);
56 // We don't need a clock source for RTC itself. Skip it.
57 ertc_write_protect_enable();
58 ertc_write_protect_disable();
62 #elif defined(USE_HAL_DRIVER)
64 uint32_t persistentObjectRead(persistentObjectId_e id
)
66 RTC_HandleTypeDef rtcHandle
= { .Instance
= RTC
};
68 uint32_t value
= HAL_RTCEx_BKUPRead(&rtcHandle
, id
);
73 void persistentObjectWrite(persistentObjectId_e id
, uint32_t value
)
75 RTC_HandleTypeDef rtcHandle
= { .Instance
= RTC
};
77 HAL_RTCEx_BKUPWrite(&rtcHandle
, id
, value
);
80 void persistentObjectRTCEnable(void)
82 RTC_HandleTypeDef rtcHandle
= { .Instance
= RTC
};
85 __HAL_RCC_PWR_CLK_ENABLE(); // Enable Access to PWR
87 HAL_PWR_EnableBkUpAccess(); // Disable backup domain protection
89 #if defined(__HAL_RCC_RTC_CLK_ENABLE)
90 // For those MCUs with RTCAPBEN bit in RCC clock enable register, turn it on.
91 __HAL_RCC_RTC_CLK_ENABLE(); // Enable RTC module
94 // We don't need a clock source for RTC itself. Skip it.
96 __HAL_RTC_WRITEPROTECTION_ENABLE(&rtcHandle
); // Reset sequence
97 __HAL_RTC_WRITEPROTECTION_DISABLE(&rtcHandle
); // Apply sequence
101 uint32_t persistentObjectRead(persistentObjectId_e id
)
103 uint32_t value
= RTC_ReadBackupRegister(id
);
108 void persistentObjectWrite(persistentObjectId_e id
, uint32_t value
)
110 RTC_WriteBackupRegister(id
, value
);
113 void persistentObjectRTCEnable(void)
115 RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR
, ENABLE
); // Enable Access to PWR
116 PWR_BackupAccessCmd(ENABLE
); // Disable backup domain protection
118 // We don't need a clock source for RTC itself. Skip it.
120 RTC_WriteProtectionCmd(ENABLE
); // Reset sequence
121 RTC_WriteProtectionCmd(DISABLE
); // Apply sequence
125 void persistentObjectInit(void)
127 // Configure and enable RTC for backup register access
129 persistentObjectRTCEnable();
131 // XXX Magic value checking may be sufficient
133 uint32_t wasSoftReset
;
135 #if defined(AT32F43x)
136 wasSoftReset
= crm_flag_get(CRM_SW_RESET_FLAG
);
137 #elif defined(STM32H7)
138 wasSoftReset
= RCC
->RSR
& RCC_RSR_SFTRSTF
;
140 wasSoftReset
= RCC
->CSR
& RCC_CSR_SFTRSTF
;
143 if (!wasSoftReset
|| (persistentObjectRead(PERSISTENT_OBJECT_MAGIC
) != PERSISTENT_OBJECT_MAGIC_VALUE
)) {
144 for (int i
= 1; i
< PERSISTENT_OBJECT_COUNT
; i
++) {
145 persistentObjectWrite(i
, 0);
147 persistentObjectWrite(PERSISTENT_OBJECT_MAGIC
, PERSISTENT_OBJECT_MAGIC_VALUE
);