1 /**************************************************************************//**
2 * @file fvc.c
3 * @version V3.00
4 * @brief FVC driver source file
5 *
6 * @copyright SPDX-License-Identifier: Apache-2.0
7 * @copyright Copyright (C) 2020 Nuvoton Technology Corp. All rights reserved.
8 *****************************************************************************/
9 #include "NuMicro.h"
10
11 /** @addtogroup Standard_Driver Standard Driver
12 @{
13 */
14
15 /** @addtogroup FVC_Driver FVC Driver
16 @{
17 */
18
19
20 /** @addtogroup FVC_EXPORTED_FUNCTIONS FVC Exported Functions
21 @{
22 */
23
24
25 /**
26 * @brief Initial firmware version counter
27 * @param None
28 * @retval 0 Successful
29 * @retval -1 Failed
30 * @details FVC needs to be initialed before using it. This function is used to initial the FVC.
31 *
32 */
FVC_Open(void)33 int32_t FVC_Open(void)
34 {
35 int32_t timeout;
36
37 /* Just return when it is ready */
38 if(FVC->STS & FVC_STS_RDY_Msk)
39 return 0;
40
41 /* Init FVC */
42 FVC->CTL = FVC_VCODE | FVC_CTL_INIT_Msk;
43
44 /* Waiting for ready */
45 timeout = 0x100000;
46 while((FVC->STS & FVC_STS_RDY_Msk) == 0)
47 {
48 if(timeout-- < 0)
49 {
50 /* Init timeout. */
51 return -1;
52 }
53 }
54
55 return 0;
56 }
57
58
59
60 /**
61 * @brief Enable anti version rollback
62 * @details FVC can limit the version number to be increased only to avoid version rollback.
63 * This function is used to enable it.
64 *
65 */
FVC_EnableMonotone(void)66 void FVC_EnableMonotone(void)
67 {
68 FVC->CTL = FVC_VCODE | FVC_CTL_MONOEN_Msk;
69 /* Waiting if FVC is in busy */
70 while(FVC->STS & FVC->STS & FVC_STS_BUSY_Msk) {}
71 }
72
73 /**
74 * @brief Set non-volatile version counter
75 * @param[in] u32NvcIdx Index number of non-volatile version counter. It could be 0, 1, 4, 5.
76 * @param[in] u32Cnt Version Number. It could be 0~63 for u32NvcIdx=0, 1, and 0~255 for u32NvcIdx=4, 5
77 * @retval 0 Successful
78 * @retval -1 Failed
79 * @details Set non-volatile version counter
80 *
81 */
FVC_SetNVC(uint32_t u32NvcIdx,uint32_t u32Cnt)82 int32_t FVC_SetNVC(uint32_t u32NvcIdx, uint32_t u32Cnt)
83 {
84 if(u32NvcIdx < 2)
85 {
86 if(u32Cnt >= 64)
87 /* The counter value is out of range */
88 return -1;
89 }
90 else if(u32NvcIdx < 4)
91 return -1;
92 else if(u32NvcIdx < 6)
93 {
94 /* The counter value is out of range */
95 if(u32Cnt >= 256)
96 /* The counter value is out of range */
97 return -1;
98 }
99 else
100 return -1;
101
102 FVC->NVC[u32NvcIdx] = (FVC->NVC[u32NvcIdx] << 16) | (u32Cnt & 0x3ful);
103 while(FVC->STS & FVC_STS_BUSY_Msk) {}
104 if(FVC->NVC[u32NvcIdx] != u32Cnt)
105 return -1;
106
107 return 0;
108 }
109
110
111 /**
112 * @brief Get non-volatile version counter
113 * @param[in] u32NvcIdx Index number of non-volatile version counter. It could be 0, 1, 4, 5.
114 * @retval the version counter
115 * @retval -1 Failed
116 * @details Get non-volatile version counter
117 *
118 */
FVC_GetNVC(uint32_t u32NvcIdx)119 int32_t FVC_GetNVC(uint32_t u32NvcIdx)
120 {
121 if((u32NvcIdx == 2) || (u32NvcIdx == 3) || (u32NvcIdx > 5))
122 return -1;
123
124 return FVC->NVC[u32NvcIdx];
125 }
126
127 /**@}*/ /* end of group FVC_EXPORTED_FUNCTIONS */
128
129 /**@}*/ /* end of group FVC_Driver */
130
131 /**@}*/ /* end of group Standard_Driver */
132