IAP2
IAP2
---------------------*/
2 /*
*/
3 /* SPDX-License-Identifier:
Apache-2.0 */
4 /* Copyright(c) 2020 Nuvoton Technology Corp. All rights
reserved. */
5 /*
*/
6 /*------------------------------------------------------------------------------------
---------------------*/
7
8 #include "ms51_8k.h"
9
10 unsigned char xdata DIDBuffer[2];
11 unsigned char xdata PIDBuffer[2];
12 unsigned char xdata UIDBuffer[12];
13 unsigned char xdata UCIDBuffer[12];
14 unsigned char xdata IAPDataBuf[128];
15 unsigned char xdata IAPCFBuf[5];
16 bit ConfigModifyFlag;
17
18 /**
19 * @brief Erase LDROM
20 * @param u16IAPStartAddress #include "ms51_8k.h" LDROM area start address
21 * @param u16IAPDataSize #include "ms51_8k.h" LDROM need be erase bytes size
22 * @return none
23 * @details Page erase LDROM area base on data start address
24 * @example Erase_LDROM(0x0000,2048);
25 */
26 void Erase_LDROM(unsigned int u16IAPStartAddress,unsigned int u16IAPDataSize)
27 {
28 unsigned int u16Count;
29
30 set_CHPCON_IAPEN; // Enable IAP function
31 set_IAPUEN_LDUEN; // LDROM modify Enable
32 IAPFD = 0xFF; // IMPORTANT !! To erase function must
setting IAPFD = 0xFF
33 IAPCN = PAGE_ERASE_LDROM;
34 for(u16Count=0x0000;u16Count<(u16IAPDataSize/PAGE_SIZE);u16Count++) //
Loop page erase LDROM special #include "ms51_8k.h" address area.
35 {
36 IAPAL = LOBYTE(u16Count*PAGE_SIZE + u16IAPStartAddress);
37 IAPAH = HIBYTE(u16Count*PAGE_SIZE + u16IAPStartAddress);
38 set_IAPTRG_IAPGO_WDCLR;
39 }
40 clr_IAPUEN_LDUEN; // Disable LDROM modify
41 clr_CHPCON_IAPEN; // Disable IAP
42 }
43
44 /**
45 * @brief LDROM blank check
46 * @param u16IAPStartAddress #include "ms51_8k.h" LDROM area start address
47 * @param u16IAPDataSize #include "ms51_8k.h" LDROM need be erase bytes size
48 * @return none
49 * @details Check each byte of LDROM is FFH or not.
50 * @example LDROM_BlanckCheck(0x0000,2048);
51 */
52 void Erase_Verify_LDROM(unsigned int u16IAPStartAddress, unsigned int u16IAPDataSize)
53 {
54 unsigned int u16Count;
55 set_CHPCON_IAPEN;
56 IAPAL = LOBYTE(u16IAPStartAddress);
57 IAPAH = HIBYTE(u16IAPStartAddress);
58 IAPCN = BYTE_READ_LDROM;
59
60 for(u16Count=0;u16Count<u16IAPDataSize;u16Count++)
61 {
62 IAPFD = 0x00;
63 set_IAPTRG_IAPGO;
64 if(IAPFD != 0xFF)
65 while(1);
66 IAPAL++;
67 if(IAPAL == 0x00)
68 IAPAH++;
69 }
70 clr_CHPCON_IAPEN;
71 }
72
73 /**
74 * @brief LDROM program loop
75 * @param u16IAPStartAddress #include "ms51_8k.h" LDROM area start address
76 * @param u16IAPDataSize #include "ms51_8k.h" LDROM need be erase bytes size
77 * @return none
78 * @details Copy IAPDataBuf to LDROM
79 * @example LDROM_Program(0x0000,1024);
80 */
81 void Program_LDROM(unsigned int u16IAPStartAddress, unsigned int u16IAPDataSize)
82 {
83 unsigned int u16Count;
84
85 set_CHPCON_IAPEN;
86 set_IAPUEN_LDUEN;
87 IAPAL = LOBYTE(u16IAPStartAddress);
88 IAPAH = HIBYTE(u16IAPStartAddress);
89 IAPCN = BYTE_PROGRAM_LDROM;
90
91 for(u16Count=0;u16Count<u16IAPDataSize;u16Count++)
92 {
93 IAPFD = IAPDataBuf[u16Count];
94 set_IAPTRG_IAPGO_WDCLR;
95 IAPAL++;
96 if(IAPAL == 0)
97 {
98 IAPAH++;
99 }
100 }
101 clr_IAPUEN_LDUEN;
102 clr_CHPCON_IAPEN;
103 }
104
105
106 /**
107 * @brief LDROM check loop
108 * @param u16IAPStartAddress #include "ms51_8k.h" LDROM area start address
109 * @param u16IAPDataSize #include "ms51_8k.h" LDROM need be erase bytes size
110 * @return none
111 * @details Check with XRAM IAPDataBuf with LDROM
112 * @example LDROM_Program_Verify(0x0000,1024);
113 */
114 void Program_Verify_LDROM(unsigned int u16IAPStartAddress, unsigned int u16IAPDataSize
)
115 {
116 unsigned int u16Count;
117
118 set_CHPCON_IAPEN;
119 IAPAL = LOBYTE(u16IAPStartAddress);
120 IAPAH = HIBYTE(u16IAPStartAddress);
121 IAPCN = BYTE_READ_LDROM;
122 for(u16Count=0;u16Count<u16IAPDataSize;u16Count++)
123 {
124 IAPFD = 0x00;
125 set_IAPTRG_IAPGO;
126 if (IAPFD != IAPDataBuf[u16Count])
127 while(1);
128 IAPAL++;
129 if(IAPAL == 0)
130 {
131 IAPAH++;
132 }
133 }
134 clr_CHPCON_IAPEN;
135 }
136
137 /**
138 * @brief Erase APROM
139 * @param u16IAPStartAddress #include "ms51_8k.h" APROM area start address
140 * @param u16IAPDataSize #include "ms51_8k.h" LDROM need be erase bytes size
141 * @return none
142 * @details Page erase APROM area base on data start address
143 * @example Erase_APROM(0x0000,2048);
144 */
145 void Erase_APROM(unsigned int u16IAPStartAddress, unsigned int u16IAPDataSize)
146 {
147 unsigned int u16Count;
148
149 set_CHPCON_IAPEN; // Enable IAP function
150 set_IAPUEN_APUEN; // APROM modify Enable
151 IAPFD = 0xFF; // IMPORTANT !! To erase function must
setting IAPFD = 0xFF
152 IAPCN = PAGE_ERASE_APROM;
153 for(u16Count=0x0000;u16Count<u16IAPDataSize/PAGE_SIZE;u16Count++) //
Loop page erase APROM special #include "ms51_8k.h" address area.
154 {
155 IAPAL = LOBYTE(u16Count*PAGE_SIZE + u16IAPStartAddress);
156 IAPAH = HIBYTE(u16Count*PAGE_SIZE + u16IAPStartAddress);
157 set_IAPTRG_IAPGO_WDCLR;
158 }
159 clr_IAPUEN_APUEN; // Disable APROM modify
160 clr_CHPCON_IAPEN; // Disable IAP
161 }
162
163 /**
164 * @brief APROM blank check
165 * @param u16IAPStartAddress #include "ms51_8k.h" APROM area start address
166 * @param u16IAPDataSize #include "ms51_8k.h" APROM need be erase bytes size
167 * @return none
168 * @details Check each byte of APPROM is FFH or not.
169 * @example APROM_Blank_Check(0x0000,2048);
170 */
171 void Erase_Verify_APROM(unsigned int u16IAPStartAddress, unsigned int u16IAPDataSize)
172 {
173 unsigned int u16Count;
174
175 set_CHPCON_IAPEN;
176 IAPAL = LOBYTE(u16IAPStartAddress);
177 IAPAH = HIBYTE(u16IAPStartAddress);
178 IAPCN = BYTE_READ_APROM;
179 for(u16Count=0;u16Count<u16IAPDataSize;u16Count++)
180 {
181 IAPFD = 0x00;
182 set_IAPTRG_IAPGO;
183 if(IAPFD != 0xFF)
184 while(1);
185 IAPAL++;
186 if(IAPAL == 0x00)
187 IAPAH++;
188 }
189 clr_CHPCON_IAPEN;
190 }
191
192 /**
193 * @brief APROM program loop
194 * @param u16IAPStartAddress #include "ms51_8k.h" APROM area start address
195 * @param u16IAPDataSize #include "ms51_8k.h" APROM need be erase bytes size
196 * @return none
197 * @details Copy APDataBuf to APROM
198 * @example APROM_Program(0x0000,1024);
199 */
200 void Program_APROM(unsigned int u16IAPStartAddress, unsigned int u16IAPDataSize)
201 {
202 unsigned int u16Count;
203
204 set_CHPCON_IAPEN;
205 set_IAPUEN_APUEN;
206 IAPAL = LOBYTE(u16IAPStartAddress);
207 IAPAH = HIBYTE(u16IAPStartAddress);
208 IAPCN = BYTE_PROGRAM_APROM;
209 for(u16Count=0;u16Count<u16IAPDataSize;u16Count++)
210 {
211 IAPFD=IAPDataBuf[u16Count];
212 set_IAPTRG_IAPGO_WDCLR;
213 IAPAL++;
214 if(IAPAL == 0)
215 {
216 IAPAH++;
217 }
218 }
219 clr_IAPUEN_APUEN;
220 clr_CHPCON_IAPEN;
221 }
222
223
224 /**
225 * @brief APROM check loop
226 * @param u16IAPStartAddress #include "ms51_8k.h" APROM area start address
227 * @param u16IAPDataSize #include "ms51_8k.h" APROM need be erase bytes size
228 * @return none
229 * @details Check with XRAM IAPDataBuf with APROM
230 * @example APROM_Program_Verify(0x0000,1024);
231 */
232 void Program_Verify_APROM(unsigned int u16IAPStartAddress, unsigned int u16IAPDataSize
)
233 {
234 unsigned int u16Count;
235
236 set_CHPCON_IAPEN;
237 IAPAL = LOBYTE(u16IAPStartAddress);
238 IAPAH = HIBYTE(u16IAPStartAddress);
239 IAPCN = BYTE_READ_APROM;
240 for(u16Count=0;u16Count<u16IAPDataSize;u16Count++)
241 {
242 IAPFD = 0x00;
243 set_IAPTRG_IAPGO;
244 if (IAPFD != IAPDataBuf[u16Count])
245 while(1);
246 IAPAL++;
247 if(IAPAL == 0)
248 {
249 IAPAH++;
250 }
251 }
252 clr_CHPCON_IAPEN;
253 }
254
255
256 /**
257 * @brief Modify CONFIG
258 * @param u8CF0,u8CF1,u8CF2,u8CF3,u8CF4,
259 * @return none
260 * @details 1. Check the CONFIG setting and now CONFIG value, if this value is
matched do not change, close Modify.
261 2. if value not match save old config define in XRAM, erase config
and program as param define, if fail load saved config and program to
recover.
262 3. All interrupt is disabled in modify CONFIG process.
263 * @example Modify_CONFIG(0xEF,0xFB,0xEF,0xFF,0xFF);
264 */
265 void Modify_CONFIG(unsigned char u8CF0,unsigned char u8CF1,unsigned char u8CF2,
unsigned char u8CF3,unsigned char u8CF4)
266 {
267 unsigned char u8Count;
268
269 if(PCON&SET_BIT4) /* Check with power on flag. Only the first power on
check with CONFIG */
270 {
271 BIT_TMP = EA;
272 EA = 0;
273
274 set_CHPCON_IAPEN; // Enable IAP function
275 IAPCN = BYTE_READ_CONFIG;
276 IAPAH = 0x00;
277 /* Check CONFIG setting data */
278 IAPAL = 0;
279 set_IAPTRG_IAPGO;
280 if (IAPFD != u8CF0)
281 goto COPRST;
282 IAPAL++;
283 set_IAPTRG_IAPGO;
284 if (IAPFD != u8CF1)
285 goto COPRST;
286 IAPAL++;
287 set_IAPTRG_IAPGO;
288 if (IAPFD != u8CF2)
289 goto COPRST;
290 IAPAL++;
291 set_IAPTRG_IAPGO;
292 if (IAPFD != u8CF3)
293 goto COPRST;
294 IAPAL++;
295 set_IAPTRG_IAPGO;
296 if (IAPFD != u8CF4)
297 goto COPRST;
298 goto CFCLOSE;
299 /* Loop save original CONFIG data in XRAM */
300
301 COPRST:
302 ConfigModifyFlag = 1; // CONFIG modify flag set.
303 for(u8Count=0;u8Count<5;u8Count++)
304 {
305 IAPAL = u8Count;
306 set_IAPTRG_IAPGO;
307 IAPCFBuf[u8Count] = IAPFD;
308 }
309 /* Erase CONFIG setting */
310 set_IAPUEN_CFUEN; // CONFIG modify Enable
311 IAPFD = 0xFF; // IMPORTANT !! To erase function must
setting IAPFD = 0xFF
312 IAPCN = PAGE_ERASE_CONFIG;
313 IAPAL = 0x00;
314 set_IAPTRG_IAPGO_WDCLR;
315 /* Modify CONFIG setting as customer define */
316 IAPCN = BYTE_PROGRAM_CONFIG;
317 IAPFD = u8CF0;
318 set_IAPTRG_IAPGO_WDCLR;
319 IAPAL++;
320 IAPFD = u8CF1;
321 set_IAPTRG_IAPGO_WDCLR;
322 IAPAL++;
323 IAPFD = u8CF2;
324 set_IAPTRG_IAPGO_WDCLR;
325 IAPAL++;
326 IAPFD = u8CF3;
327 set_IAPTRG_IAPGO_WDCLR;
328 IAPAL++;
329 IAPFD = u8CF4;
330 set_IAPTRG_IAPGO_WDCLR;
331 clr_IAPUEN_CFUEN;
332 /* Check programed data, if not match, program the storaged before data. */
333 IAPCN = BYTE_READ_CONFIG;
334 IAPAL = 0x00;
335 set_IAPTRG_IAPGO;
336 if (IAPFD != u8CF0)
337 goto MDCFEND;
338 IAPAL++;
339 set_IAPTRG_IAPGO;
340 if (IAPFD != u8CF1)
341 goto MDCFEND;
342 IAPAL++;
343 set_IAPTRG_IAPGO;
344 if (IAPFD != u8CF2)
345 goto MDCFEND;
346 IAPAL++;
347 set_IAPTRG_IAPGO;
348 if (IAPFD != u8CF3)
349 goto MDCFEND;
350 IAPAL++;
351 set_IAPTRG_IAPGO;
352 if (IAPFD != u8CF4)
353 goto MDCFEND;
354 goto CFCLOSE;
355 MDCFEND:
356 for(u8Count=0;u8Count<5;u8Count++) // Loop save CONFIG data in XRAM
357 {
358 IAPAL = u8Count;
359 IAPFD = IAPCFBuf[u8Count];
360 set_IAPTRG_IAPGO_WDCLR;
361 }
362 CFCLOSE:
363 clr_IAPUEN_CFUEN; // Disable APROM modify
364 clr_CHPCON_IAPEN; // Disable IAP
365
366 EA = BIT_TMP;
367 PCON&=CLR_BIT4; // Clear power on flag to avoid software
reset modify CONFIG again. */
368
369 }
370 }
371
372 /**
373 * @brief Read CONFIG
374 * @param None,
375 * @return none
376 * @details 1. Check the CONFIG setting and now CONFIG value, if this value is
matched do not change, close Modify.
377 2. if value not match save old config define in XRAM, erase config
and program as param define, if fail load saved config and program to
recover.
378 3. All interrupt is disabled in modify CONFIG process.
379 * @example Read_CONFIG();
380 */
381 void Read_CONFIG(void)
382 {
383 unsigned char u8Count;
384
385 set_CHPCON_IAPEN; // Enable IAP function
386 IAPCN = BYTE_READ_CONFIG;
387 IAPAH = 0x00;
388 /* Loop save original CONFIG data in XRAM */
389 for(u8Count=0;u8Count<5;u8Count++)
390 {
391 IAPAL = u8Count;
392 set_IAPTRG_IAPGO_WDCLR;
393 IAPCFBuf[u8Count] = IAPFD;
394 }
395 clr_CHPCON_IAPEN; // Disable IAP
396 }
397
398
399 /**
400 * @brief Read UID loop
401 * @param none
402 * @return none
403 * @details IAP command read UID area storage data in XRAM LIB_UIDBuffer[0:8]
404 * @example UID_Read();
405 */
406 void Read_UID(void)
407 {
408 unsigned char u8Count;
409
410 set_CHPCON_IAPEN;
411 IAPAL = 0x00;
412 IAPAH = 0x00;
413 IAPCN = READ_UID;
414 for(u8Count=0;u8Count<12;u8Count++)
415 {
416 IAPFD = 0x00;
417 set_IAPTRG_IAPGO;
418 UIDBuffer[u8Count] = IAPFD ;
419 IAPAL++;
420 }
421 clr_CHPCON_IAPEN;
422 }
423
424 /**
425 * @brief Read UCID loop
426 * @param none
427 * @return none
428 * @details IAP command read UCID area storage data in XRAM UCIDBuffer[0:8]
429 * @example UCID_Read();
430 */
431 void Read_UCID(void)
432 {
433 unsigned char u8Count;
434
435 set_CHPCON_IAPEN;
436 IAPAL = 0x20;
437 IAPAH = 0x00;
438 IAPCN = READ_UID;
439 for(u8Count=0;u8Count<12;u8Count++)
440 {
441 IAPFD = 0x00;
442 set_IAPTRG_IAPGO;
443 UCIDBuffer[u8Count] = IAPFD ;
444 IAPAL++;
445 }
446 clr_CHPCON_IAPEN;
447 }
448
449
450 /**
451 * @brief Read DID loop
452 * @param none
453 * @return none
454 * @details IAP command read DID area storage data in XRAM LIB_UIDBuffer[0:1]
455 * @example DID_Read();
456 */
457 void Read_DID(void)
458 {
459 unsigned char u8Count;
460
461 set_CHPCON_IAPEN;
462 IAPAL = 0x00;
463 IAPAH = 0x00;
464 IAPCN = READ_DID;
465 for(u8Count=0;u8Count<2;u8Count++)
466 {
467 IAPFD = 0x00;
468 set_IAPTRG_IAPGO;
469 DIDBuffer[u8Count] = IAPFD ;
470 IAPAL++;
471 }
472 clr_CHPCON_IAPEN;
473 }
474
475 /**
476 * @brief Read PID loop
477 * @param none
478 * @return none
479 * @details IAP command read PID area storage data in XRAM LIB_PIDBuffer[0:1]
480 * @example PID_Read();
481 */
482 void Read_PID(void)
483 {
484 unsigned char u8Count;
485
486 set_CHPCON_IAPEN;
487 IAPAL = 0x02;
488 IAPAH = 0x00;
489 IAPCN = READ_DID;
490 for(u8Count=0;u8Count<2;u8Count++)
491 {
492 IAPFD = 0x00;
493 set_IAPTRG_IAPGO;
494 PIDBuffer[u8Count] = IAPFD ;
495 IAPAL++;
496 }
497 clr_CHPCON_IAPEN;
498 }