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>© 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