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