1 /*
2  * v3_0p_hw_nguif.c
3  *
4  * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
5  *
6  *
7  *  Redistribution and use in source and binary forms, with or without
8  *  modification, are permitted provided that the following conditions
9  *  are met:
10  *
11  *    Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  *
14  *    Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the
17  *    distribution.
18  *
19  *    Neither the name of Texas Instruments Incorporated nor the names of
20  *    its contributors may be used to endorse or promote products derived
21  *    from this software without specific prior written permission.
22  *
23  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34  */
35 
36 //!  \ingroup MODULBIOS
37 //!  \file v3_0p_hw_uif.c
38 //!  \brief Bios included HAL (zero) and update function
39 //! \li forwarding (execute) messages to HAL
40 //! \li upload of HAL macros
41 //! \li loop management
42 
43 #include "hw_compiler_specific.h"
44 #include <stdlib.h>
45 
46 #include "bios.h"
47 #include "v3_0p.h"
48 #include "HAL_FLASH.h"
49 #include "MemorySegments.h"
50 #include "../../hil/msp_fet/archFpga.h"
51 #include "../fet/v3_0p_hw_fet.h"
52 
53 #include "USB_API/USB_Common/types.h"
54 #include "USB_API/USB_Common/usb.h"                 //USB-specific functions
55 #include "F5xx_F6xx_Core_Lib/HAL_UCS.h"
56 
57 
calculateCrc(unsigned short sum,unsigned short * adress,unsigned long segmentLength)58 unsigned short calculateCrc(unsigned short sum, unsigned short *adress, unsigned long segmentLength)
59 {
60   //Initialize CRC register
61   CRCINIRES = sum;
62 
63   //Compute CRC over the given segment
64   while (segmentLength--)
65   {
66     CRCDIRB = *adress++;
67   }
68   //Return CRC result
69   return CRCINIRES;
70 }
71 
V3OP_GetHilCrc()72 unsigned short V3OP_GetHilCrc()
73 {
74     unsigned short hilCrc = 0x0000;
75     unsigned long segmentLength = 0;
76     unsigned short *address  = 0;
77 
78     //calculate CRC for HIL info segment 1 -------------------------------------
79     segmentLength = (CHECKSUM_HIL[0] - INFO_SEGMENTS_HIL[0])/2;
80     address = (unsigned short*)INFO_SEGMENTS_HIL[0];
81     hilCrc = calculateCrc(hilCrc, address, segmentLength);
82 
83     //calculate CRC for HIL info segment 2
84     segmentLength = (INFO_SEGMENTS_HIL[1] - CHECKSUM_HIL[1])/2;
85     address = (unsigned short*)(CHECKSUM_HIL[1] + 1);
86     hilCrc = calculateCrc(hilCrc, address, segmentLength);
87 
88     //calculate CRC for HIL main segment
89     segmentLength = (HIL_SEGMENTS[1] - HIL_SEGMENTS[0]+1)/2;
90     address = (unsigned short*)HIL_SEGMENTS[0];
91     hilCrc = calculateCrc(hilCrc, address, segmentLength);
92 
93 #ifdef MSP_FET
94     //calculate CRC for Hil main segment  2
95     segmentLength = (HIL_SEGMENTS[3] - HIL_SEGMENTS[2] + 1)/2;
96     address = (unsigned short*)HIL_SEGMENTS[2];
97     hilCrc = calculateCrc(hilCrc, address, segmentLength);
98 #endif
99     //--------------------------------------------------------------------------
100 
101     return hilCrc;
102 }
103 
V3OP_GetHalFpgaCrc()104 unsigned short V3OP_GetHalFpgaCrc()
105 {
106     unsigned short halCrc = 0x0000;
107 #ifdef MSP_FET
108     unsigned long segmentLength = 0;
109     unsigned short *address  = 0;
110 
111      //calculate CRC for Hal info segment 1 --------------------------------------
112     segmentLength = (CHECKSUM_HAL[0] - INFO_SEGMENTS_HAL[0])/2;
113     address = (unsigned short*)INFO_SEGMENTS_HAL[0];
114     halCrc = calculateCrc(halCrc, address, segmentLength);
115     //calculate CRC for Hal info segment 2
116     segmentLength = (INFO_SEGMENTS_HAL[1] - CHECKSUM_HAL[1])/2;
117     address = (unsigned short*)(CHECKSUM_HAL[1] + 1);
118     halCrc = calculateCrc(halCrc, address, segmentLength);
119 
120      //calculate CRC for Hal main segment  1
121     segmentLength = (HAL_FPGA_SEGMENTS[1] - HAL_FPGA_SEGMENTS[0] + 1)/2;
122     address = (unsigned short*)HAL_FPGA_SEGMENTS[0];
123     halCrc = calculateCrc(halCrc, address, segmentLength);
124     //--------------------------------------------------------------------------
125 #endif
126     return halCrc;
127 }
128 
V3OP_GetHalCrc()129 unsigned short V3OP_GetHalCrc()
130 {
131     unsigned short halCrc = 0x0000;
132     unsigned long segmentLength = 0;
133     unsigned short *address  = 0;
134 
135      //calculate CRC for Hal info segment 1 --------------------------------------
136     segmentLength = (CHECKSUM_HAL[0] - INFO_SEGMENTS_HAL[0])/2;
137     address = (unsigned short*)INFO_SEGMENTS_HAL[0];
138     halCrc = calculateCrc(halCrc, address, segmentLength);
139     //calculate CRC for Hal info segment 2
140     segmentLength = (INFO_SEGMENTS_HAL[1] - CHECKSUM_HAL[1])/2;
141     address = (unsigned short*)(CHECKSUM_HAL[1] + 1);
142     halCrc = calculateCrc(halCrc, address, segmentLength);
143 
144      //calculate CRC for Hal main segment  1
145     segmentLength = (HAL_SEGMENTS[1] - HAL_SEGMENTS[0] + 1)/2;
146     address = (unsigned short*)HAL_SEGMENTS[0];
147     halCrc = calculateCrc(halCrc, address, segmentLength);
148 #ifdef eZ_FET
149     //calculate CRC for Hal main segment  2
150     segmentLength = (HAL_SEGMENTS[3] - HAL_SEGMENTS[2] + 1)/2;
151     address = (unsigned short*)HAL_SEGMENTS[2];
152     halCrc = calculateCrc(halCrc, address, segmentLength);
153 #endif
154     //--------------------------------------------------------------------------
155 
156     return halCrc;
157 }
158 
V3OP_GetCoreCrc()159 unsigned short V3OP_GetCoreCrc()
160 {
161     unsigned short coreCrc = 0x0000;
162     unsigned long segmentLength = 0;
163     unsigned short *address  = 0;
164 
165     //calculate CRC for core info segment 1 ------------------------------------
166     segmentLength = (CHECKSUM_CORE[0] - CORE_SEGMENTS[0])/2;
167     address = (unsigned short*)CORE_SEGMENTS[0];
168     coreCrc = calculateCrc(coreCrc, address, segmentLength);
169 
170     //calculate CRC for core main segment
171     segmentLength = (CORE_SEGMENTS[1] - CHECKSUM_CORE[1] + 1)/2;
172     address = (unsigned short*) (CHECKSUM_CORE[1] + 1);
173     coreCrc = calculateCrc(coreCrc, address, segmentLength);
174 
175     //calculate CRC for reset vector segment
176     segmentLength = (CORE_SEGMENTS_RESET[1] - CORE_SEGMENTS_RESET[0] + 1)/2;
177     address = (unsigned short*)CORE_SEGMENTS_RESET[0];
178     coreCrc = calculateCrc(coreCrc, address, segmentLength);
179     //--------------------------------------------------------------------------
180 
181     return coreCrc;
182 }
183 
V3OP_GetDcdcCrc()184 unsigned short V3OP_GetDcdcCrc()
185 {
186     unsigned short dcdcCrc = 0x0000;
187     unsigned long segmentLength = 0;
188     unsigned short *address  = 0;
189 
190     //calculate CRC for dcdc info segment 1 -------------------------------------
191     segmentLength = (CHECKSUM_DCDC[0] - INFO_SEGMENTS_DCDC[0])/2;
192     address = (unsigned short*)INFO_SEGMENTS_DCDC[0];
193     dcdcCrc = calculateCrc(dcdcCrc, address, segmentLength);
194 
195     //calculate CRC for dcdc info segment 1
196     segmentLength = (INFO_SEGMENTS_DCDC[1] - CHECKSUM_DCDC[1])/2;
197     address = (unsigned short*)(CHECKSUM_DCDC[1] + 1);
198     dcdcCrc = calculateCrc(dcdcCrc, address, segmentLength);
199 
200     //calculate CRC for dcdc main segment
201     segmentLength = (DCDC_SEGMENTS[1] - DCDC_SEGMENTS[0] + 1)/2;
202     address = (unsigned short*)DCDC_SEGMENTS[0];
203     dcdcCrc = calculateCrc(dcdcCrc, address, segmentLength);
204     //--------------------------------------------------------------------------
205 
206     return dcdcCrc;
207 }
208 
V3OP_GetComChannelCrc()209 unsigned short V3OP_GetComChannelCrc()
210 {
211     unsigned short comChannelCrc = 0x0000;
212     unsigned long segmentLength = 0;
213     unsigned short *address  = 0;
214 
215     //calculate CRC for comchannel info segment 1 -------------------------------------
216     segmentLength = (CHECKSUM_COMCHANNEL[0] - INFO_SEGMENTS_COMCHANNEL[0])/2;
217     address = (unsigned short*)INFO_SEGMENTS_COMCHANNEL[0];
218     comChannelCrc = calculateCrc(comChannelCrc, address, segmentLength);
219 
220     //calculate CRC for comchannel info segment 1
221     segmentLength = (INFO_SEGMENTS_COMCHANNEL[1] - CHECKSUM_COMCHANNEL[1])/2;
222     address = (unsigned short*)(CHECKSUM_COMCHANNEL[1] + 1);
223     comChannelCrc = calculateCrc(comChannelCrc, address, segmentLength);
224 
225     //calculate CRC for comchannel main segment
226     segmentLength = (COMCHANNEL_SEGMENTS[1] - COMCHANNEL_SEGMENTS[0] + 1)/2;
227     address = (unsigned short*)COMCHANNEL_SEGMENTS[0];
228     comChannelCrc = calculateCrc(comChannelCrc, address, segmentLength);
229     //--------------------------------------------------------------------------
230 
231   return comChannelCrc;
232 }
233 
V3OP_HilCrcOk()234 unsigned char V3OP_HilCrcOk()
235 {
236   return(V3OP_GetHilCrc() == *((unsigned short*)CHECKSUM_HIL[0]));
237 }
238 
V3OP_HalCrcOk()239 unsigned char V3OP_HalCrcOk()
240 {
241   return(V3OP_GetHalCrc() == *((unsigned short*)CHECKSUM_HAL[0]));
242 }
243 
V3OP_HalFpgaCrcOk()244 unsigned char V3OP_HalFpgaCrcOk()
245 {
246   return(V3OP_GetHalFpgaCrc() == *((unsigned short*)CHECKSUM_HAL[0]));
247 }
248 
V3OP_coreCrcOk()249 unsigned char V3OP_coreCrcOk()
250 {
251   return(V3OP_GetCoreCrc() == *((unsigned short*)CHECKSUM_CORE[0]));
252 }
253 
V3OP_DcdcCrcOk()254 unsigned char V3OP_DcdcCrcOk()
255 {
256   return(V3OP_GetDcdcCrc() == *((unsigned short*)CHECKSUM_DCDC[0]));
257 }
258 
V3OP_ComChannelCrcOk()259 unsigned char V3OP_ComChannelCrcOk()
260 {
261   return(V3OP_GetComChannelCrc() == *((unsigned short*)CHECKSUM_COMCHANNEL[0]));
262 }
263 //! \brief test address on memory type
264 //! \param[in] addr address to test
265 //! \return 0 -> flash memory
266 //! \return 1 -> info memory
267 //! \return 2 -> RAM
268 #pragma optimize = low
V3OP_GetSegmentType(unsigned long addr)269 unsigned long V3OP_GetSegmentType(unsigned long addr)
270 {
271     unsigned short i = 0;
272     for(i = 0; i < (sizeof(INFO_SEGMENTS_HIL)/sizeof(unsigned long)); i+=2)
273     {
274         if((addr >= INFO_SEGMENTS_HIL[i]) && (addr <= INFO_SEGMENTS_HIL[i+1]))
275         {
276             return (INFO_SEGMENT_HIL);
277         }
278     }
279     for(i = 0; i < (sizeof(INFO_SEGMENTS_HAL)/sizeof(unsigned long)); i+=2)
280     {
281         if((addr >= INFO_SEGMENTS_HAL[i]) && (addr <= INFO_SEGMENTS_HAL[i+1]))
282         {
283             return (INFO_SEGMENT_HAL);
284         }
285     }
286     for(i = 0; i < (sizeof(HAL_SEGMENTS)/sizeof(unsigned long)); i+=2)
287     {
288         if((addr >= HAL_SEGMENTS[i]) && (addr <= HAL_SEGMENTS[i+1]))
289         {
290             return (HAL_SEGMENT);
291         }
292     }
293     #ifdef MSP_FET
294     for(i = 0; i < (sizeof(HAL_FPGA_SEGMENTS)/sizeof(unsigned long)); i+=2)
295     {
296         if((addr >= HAL_FPGA_SEGMENTS[i]) && (addr <= HAL_FPGA_SEGMENTS[i+1]))
297         {
298             return (HAL_SEGMENT_FPGA);
299         }
300     }
301     #endif
302     for(i = 0; i < (sizeof(HIL_SEGMENTS)/sizeof(unsigned long)); i+=2)
303     {
304         if((addr >= HIL_SEGMENTS[i]) && (addr <= HIL_SEGMENTS[i+1]))
305         {
306             return (HIL_SEGMENT);
307         }
308     }
309     // dcdc segments
310     for(i = 0; i < (sizeof(DCDC_SEGMENTS)/sizeof(unsigned long)); i+=2)
311     {
312         if((addr >= DCDC_SEGMENTS[i]) && (addr <= DCDC_SEGMENTS[i+1]))
313         {
314             return (DCDC_SEGMENT);
315         }
316     }
317     for(i = 0; i < (sizeof(INFO_SEGMENTS_DCDC)/sizeof(unsigned long)); i+=2)
318     {
319         if((addr >= INFO_SEGMENTS_DCDC[i]) && (addr <= INFO_SEGMENTS_DCDC[i+1]))
320         {
321             return (INFO_SEGMENT_DCDC);
322         }
323     }
324     // comchannel segments
325     for(i = 0; i < (sizeof(COMCHANNEL_SEGMENTS)/sizeof(unsigned long)); i+=2)
326     {
327         if((addr >= COMCHANNEL_SEGMENTS[i]) && (addr <= COMCHANNEL_SEGMENTS[i+1]))
328         {
329             return (COMCHANNEL_SEGMENT);
330         }
331     }
332     // INFO comchannel segments
333     for(i = 0; i < (sizeof(INFO_SEGMENTS_COMCHANNEL)/sizeof(unsigned long)); i+=2)
334     {
335         if((addr >= INFO_SEGMENTS_COMCHANNEL[i]) && (addr <= INFO_SEGMENTS_COMCHANNEL[i+1]))
336         {
337             return (INFO_SEGMENT_COMCHANNEL);
338         }
339     }
340     return 0;
341 }
342 
343 //! \brief test address on write access
344 //! \param[in] addr address to test
345 //! \return 0 -> no write access
346 //! \return 1 -> write allow
V3OP_WriteAllowed(unsigned short addr)347 unsigned char V3OP_WriteAllowed(unsigned short addr)
348 {
349     return(0);
350 }
351 //! \brief test address on erase access
352 //! \param[in] addr address to test
353 //! \return 0 -> no erase access
354 //! \return 1 -> erase allow
V3OP_EraseAllowed(unsigned short StartAddr)355 unsigned char V3OP_EraseAllowed(unsigned short StartAddr)
356 {
357     return(0);
358 }
359 
360 //! \brief erase on UIF (HAL) all blocks which included in start address + size
361 //! \param[in] *payload pointer to receive buffer
362 //! \return 1 -> flash erase done
363 //! \return <0 -> error
364 #pragma optimize = low
V3OP_CoreFlashFunctionErase(unsigned char * payload)365 short V3OP_CoreFlashFunctionErase(unsigned char *payload)
366 {
367     unsigned long address_pointer;
368     unsigned long  start_addr = (*(unsigned long*)&payload[4] & 0xFFFFF);
369     unsigned long  end_addr   = start_addr + (*(unsigned long*)&payload[8] & 0xFFFFF)-2;
370     unsigned char  segment_type;
371     unsigned long segmentSize =0;
372 
373     segment_type = V3OP_GetSegmentType(start_addr);
374 
375     if(segment_type == NO_SEGMENT)
376     {
377         return -1;
378     }
379 
380     // erase INFO mem
381     if(segment_type == HAL_SEGMENT || segment_type == INFO_SEGMENT_HAL)
382     {
383         segmentSize = SEGMENT_SIZE_HAL_HIL;
384         // First erase entry point into Hil Layer
385         // IF firmware update is interrupted HIL could not be started
386         Flash_SegmentErase((unsigned short*)INFO_SEGMENTS_HAL[1]);
387     }
388 
389     if(segment_type == HIL_SEGMENT || segment_type == INFO_SEGMENT_HIL)
390     {
391         segmentSize = SEGMENT_SIZE_HAL_HIL;
392         // First erase entry point into HAL Layer
393         // IF firmware update is interrupted HAL could not be started
394         Flash_SegmentErase((unsigned short*)INFO_SEGMENTS_HIL[0]);
395     }
396 
397     if(segment_type == INFO_SEGMENT_DCDC || segment_type == DCDC_SEGMENT)
398     {
399         segmentSize = SEGMENT_SIZE_HAL_HIL;
400         // First erase entry point into HAL Layer
401         // IF firmware update is interrupted HAL could not be started
402         Flash_SegmentErase((unsigned short*)INFO_SEGMENTS_DCDC[0]);
403     }
404 
405     if(segment_type == COMCHANNEL_SEGMENT || segment_type == INFO_SEGMENT_COMCHANNEL)
406     {
407         segmentSize = SEGMENT_SIZE_HAL_HIL;
408         // First erase entry point into HAL Layer
409         // IF firmware update is interrupted HAL could not be started
410         UnlockInfoA();
411         Flash_SegmentErase((unsigned short*)INFO_SEGMENTS_COMCHANNEL[0]);
412     }
413 
414     // Erase HIL/HAL/DCDC/COM
415     for(address_pointer = start_addr; address_pointer < end_addr; address_pointer += segmentSize)
416     {
417         if(V3OP_GetSegmentType(address_pointer) != NO_SEGMENT)
418         {
419             Flash_SegmentErase((unsigned short*)address_pointer);
420         }
421     }
422 
423     // Do erase check of HIL/HAL/DCDC
424     for(address_pointer = start_addr; address_pointer < end_addr; address_pointer += segmentSize)
425     {
426         if(V3OP_GetSegmentType(address_pointer) != NO_SEGMENT)
427         {
428             Flash_EraseCheck((unsigned char*)address_pointer, (segmentSize+1)); // (unsigned long *Flash_ptr, unsigned long len)
429         }
430     }
431     LockInfoA();
432     return(1);
433 }
434 //! \brief write payload to UIF (HAL) flash memory, RAM is allowed, too
435 //! \param[in] *payload pointer to receive buffer
436 //! \details on first function call the:
437 //! \li bytes 4 -7: the flash address
438 //! \li bytes 8 -11: data length
439 //! \li bytes 12 ... payload
440 //! \details if data length is larger then message size the function returns after writing the message. Direct follow calls
441 //! of this function continue writing.
442 //! \return 1 -> flash write done
443 //! \return <0 -> error
444 #pragma optimize = low
V3OP_CoreFlashFunctionWrite(unsigned char * payload,unsigned short v30p_stream_flags_)445 short V3OP_CoreFlashFunctionWrite(unsigned char *payload, unsigned short v30p_stream_flags_)
446 {
447     static unsigned long address_pointer;
448     static unsigned long  start_addr = 0; //(*(unsigned long*)&payload[4] & 0xFFFFF);
449     static unsigned long  end_addr   = 0; //start_addr + (*(unsigned long*)&payload[8] & 0xFFFFF);
450     unsigned char  segment_type;
451     unsigned short *data_ptr = NULL;
452     unsigned short *data_ptr_end = NULL;
453     static unsigned long segmentSize =0;
454 
455 
456     if(v30p_stream_flags_ & MESSAGE_NEW_MSG)
457     {
458         start_addr = (*(unsigned long*)&payload[4] & 0xFFFFF);
459         end_addr   = start_addr + (*(unsigned long*)&payload[8] & 0xFFFFF);
460         data_ptr = (unsigned short*)&payload[12];
461         data_ptr_end = data_ptr + (payload[0] - 11) / sizeof(unsigned short); // write words /2
462         segment_type = V3OP_GetSegmentType(start_addr);
463 
464         if(segment_type == NO_SEGMENT)
465         {
466             return -1;
467         }
468         // 2 bytes are written in one line
469         segmentSize = 2;
470         address_pointer = start_addr;
471         UnlockInfoA();
472     }
473     else
474     {
475         data_ptr = (unsigned short*)&payload[4];
476         data_ptr_end = data_ptr + (payload[0] - 3) / sizeof(unsigned short);
477         LockInfoA();
478     }
479     for(;(address_pointer < end_addr) && (data_ptr < (data_ptr_end)); address_pointer += segmentSize)
480     {
481         // check if wirte is going into info or HAL/Hil segment
482         // don't programm any core segment
483         if(V3OP_GetSegmentType(address_pointer) != NO_SEGMENT)
484         {
485             FlashWrite_16(data_ptr, (unsigned short*)address_pointer, 1);
486             data_ptr++;
487         }
488     }
489     return 0;
490 }
491 
492 //! \brief reads UIF memory, inclusive BIOS area
493 //! \param[in] *payload pointer to receive buffer
494 //! \li bytes 4 -7: the flash address
495 //! \li bytes 8 -11: data length
496 //! \return 0
V3OP_CoreFlashFunctionRead(unsigned char * payload)497 short V3OP_CoreFlashFunctionRead(unsigned char *payload)
498 {
499     return(0);
500 }
501 
V3OP_UpCore(void)502 void V3OP_UpCore(void)
503 {
504     _DINT_FET(); // Ensure no application interrupts fire during stop
505     USB_disconnect();
506     FPGA_RESET_ASSERT
507     //~1.6 s delay
508     __delay_cycles(40000000);
509 
510     USB_disable();
511     XT2_Stop();
512     //erase infoB
513     Flash_SegmentErase((unsigned short*)0x197F);
514     //erase infoC
515     Flash_SegmentErase((unsigned short*)0x18FF);
516     //erase infoD
517     Flash_SegmentErase((unsigned short*)0x187F);
518     // erase flash reset vector to invoke usb bsl by next startup
519     Flash_SegmentErase((unsigned short*)0xFFFE);
520 
521     //~1.6 s delay
522     __delay_cycles(40000000);
523     PMMCTL0 = PMMPW | PMMSWBOR; // generate BOR for reseting device
524 }
525 
V3OP_SystemOk(void)526 unsigned short V3OP_SystemOk(void)
527 {
528     if(!V3OP_coreCrcOk())
529     {
530         Flash_SegmentErase((unsigned short*)0xFFFE);
531         return 0;
532     }
533     return 1;
534 }
535