OSDN Git Service

[LCD] Add backlight manipulation.
[openi2cradio/OpenI2CRadio.git] / main.c
1 /*
2  * OpenI2CRADIO
3  * Config & Main routine.
4  * Copyright (C) 2013-06-10 K.Ohta <whatisthis.sowhat ai gmail.com>
5  * License: GPL2+LE
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; either version 2,
10  *  or (at your option) any later version.
11  *  This library / program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14  *  See the GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this library; see the file COPYING. If not, write to the
18  *  Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
19  *  MA 02110-1301, USA.
20  *
21  *  As a special exception, if you link this(includeed from sdcc) library
22  *  with other files, some of which are compiled with SDCC,
23  *  to produce an executable, this library does not by itself cause
24  *  the resulting executable to be covered by the GNU General Public License.
25  *  This exception does not however invalidate any other reasons why
26  *  the executable file might be covered by the GNU General Public License.
27  */
28
29 #include <stdarg.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <sdcc-lib.h>
34 #include <pic18fregs.h> /* ONLY FOR PIC18x */
35 #include <signal.h>
36 #include <delay.h>
37
38 #include "iodef.h"
39 #include "idle.h"
40 #include "i2c_io.h"
41 #include "akc6955.h"
42 #include "lcd_acm1602.h"
43 #include "ui.h"
44 #include "eeprom.h"
45
46 /*
47  * Config words.
48  */
49 #if defined(pic18f23k22) || defined(pic18f24k22) || defined(pic18f25k22) || defined(pic18f26k22)
50 //#pragma stack 0x200 256 // Set stack size to 256bytes.
51 #pragma config FOSC=INTIO67,BORV=190,BOREN=ON,PWRTEN=ON
52 #pragma config WDTEN=ON,WDTPS=32768
53 #pragma config PBADEN=OFF,MCLRE=EXTMCLR,STVREN=ON,LVP=OFF,DEBUG=ON//,XINST=ON
54 //#pragma config PBADEN=OFF,MCLRE=EXTMCLR,STVREN=ON,LVP=OFF//,XINST=ON
55 #pragma config CP0=OFF,CP1=OFF,CPB=OFF,CPD=OFF
56 #pragma config WRT0=OFF,WRT1=OFF,WRTB=OFF,WRTC=OFF,WRTD=OFF
57 #pragma config EBTR0=OFF,EBTR1=OFF,EBTRB=OFF
58 #endif
59 // For 4xK20 or 2xK20 Series
60 #if defined(pic18f43k20) || defined(pic18f44k20) || defined(pic18f45k20) || defined(pic18f46k20) || \
61     defined(pic18f23k20) || defined(pic18f24k20) || defined(pic18f25k20) || defined(pic18f26k20)
62 #pragma stack 0x200 256
63 #pragma config FOSC=HS,FCMEN=ON,PWRT=ON,BOREN=ON,BORV=22
64 #pragma config WDTEN=ON,WDTPS=32768,PBADEN=OFF,HFOFST=ON,LPT1OSC=OFF,MCLRE=ON
65 #pragma config STVREN=ON,DEBUG=ON
66 #pragma config CP0=OFF,CP1=OFF,CP2=OFF,CP3=OFF
67 #pragma config CPB=OFF,CPD=OFF
68 #pragma config WRT0=OFF,WRT1=OFF,WRT2=OFF,WRT3=OFF
69 #pragma config WRTC=OFF,WRTB=OFF,WRTD=OFF
70 #pragma config EBTR0=OFF,EBTR1=OFF,EBTR2=OFF,EBTR3=OFF,EBTRB=OFF
71 #endif
72
73 //#define _LCD_DEBUG 1
74
75 SIGHANDLER(TMR0_handler)
76 {
77    unsigned char tmr0f;
78    unsigned char t0con;
79
80    // Stop timer0
81    t0con = T0CON;
82    t0con &= ~_IDLEN;
83    T0CON = t0con;
84
85    // Read IOKEYS
86 //   readkey_io();
87
88    // Clear interrupt flag
89    tmr0f = INTCON;
90    tmr0f &= ~(_TMR0IF | _TMR0IE);
91    INTCON = tmr0f;
92
93    return;
94 }
95
96
97 DEF_INTLOW(intlow_handler)
98   DEF_HANDLER(SIG_TMR0, TMR0_handler)
99 END_DEF
100
101
102 unsigned int amfreq;
103 unsigned int fmfreq;
104 unsigned char amband;
105 unsigned char fmband;
106 unsigned char fm;
107 unsigned char am_mode3k;
108 unsigned char am_userbandnum;
109 unsigned char fm_userbandnum;
110 typedef struct {
111     unsigned char mode3k; // mode3k if am
112     unsigned char start;
113     unsigned char stop;
114     unsigned int freq;
115 } _userband_t;
116 #define USER_BAND_NUM 4
117 _userband_t am_usrbands[USER_BAND_NUM];
118 _userband_t fm_usrbands[USER_BAND_NUM];
119
120 unsigned char enter_mode;
121 unsigned char numeric_mode;
122 unsigned char menu_node;
123 int backlight_long;
124 unsigned char help_flag;
125 int help_line;
126 int help_section;
127 int ui_language;
128 unsigned int ui_idlecount;
129 unsigned char scanflag;
130
131 int recv_signal;
132 int backlight_counter;
133 unsigned char backlight_level;
134
135 unsigned int writeword_eeprom(unsigned int p, unsigned int *sum, unsigned int word)
136 {
137     if(eeprom_writebyte(p, word >> 8) == 0) return p; // Error
138     *sum = calcsum_byte(*sum, (word >> 8));
139
140     if(eeprom_writebyte(p, word & 0xff) == 0) return p+1; // Error
141     *sum = calcsum_byte(*sum, word & 0xff);
142     return 0xffff;
143 }
144
145 unsigned int writebyte_eeprom(unsigned int p, unsigned int *sum, unsigned char b)
146 {
147     if(eeprom_writebyte(p, b) == 0) return p; // Error
148     *sum = calcsum_byte(*sum, b);
149     return 0xffff;
150 }
151
152 void save_eeprom(void)
153 {
154     unsigned int p = 0;
155     unsigned int sum = 0x0000;
156     unsigned char i;
157
158     // Magic word
159     writeword_eeprom(p, &sum, 0x1298);
160     p+= 2;
161     // amfreq
162     writeword_eeprom(p, &sum, amfreq);
163     p+= 2;
164     // amfreq
165     writeword_eeprom(p, &sum, fmfreq);
166     p+= 2;
167
168     writebyte_eeprom(p, &sum, amband);
169     p++;
170     writebyte_eeprom(p, &sum, fmband);
171     p++;
172     writebyte_eeprom(p, &sum, fm);
173     p++;
174     writebyte_eeprom(p, &sum, am_mode3k);
175     p++;
176     writebyte_eeprom(p, &sum, am_userbandnum);
177     p++;
178     writebyte_eeprom(p, &sum, fm_userbandnum);
179     p++;
180
181     for(i = 0 ; i < USER_BAND_NUM; i++){
182         writebyte_eeprom(p, &sum, am_usrbands[i].mode3k);
183         writebyte_eeprom(p + 1, &sum, am_usrbands[i].start);
184         writebyte_eeprom(p + 2, &sum, am_usrbands[i].stop);
185         writeword_eeprom(p + 3, &sum, am_usrbands[i].freq);
186         p += 5;
187     }
188     for(i = 0 ; i < USER_BAND_NUM; i++){
189         writebyte_eeprom(p, &sum, fm_usrbands[i].mode3k);
190         writebyte_eeprom(p + 1, &sum, fm_usrbands[i].start);
191         writebyte_eeprom(p + 2, &sum, fm_usrbands[i].stop);
192         writeword_eeprom(p + 3, &sum, fm_usrbands[i].freq);
193         p += 5;
194     }
195     // Write checksum
196     eeprom_writebyte(p, sum >> 8);
197     eeprom_writebyte(p + 1, sum & 0xff);
198     p+= 2;
199 }
200
201 unsigned int readword_eeprom(unsigned int p, unsigned int *sum)
202 {
203     unsigned char h,l;
204     unsigned int s;
205
206     h = eeprom_readbyte(p);
207     *sum = calcsum_byte(*sum, h);
208
209     l = eeprom_readbyte(p + 1);
210     *sum = calcsum_byte(*sum, l);
211
212     s = (h << 8) + l;
213     return s;
214 }
215
216 unsigned char readbyte_eeprom(unsigned int p, unsigned int *sum)
217 {
218     unsigned char b;
219
220     b = eeprom_readbyte(p);
221     *sum = calcsum_byte(*sum, b);
222
223     return b;
224 }
225
226
227 unsigned char load_eeprom(void)
228 {
229     unsigned int p = 0;
230     unsigned int sum = 0x0000;
231     unsigned char i;
232     unsigned int magic;
233
234     // Magic word
235     magic = readword_eeprom(p, &sum);
236     if(magic != 0x1298) return 0x01; // NO MAGICWORD
237     p+= 2;
238     // amfreq
239     amfreq = readword_eeprom(p, &sum);
240     p+= 2;
241     // fmfreq
242     fmfreq = readword_eeprom(p, &sum);
243     p+= 2;
244
245     amband = readbyte_eeprom(p, &sum);
246     p++;
247     fmband = readbyte_eeprom(p, &sum);
248     p++;
249     fm = readbyte_eeprom(p, &sum);
250     p++;
251     am_mode3k = readbyte_eeprom(p, &sum);
252     p++;
253     am_userbandnum = readbyte_eeprom(p, &sum);
254     p++;
255     fm_userbandnum = readbyte_eeprom(p, &sum);
256     p++;
257
258     for(i = 0 ; i < USER_BAND_NUM; i++){
259         am_usrbands[i].mode3k = readbyte_eeprom(p, &sum);
260         am_usrbands[i].start  = readbyte_eeprom(p + 1, &sum);
261         am_usrbands[i].stop   = readbyte_eeprom(p + 2, &sum);
262         am_usrbands[i].freq   = readword_eeprom(p + 3, &sum);
263         p += 5;
264     }
265     for(i = 0 ; i < USER_BAND_NUM; i++){
266         fm_usrbands[i].mode3k = readbyte_eeprom(p, &sum);
267         fm_usrbands[i].start  = readbyte_eeprom(p + 1, &sum);
268         fm_usrbands[i].stop   = readbyte_eeprom(p + 2, &sum);
269         fm_usrbands[i].freq   = readword_eeprom(p + 3, &sum);
270         p += 5;
271     }
272     // Write checksum
273     magic = (eeprom_readbyte(p) << 8) + eeprom_readbyte(p+1);
274
275     p+= 2;
276     if(sum != magic) return 0x00;
277     return 0xff;
278 }
279
280
281 void toggle_amfm(void)
282 {
283     if(fm != 0){
284         fm = 0;
285 #ifndef _LCD_DEBUG
286         akc6955_chg_fm(fm);
287         akc6955_set_amband(amband);
288         akc6955_set_freq(amfreq);
289 #endif
290     } else {
291         fm = 0xff;
292 #ifndef _LCD_DEBUG
293         akc6955_chg_fm(fm);
294         akc6955_set_fmband(fmband);
295         akc6955_set_freq(fmfreq);
296 #endif
297     }
298 }
299
300 static void update_status(void)
301 {
302 #ifndef _LCD_DEBUG
303         recv_signal = akc6955_read_level();
304         if(fm != 0){
305             fmfreq = akc6955_get_freq();
306         } else {
307             amfreq = akc6955_get_freq();
308         }
309 #endif
310
311 }
312
313
314 void set_volume(void)
315 {
316 }
317
318 void update_display(void)
319 {
320     if(fm != 0){ // FM
321         _LOCATE(0,0);
322         if(fmband < AKC6955_BAND_TV1) {
323             printstr("FM");
324             _PUTCHAR('1' + (fmband & 7));
325         } else if(fmband < AKC6955_BAND_FMUSER){
326             printstr("TV");
327             _PUTCHAR('1' + fmband - AKC6955_BAND_TV1);
328         } else { // USER
329             printstr("FMUSR");
330         }
331     } else { // AM
332         _LOCATE(0,1);
333         if(amband == AKC6955_BAND_LW) {
334             printstr("LW");
335         } else if(amband <AKC6955_BAND_SW1) { //MW
336             printstr("MW");
337             _PUTCHAR('1' + amband - AKC6955_BAND_MW1);
338         } else if(amband < AKC6955_BAND_AMUSER) { //MW
339             printstr("SW");
340             _PUTCHAR('1' + amband - AKC6955_BAND_SW1);
341         } else if(amband == AKC6955_BAND_MW4){
342             printstr("MW4");
343         } else {
344             printstr("AMUSR");
345         }
346      }
347      _LOCATE(16-4 ,1);
348      if(fm != 0){
349          printstr("MHz");
350      } else {
351          printstr("KHz");
352      }
353      _LOCATE(16-5, 1);
354      if(fm != 0){
355          int freq_lo = fmfreq % 100;
356          int freq_hi = fmfreq / 100;
357          print_numeric(freq_hi, 0xff);
358          _PUTCHAR('.');
359          print_numeric(freq_lo, 0xff);
360      } else {
361          print_numeric(amfreq, 0xff);
362      }
363      // Signal
364      _LOCATE(0, 0);
365      printstr("S=");
366      print_numeric(recv_signal, 0xff);
367 }
368
369 void scan_start()
370 {
371     unsigned char input_flag;
372     unsigned char c;
373
374     do {
375         if(scanflag == 0){
376         // New Scan
377             _CLS();
378             printstr("Scan A=ABORT");
379             _LOCATE(0,1);
380             printstr("U=6, D=4");
381             do {
382                 input_flag = readkey_compare();
383                 idle(0xff80);
384             } while(input_flag == 0);
385             c = pop_keyinfifo();
386             if(c == charcode_6){
387                     akc6955_do_scan(0xff);
388             } else if(c == charcode_4){
389                     akc6955_do_scan(0);
390             } else {
391                 break;
392             }
393             scanflag = 0xff;
394         } else {
395             do {
396                 input_flag = readkey_compare();
397                 idle(0xff80);
398             } while(input_flag == 0);
399             c = pop_keyinfifo();
400
401             if(c == charcode_a){
402                 akc6955_abort_scan();
403                 break;
404             } else if(c == charcode_4){
405                 akc6955_abort_scan();
406                 akc6955_do_scan(0);
407                 continue;
408             } else if(c == charcode_6){
409                 akc6955_abort_scan();
410                 akc6955_do_scan(0xff);
411                 continue;
412             }
413             if(akc6955_chk_donescan() != 0) break;
414         }
415         idle(0xff00);
416     } while(1);
417     scanflag=0;
418     _CLS();
419     update_status();
420     update_display();
421 }
422
423 void setfreq_direct(void)
424 {
425     unsigned int val;
426     _CLS();
427     if(fm != 0){
428         // FM
429         _LOCATE(0,0);
430         printstr("Set Freq:FM");
431         val = fmfreq;
432         val = read_numeric(val, 5, 7, 1);
433         fmfreq = val;
434         akc6955_set_freq(val);
435     } else {
436         // FM
437         _LOCATE(0,0);
438         printstr("Set Freq:AM");
439         val = amfreq;
440         val = read_numeric(val, 5, 7, 1);
441         amfreq = val;
442         akc6955_set_freq(val);
443     }
444     idle(0xff00);
445     update_status();
446     update_display();
447 }
448
449 void setband_direct(void)
450 {
451     unsigned int band;
452     _CLS();
453     _LOCATE(0,0);
454     if(fm != 0){
455         printstr("Set Band:FM");
456         band = fmband & 7;
457         band = read_numeric(band, 2, 7, 1);
458         akc6955_set_fmband(band);
459         akc6955_do_tune();
460         idle(0xff00);
461     } else {
462         printstr("Set Band:AM");
463         band = amband & 0x1f;
464         band = read_numeric(band, 2, 7, 1);
465         akc6955_set_amband(band);
466         akc6955_do_tune();
467     }
468     idle(0xff00);
469     update_status();
470     update_display();
471 }
472
473 void call_userband(unsigned char num)
474 {
475     unsigned int freq;
476     unsigned int ch;
477     if(num >= USER_BAND_NUM) return;
478     if(fm != 0){
479         freq = fm_usrbands[num].freq;
480         ch = ((freq - 3000) / 25) * 10;
481         akc6955_set_userband(fm_usrbands[num].start, fm_usrbands[num].stop, ch,
482                             fm_usrbands[num].mode3k);
483     } else {
484         unsigned int p = 5;
485         if(am_usrbands[num].mode3k != 0) p = 3;
486         freq = am_usrbands[num].freq;
487         ch = freq / p;
488         akc6955_set_userband(am_usrbands[num].start, am_usrbands[num].stop, ch,
489                             am_usrbands[num].mode3k);
490     }
491     if(fm != 0) {
492         fmband = AKC6955_BAND_AMUSER;
493     } else {
494         amband = AKC6955_BAND_AMUSER;
495     }
496     idle(0xff00);
497     update_status();
498     update_display();
499 }
500
501 void set_userband(void)
502 {
503     unsigned int from,to;
504     unsigned char c;
505     unsigned char p;
506     unsigned char mode3k;
507     unsigned int input_flag;
508     char cc;
509
510     _CLS();
511     _LOCATE(0,0);
512     printstr("User ch:");
513     do {
514         input_flag = readkey_compare();
515         idle(0xff80);
516     } while(input_flag == 0);
517     c = pop_keyinfifo();
518
519     if(c > charcode_0) return;
520     if(c < charcode_1) return;
521     if(c == charcode_0) {
522         c = 0;
523     } else {
524         c = c - charcode_1 + 1;
525     }
526     if(c >= USER_BAND_NUM) return;
527     if(fm != 0){
528         from = fm_usrbands[c].start * 80 + 3000; // 32*25/10
529         to = fm_usrbands[c].stop * 80 + 3000;
530         _CLS();
531         _LOCATE(0,0);
532         printstr("FM #");
533         print_numeric_nosupress(c, 1);
534         printstr(" From:");
535         from = read_numeric(from, 5, 7, 1);
536         _CLS();
537         _LOCATE(0,0);
538         printstr("FM #");
539         print_numeric_nosupress(c, 1);
540         printstr(" To:");
541         to = read_numeric(to, 5, 7, 1);
542         fm_usrbands[c].start = (from - 3000) / 80;
543         fm_usrbands[c].stop = (to - 3000) / 80;
544         fm_usrbands[c].freq = from * 80 + 3000;
545         fm_userbandnum = c;
546     } else {
547         mode3k = am_usrbands[c].mode3k;
548         p = 96; // 3*32
549         if(mode3k == 0) p = 160; // 5*32
550         from = am_usrbands[c].start * p; 
551         to = am_usrbands[c].stop * p;
552         _CLS();
553         _LOCATE(0,0);
554         printstr("AM #");
555         print_numeric_nosupress(c, 1);
556         printstr(" Step:");
557         _LOCATE(0,1);
558         printstr("0=3k 1=5k");
559         do {
560             input_flag = readkey_compare();
561             idle(0xff80);
562         } while(input_flag == 0);
563         cc = pop_keyinfifo();
564
565         if(cc == charcode_0){
566             p = 96;
567             mode3k = 0xff;
568         } else if(cc = charcode_1) {
569             p = 160;
570             mode3k = 0;
571         }
572         _CLS();
573         _LOCATE(0,0);
574         printstr("AM #");
575         print_numeric_nosupress(c, 1);
576         printstr(" From:");
577         from = read_numeric(from, 5, 7, 1);
578         _CLS();
579         _LOCATE(0,0);
580         printstr("AM #");
581         print_numeric_nosupress(c, 1);
582         printstr(" To:");
583         to = read_numeric(to, 5, 7, 1);
584         am_usrbands[c].start = from / p;
585         am_usrbands[c].stop = to  / p;
586         am_usrbands[c].mode3k = mode3k;
587         am_usrbands[c].freq = from * p;
588         am_userbandnum = c;
589     }
590     call_userband(c);
591 }
592
593 void input_userband(void)
594 {
595     unsigned char c;
596     unsigned char input_flag;
597     do{
598     _CLS();
599     _LOCATE(0,0);
600     printstr("User Band");
601     _LOCATE(0,1);
602     printstr("   #");
603     do {
604         input_flag = readkey_compare();
605         idle(0xff80);
606     } while(input_flag == 0);
607     c = pop_keyinfifo();
608
609     if((c >= charcode_a) && (c <= charcode_f)){
610         break;
611     }
612     if(c == charcode_0) {
613         _PUTCHAR('0');
614         if(fm != 0){
615            fm_userbandnum = 0;
616         } else {
617            am_userbandnum = 0;
618         }
619         call_userband(0);
620     } else {
621         c = c - charcode_1 + 1;
622         if(c < USER_BAND_NUM) {
623             _PUTCHAR(c + '0');
624             if(fm != 0){
625                fm_userbandnum = c;
626             } else {
627                 am_userbandnum = c;
628             }
629             call_userband(c);
630         }
631     }
632     idle(0xff00);
633     } while(1);
634     _CLS();
635 }
636
637
638 void main_menu(void)
639 {
640     unsigned char c;
641     unsigned int input_flag;
642     _CLS();
643     _LOCATE(0,0);
644     printstr("Menu:F=HELP");
645     _LOCATE(1,0);
646     printstr("A=CANCEL");
647     do{
648         do {
649             input_flag = readkey_compare();
650             idle(0xff80);
651         } while(input_flag == 0);
652
653         c = pop_keyinfifo();
654         if((c < charcode_1) || ( c >charcode_s3)) {
655             idle(0xff00);
656             continue; // Error
657         }
658         if(c == charcode_f){
659             // HELP
660         } else if(c == charcode_a){
661             // Cancel
662             break;
663         } else if(c == charcode_1){
664             // AM
665             fm = 0;
666             akc6955_chg_fm(fm);
667             akc6955_set_amband(amband);
668             akc6955_set_freq(amfreq);
669             break;
670         } else if(c == charcode_2){
671             // Band
672             setband_direct();
673             break;
674         } else if(c == charcode_3){
675             // Band
676             setfreq_direct();
677             break;
678         } else if(c == charcode_4){
679             // fm
680             fm = 0xff;
681             akc6955_chg_fm(fm);
682             akc6955_set_fmband(fmband);
683             akc6955_set_freq(fmfreq);
684             break;
685         } else if(c == charcode_5){
686             // Scan
687             break;
688         } else if(c == charcode_6){
689             // Set gain
690             break;
691         } else if(c == charcode_7){
692             // Set volume
693             break;
694         } else if(c == charcode_8){
695             // Set sensitivity
696             break;
697         } else if(c == charcode_9){
698             // Set NF
699             break;
700         } else if(c == charcode_0){
701             // Setup Menu
702             break;
703         } else if(c == charcode_b){
704             // Call userband
705             input_userband();
706             break;
707         } else if(c == charcode_c){
708             // Set userband
709             set_userband();
710             break;
711         } else if(c == charcode_d){
712             // Reserve
713             break;
714         } else if(c == charcode_e){
715             // Reserve
716             break;
717         }
718         idle(0xff00);
719     } while(1);
720 }
721
722 void setfreq_updown(unsigned char ctlword)
723 {
724 #ifndef _LCD_DEBUG
725     switch(ctlword){
726         case charcode_8: // Change band
727             if(fm != 0){
728                 amband++;
729                 if(amband > 18) amband = 0;
730 //                amfreq = akc6955_setfreq(amfreq)
731                 akc6955_set_amband(amband);
732                 _AKC6955_WAIT_62_5MS(); // 62.5ms
733                 amband = akc6955_get_amband();
734                 amfreq = akc6955_get_freq();
735             } else {
736                 fmband++;
737                 if(fmband > 7) fmband = 0;
738 //                amfreq = akc6955_setfreq(amfreq)
739                 akc6955_set_fmband(fmband);
740                 _AKC6955_WAIT_62_5MS(); // 62.5ms
741                 fmband = akc6955_get_fmband();
742                 fmfreq = akc6955_get_freq();
743             }
744             break;
745         case charcode_2: // Change band
746             if(fm != 0){
747                 amband--;
748                 if(amband == 0) amband = 18;
749                 if(amband >= 18) amband = 18;
750 //                amfreq = akc6955_setfreq(amfreq)
751                 akc6955_set_amband(amband);
752                 _AKC6955_WAIT_62_5MS(); // 62.5ms
753                 amband = akc6955_get_amband();
754                 amfreq = akc6955_get_freq();
755             } else {
756                 fmband--;
757                 if(fmband == 0) fmband = 7;
758                 if(fmband >= 7) fmband = 7;
759 //                amfreq = akc6955_setfreq(amfreq)
760                 akc6955_set_fmband(fmband);
761                 _AKC6955_WAIT_62_5MS(); // 62.5ms
762                 fmband = akc6955_get_fmband();
763                 fmfreq = akc6955_get_freq();
764             }
765             break;
766         case charcode_4: // Down Freq;
767             if(fm != 0){
768                 fmfreq = akc6955_down_freq(10); // DOWN 100KHz
769             } else {
770                 amfreq = akc6955_down_freq(10); // DOWN 10KHz
771             }
772             break;
773         case charcode_6: // Down Freq;
774             if(fm != 0){
775                 fmfreq = akc6955_up_freq(10); // UP 100KHz
776             } else {
777                 amfreq = akc6955_up_freq(10); // UP 10KHz
778             }
779             break;
780         case charcode_7: // Down Fast;
781             if(fm != 0){
782                 fmfreq = akc6955_down_freq(50); // DOWN 500KHz
783             } else {
784                 amfreq = akc6955_down_freq(50); // DOWN 50KHz
785             }
786             break;
787         case charcode_9: // Down Fast;
788             if(fm != 0){
789                 fmfreq = akc6955_up_freq(50); // UP 100KHz
790             } else {
791                 amfreq = akc6955_up_freq(50); // UP 10KHz
792             }
793             break;
794         case charcode_1: // Down Slow;
795             if(fm != 0){
796                 fmfreq = akc6955_down_freq(5); // DOWN 50KHz
797             } else {
798                 amfreq = akc6955_down_freq(5); // DOWN 50KHz
799             }
800             break;
801         case charcode_3: // Down Slow;
802             if(fm != 0){
803                 fmfreq = akc6955_up_freq(5); // UP 50KHz
804             } else {
805                 amfreq = akc6955_up_freq(5); // UP 5KHz
806             }
807             break;
808         case charcode_0: // Step
809             if(fm == 0){
810                 if(am_mode3k == 0) {
811                     am_mode3k = 0xff;
812                 } else {
813                     am_mode3k = 0;
814                 }
815                 amfreq = akc6955_mode3k(am_mode3k);
816             }
817             break;
818         case charcode_a: // Toggle FM
819             toggle_amfm();
820             break;
821         case charcode_b:
822             input_userband();
823             break;
824         case charcode_c:
825             set_userband();
826             break;
827         case charcode_d:
828             set_volume();
829             break;
830         case charcode_e: // Backlight ON/OFF
831             if(backlight_counter > 0) {
832                backlight_counter = 0;
833             } else {
834                backlight_counter = backlight_long;
835             }
836             break;
837         case charcode_f:
838             main_menu();
839             break;
840         default:
841             break;
842     }
843 #endif
844 }
845 /*
846  * 
847  */
848 static void setdefault(void)
849 {
850     char i;
851     amfreq = 954;
852     fmfreq = 8000; // 10KHz order.
853     amband = AKC6955_BAND_MW2;
854     fmband = AKC6955_BAND_FM2;
855     am_mode3k = 0xff;
856     fm = 0;
857     recv_signal = 0;
858     am_userbandnum = 0;
859     fm_userbandnum = 0;
860     for(i = 0; i < 4; i++){
861         am_usrbands[i].start = 0x19;
862         am_usrbands[i].stop  = 0x32;
863     }
864     for(i = 0; i < 4; i++){
865         fm_usrbands[i].start = 0x19;
866         fm_usrbands[i].stop  = 0x32;
867     }
868
869
870 }
871
872 int main(void)
873 {
874     char readchar;
875     unsigned char input_flag;
876     unsigned char c;
877     unsigned int i;
878 #ifdef _LCD_DEBUG
879     unsigned char power_flag;
880 #endif
881 //    OSCCON =  _IDLEN & 0b11111100;
882
883     keyin_init();
884     keyin_ioinit();
885     idle_init();
886
887     //i2c1_init();
888
889 //    _AKC6955_WAIT_125_0MS(); // Wait 125ms
890 #ifdef _LCD_DEBUG
891     power_flag = 0xff;
892 #endif
893     backlight_long = 256;
894     backlight_counter = backlight_long;
895     backlight_level = 255;
896     ui_idlecount = 0xf800;
897
898     acm1602_init(0xa0, 1); //Init LCD
899     _AKC6955_WAIT_125_0MS(); // Wait 125ms
900     _LOCATE(0,0);
901     printstr("Hello;-)");
902     acm1602_setbacklight(0xff);
903 #if 1
904     i = 10001;
905     do {
906         idle(0xff00);
907         ClrWdt();
908         _LOCATE(8,1);
909 //        print_numeric_nosupress(i, 5);
910         print_numeric(i, 1);
911 //        PORTDbits.RD3 = i & 1;
912         i = i + 1;
913     }while(1);
914 #else
915     switch(load_eeprom()) {
916         case 0x01: // No magic-word
917             idle(0xff80);
918             _CLS();
919             setdefault();
920             _LOCATE(0,0);
921             printstr("EEPROM FORMATTING");
922             _LOCATE(0,1);
923             printstr("Press any key");
924             do {
925                 input_flag = readkey_compare();
926                 idle(0xff80);
927             } while(input_flag == 0);
928             c = pop_keyinfifo();
929             format_eeprom(0,254);
930             save_eeprom();
931             break;
932         case 0x00: // Checksum error
933             idle(0xff80);
934             _CLS();
935             _LOCATE(0,0);
936             printstr("X-) Sum Error");
937             _LOCATE(0,1);
938             printstr("Press any key to format");
939             do {
940                 input_flag = readkey_compare();
941                 idle(0xff80);
942             } while(input_flag == 0);
943             
944             c = pop_keyinfifo();
945             format_eeprom(0,254);
946             setdefault();
947             save_eeprom();
948             break;
949         case 0xff: // Success
950             break;
951         default: // Unknown error
952             setdefault();
953             break;
954     }
955     // Init AKC6955
956     /* Check EEPROM */
957     /* Push default parameters to AKC6955*/
958     scanflag = 0;
959 #ifndef _LCD_DEBUG
960     akc6955_chg_fm(fm); // Set to AM
961     akc6955_set_amband(amband);
962     akc6955_set_freq(amfreq); // Dummy, TBS (954KHz)
963     akc6955_set_power(0xff); // Power ON
964 #endif
965 #ifdef _LCD_DEBUG
966     idle(0xf000);
967 #else
968     idle(0xff00);
969 #endif
970     _CLS();
971     update_status();
972     update_display();
973     do {
974         /* Main routine*/
975         input_flag = readkey_compare();
976         if(input_flag != 0){
977             readchar = pop_keyinfifo();
978             if((readchar >= charcode_1) && (readchar <= charcode_f)) {
979                     setfreq_updown(readchar);
980             } else {
981                 // Other is skip
982             }
983         }
984         // Check battery (include idle?)
985         // Read AKJC6955's status
986         update_status();
987         // Putstring to LCD.
988
989         update_display();
990         if(backlight_counter > 0) {
991             backlight_counter--;
992             set_backlight(0xff, backlight_level); // Turn ON
993         } else {
994             set_backlight(0x00, 0); // Turn OFF
995         }
996 #ifdef _LCD_DEBUG
997         if(power_flag != 0x00) {
998             power_flag = 0x00;
999         } else {
1000             power_flag = 0xff;
1001         }
1002         setsignal_tune(power_flag);
1003 #endif
1004         idle(ui_idlecount);
1005     } while(1);
1006 #endif
1007 }
1008