• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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