1 /*
2 * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <app_demo_efuse.h>
17
get_efuse_id_size_test(hi_void)18 hi_u32 get_efuse_id_size_test(hi_void)
19 {
20 hi_s32 i;
21 hi_u32 efuse_size;
22
23 for (i = 0; i < HI_EFUSE_IDX_MAX; i++) {
24 efuse_size = hi_efuse_get_id_size((hi_efuse_idx)i);
25 if (efuse_size == HI_ERR_EFUSE_INVALIDATE_ID) {
26 printf("***exception***! failed to get size of efuse ID%d(0x%02X)\n", i, i);
27 return efuse_size;
28 }
29
30 printf("size of efuse ID%d(0x%02X) = %d\n", i, i, efuse_size);
31 }
32
33 return HI_ERR_SUCCESS;
34 }
35
efuse_get_lock_stat(hi_void)36 hi_void efuse_get_lock_stat(hi_void)
37 {
38 hi_u64 lock_data;
39
40 hi_efuse_get_lockstat(&lock_data);
41 printf("lock_stat = 0x%08X ", (hi_u32)((lock_data >> 32) & 0xFFFFFFFF)); /* right shift 32bits */
42 printf("%08X\n", (hi_u32)(lock_data & 0xFFFFFFFF));
43 }
44
efuse_usr_read(hi_void)45 hi_u32 efuse_usr_read(hi_void)
46 {
47 hi_u32 ret;
48 hi_u32 read_data[EFUSE_USR_RW_SAMPLE_BUFF_MAX_LEN] = {0};
49 hi_u16 start_bit = 0x75C; /* The offset address of customer_rsvd0 is 0x75C */
50 hi_u16 rw_bits = 64; /* The lenth of customer_rsvd0 is 64bits */
51 hi_u16 align_size;
52 hi_u8 tmp_data[9] = {0}; /* 9 bytes(72 bits) for customer_rsvd0 field, length 8-bit aligned. */
53 hi_u64 first_u64;
54 hi_u8 second_u8;
55
56 hi_u8 diff_head_read = start_bit % 8; /* The start address is read in 8-bit alignment mode. */
57 start_bit = start_bit - diff_head_read;
58 align_size = (((rw_bits + diff_head_read) >> 3) + 1) << 3; /* 3-bit offset */
59
60 ret = hi_efuse_usr_read(start_bit, align_size, (hi_u8 *)tmp_data);
61 if (ret != HI_ERR_SUCCESS) {
62 printf("Failed to read EFUSE at line%d! Err code = %X\n", __LINE__, ret);
63 return ret;
64 }
65
66 first_u64 = *(hi_u64 *)&tmp_data[0];
67 second_u8 = *(hi_u8 *)&tmp_data[8]; /* the last u8 bit */
68 /* The lower bits of the first u64 multi-read are discarded.(The diff_head_read) */
69 first_u64 = first_u64 >> diff_head_read;
70 /*
71 * The least significant eight bits of tmp_data are shifted leftward by 64-diff_head_read bits
72 * as the most significant 64 bits of tmp_data.diff_head_read)
73 */
74 first_u64 = first_u64 | ((hi_u64)second_u8 << (64 - diff_head_read)); /* (64 - diff_head_read)bits */
75 *(hi_u64 *)read_data = first_u64;
76
77 printf("usr_data = 0x%08X %08X\n", read_data[0], read_data[1]);
78
79 return HI_ERR_SUCCESS;
80 }
81
efuse_usr_write(hi_void)82 hi_u32 efuse_usr_write(hi_void)
83 {
84 hi_u32 ret;
85 hi_u32 write_data[EFUSE_USR_RW_SAMPLE_BUFF_MAX_LEN] = {
86 0x0,
87 0x1,
88 };
89 hi_u16 start_bit = 0x75C; /* Offset address:0x75C */
90 hi_u16 rw_bits = 64; /* length:64bits */
91
92 ret = efuse_usr_read();
93 if (ret != HI_ERR_SUCCESS) {
94 return ret;
95 }
96
97 ret = hi_efuse_usr_write(start_bit, rw_bits, (hi_u8 *)write_data);
98 if (ret != HI_ERR_SUCCESS) {
99 printf("Failed to write EFUSE!\n");
100 return ret;
101 }
102
103 return HI_ERR_SUCCESS;
104 }
105
efuse_usr_lock(hi_void)106 hi_u32 efuse_usr_lock(hi_void)
107 {
108 hi_u32 ret;
109 hi_u8 lock_data = 0x1;
110 hi_u16 lock_start_bit = 0x7FD; /* Offset address:0x7FD */
111 hi_u16 lock_bits = 1; /* length:1bit */
112
113 efuse_get_lock_stat();
114
115 ret = hi_efuse_usr_write(lock_start_bit, lock_bits, &lock_data);
116 if (ret != HI_ERR_SUCCESS) {
117 printf("Failed to lock EFUSE!\n");
118 return ret;
119 }
120
121 efuse_get_lock_stat();
122
123 return HI_ERR_SUCCESS;
124 }
125
sample_usr_efuse(hi_void)126 hi_u32 sample_usr_efuse(hi_void)
127 {
128 hi_u32 ret;
129
130 #ifdef EFUSE_WRITE_ENABLE
131 ret = efuse_usr_write();
132 if (ret != HI_ERR_SUCCESS) {
133 return ret;
134 }
135 #endif
136
137 ret = efuse_usr_read();
138 if (ret != HI_ERR_SUCCESS) {
139 return ret;
140 }
141
142 #ifdef EFUSE_LOCK_ENABLE
143 ret = efuse_usr_lock();
144 if (ret != HI_ERR_SUCCESS) {
145 return ret;
146 }
147 #endif
148
149 return HI_ERR_SUCCESS;
150 }
151
efuse_id_read(hi_void)152 hi_u32 efuse_id_read(hi_void)
153 {
154 hi_u32 ret;
155 hi_u32 read_data[EFUSE_USR_RW_SAMPLE_BUFF_MAX_LEN] = {0};
156 hi_efuse_idx efuse_id = HI_EFUSE_CUSTOMER_RSVD0_RW_ID;
157
158 ret = hi_efuse_read(efuse_id, (hi_u8 *)read_data, (hi_u8)sizeof(read_data));
159 if (ret != HI_ERR_SUCCESS) {
160 printf("Failed to read EFUSE at line%d! Err code = %X\n", __LINE__, ret);
161 return ret;
162 }
163 printf("id_data = 0x%08X %08X\n", read_data[0], read_data[1]);
164
165 return HI_ERR_SUCCESS;
166 }
167
efuse_id_write(hi_void)168 hi_u32 efuse_id_write(hi_void)
169 {
170 hi_u32 ret;
171 hi_u32 write_data[EFUSE_USR_RW_SAMPLE_BUFF_MAX_LEN] = {
172 0x1,
173 0x0,
174 };
175 hi_efuse_idx efuse_id = HI_EFUSE_CUSTOMER_RSVD0_RW_ID;
176
177 ret = efuse_id_read();
178 if (ret != HI_ERR_SUCCESS) {
179 return ret;
180 }
181
182 ret = hi_efuse_write(efuse_id, (hi_u8 *)write_data);
183 if (ret != HI_ERR_SUCCESS) {
184 printf("Failed to write EFUSE!\n");
185 return ret;
186 }
187
188 return HI_ERR_SUCCESS;
189 }
190
efuse_id_lock(hi_void)191 hi_u32 efuse_id_lock(hi_void)
192 {
193 hi_u32 ret;
194 hi_efuse_lock_id lock_id = HI_EFUSE_LOCK_CUSTOMER_RSVD0_ID;
195 efuse_get_lock_stat();
196
197 ret = hi_efuse_lock(lock_id);
198 if (ret != HI_ERR_SUCCESS) {
199 printf("Failed to lock EFUSE!\n");
200 return ret;
201 }
202
203 efuse_get_lock_stat();
204
205 return HI_ERR_SUCCESS;
206 }
207
sample_id_efuse(hi_void)208 hi_u32 sample_id_efuse(hi_void)
209 {
210 hi_u32 ret;
211
212 #ifdef EFUSE_WRITE_ENABLE
213 ret = efuse_id_write();
214 if (ret != HI_ERR_SUCCESS) {
215 return ret;
216 }
217 #endif
218
219 ret = efuse_id_read();
220 if (ret != HI_ERR_SUCCESS) {
221 return ret;
222 }
223
224 #ifdef EFUSE_LOCK_ENABLE
225 ret = efuse_id_lock();
226 if (ret != HI_ERR_SUCCESS) {
227 return ret;
228 }
229 #endif
230
231 return HI_ERR_SUCCESS;
232 }
233
234 /*
235 * This demo simply shows how to use efuse interface to write, read and lock customer_rsvd0 field.
236 * -note: Efuse is a one-time programmable logic. Once set, it cannot be modified.
237 * Be careful when using write and lock interfaces.
238 */
efuse_demo(hi_void)239 hi_void efuse_demo(hi_void)
240 {
241 hi_u32 ret;
242
243 ret = get_efuse_id_size_test();
244 if (ret != HI_ERR_SUCCESS) {
245 return;
246 }
247
248 ret = sample_id_efuse();
249 if (ret != HI_ERR_SUCCESS) {
250 return;
251 }
252
253 ret = sample_usr_efuse();
254 if (ret != HI_ERR_SUCCESS) {
255 return;
256 }
257 }
258