1 /**
2     *****************************************************************************
3     * @file     cmem7_efuse.c
4     *
5     * @brief    CMEM7 EFUSE source file
6     *
7     *
8     * @version  V1.0
9     * @date     3. September 2013
10     *
11     * @note
12     *
13     *****************************************************************************
14     * @attention
15     *
16     * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
17     * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
18     * TIME. AS A RESULT, CAPITAL-MICRO SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
19     * INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
20     * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
21     * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
22     *
23     * <h2><center>&copy; COPYRIGHT 2013 Capital-micro </center></h2>
24     *****************************************************************************
25     */
26 
27 #include "cmem7_efuse.h"
28 
efuse_SetClock(uint8_t dividor)29 static void efuse_SetClock(uint8_t dividor) {
30     if (dividor <= 2) {
31         GLOBAL_CTRL->CLK_SEL_1_b.EFUSE_CLK = 0;
32     } else if (dividor <= 4) {
33         GLOBAL_CTRL->CLK_SEL_1_b.EFUSE_CLK = 1;
34     } else if (dividor <= 8) {
35         GLOBAL_CTRL->CLK_SEL_1_b.EFUSE_CLK = 2;
36     } else {
37         GLOBAL_CTRL->CLK_SEL_1_b.EFUSE_CLK = 3;
38     }
39 }
40 
efuse_GetClock()41 static uint32_t efuse_GetClock() {
42     return SYSTEM_CLOCK_FREQ / (1 << (GLOBAL_CTRL->CLK_SEL_1_b.EFUSE_CLK + 1));
43 }
44 
45 // static uint8_t efuse_Crc8Bit(uint8_t data, uint8_t crc) {
46 //  uint8_t newCrc;
47 //  uint8_t d[8], c[8], i;
48 //
49 //  for (i = 0; i < 8; i++) {
50 //      d[i] = (data >> i) & 0x01;
51 //      c[i] = (crc >> i) & 0x01;
52 //  }
53 //
54 //  newCrc = d[7] ^ d[6] ^ d[0] ^ c[0] ^ c[6] ^ c[7];
55 //  newCrc |= (d[6] ^ d[1] ^ d[0] ^ c[0] ^ c[1] ^ c[6]) << 1;
56 //  newCrc |= (d[6] ^ d[2] ^ d[1] ^ d[0] ^ c[0] ^ c[1] ^ c[2] ^ c[6]) << 2;
57 //  newCrc |= (d[7] ^ d[3] ^ d[2] ^ d[1] ^ c[1] ^ c[2] ^ c[3] ^ c[7]) << 3;
58 //  newCrc |= (d[4] ^ d[3] ^ d[2] ^ c[2] ^ c[3] ^ c[4]) << 4;
59 //  newCrc |= (d[5] ^ d[4] ^ d[3] ^ c[3] ^ c[4] ^ c[5]) << 5;
60 //  newCrc |= (d[6] ^ d[5] ^ d[4] ^ c[4] ^ c[5] ^ c[6]) << 6;
61 //  newCrc |= (d[7] ^ d[6] ^ d[5] ^ c[5] ^ c[6] ^ c[7]) << 1;
62 //
63 //  return newCrc;
64 // }
65 
66 // static uint8_t efuse_Crc(EFUSE_AesKey* key, uint8_t lock, BOOL isLowRegion) {
67 //  uint8_t crc = 0;
68 //
69 //  if (isLowRegion) {
70 //      crc = efuse_Crc8Bit(key->key0, crc);
71 //      crc = efuse_Crc8Bit(key->key0 >> 8, crc);
72 //      crc = efuse_Crc8Bit(key->key0 >> 16, crc);
73 //      crc = efuse_Crc8Bit(key->key0 >> 24, crc);
74 //      crc = efuse_Crc8Bit(key->key1, crc);
75 //      crc = efuse_Crc8Bit(key->key1 >> 8, crc);
76 //      crc = efuse_Crc8Bit(key->key1 >> 16, crc);
77 //      crc = efuse_Crc8Bit(key->key1 >> 24, crc);
78 //      crc = efuse_Crc8Bit(key->key2, crc);
79 //      crc = efuse_Crc8Bit(key->key2 >> 8, crc);
80 //      crc = efuse_Crc8Bit(key->key2 >> 16, crc);
81 //      crc = efuse_Crc8Bit(key->key2 >> 24, crc);
82 //      crc = efuse_Crc8Bit(key->key3, crc);
83 //      crc = efuse_Crc8Bit(key->key3 >> 8, crc);
84 //      crc = efuse_Crc8Bit(key->key3 >> 16, crc);
85 //      crc = efuse_Crc8Bit(key->key3 >> 24, crc);
86 //      crc = efuse_Crc8Bit(lock, crc);
87 //      crc = efuse_Crc8Bit(0x0, crc);
88 //      crc = efuse_Crc8Bit(0x0, crc);
89 //  } else {
90 //      crc = efuse_Crc8Bit(key->key4, crc);
91 //      crc = efuse_Crc8Bit(key->key4 >> 8, crc);
92 //      crc = efuse_Crc8Bit(key->key4 >> 16, crc);
93 //      crc = efuse_Crc8Bit(key->key4 >> 24, crc);
94 //      crc = efuse_Crc8Bit(key->key5, crc);
95 //      crc = efuse_Crc8Bit(key->key5 >> 8, crc);
96 //      crc = efuse_Crc8Bit(key->key5 >> 16, crc);
97 //      crc = efuse_Crc8Bit(key->key5 >> 24, crc);
98 //      crc = efuse_Crc8Bit(key->key6, crc);
99 //      crc = efuse_Crc8Bit(key->key6 >> 8, crc);
100 //      crc = efuse_Crc8Bit(key->key6 >> 16, crc);
101 //      crc = efuse_Crc8Bit(key->key6 >> 24, crc);
102 //      crc = efuse_Crc8Bit(key->key7, crc);
103 //      crc = efuse_Crc8Bit(key->key7 >> 8, crc);
104 //      crc = efuse_Crc8Bit(key->key7 >> 16, crc);
105 //      crc = efuse_Crc8Bit(key->key7 >> 24, crc);
106 //      crc = efuse_Crc8Bit(lock, crc);
107 //      crc = efuse_Crc8Bit(0x0, crc);
108 //      crc = efuse_Crc8Bit(0x0, crc);
109 //  }
110 //
111 //  return crc;
112 // }
113 
EFUSE_Init(EFUSE_InitTypeDef * init)114 void EFUSE_Init(EFUSE_InitTypeDef* init) {
115     assert_param(init);
116     assert_param(IS_EFUSE_TMRF(init->EFUSE_TMRF));
117 
118     efuse_SetClock(init->EFUSE_ClockDividor);
119     EFUSE->USER_CTRL_LOW_b.TMRF = init->EFUSE_TMRF;
120     EFUSE->USER_CTRL_HI_b.TMRF = init->EFUSE_TMRF;
121     if (init->timing) {
122         uint32_t value;
123 
124         value = (init->timing->EFUSE_Tpwph * (efuse_GetClock() / 1000000) / 1000);
125         value = (value == 0) ? 1 : value;
126         EFUSE->TIMING_0_b.TPWPH = value >> 2;
127         EFUSE->TIMING_1_b.TPWPH = value & 0x00000003;
128 
129         value = (init->timing->EFUSE_Trac * (efuse_GetClock() / 1000000) / 1000);
130         value = (value == 0) ? 1 : value;
131         EFUSE->TIMING_0_b.TRAC = value;
132 
133         value = (init->timing->EFUSE_Trah * (efuse_GetClock() / 1000000) / 1000);
134         value = (value == 0) ? 1 : value;
135         EFUSE->TIMING_0_b.TRAH = value;
136 
137         value = (init->timing->EFUSE_Trpw * (efuse_GetClock() / 1000000) / 1000);
138         value = (value == 0) ? 1 : value;
139         EFUSE->TIMING_0_b.TRPW = value;
140 
141         value = (init->timing->EFUSE_Trc * (efuse_GetClock() / 1000000) / 1000);
142         value = (value == 0) ? 1 : value;
143         EFUSE->TIMING_0_b.TRC = value;
144 
145         value = (init->timing->EFUSE_Tesr * (efuse_GetClock() / 1000000) / 1000);
146         value = (value == 0) ? 1 : value;
147         EFUSE->TIMING_0_b.TESR = value;
148 
149         value = (init->timing->EFUSE_Tprs * (efuse_GetClock() / 1000000) / 1000);
150         value = (value == 0) ? 1 : value;
151         EFUSE->TIMING_0_b.TPRS = value;
152 
153         value = (init->timing->EFUSE_Tpi * (efuse_GetClock() / 1000000) / 1000);
154         value = (value == 0) ? 1 : value;
155         EFUSE->TIMING_1_b.TPIT = value;
156 
157         value = (init->timing->EFUSE_Tpp * (efuse_GetClock() / 1000000) / 1000);
158         value = (value == 0) ? 1 : value;
159         EFUSE->TIMING_1_b.TPP = value;
160 
161         value = (init->timing->EFUSE_Teps * (efuse_GetClock() / 1000000) / 1000);
162         value = (value == 0) ? 1 : value;
163         EFUSE->TIMING_1_b.TEPS = value;
164 
165         value = (init->timing->EFUSE_Teps * (efuse_GetClock() / 1000000) / 1000);
166         value = (value == 0) ? 1 : value;
167         EFUSE->TIMING_1_b.TPWPS = value;
168     }
169 }
170 
171 /* It only can be written once */
172 // BOOL EFUSE_Write(EFUSE_AesKey* key) {
173 //   assert_param(key);
174 //
175 //  if ((EFUSE->USER_CTRL_LOW_b.LOCK || EFUSE->USER_CTRL_LOW_b.BUSY) ||
176 //      (EFUSE->USER_CTRL_HI_b.LOCK || EFUSE->USER_CTRL_HI_b.BUSY)) {
177 //      return FALSE;
178 //  }
179 //
180 //  // write low region
181 //  EFUSE->USER_DATA0_LOW = key->key0;
182 //  EFUSE->USER_DATA1_LOW = key->key1;
183 //  EFUSE->USER_DATA2_LOW = key->key2;
184 //  EFUSE->USER_DATA3_LOW = key->key3;
185 //  EFUSE->USER_DATA4_LOW_b.CRC = efuse_Crc(key, 0x1, TRUE);
186 //  EFUSE->USER_DATA4_LOW_b.LOCK = 1;
187 //  EFUSE->USER_CTRL_LOW_b.WR_EN = FALSE;
188 //  EFUSE->USER_CTRL_LOW_b.WR_EN = TRUE;
189 //
190 //  udelay(1000);
191 //  while (EFUSE->USER_CTRL_LOW_b.BUSY) ;
192 //
193 //  if (EFUSE->USER_CTRL_LOW_b.WR_CRC_ERR) {
194 //      return FALSE;
195 //  }
196 //
197 //  // write high region
198 //  EFUSE->USER_DATA0_HI = key->key4;
199 //  EFUSE->USER_DATA1_HI = key->key5;
200 //  EFUSE->USER_DATA2_HI = key->key6;
201 //  EFUSE->USER_DATA3_HI = key->key7;
202 //  EFUSE->USER_DATA4_HI_b.CRC = efuse_Crc(key, 0x1, FALSE);
203 //  EFUSE->USER_DATA4_HI_b.LOCK = 1;
204 //  EFUSE->USER_CTRL_HI_b.WR_EN = FALSE;
205 //  EFUSE->USER_CTRL_HI_b.WR_EN = TRUE;
206 //
207 //  udelay(1000);
208 //  while (EFUSE->USER_CTRL_HI_b.BUSY) ;
209 //
210 //  if (EFUSE->USER_CTRL_HI_b.WR_CRC_ERR) {
211 //      return FALSE;
212 //  }
213 //  return TRUE;
214 // }
215 
EFUSE_Compare(EFUSE_AesKey * key)216 BOOL EFUSE_Compare(EFUSE_AesKey* key) {
217   assert_param(key);
218 
219     if (EFUSE->USER_CTRL_LOW_b.BUSY || EFUSE->USER_CTRL_HI_b.BUSY) {
220         return FALSE;
221     }
222 
223     // compare low region
224     EFUSE->USER_DATA0_LOW = key->key0;
225     EFUSE->USER_DATA1_LOW = key->key1;
226     EFUSE->USER_DATA2_LOW = key->key2;
227     EFUSE->USER_DATA3_LOW = key->key3;
228     EFUSE->USER_CTRL_LOW_b.RD_EN = FALSE;
229     EFUSE->USER_CTRL_LOW_b.RD_EN = TRUE;
230 
231     udelay(2);
232     while (EFUSE->USER_CTRL_LOW_b.BUSY) ;
233 
234     if (EFUSE->USER_CTRL_LOW_b.COMPARE_FAIL) {
235         return FALSE;
236     }
237 
238     // compare high region
239     EFUSE->USER_DATA0_HI = key->key4;
240     EFUSE->USER_DATA1_HI = key->key5;
241     EFUSE->USER_DATA2_HI = key->key6;
242     EFUSE->USER_DATA3_HI = key->key7;
243     EFUSE->USER_CTRL_HI_b.RD_EN = FALSE;
244     EFUSE->USER_CTRL_HI_b.RD_EN = TRUE;
245 
246     udelay(2);
247     while (EFUSE->USER_CTRL_HI_b.BUSY) ;
248 
249     if (EFUSE->USER_CTRL_HI_b.COMPARE_FAIL) {
250         return FALSE;
251     }
252 
253     return TRUE;
254 }
255 
256