source: svn/newcon3bcm2_21bu/dst/app/src/Function/App_Fnc_RfUpdate.c

Last change on this file was 76, checked in by megakiss, 10 years ago

1W 대기전력을 만족시키기 위하여 POWEROFF시 튜너를 Standby 상태로 함

  • Property svn:executable set to *
File size: 32.5 KB
Line 
1/****************************************************************************
2* NAME: App_Fnc_RfUpdate.c
3*----------------------------------------------------------------------------
4* Copyright (c) DIGITAL STREAM Technology Inc.
5*----------------------------------------------------------------------------
6* CREATED_BY: Do Gon Lee
7* CREATION_DATE: 2009/08/28
8* $Author: foxhunt $
9* $Revision: 1.0 $
10* $Date: 2009/08/28 10:47:19 $
11*----------------------------------------------------------------------------
12* Function Module:
13* - Update HRM Firmware using RF transmission.
14* PURPOSE:
15* - RF Update API
16* Dependency:
17* -     DMW RF Update library
18*****************************************************************************/
19
20/*_____ I N C L U D E __________________________________________*/
21
22#include "App_Main.h"
23#include "DMW_ChannelAPI.h"
24
25#if SUPPORT_RFUPDATE
26
27#include "App_Fnc_RfUpdate.h"
28
29#include "DMW_RfDownload.h"
30
31#include "DHL_DEV.h"
32
33
34
35
36
37/*_____ D E F I N I T I O N ____________________________________*/
38
39#if COMMENT
40____DbgPrint____(){}
41#endif
42
43DHL_MODULE("@f_rfu", 0);
44
45
46
47
48
49#if COMMENT
50____Config____(){}
51#endif
52
53#define RFUPDATE_PID 0x1FEF     /* 8175 */
54#define RFUPDATE_TID 0xFD               /* 253 */
55#define RFUPDATE_AID 0                  /* application id */
56
57#define RFUPDATE_STRESS_TEST 0  /* 081208 add : to perform rfupdate stress test, enable this. */
58
59#define APP_ID_TAG_SIZE 64      /* stage4_update.c ¿Í À̸§ÀÌ °ãÃļ­ º¯°æ. */
60
61#define STATIC_KEY 0xAA
62#define INIT_DKEY(k) ((k)=0x11)
63#define ROLL_DKEY(k) (k)=((k)*((k+1)) % 0xfd)
64
65
66
67
68
69#if COMMENT
70____Types____(){}
71#endif
72
73
74
75
76
77#if COMMENT
78____Variables____(){}
79#endif
80
81DHL_FLASHID g_sflashId = 0;     /* flash id */
82
83
84int g_RfUpdate_SkipBootUpdate = 0;
85        /*
86                 cafrii 071116, change 1->0
87                  rf update¸¦ ÅëÇØ¼­µµ boot code°¡ updateµÇ¾î¾ß ÇÔ.
88                  À̸¦ À§Çؼ­´Â flash boot ¿µ¿ªµµ update°¡ µÉ ¼ö ÀÖµµ·Ï flash driver ¼öÁ¤ ÇÊ¿äÇÔ.
89        */
90
91int g_RfUpdate_ForceBootUpdate;
92        /* cafrii 081208 add
93                 stress test¸¦ À§Çؼ­ °­Á¦ update ¸ðµå Ãß°¡. */
94
95
96int g_RfUpdate_TotalUpdateSize;
97        /*
98                 write progressive percentage °è»êÀ» À§Çؼ­´Â
99                 ÇöÀç ÁøÇà ÁÖ¼Ò¿Í Àüü Å©±â Á¤º¸°¡ ÇÊ¿äÇѵ¥,
100                 callback¿¡¼­ ÀÌ °ªµéÀ» ¾Ë±â ¾î·Á¿ì´Ï Àü¿ª º¯¼ö·Î °øÀ¯.
101                 todo :  fupdate context Á¤º¸µéÀ» ¸ð¾ÆµÎ¸é ÁÁ°ÚÀ½.
102        */
103
104
105
106
107
108/*_____ F U N C T I O N ________________________________________*/
109
110#if COMMENT
111____BOOT____(){}
112#endif
113
114/******************************************************************************************
115FUNCTION:
116  - SafeUpdateBootCode
117
118Purpose:
119  -
120******************************************************************************************/
121static int SafeUpdateBootCode(UINT8 *buf)
122{
123        int err = 0;
124        int i;
125        UINT32 mask;
126        UINT32 addr = 0;
127        int boot_size;
128        DHL_FUPDATE_INFO info;
129
130        dhl_fupdate_get_info(&info);
131        boot_size = info.sz_boot_block;
132
133#if APP_PORTING
134        DHL_SYS_DisableWatchdog();
135#endif
136
137        mask = OS_DisableInterrupts();
138
139        for (i=0; i<5; i++)
140        {
141                dhl_dbg_shutdown_console();
142       
143                err = dhl_fupdate_flash(addr, buf, boot_size, 
144                                FUPDATE_DISABLE_INTR, 0, 0); 
145                                /* no callback allowed during interrupt disabled. */
146
147//BKTODO                dhl_dbg_start_console();
148                printf("console restarted.\n");
149               
150                if (err == 0) {
151                        printf("## boot updated successfully\n");
152                        goto label_exit;
153                }
154                printf("## boot update err, retry..\n");
155
156                /* interrupt disabled »óÅ¿¡¼­´Â delay µ¿ÀÛ ¾ÈÇÔ!! */
157                /* OS_Delay(OS_GetTicksPerSecond()/4); */
158        }
159        printf("## boot update failed !!\n");
160
161label_exit:
162
163        OS_RestoreInterrupts(mask);
164        DHL_SYS_EnableWatchdog();
165
166        /* todo:
167                 watchdogÀÌ Ç×»ó enable µÈ °ÍÀº ¾Æ´ÒÅ×´Ï,
168                 ÇöÀç watchdog »óŸ¦ ±â¾ïÇØ µÎ¾ú´Ù°¡ º¹¿øÀ» Çϵµ·Ï ÇÏÀÚ. */
169
170        return err;
171}
172
173
174
175
176
177#if COMMENT
178____Encrypt____(){}
179#endif
180
181/******************************************************************************************
182FUNCTION:
183  - RfUpdate_DecryptTag
184
185Purpose:
186  -
187******************************************************************************************/
188void RfUpdate_DecryptTag(UINT8 *enc, UINT8 *dec, UINT32 ikey, BOOL bDump)
189{
190        int k;
191        UINT8 dynamic_key, static_key = STATIC_KEY;
192
193        if (bDump) {
194                dprint("---- original encrypted data\n");
195                memdump3(enc, APP_ID_TAG_SIZE, 0, -(int)enc, MEMDUMP_NOHDR);
196        }
197
198        /* cafrii 070806 add new phase */
199        for (k=0; k<APP_ID_TAG_SIZE; k+=4)
200        {
201                /* order swapped XOR */
202                enc[k+0] ^= ((ikey >> 24) & 0xff);
203                enc[k+1] ^= ((ikey >>  8) & 0xff);
204                enc[k+2] ^= ((ikey >> 16) & 0xff);
205                enc[k+3] ^= ((ikey >>  0) & 0xff);
206        }
207
208        INIT_DKEY(dynamic_key);
209        for (k=0; k<APP_ID_TAG_SIZE; k++)
210        {
211                dec[k] = k==0 ? 
212                        static_key ^ enc[0] ^ dynamic_key :
213                        enc[k-1] ^ enc[k] ^ dynamic_key;
214                ROLL_DKEY(dynamic_key);
215        }
216
217        if (bDump) {
218                dprint("---- decrypted data\n");
219                memdump3(dec, APP_ID_TAG_SIZE, 0, -(int)dec, MEMDUMP_NOHDR);
220        }
221}
222
223
224/******************************************************************************************
225FUNCTION:
226  - RfUpdate_CheckIdTag
227
228Purpose:
229  -
230******************************************************************************************/
231int RfUpdate_CheckIdTag(DataChunkList *list, APP_ID_TAG_V1 *ptag)
232{
233        /* check 1: "digital stream" °Ë»ö */
234        char *keywd;
235
236        int i;
237        int nSizeToCheckKey = list->TotalPayloadSize - APP_ID_TAG_SIZE;
238        UINT32 ikey;
239       
240        APP_ID_TAG_V1 tag_enc;
241        int NumChunk = list->NumChunk;
242
243#if 0   
244        TLASSERT(sizeof(APP_ID_TAG_V1) == APP_ID_TAG_SIZE, "");
245#else
246        if(sizeof(APP_ID_TAG_V1) != APP_ID_TAG_SIZE)
247                return -1;
248#endif
249       
250        /* TAG´Â µ¥ÀÌÅÍÀÇ ¸Ç ¸¶Áö¸·¿¡ À§Ä¡ÇÑ´Ù. */
251        if (list->TotalPayloadSize < APP_ID_TAG_SIZE)
252                /* TAG sizeº¸´Ùµµ ÀÛÀº °æ¿ì¶ó¸é Á¦´ë·Î µÈ µ¥ÀÌÅͰ¡ ¾Æ´Ï´Ù. */
253                return -1;
254
255        /* ¸Ç ¸¶Áö¸· chunk¿¡¼­ TAG ºÎºÐÀ» °¡Á®¿Â´Ù.
256                 ÁÖÀÇ! ChunkÀÇ °æ°è¿¡ °ÉÃÄ ÀÖÀ» ¼öµµ ÀÖÀ¸¹Ç·Î ÁÖÀÇ.. */
257        if (list->ChunkSize[NumChunk-1] >= APP_ID_TAG_SIZE)
258        {
259                /* °æ°è °ÉÄ¡Áö ¾ÊÀ½. */
260                memcpy((UINT8 *)&tag_enc, 
261                        list->ChunkList[NumChunk-1] + list->ChunkSize[NumChunk-1] - APP_ID_TAG_SIZE,
262                        sizeof(tag_enc));
263        }
264        else 
265        {
266                /* °æ°è¿¡ °ÉÃÄ ÀÖÀ½. */
267                int len1, len2;
268                len2 = list->ChunkSize[NumChunk-1];
269                len1 = APP_ID_TAG_SIZE - len2;
270
271                dprint("  tag separated: [%d] len1 %d, [%d] len2 %d\n",
272                                                NumChunk-1, len1, NumChunk-2, len2);
273                memcpy((UINT8 *)&tag_enc,
274                        list->ChunkList[NumChunk-2] + list->ChunkSize[NumChunk-2] - len1,
275                        len1);
276                memcpy((UINT8 *)&tag_enc + len1,
277                        list->ChunkList[NumChunk-1],
278                        len2);
279        }
280
281        /* ikey °è»ê..
282                 TotalPayloadSize Å©±â¿¡¼­ tag ºÎºÐ¸¸ Á¦¿ÜÇÑ Å©±â.. */
283        ikey = 0xffffffff;
284        for (i=0; i<list->NumChunk; i++)
285        {
286                UINT8 *p = list->ChunkList[i];
287                int n = list->ChunkSize[i];
288
289                if (n > nSizeToCheckKey)
290                        n = nSizeToCheckKey;
291                       
292                ikey = DHL_DMX_CalculateExCRC(ikey, p, n);
293                nSizeToCheckKey -= n;
294
295                if (nSizeToCheckKey < 0) break;
296        }
297        dprint("  key value: 0x%08x\n", ikey);
298       
299
300        dprint("  decrypt id tag..\n");
301        RfUpdate_DecryptTag((UINT8 *)&tag_enc, (UINT8 *)ptag, ikey, FALSE);
302
303        /* check 1: "digital stream" °Ë»ö */
304        keywd = "digital stream";
305        if (strncmp((char *)ptag->svendor, keywd, strlen(keywd)))
306        {
307                ptag->svendor[sizeof(ptag->svendor)-1] = 0;
308                dprint("!! invalid vendor info <%s>\n", ptag->svendor);
309                return -1;
310        }
311
312#if 0 /* this check is caller's responsibility.. */
313        /* check 2: "phoenix" °Ë»ö */
314        keywd = "phoenix";
315        if (strincmp((char *)ptag->smodel, keywd, strlen(keywd)))
316        {
317                ptag->smodel[sizeof(ptag->smodel)-1] = 0;
318                dprint("!! invalid model info <%s>\n", ptag->smodel);
319                return -1;
320        }
321#endif
322
323        return 0;
324}
325
326
327
328
329
330#if COMMENT
331____Update____(){}
332#endif
333
334void (*g_RfUpdate_Callback)(RfUpdateReport msg, UINT32 value);
335        /*
336                 application (UI) client°¡ ÀÎÀÚ·Î Àü´ÞÇÑ callback ÁÖ¼Ò.
337                 fupdate ¼¼ºÎ µ¿ÀÛ ÁøÇàÇϸ鼭 ¸Å »óÅ Á¤º¸¸¦ report ÇØ ÁØ´Ù.
338        */
339
340/******************************************************************************************
341FUNCTION:
342  - RfUpdate_Report
343
344Purpose:
345  -
346******************************************************************************************/
347static void RfUpdate_Report(RfUpdateReport msg, UINT32 value)
348{
349        if (g_RfUpdate_Callback)
350                (*g_RfUpdate_Callback)(msg, value);
351}
352
353
354/******************************************************************************************
355FUNCTION:
356  - RfUpdate_DownloadCallback
357
358Purpose:
359  - RF download API MW ÇÔ¼ö¿¡ Àü´ÞµÇ´Â callback.
360   @value is percentage of download progress.
361******************************************************************************************/
362static void RfUpdate_DownloadCallback(RfDownloadReport msg, UINT32 value)
363{
364        RfUpdate_Report(RFUPDATE_REPORT_DOWNLOAD, value);
365}
366
367
368/******************************************************************************************
369FUNCTION:
370  - RfUpdate_FlashUpdateCallback
371
372Purpose:
373  - Fupdate DHL API ÇÔ¼ö¿¡ Àü´ÞµÇ´Â callback.
374         @offset is address of flash sector that is being updated.
375         @param is user parameter that is passed as an argument.
376******************************************************************************************/
377static void RfUpdate_FlashUpdateCallback(UINT32 offset, UINT32 param)
378{
379        int percentage;
380        percentage = g_RfUpdate_TotalUpdateSize ? 
381                        (100*offset)/g_RfUpdate_TotalUpdateSize : 0;
382       
383        RfUpdate_Report(RFUPDATE_REPORT_WRITE, percentage);
384}
385
386
387/******************************************************************************************
388FUNCTION:
389  - RfUpdate_Tune
390
391Purpose:
392  -
393******************************************************************************************/
394STATUS RfUpdate_Tune(tDHL_FreqStd std, UINT32 rf, tDHL_Demod mod, 
395                                                int nTimeOutSecond, BOOL (*checkfn)(void))
396{
397        BOOL bLocked;
398        UINT32 uTickStart;
399        INT32 uTimeOut;
400        STATUS status = statusOK;
401
402        dprint(1, "FreqStd: %d, rf %d, modulation %d\n", std, rf, mod);
403       
404        DMW_HAL_SetChannelStandard(std);
405        DMW_HAL_TunerSetChannel(rf, mod, 0, FREQTUNE_FIXED, NULL);
406
407        uTimeOut = OS_GetTicksPerSecond() * nTimeOutSecond;
408        uTickStart = OS_GetTickCount();
409
410        while (1)
411        {
412                bLocked = DMW_HAL_DetectNIMChannel();
413                if (bLocked)
414                        break;
415
416                if ((INT32)(OS_GetTickCount()-uTickStart) > uTimeOut)
417                        break;
418               
419                if (checkfn && checkfn()) {
420                        status = statusCancelled;
421                        break;
422                }
423                OS_Delay(OS_GetTicksPerSecond()/10);
424        }
425
426        if (DMW_HAL_DetectNIMChannel() == FALSE) {
427                dprint(1, "!! signal lock failed!\n");
428
429                if (status == statusCancelled)
430                        return status;
431
432                return statusNoSignal;
433        }
434
435        return statusOK;
436}
437
438
439/******************************************************************************************
440FUNCTION:
441  - RfUpdate_SampleCallback
442
443Purpose:
444  - Rf Update¸¦ Çϸ鼭 °¢ »óȲÀ» ¾Ë·ÁÁÖ´Â event callback ¿¹Á¦.
445******************************************************************************************/
446static void RfUpdate_SampleCallback(RfUpdateReport msg, UINT32 value)
447{
448        char *pre = "---- report: ";
449
450        if (msg == RFUPDATE_REPORT_TUNE)
451        {
452                printf("%s tune %d\n", pre, value);
453        }
454        else if (msg == RFUPDATE_REPORT_DOWNLOAD)
455        {
456                if (value <= 100)
457                        printf("%s download %d\n", pre, value);
458        }
459        else if (msg == RFUPDATE_REPORT_BOOTCODE)
460        {
461                printf("%s boot code update %d", pre, value);
462        }
463        else if (msg == RFUPDATE_REPORT_ERASE)
464        {
465                if (value <= 100) {
466                        printf("%s erase %d\n", pre, value);
467                }
468        }
469        else if (msg == RFUPDATE_REPORT_BLANKCHECK)
470        {
471                printf("%s blank check\n", pre);
472        }
473        else if (msg == RFUPDATE_REPORT_WRITE)
474        {
475                if (value <= 100) {
476                        printf("%s write %d\n", pre, value);
477                }
478        }
479        else if (msg == RFUPDATE_REPORT_VERIFY)
480        {
481                printf("%s verify\n", pre);
482        }
483        else
484                printf("%s msg [%d], value [%d]\n", pre, msg, value);
485}
486
487
488/******************************************************************************************
489FUNCTION:
490  - RfUpdate_CheckId
491
492Purpose:
493  - download ¹ÞÀº imageÀÇ id tag °Ë»ç¸¦ ¼öÇàÇÏ´Â ÇÔ¼ö.
494******************************************************************************************/
495RFUPDATE_RESULT RfUpdate_CheckId(DataChunkList *list)
496{
497        int r;
498        int result = RFUPDATE_OK;
499        APP_ID_TAG_V1 tag_dec;
500        char *keywd;
501
502        r = RfUpdate_CheckIdTag(list, &tag_dec);
503        if (r) {
504                dprint(1, "!! id tag err %d\n", r);
505                result = RFUPDATE_ERR_BADID;
506                goto label_exit;
507        }
508
509        keywd = "cb3";
510        if (strncmp((char *)tag_dec.smodel, keywd, strlen(keywd)))
511        {
512                tag_dec.smodel[sizeof(tag_dec.smodel)-1] = 0;
513                dprint(1, "!! invalid model info <%s>\n", tag_dec.smodel);
514
515                keywd = "generic";
516                if (strncmp((char *)tag_dec.smodel, keywd, strlen(keywd)) == 0) {
517                        /* generic keyword to convert between models. */
518                }
519                result = RFUPDATE_ERR_BADID;
520                goto label_exit;
521        }
522
523        dprint(1, "---- tag_info ----\n");
524        dprint(1, "    v: [%s]\n", tag_dec.svendor);
525        if (tag_dec.sclass[0])
526                dprint(1, "    c: [%s]\n", tag_dec.sclass);
527        if (tag_dec.smodel[0])
528                dprint(1, "    m: [%s]\n", tag_dec.smodel);
529        if (tag_dec.sdesc[0])
530                dprint(1, "    d: [%s]\n", tag_dec.sdesc);
531
532
533        if (g_RfUpdate_Callback)
534                (*g_RfUpdate_Callback)(RFUPDATE_REPORT_TAG, (int)&tag_dec);
535
536label_exit:
537        return result;
538}
539
540
541/******************************************************************************************
542FUNCTION:
543  - RfUpdate_CompareTest
544
545Purpose:
546  - Ưº°È÷ ¼öÇàÇÏ´Â ÀÏÀº ¾ø°í ±×³É Á¤º¸¸¸ Ãâ·ÂÇÑ´Ù.
547******************************************************************************************/
548void RfUpdate_CompareTest(DataChunkList *list)
549{
550        int i;
551        int offset = 0;
552
553        int n, offshow;
554        UINT32 flash_base = FLASH_BASE; /* memory mapped address of flash area. */
555
556        dprint(1, "compare img in flash and downloaded..\n");
557       
558        /* ½ÇÁ¦ flash¿¡ ±â·ÏµÈ image¿Í ºñ±³Çغ¸ÀÚ. */
559        for (i=0; i<list->NumChunk; i++)
560        {
561                n = _memcmp((void *)(flash_base + offset), list->ChunkList[i], list->ChunkSize[i]);
562                if (n >= 0) {
563                        dprint(1, " chunk[%d] !! diff at chunk offset 0x%x (gloabal offset 0x%x)\n", 
564                                        i, n, offset + n);
565
566                        /* mismatch point·ÎºÎÅÍ -16 ~ + 48 ¿µ¿ªÀ» dump ÇÑ´Ù.
567                                 È¤½Ã offset 16 ¾Æ·¡¿¡¼­ mismatch °¡ ³¯ °æ¿ì¸¦ ´ëºñÇØ¾ß ÇÔ. */
568                        offshow = max(0, n-16);
569                        memdump3((void *)(flash_base + offset + offshow), 64, "Flash", 0, 0);
570                        memdump3(list->ChunkList[i] + offshow, 64, "RF", 0, 0);
571
572                        break;
573                }
574                else
575                        dprint(1, " chunk[%d] same\n", i);
576
577                offset += list->ChunkSize[i];
578        }
579}
580
581
582/******************************************************************************************
583FUNCTION:
584  - RfUpdate_CheckBootBlock
585
586Purpose:
587  - boot block update¸¦ Àü´ãÇÏ´Â ÇÔ¼ö.
588  - boot blockÀÇ Å©±â´Â DHL API¸¦ ÅëÇØ ¾ò¾î¿Í¾ß ÇÑ´Ù. (platform dependent)
589        - boot blockÀ» update ÇÒ ¶§¿¡´Â interrupt disable ÀÌ ÇÊ¿äÇÒ ¼ö ÀÖ´Ù.
590TODO : ÀÌ »çÇ× ¿ª½Ã platform ÀÇÁ¸ÀûÀε¥, ÀÏ´Ü À̰÷¿¡¼­ ÁöÁ¤ÇÑ´Ù.
591******************************************************************************************/
592int RfUpdate_CheckBootBlock(DataChunkList *list)
593{
594        int result = 0;
595        UINT8 *buffer = NULL;
596        int boot_size;
597        int diff;
598
599        DHL_FUPDATE_INFO info;
600
601        dprint("%s:\n", __FUNCTION__);
602
603        /* data chunk Áß¿¡ ù¹øÂ° chunk´Â ²À boot code sizeº¸´Ù Ä¿¾ß ÇÏ´Â °ÍÀ¸·Î °¡Á¤.
604                 ±×·¸Áö ¾ÊÀ» °æ¿ì segmented µÈ chunkµéÀ» °í·ÁÇØ¾ß ÇÏ´Ï ±ÍÂú´Ù.
605                 ¸¸¾à section ´ÜÀ§·Î ¼ö½ÅµÈ °æ¿ì section ÃÖ´ë Å©±â°¡ 4K¶ó´Â °É °í·ÁÇϸé
606                 ÀÌ Á¶°Ç üũ´Â Áß¿äÇÏ´Ù. */ 
607        dhl_fupdate_get_info(&info);
608        boot_size = info.sz_boot_block;
609       
610        /* boot block ¿µ¿ªÀÌ ¿©·¯ chunk·Î ³ª´²Á® ÀÖ´Ù¸é Á» °ï¶õÇÔ.. */
611        if (list->ChunkSize[0] < boot_size)
612        {
613                result = RFUPDATE_ERR_GENERAL;
614                goto label_exit;
615        }
616       
617        buffer = OS_Calloc(1, boot_size);
618        if (buffer == NULL) {
619                dprint("!! out of memory for boot block\n");
620                result = RFUPDATE_ERR_MEMORY;
621                goto label_exit;
622        }
623
624        result = DHL_DEV_FlashRead(g_sflashId, 0, buffer, boot_size);
625        if (result) {
626                dprint("!! flash read err %d\n", result);
627                result = RFUPDATE_ERR_FLASH;
628                goto label_exit;
629        }
630       
631        diff = _memcmp(buffer, list->ChunkList[0], boot_size);
632        /* get different (mismatch) position. */
633
634        if (diff >= 0 && diff < boot_size)
635                dprint("## !! boot code diff at offset 0x%x, flash 0x%x != rx 0x%x\n", 
636                                        diff, buffer[diff], list->ChunkList[0][diff]);
637
638        if (g_RfUpdate_SkipBootUpdate)
639        {
640                dprint("## skip boot update mode. ignore boot code difference\n");
641                diff = -1;
642        }
643        else if (g_RfUpdate_ForceBootUpdate)
644        {
645                dprint("## force boot update mode for test\n");
646                diff = 0;
647        }
648
649        if (diff < 0)   /* GOOD!! boot code unchanged. skip boot code update. */
650        {
651                dprint("boot code not changed. skip %d bytes\n", boot_size);           
652        }
653        else    /* diff is within [0 ~ BOOTBLOCK_SIZE-1].. bad news. we have to udpate bootcode. */
654        {
655                dprint("!! boot code changed: offset 0x%x, %02x != %02x\n",
656                                diff, buffer[diff], list->ChunkList[0][diff]);
657
658                RfUpdate_Report(RFUPDATE_REPORT_BOOTCODE, 0);
659
660                dprint("start boot code update!\n");
661                result = SafeUpdateBootCode(list->ChunkList[0]);
662                if (result) {
663                        dprint("!! boot update err! flash damanged\n");
664                        result = RFUPDATE_ERR_FLASH;
665                        goto label_exit;
666                }
667
668                RfUpdate_Report(RFUPDATE_REPORT_BOOTCODE, 100);
669        }
670
671label_exit:
672        if (buffer)
673                OS_Free(&buffer);
674
675        return result;
676}
677
678
679/******************************************************************************************
680FUNCTION:
681  - RfUpdate_ProgramFlash
682
683Purpose:
684  - ½ÇÁ¦·Î flash¿¡ firmware¸¦ update ÇÏ´Â ÇÔ¼ö.
685  - flash update¸¦ ÇÑ ÈÄ¿¡ ´Ù½Ã Çѹø verify±îÁö ¼öÇàÇÑ´Ù.
686  - firmware image´Â chunked list ÇüÅ·Π@list·Î Àü´ÞµÈ´Ù.
687******************************************************************************************/
688int RfUpdate_ProgramFlash(DataChunkList *list)
689{
690        UINT32 offset;
691        int i, result = RFUPDATE_OK;
692        int bootsize;
693       
694        UINT8 *buf = NULL;      /* verify ¿ë read back buffer */
695        int nMaxChunkSize = 0;
696
697        UINT8 *chunk_ptr;
698        int chunk_sz;
699
700        DHL_FUPDATE_INFO fuinfo;
701        dhl_fupdate_get_info(&fuinfo);
702       
703        /* boot blockÀº º°µµÀÇ ÇÔ¼ö¿¡¼­ ó¸® ÇϹǷÎ, ±× ºÎºÐÀº Á¦¿ÜÇϰí updateÇÑ´Ù. */
704        offset = bootsize = fuinfo.sz_boot_block;
705       
706        dprint("%s: flash base %x, size %d\n", __FUNCTION__, offset, list->TotalPayloadSize-offset);
707
708        g_RfUpdate_TotalUpdateSize = list->TotalPayloadSize;
709
710        RfUpdate_Report(RFUPDATE_REPORT_WRITE, 0);
711
712        for (i=0; i<list->NumChunk; i++)
713        {
714                chunk_ptr = list->ChunkList[i] + (i == 0 ? bootsize : 0); 
715                chunk_sz = list->ChunkSize[i] - (i == 0 ? bootsize : 0);
716               
717                result = dhl_fupdate_flash(offset, 
718                                chunk_ptr,
719                                chunk_sz,
720                                0,      /* no special flags. */
721                                RfUpdate_FlashUpdateCallback,
722                                offset);
723                               
724                if (result) {
725                        dprint("!! flash write err\n");
726                        result = RFUPDATE_ERR_FLASH;
727                        goto label_exit;
728                }
729                offset += chunk_sz;
730        }
731
732        RfUpdate_Report(RFUPDATE_REPORT_WRITE, 100);
733
734        /* verify¸¦ À§Çؼ­ read back buffer¸¦ ÇÒ´çÇÑ´Ù. max chunk size °è»ê. */
735        for (i=0; i<list->NumChunk; i++)
736                nMaxChunkSize = max(list->ChunkSize[i], nMaxChunkSize);
737
738        buf = OS_Calloc(1, nMaxChunkSize);
739        if (buf == NULL) {
740                dprint("!! out of memory for verify buf, sz %d\n", nMaxChunkSize);
741                result = RFUPDATE_ERR_MEMORY;
742                goto label_exit;
743        }
744
745        offset = bootsize;
746        dprint("@@ verify: from 0x%x\n", offset);
747       
748        for (i=0; i<list->NumChunk; i++)
749        {
750                int diff;
751                chunk_ptr = list->ChunkList[i] + (i == 0 ? bootsize : 0); 
752                chunk_sz = list->ChunkSize[i] - (i == 0 ? bootsize : 0);
753
754                dprint("@@ verify[%d]: addr 0x%x, sz 0x%x\n", i, offset, chunk_sz);
755
756                result = DHL_DEV_FlashRead(g_sflashId, offset, buf, chunk_sz);
757
758                diff = _memcmp(buf, chunk_ptr, chunk_sz);
759
760                if (diff >= 0) {
761                        dprint("!! flash verify err, [0x%x] write %02x != read %02x\n", 
762                                        offset + diff,
763                                        chunk_ptr[diff], buf[diff]);
764                        result = RFUPDATE_ERR_VERIFY;
765                        goto label_exit;
766                }
767                offset += chunk_sz;
768        }
769
770        RfUpdate_Report(RFUPDATE_REPORT_VERIFY, 100);
771
772label_exit:
773
774        OS_Free(&buf);
775
776        return result;  /* cafrii 071116 bugfix, return err code */
777}
778
779
780
781
782
783#if COMMENT
784____APIs____(){}
785#endif
786
787/******************************************************************************************
788FUNCTION:
789  - App_RfUpdateStart
790
791Note:
792  - test : App_RfUpdateStart 0 23 1 30
793******************************************************************************************/
794RFUPDATE_RESULT App_RfUpdateStart(tDHL_FreqStd std, 
795                                                UINT32 rf, tDHL_Demod mod,
796                                                UINT32 timeoutSec, 
797                                                void (*reportfn)(RfUpdateReport msg, UINT32 value),
798                                                BOOL(*checkfn)(void))
799{
800        int i, r;
801        RFUPDATE_RESULT result = RFUPDATE_OK;
802
803        RfDownloadInfo info;
804        DataChunkList list;
805
806        tDHL_FreqStd fs_backup;
807       
808        BOOL bPrevPrintfMode;
809       
810        dprint(1, "%s:\n", __FUNCTION__);
811
812        bPrevPrintfMode = DHL_DBG_SetStdOutputMode(TRUE); // flush mode..
813
814        if (reportfn == NULL)
815                reportfn = RfUpdate_SampleCallback;
816
817        g_RfUpdate_Callback = reportfn;
818
819        memset(&info, 0, sizeof(info));
820        memset(&list, 0, sizeof(list));
821       
822        App_ChTuneStopTV();
823
824        RfUpdate_Report(RFUPDATE_REPORT_TUNE, 0);
825
826        dprint(1, "  channel tunning RF %d \n" , rf);
827
828        fs_backup = g_CableSystem;
829       
830        r = RfUpdate_Tune(std, rf, mod, 10, checkfn);
831        if (r == statusCancelled) {
832                result = RFUPDATE_ERR_CANCELLED;
833                goto label_exit;
834        }
835       
836        if (r == statusCancelled) {
837                result = RFUPDATE_ERR_CANCELLED;
838                goto label_exit;
839        }
840       
841        if (r) {
842                dprint(1, "!! tune failed\n");
843                result = RFUPDATE_ERR_TUNE;
844                goto label_exit;
845        }
846
847        RfUpdate_Report(RFUPDATE_REPORT_TUNE, 100);
848       
849        info.Pid = RFUPDATE_PID;
850        info.TableId = RFUPDATE_TID;
851
852        info.f_alloc = (MEM_ALLOC_FN) dhl_fupdate_malloc;
853        info.f_free = (MEM_FREE_FN) dhl_fupdate_free;
854       
855        dprint(1, "  user-flash pid: 0x%x, tableid: 0x%x\n", info.Pid, info.TableId);
856
857        RfUpdate_Report(RFUPDATE_REPORT_DOWNLOAD, 0);
858
859        r = RfDownload_Download(&info, timeoutSec, RfUpdate_DownloadCallback, checkfn);
860        if (r) {
861                dprint(1, "!! download err %d\n", r);
862               
863                if (r == statusCancelled)
864                        result = RFUPDATE_ERR_CANCELLED;
865                else
866                        result = RFUPDATE_ERR_DOWNLOAD;
867                goto label_exit;
868        }
869        dprint(1, "  download ok\n");
870
871        RfUpdate_Report(RFUPDATE_REPORT_DOWNLOAD, 100);
872
873        for (i=0; i<info.NumPrvts; i++)
874        {
875                dprint(1, " PRVT[%d]: ver %d, tidex 0x%04x\n", 
876                                i,
877                                info.PrvtList[i]->version_number, info.PrvtList[i]->table_id_extension);
878                memdump3(info.PrvtList[i]->private_data_byte, 32, 0, 0, MEMDUMP_NOHDR);
879        }
880
881        /* header¸¦ ºÐ¼®Çϰí verifyÇÏ¿© list Á¤º¸¸¦ »ý¼ºÇÑ´Ù. */
882        r = RfDownload_VerifyHeader(&info, &list);
883        if (r) {
884                dprint(1, "!! verify header err %d\n", r);
885                result = RFUPDATE_ERR_BADHEADER;
886                goto label_exit;
887        }
888
889        dprint(1, "  header verified. %d chunks.\n", list.NumChunk);
890
891        for (i=0; i<list.NumChunk; i++)
892                dprint(1, "   chunk %d: 0x%x sz %d\n", i, list.ChunkList[i], list.ChunkSize[i]);
893
894
895        result = RfUpdate_CheckId(&list);
896        if (result != RFUPDATE_OK)
897                goto label_exit;
898
899        RfUpdate_CompareTest(&list);
900       
901        /* ID tag µîÀÇ Á¤º¸°¡ »ç¿ëÀÚ°¡ È®ÀÎÇϰí
902                 ¹®Á¦°¡ ÀÖÀ» °æ¿ì Ãë¼Ò¸¦ Çϱâ À§ÇÑ ÃÖ¼ÒÇÑÀÇ ½Ã°£. */
903        for (i=3; i>0; i--) 
904        {       
905                dprint(1, "  now, update ready.. countdown %d\n", i);
906
907                RfUpdate_Report(RFUPDATE_REPORT_BURNREADY, i);
908               
909                OS_Delay(OS_GetTicksPerSecond());
910                if (checkfn && checkfn()) {
911                        dprint(1, "!! cancelled by user\n");
912                        result = RFUPDATE_ERR_CANCELLED;
913                        goto label_exit;
914                }       
915        }
916
917        r = RfUpdate_CheckBootBlock(&list);
918        if (r)
919        {
920                result = RFUPDATE_ERR_FLASH;
921                goto label_exit;
922        }
923
924        dprint(1, "  flash update start...\n");
925
926        r = RfUpdate_ProgramFlash(&list);
927        if (r)
928        {
929                dprint(1, "!! program flash err\n", r);
930                RfUpdate_Report(RFUPDATE_REPORT_ERROR, r);
931               
932                result = RFUPDATE_ERR_FLASH;;
933        }
934        dprint(1, " \n");
935
936label_exit:
937        RfDownload_CleanUp(&info, &list);
938
939        DHL_DBG_SetStdOutputMode(bPrevPrintfMode);
940
941        dprint(1, "Recover back to freq type %d\n", fs_backup);
942        DMW_HAL_SetChannelStandard(fs_backup);
943
944        return result;
945}
946
947
948
949
950
951#if COMMENT
952____HostCmd____(){}
953#endif
954
955#if 0
956BOOL g_Rfupdate_RequestPowerOff;
957
958tDHL_FreqStd g_Rfupdate_chtype = FREQ_AIR;
959int g_Rfupdate_rf = 18;
960
961
962void RfUpdatePrint(char *s)
963{
964        char buf[120];
965       
966        /* sprintf(buf, "RF UPDATE\n\n%s", s); */
967        /* App_DrawMessageBox(buf, 10000000); */
968       
969        dprint(0, buf);
970}
971
972
973/******************************************************************************************
974FUNCTION:
975  - _RfUpdateCallback
976
977Purpose:
978  -
979******************************************************************************************/
980void _RfUpdateCallback(RfUpdateReport msg, UINT32 value)
981{
982        char buf[100];
983
984        if (msg == RFUPDATE_REPORT_TUNE)
985        {
986                if (value == 0) { // tune start
987                        sprintf(buf, "%s RF %d\ntry to tuning..",
988                                g_Rfupdate_chtype==FREQ_AIR ? "Antenna" : "Cable", g_Rfupdate_rf);
989                        RfUpdatePrint(buf);
990                }
991                else if (value == 100) {
992                        sprintf(buf, "tune OK\r");
993                        RfUpdatePrint(buf);
994                }
995                else if (value < 100) {
996                        sprintf(buf, "try to tuning, %d%s try..\n", value,
997                                value==1 ? "st" :
998                                value==2 ? "nd" :
999                                value==3 ? "rd" : "th");
1000                }
1001        }
1002        else if (msg == RFUPDATE_REPORT_DOWNLOAD)
1003        {
1004                if (value <= 100) {
1005                        sprintf(buf, "download %d..\r", value);
1006                        RfUpdatePrint(buf);
1007                }
1008        }
1009        else if (msg == RFUPDATE_REPORT_TAG)
1010        {
1011                APP_ID_TAG_V1 *tag = (APP_ID_TAG_V1 *)value;
1012
1013                sprintf(buf, "%s\n", tag->svendor);
1014                /* if (tag->sclass[0])
1015                                sprintf(buf+strlen(buf), " c: [%s]", tag->sclass); */
1016                if (tag->smodel[0])     /* apro-1 */
1017                        sprintf(buf+strlen(buf), " %s\n", tag->smodel);
1018                if (tag->sdesc[0])      /* version */
1019                        sprintf(buf+strlen(buf), " %s\n", tag->sdesc);
1020                /* strcat(buf, "\n\n"); */
1021                RfUpdatePrint(buf);
1022                OS_Delay(OS_GetTicksPerSecond()*2);
1023        }
1024        else if (msg == RFUPDATE_REPORT_BURNREADY)
1025        {
1026                sprintf(buf, "update ready, countdown %d..\r", value);
1027                RfUpdatePrint(buf);
1028        }
1029        else if (msg == RFUPDATE_REPORT_STAGE2)
1030        {
1031                if (value == 0) {
1032                        sprintf(buf, "critical block to be updated..\r");
1033                        RfUpdatePrint(buf);
1034                        OS_Delay(OS_GetTicksPerSecond());
1035                }
1036                else if (value == 100) {
1037                        sprintf(buf, "download %d..\n", value);
1038                        RfUpdatePrint(buf);
1039                }
1040        }
1041        else if (msg == RFUPDATE_REPORT_BOOTCODE)
1042        {
1043                sprintf(buf, "boot code will be updated..\r");
1044                RfUpdatePrint(buf);
1045                OS_Delay(OS_GetTicksPerSecond());
1046        }
1047        else if (msg == RFUPDATE_REPORT_ERASE)
1048        {
1049                if (value <= 100) {
1050                        sprintf(buf, "erase %d..\r", value);
1051                        RfUpdatePrint(buf);
1052                }
1053        }
1054        else if (msg == RFUPDATE_REPORT_BLANKCHECK)
1055        {
1056                sprintf(buf, "blank check..\r");
1057                RfUpdatePrint(buf);
1058        }
1059        else if (msg == RFUPDATE_REPORT_WRITE)
1060        {
1061                if (value <= 100) {
1062                        sprintf(buf, "write %d..\r", value);
1063                        RfUpdatePrint(buf);
1064                }
1065        }
1066        else if (msg == RFUPDATE_REPORT_VERIFY)
1067        {
1068                sprintf(buf, "verify %d..\r", value);
1069                RfUpdatePrint(buf);
1070        }
1071        else if (msg == RFUPDATE_REPORT_ERROR)
1072        {
1073                sprintf(buf, "!! error: code %d !!\r", value);
1074                RfUpdatePrint(buf);
1075        }
1076        else
1077        {
1078                sprintf(buf, "!! unknown msg [%d], value [%d]\n", msg, value);
1079                RfUpdatePrint(buf);
1080        }
1081}
1082
1083
1084/******************************************************************************************
1085FUNCTION:
1086  - _RfUpdateCheckCancel
1087
1088Purpose:
1089  - cancel check ÇÔ¼ö·Î µî·ÏÇÒ ÇÔ¼ö. ÁÖ±âÀûÀ¸·Î ºÒ·Á¼­ ÇöÀç ÀÛ¾÷À» Ãë¼ÒÇÒ °ÍÀÎÁö
1090******************************************************************************************/
1091BOOL _RfUpdateCheckCancel(void)
1092{
1093#if 1
1094        return FALSE;
1095       
1096#else
1097        int err;
1098        UINT8 cmd_buf[MAX_COMMAND_SIZE];
1099
1100        /* flash update ¼Óµµ¸¦ ³ôÀ̱â À§ÇØ ÃÖ´ëÇÑ delay tickÀ» ÀÛ°Ô ÇÑ´Ù. */
1101        err = App_GetCommand(cmd_buf, 1);       /* OS_GetTicksPerSecond()/10); */
1102        if (err) {
1103                return FALSE;
1104        }
1105
1106        if (cmd_buf[0] == CMD_ENTER_LOW_POWER) {
1107                g_Rfupdate_RequestPowerOff = TRUE;
1108                dprint(1, "!! power off request inside checkfn\n");
1109                return TRUE;
1110        }
1111       
1112        return FALSE;
1113#endif  /* #if 1 */
1114}
1115
1116
1117/******************************************************************************************
1118FUNCTION:
1119  - App_RfUpdateSetting
1120
1121Purpose:
1122  -
1123******************************************************************************************/
1124void App_RfUpdateSetting(UINT8 chtype, UINT8 rf)
1125{
1126        g_Rfupdate_chtype = (tDHL_FreqStd)chtype;
1127        g_Rfupdate_rf = rf;
1128}
1129
1130
1131/******************************************************************************************
1132FUNCTION:
1133  - App_RfUpdateSetting
1134
1135Purpose:
1136  - HOST Command¿¡ ÀÇÇØ¼­ RF update¸¦ ½ÃÀÛÇÑ´Ù.
1137 Note : cafrii 070214 add
1138******************************************************************************************/
1139void App_RfUpdateByCommand(void)
1140{
1141        RFUPDATE_RESULT result;
1142        /* char buf[30]; */
1143
1144        dprint(1, "%s:\n", __FUNCTION__);
1145
1146        App_ChTuneStopTV();
1147
1148        /* App_SetImAliveState(0); */
1149
1150        g_Rfupdate_RequestPowerOff = FALSE;
1151        result = App_RfUpdateStart(g_Rfupdate_chtype, 
1152                                                g_Rfupdate_rf, Modulation_8VSB,
1153                                                20,     /* 20 second timeout for download */
1154                                                _RfUpdateCallback,
1155                                                _RfUpdateCheckCancel);
1156
1157        if (g_Rfupdate_RequestPowerOff)
1158        {
1159                dprint(1, "!! RF update canceled by power off\n");
1160                return; /* SM_EXIT_POWER; */
1161        }
1162
1163        if (result) {
1164                /* App_DrawMessageBox("RF UPDATE\n\n FAILED!!", 20000); */
1165        }
1166        else {
1167                /* App_DrawMessageBox("RF UPDATE\n\n SUCCESS", 20000); */
1168        }
1169}
1170
1171#endif  /* #if 0 */
1172
1173
1174
1175
1176
1177#if COMMENT
1178____Test____(){}
1179#endif
1180
1181#if RFUPDATE_STRESS_TEST
1182
1183/*
1184        cafrii 081208 add.
1185       
1186        This codes are for rf update stress test (specially requsted by jjk).
1187        it does not test all procedures of rf update.
1188        it only test flash update portion.
1189       
1190        FYI, it takes approx. 1 day to repeat 1000 test.
1191
1192        shell test procedure:
1193
1194        to start test 10 times,
1195                Shell> RfUpdate_StressTest 10 &
1196       
1197        to stop testing:
1198                Shell> RfUpdate_StressTest
1199       
1200        note that this is not so responsiveness.
1201*/
1202
1203int g_Rfupdate_StressTestWorking;
1204
1205
1206/******************************************************************************************
1207FUNCTION:
1208  - RfUpdate_StressTest
1209
1210Purpose:
1211  - RF update stress test function
1212******************************************************************************************/
1213void RfUpdate_StressTest(int max_count)
1214{
1215        extern int g_dhl_force_update_block;
1216
1217        UINT8 *buf = NULL;
1218        DHL_RESULT result;
1219        int image_size = 1024*1024 - 64*1024;   /* except nvram block */
1220        DataChunkList list;
1221        UINT8 *chunk_list[1];
1222        UINT32 chunk_size[1];
1223        int count = 0;
1224        int err;
1225        int old_fub1, old_fub2;
1226        UINT32 tickStart;
1227       
1228        if (max_count == 0) {
1229                /* stop current stress test..    */
1230                if (g_Rfupdate_StressTestWorking) {
1231                        g_Rfupdate_StressTestWorking = 0;
1232                        printf("stress test stop requested.\n");
1233                }
1234                else
1235                        printf("No stress test progress..\n");
1236                return;
1237        }
1238               
1239        /* configuration for stress test */
1240        old_fub1 = g_RfUpdate_ForceBootUpdate;
1241        g_RfUpdate_ForceBootUpdate = 1;
1242       
1243        old_fub2 = g_dhl_force_update_block;
1244        g_dhl_force_update_block = 1;
1245       
1246        /* read current flash image content */
1247        buf = OS_Malloc(1024*1024);
1248       
1249        if (!buf) {
1250                printf("!! out of mem for flash img dup\n");
1251                goto end;
1252        }
1253       
1254        result = DHL_DEV_FlashRead(g_sflashId, 0, buf, image_size);
1255        if (result) {
1256                printf("!! flash read err %d\n", result);
1257                result = RFUPDATE_ERR_FLASH;
1258                goto end;
1259        }
1260       
1261        chunk_list[0] = buf;
1262        chunk_size[0] = image_size;
1263       
1264        list.NumChunk = 1;
1265        list.ChunkList = chunk_list;
1266        list.ChunkSize = chunk_size;
1267        list.TotalPayloadSize = image_size;
1268
1269        g_Rfupdate_StressTestWorking = 1;
1270
1271        while (count < max_count && g_Rfupdate_StressTestWorking == 1)
1272        {
1273                tickStart = OS_GetTickCount();
1274               
1275                printf("=======================\n");
1276                printf(" rfupdate test %d / %d\n", count, max_count);
1277                printf("=======================\n");
1278       
1279                err = RfUpdate_CheckBootBlock(&list);
1280                if (err) {
1281                        printf("!! boot block update err %d\n");
1282                        goto end;
1283                }
1284               
1285                err = RfUpdate_ProgramFlash(&list);
1286                if (err) {
1287                        printf("!! program flash err %d\n");   
1288                        goto end;
1289                }
1290               
1291                printf("--> %d second elapsed\n", (OS_GetTickCount()-tickStart)/OS_GetTicksPerSecond());
1292                count++;
1293        }
1294
1295end:
1296        if (buf)
1297                OS_Free(&buf);
1298               
1299        g_RfUpdate_ForceBootUpdate = old_fub1;
1300        g_dhl_force_update_block = old_fub2;
1301
1302}
1303
1304#endif  /* RFUPDATE_STRESS_TEST */
1305
1306
1307
1308
1309
1310#if COMMENT
1311____Init____(){}
1312#endif
1313
1314/******************************************************************************************
1315FUNCTION:
1316  - App_RfUpdateInit
1317
1318Purpose:
1319  - RF update initialize
1320******************************************************************************************/
1321void App_RfUpdateInit(void)
1322{
1323        dhl_fupdate_init();
1324
1325        DHL_DBG_RegisterFunctionSymbol("rfupdate", App_RfUpdateStart);
1326
1327        DHL_DBG_RegisterVarSymbol(DHL_VAR_SYM_ARGS(g_RfUpdate_SkipBootUpdate));
1328}
1329
1330
1331#endif /* SUPPORT_RFUPDATE */
1332
1333// megakiss 2012.10.30
1334// Newcon2ÀÇ SDDS ¼ö½ÅÀ» À§ÇÑ ÄÚµå
1335// KBS ½ºÆ®¸² kview_480i_mpeg2.tp »ç¿ë
1336// °øÀå¿¡¼­ ¾à¼ÓµÈ Á֯ļö 18À¸·Î Æ©´×ÇÑ´Ù.
1337// SDDS ¼ö½Å ÈÄ MW Äݹ鿡 ÀÇÇØ¼­ ÁøÇà OSD¸¦ ¶ç¿î´Ù.
1338void App_RFUpdateTuneKBS_RF18()
1339{
1340        int idx = -1;
1341        DMW_CDB_ClearAll();
1342        DMW_MSC_LockUcm();
1343        idx=DMW_CDB_MakeNewUcm(7, 1, 18, TRUE , Modulation_8VSB);
1344        if(idx>=0)
1345        {
1346                g_UCM[idx].Skipped = 0;
1347                g_UCM[idx].ShortName[0] = (UINT16)'K';
1348                g_UCM[idx].ShortName[1] = (UINT16)'B';
1349                g_UCM[idx].ShortName[2] = (UINT16)'S';
1350                g_UCM[idx].ShortName[3] = (UINT16)'-';
1351                g_UCM[idx].ShortName[4] = (UINT16)'H';
1352                g_UCM[idx].ShortName[5] = (UINT16)'D';
1353        }
1354        DMW_MSC_UnlockUcm();
1355        App_ChTuneByDigitKey(7, 1);                                             
1356}
1357
1358/* end of file */
Note: See TracBrowser for help on using the repository browser.