OSDN Git Service

[Schematic] Remove capacitor of MCLR/Power circuit, due of unstable.
[openi2cradio/OpenI2CRadio.git] / menu.c
1 /*
2  * OpenI2CRADIO
3  * Menu sub-routines.
4  * Copyright (C) 2013-06-21 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 "menu.h"
30 #include "power.h"
31 #include "commondef.h"
32
33 const char *updown_helpstr[20] = {
34         "Help", "F=exit any=continue",
35         "5: Menu", " ",
36         "1: Slow Down", "3: Slow Up",
37         "4: Down", "6: Up",
38         "7: Fast Down", "9: Fast Up",
39         "2: Band Down", "8: Band Up",
40         "0: Mode3K", " ",
41         "a: AM/FM", "b: Volume",
42         "c: Scan", "d: Stereo mode",
43         "e: Backlight", "f: (Exit) Help",
44     };
45
46 const char *setup_helpstr[16] = {
47         "Help", "F=exit any=continue",
48         "0: Power OFF", "C: Save status",
49         "d: Reset default", "E: BL time",
50         "A: Load", "",
51         "1: FM CNR", "2: AM CNR"
52         "3: FM STEREO", "4: Reserve"
53         "6: Reserve", "7: Reserve",
54         "8: Reserve", "9: Reserve",
55         "5: Cancel", "f: (Exit) Help",
56     };
57
58 const char *mainmenu_helpstr[18] = {
59         "Help", "F=exit any=continue",
60         "0: Setup", "1: Reserve",
61         "2: Band", "3: Freq",
62         "4: Reserve", "5: Scan"
63         "6: Gain", "7: Volume",
64         "8: FM Wide/Narrow", "9: Reserved",
65         "a: PowOFF", "b: Cancel",
66         "c: Set user", "d: Input user",
67         "e: AM/FM", "f: (Exit) Help"
68 };
69
70 const char *numeric_helpstr[10] = {
71      "On numeric input", " ",
72     "0-9: Numeric", "f: enter",
73     "a: Delete", "b: Reset value",
74     "d: Left", "e: Right",
75     "Press any key", " to continue."
76 };
77
78 void toggle_amfm(void)
79 {
80     unsigned int freq;
81     if(fm != 0){
82         fm = 0;
83         fmfreq_bank[fmband] = fmfreq;
84   //      akc6955_set_amband(amband);
85         freq = amfreq_bank[amband];
86     } else {
87         fm = 0xff;
88         amfreq_bank[amband] = amfreq;
89 //        akc6955_set_fmband(fmband);
90         freq = fmfreq_bank[fmband];
91     }
92     akc6955_chg_fm(fm, freq);
93     idle_time_ms(500);
94 //    akc6955_set_freq(freq);
95 }
96
97
98 void set_thresh_fmstereo(unsigned char a)
99 {
100     unsigned char b;
101     a = a & 0x03;
102     threshold_fmstereo = a;
103     b = akc6955_readcmd(AKC6955_THRESH) & 0xfc;
104     akc6955_writecmd(AKC6955_THRESH, a | b);
105 }
106
107 void set_thresh_width(unsigned char a)
108 {
109     unsigned char b;
110     a = a & 0x03;
111     threshold_width = a;
112     a = a << 2; // << 2
113     b = akc6955_readcmd(AKC6955_THRESH) & 0xf3;;
114     akc6955_writecmd(AKC6955_THRESH, a | b);
115 }
116
117 void set_thresh_amcnr(unsigned char a)
118 {
119     unsigned char b;
120     a = a & 0x03;
121     threshold_amcnr = a;
122     a = a << 4; // << 4
123     b = akc6955_readcmd(AKC6955_THRESH) & 0xcf;
124     akc6955_writecmd(AKC6955_THRESH, a | b);
125 }
126
127 void set_thresh_fmcnr(unsigned char a)
128 {
129     unsigned char b;
130     a = a & 0x03;
131     threshold_fmcnr = a;
132     a = a << 6; // << 4
133     b = akc6955_readcmd(AKC6955_THRESH) & 0x3f;
134     akc6955_writecmd(AKC6955_THRESH, a | b);
135 }
136
137 void set_stereomode(void)
138 {
139     __bitops_t mode;
140     mode.byte = 0x00;
141     if(stereo == 0x00){
142             mode.b0 = 1; // Force mono
143     } else if(stereo < 0x80){
144             mode.b1 = 1; // Force stereo
145     }
146     akc6955_set_stereomode(mode.byte);
147 }
148
149 void set_stereo(void)
150 {
151     if(stereo == 0xff) {// Force Mono
152         stereo = 0x00;
153     } else if(stereo == 0x00) { //Mono->Stereo
154         stereo = 0x7f;
155     } else { // Default, Stereo->auto
156         stereo = 0xff;
157     }
158     set_stereomode();
159 }
160
161
162 void set_volume(void)
163 {
164     unsigned char c;
165     unsigned char d;
166     unsigned char p;
167     unsigned char fact;
168
169     _CLS();
170     do {
171     _LOCATE(0,0);
172      d = akc6955_getvolumemode();
173       if(d == 0){
174          _PUTCHAR('D');
175        } else {
176          _PUTCHAR('K');
177        }
178      printstr(" Vol:");
179      print_numeric_nosupress(volume, 2);
180      printstr("  F:Exit");
181      _LOCATE(0,1);
182      printstr("Pre:");
183      _PUTCHAR('0' + (prevolume & 3));
184      _LOCATE(16-4, 1);
185      if(lowboost == 0x00){
186          printstr("   ");
187      } else {
188          printstr("LOW");
189      }
190      _HOME();
191      c = pollkeys(pollkeybuf, 60, 1);
192      p = 0;
193      while(c > 0) {
194          switch(pollkeybuf[p]) {
195              case charcode_6:
196                  volume++;
197                  if(volume > 63) volume = 63;
198                  break;
199              case charcode_4:
200                  volume--;
201                  if(volume < 23) volume = 23;
202                  break;
203              case charcode_f:
204                  return;
205              case charcode_a:
206                  fact = 0xff;
207                  if(d != 0){
208                      fact = 0x00;
209                  }
210                  akc6955_setvolumemode(fact);
211                  break;
212              case charcode_b:
213                  prevolume++;
214                  if(prevolume > 3) prevolume = 0;
215                  akc6955_set_prevolume(prevolume);
216                  break;
217              case charcode_d:
218                  fact = 0x00;
219                  if(lowboost == 0x00){
220                      fact = 0xff;
221                  }
222                  lowboost = fact;
223                  akc6955_set_lowboost(lowboost);
224                  break;
225              default:
226                  break;
227          }
228          c--;
229          p++;
230         }
231      if(volume < 24){
232          set_examp_mute(1);
233      } else {
234          set_examp_mute(0);
235      }
236      akc6955_setvolume(volume);
237 //    _HOME();
238     } while(1);
239 }
240
241 void scan_start(void)
242 {
243     unsigned char c;
244     _CLS();
245     _LOCATE(0,0);
246     printstr("Scan F/A/4/6");
247     do {
248         update_status();
249         print_freq(1);
250         c = pollkey_single();
251        // New Scan
252        if(c == charcode_6){
253            scanflag = 0xff;
254            akc6955_do_scan(0xff);
255        } else if(c == charcode_4){
256            scanflag = 0xff;
257            akc6955_do_scan(0);
258        } else if(c == charcode_a){
259            scanflag = 0;
260            akc6955_abort_scan();
261            break;
262        } else if(c == charcode_f){
263            break;
264        } else {
265            if((scanflag != 0) && (akc6955_chk_donescan() != 0)) {
266                 scanflag = 0;
267                 _LOCATE(0,0);
268                 printstr("Scan F/A/4/6");
269                 update_status();
270                 print_freq(1);
271            }
272        }
273     _HOME();
274     } while(1);
275     _CLS();
276 }
277
278 void setfreq_direct(void)
279 {
280     unsigned int val;
281     _CLS();
282     _LOCATE(0,0);
283     printstr("Set Freq:");
284     _LOCATE(0,1);
285     if(fm != 0){
286         // FM
287         printstr("FM ");
288         val = fmfreq;
289         val = read_numeric(val, 5, 7, 1);
290         fmfreq = val;
291     } else {
292         // FM
293         printstr("AM ");
294         val = amfreq;
295         val = read_numeric(val, 5, 7, 1);
296         amfreq = val;
297     }
298     akc6955_set_freq(val);
299 }
300
301 void setband_direct(void)
302 {
303     unsigned int band;
304     _CLS();
305     _LOCATE(0,0);
306     if(fm != 0){
307         printstr("Set Band:FM#");
308         band = fmband & 7;
309         fmband = read_numeric(band, 2, 7, 1);
310         akc6955_set_fmband(fmband);
311         akc6955_do_tune();
312     } else {
313         printstr("Set Band:AM#");
314         band = amband & 0x1f;
315         amband = read_numeric(band, 2, 7, 1);
316         akc6955_set_amband(amband);
317         akc6955_do_tune();
318     }
319 }
320
321 void call_userband(unsigned char num)
322 {
323     unsigned int freq;
324     unsigned int ch;
325     if(num >= USER_BAND_NUM) return;
326     if(fm != 0){
327         freq = fm_usrbands[num].freq;
328         ch = ((freq - 3000) / 25) * 10;
329         akc6955_set_userband(fm_usrbands[num].start, fm_usrbands[num].stop, ch,
330                             fm_usrbands[num].mode3k);
331         fmband = AKC6955_BAND_AMUSER;
332     } else {
333         unsigned int p = 5;
334         if(am_usrbands[num].mode3k != 0) p = 3;
335         freq = am_usrbands[num].freq;
336         ch = freq / p;
337         akc6955_set_userband(am_usrbands[num].start, am_usrbands[num].stop, ch,
338                             am_usrbands[num].mode3k);
339         amband = AKC6955_BAND_AMUSER;
340     }
341 }
342
343 void set_userband(void)
344 {
345     unsigned int from,to;
346     unsigned char c;
347     unsigned char p;
348     unsigned char mode3k;
349     char cc;
350
351     _CLS();
352     _LOCATE(0,0);
353     printstr("User ch:");
354     c = pollkey_single();
355
356     if(c > charcode_0) return;
357     if(c < charcode_1) return;
358     if(c == charcode_0) {
359         c = 0;
360     } else {
361         c = c - charcode_1 + 1;
362     }
363     if(c >= USER_BAND_NUM) return;
364     if(fm != 0){
365         from = fm_usrbands[c].start * 80 + 3000; // 32*25/10
366         to = fm_usrbands[c].stop * 80 + 3000;
367         _CLS();
368         _LOCATE(0,0);
369         printstr("FM#");
370         print_numeric_nosupress(c, 1);
371         printstr(" From:");
372         from = read_numeric(from, 5, 7, 1);
373         _LOCATE(6,1);
374         printstr("To:");
375         to = read_numeric(to, 5, 7, 1);
376         fm_usrbands[c].start = (from - 3000) / 80;
377         fm_usrbands[c].stop = (to - 3000) / 80;
378         fm_usrbands[c].freq = from * 80 + 3000;
379         fm_userbandnum = c;
380     } else {
381         mode3k = am_usrbands[c].mode3k;
382         p = 96; // 3*32
383         if(mode3k == 0) p = 160; // 5*32
384         from = am_usrbands[c].start * p;
385         to = am_usrbands[c].stop * p;
386         _CLS();
387         _LOCATE(0,0);
388         printstr("AM#");
389         print_numeric_nosupress(c, 1);
390         printstr(" Step:");
391         _LOCATE(0,1);
392         printstr("0=3k 1=5k");
393         cc = pollkey_single();
394         if(cc == charcode_0){
395             p = 96;
396             mode3k = 0xff;
397         } else if(cc = charcode_1) {
398             p = 160;
399             mode3k = 0;
400         }
401         _CLS();
402         _LOCATE(0,0);
403         printstr("AM#");
404         print_numeric_nosupress(c, 1);
405         printstr(" From:");
406         from = read_numeric(from, 5, 7, 1);
407         _LOCATE(6, 1);
408         printstr(" To:");
409         to = read_numeric(to, 5, 7, 1);
410         am_usrbands[c].start = from / p;
411         am_usrbands[c].stop = to  / p;
412         am_usrbands[c].mode3k = mode3k;
413         am_usrbands[c].freq = from * p;
414         am_userbandnum = c;
415     }
416     call_userband(c);
417 }
418
419 void input_userband(void)
420 {
421     unsigned char c;
422     do{
423     _CLS();
424     _LOCATE(0,0);
425     printstr("User Band");
426     _LOCATE(0,1);
427     printstr("   #");
428     c = pollkey_single();
429
430     if((c >= charcode_a) && (c <= charcode_f)){
431         break;
432     }
433     if(c == charcode_0) {
434         _PUTCHAR('0');
435         if(fm != 0){
436            fm_userbandnum = 0;
437         } else {
438            am_userbandnum = 0;
439         }
440         call_userband(0);
441     } else {
442         c = c - charcode_1 + 1;
443         if(c < USER_BAND_NUM) {
444             _PUTCHAR(c + '0');
445             if(fm != 0){
446                fm_userbandnum = c;
447             } else {
448                 am_userbandnum = c;
449             }
450             call_userband(c);
451         }
452     }
453     idle(ui_idlecount);
454     } while(1);
455     _CLS();
456 }
457
458 unsigned char printhelp_2lines(char *l1, char *l2)
459 {
460     _CLS();
461     _LOCATE(0,0);
462     printstr(l1);
463     _LOCATE(0,1);
464     printstr(l2);
465     _HOME();
466     return pollkey_single();
467 }
468
469 unsigned char numeric_help(void)
470 {
471     unsigned char c;
472     char l;
473     l = 0;
474     do {
475         c = printhelp_2lines(numeric_helpstr[l], numeric_helpstr[l + 1]);
476         if(c == charcode_f) return charcode_f;
477         l += 2;
478     } while(l < 10);
479     return c;
480 }
481
482 void mainmenu_help(void)
483 {
484     unsigned char c;
485     
486     char l;
487     l = 0;
488     do {
489         c = printhelp_2lines(mainmenu_helpstr[l], mainmenu_helpstr[l + 1]);
490         if(c == charcode_f) return;
491         l += 2;
492         if(l >= 18) {
493             c = numeric_help();
494             if(c == charcode_f) return;
495             l = 0;
496         }
497     } while(1);
498 }
499
500 void updown_help(void)
501 {
502     unsigned char c;
503     char l;
504
505     l = 0;
506     do {
507         c = printhelp_2lines(updown_helpstr[l], updown_helpstr[l + 1]);
508         if(c == charcode_f) return;
509         l += 2;
510         if(l >= 20) {
511             c = numeric_help();
512             if(c == charcode_f) return;
513             l = 0;
514         }
515     } while(1);
516 }
517
518 void menu_poweroff(void)
519 {
520     unsigned char c;
521     c = printhelp_2lines("Poweroff", "A=Yes");
522     if(c == charcode_a) {
523         shutdown(1);
524     }
525 }
526
527 void setup_akc6955(void)
528 {
529 //    akc6955_chg_fm(fm); // Set to AM
530 #if 0
531 /*
532  * CR_DEF[18]= {
533             0x4c,  //REG00    //Modify
534             0x10,  //REG01
535             0x4a,  //REG02
536             0xc8,  //REG03
537             0x19,  //REG04
538             0x32,  //REG05
539             0xa1,  //REG06
540             0xa1,  //REG07
541             0x54,  //REG08
542             0xC7,  //REG09
543             0x7f,  //REG10
544             0xe0,  //REG11
545             0x00,  //REG12
546             0x0C,  //REG13
547             0x40,  //REG14
548             0x82,  //REG15        //Modify
549             0xcc,  //REG16
550             0xf9   //REG17
551  */
552     akc6955_writecmd(0x00, 0x4c);
553     akc6955_writecmd(0x01, 0b00010000);
554     akc6955_writecmd(0x02, 0b01001010);
555     akc6955_writecmd(0x03, 0xc8);
556     akc6955_writecmd(0x04, 0x19);
557     akc6955_writecmd(0x05, 0x32);
558     akc6955_writecmd(0x06, 0xa1);
559     akc6955_writecmd(0x07, 0b10100001);
560     akc6955_writecmd(0x08, 0b01010000);
561     akc6955_writecmd(0x09, 0b11000111);
562     akc6955_writecmd(0x09, 0b01111111);
563     akc6955_writecmd(0x0b, 0b11100000);
564     akc6955_writecmd(0x0c, 0b00000000);
565     akc6955_writecmd(0x0d, 0b00001100);
566     akc6955_writecmd(0x0e, 0x40);
567     akc6955_writecmd(0x0f, 0x82);
568     akc6955_writecmd(0x10, 0xcc);
569     akc6955_writecmd(0x11, 0xf9);
570
571
572 #else
573     akc6955_writecmd(AKC6955_POWER, 0xc0);  // You musto *not* mute, set b2 to '0".
574     akc6955_writecmd(AKC6955_VOLUME, 0xc0); // You must select to radio(b1 = '0).
575     if(fm == 0) {
576         akc6955_set_amband(amband);
577         if(amband == AKC6955_BAND_AMUSER) call_userband(am_userbandnum);
578         amfreq = amfreq_bank[amband];
579         akc6955_chg_fm(0, amfreq); // Set to AM
580         akc6955_set_freq(amfreq);
581     } else {
582         akc6955_set_fmband(fmband);
583         if(fmband == AKC6955_BAND_FMUSER) call_userband(fm_userbandnum);
584         fmfreq = fmfreq_bank[fmband];
585         akc6955_chg_fm(0xff, fmfreq); // Set to AM
586         akc6955_set_freq(fmfreq);
587     }// Dummy, TBS (954KHz)
588     akc6955_set_power(0xff); // Power ON
589     akc6955_setvolume(36); // Temporally
590     set_thresh_fmcnr(threshold_fmcnr);
591     set_thresh_amcnr(threshold_amcnr);
592     set_thresh_width(threshold_width);
593     set_thresh_fmstereo(threshold_fmstereo);
594     akc6955_setvolumemode(0);
595     akc6955_set_lowboost(lowboost);
596     set_stereomode();
597 #endif
598 }
599
600 void menu_save(void)
601 {
602     unsigned char c;
603     c = printhelp_2lines("Save settings", "A=Yes");
604     if(c == charcode_a) {
605         save_eeprom();
606     }
607 }
608
609 void menu_load(void)
610 {
611     unsigned char c;
612     c = printhelp_2lines("Load settings", "A=Yes B=Init");
613     if(c == charcode_a) {
614         c = load_eeprom();
615         if( c != 0xff) {
616             _CLS();
617             _LOCATE(0,0);
618             c = printhelp_2lines("X) Load Error", "A=Fix");
619             setdefault();
620             if(c == charcode_a){
621                 save_eeprom();
622             }
623         }
624         setup_akc6955();
625     } else if(c == charcode_b){
626         setdefault();
627         setup_akc6955();
628     }
629 }
630
631 void setup_help(void)
632 {
633     unsigned char c;
634     char l;
635     l = 0;
636     do {
637         c = printhelp_2lines(setup_helpstr[l], setup_helpstr[l + 1]);
638         if(c == charcode_f) return;
639         l += 2;
640         if(l >= 16) {
641             c = numeric_help();
642             if(c == charcode_f) return;
643             l = 0;
644         }
645     } while(1);
646     
647 }
648 void setup_menu(void)
649 {
650     unsigned char c;
651     unsigned int val;
652
653     c = printhelp_2lines("Setup F=HELP", "5=Return");
654     switch(c){
655         case charcode_f:
656             setup_help();
657             break;
658         case charcode_5:
659             break;
660         case charcode_0:
661             menu_poweroff();
662             break;
663         case charcode_c:
664             menu_save();
665             break;
666         case charcode_a:
667             menu_load();
668             break;
669         case charcode_d:
670             setdefault();
671             break;
672         case charcode_e:
673             break;
674         case charcode_4:
675             _CLS();
676             _LOCATE(0,0);
677             printstr("FM Bandwidth:");
678             akc6955_get_fmbandwidth(val);
679             val = read_numeric(val, 1, 0, 1) & 3;
680             fmbandwidth = (unsigned char)val;
681             akc6955_set_fmbandwidth(fmbandwidth);
682             break;
683         case charcode_1:
684             _CLS();
685             _LOCATE(0,0);
686             printstr("FM-CNR threshold:");
687             val = threshold_fmcnr;
688             val = read_numeric(val, 1, 0, 1);
689             set_thresh_fmcnr((unsigned char)val);
690             break;
691         case charcode_2:
692             _CLS();
693             _LOCATE(0,0);
694             printstr("AM-CNR threshold:");
695             val = threshold_amcnr;
696             val = read_numeric(val, 1, 0, 1);
697             set_thresh_amcnr((unsigned char)val);
698             break;
699         case charcode_3:
700             _CLS();
701             _LOCATE(0,0);
702             printstr("Stereo threshold:");
703             val = threshold_fmstereo;
704             val = read_numeric(val, 1, 0, 1);
705             set_thresh_fmstereo((unsigned char)val);
706             break;
707     }
708 }
709 /*
710  * Main Menu : initial-screen -> 'F'.
711  */
712 void main_menu(void)
713 {
714     unsigned char c;
715     unsigned char p;
716     unsigned char n;
717     unsigned int val;
718
719     _CLS();
720     _HOME();
721     _LOCATE(0,0);
722     printstr("Menu:F=HELP");
723     _LOCATE(0,1);
724     printstr("B=CANCEL");
725        do {
726            n = pollkeys(pollkeybuf, 60, 1);
727        } while(n == 0);
728        p = 0;
729        c = pollkeybuf[0];
730         if(c == charcode_f){
731             mainmenu_help();
732             // HELP
733         } else if(c == charcode_b){
734             // Cancel
735         } else if(c == charcode_1){
736             
737         } else if(c == charcode_2){
738             // Band
739             setband_direct();
740         } else if(c == charcode_3){
741             // Band
742             setfreq_direct();
743         } else if(c == charcode_a){
744             menu_poweroff();
745         } else if(c == charcode_5){
746             scan_start();
747             // Scan
748         } else if(c == charcode_6){
749             
750         } else if(c == charcode_4){
751
752         } else if(c == charcode_7){
753             // Set volume
754             set_volume();
755         } else if(c == charcode_8){
756             // Reserve
757         } else if(c == charcode_9){
758             _CLS();
759             _LOCATE(0,0);
760             printstr("Sig width:");
761             val = threshold_width;
762             val = read_numeric(val, 1, 0, 1);
763             set_thresh_width((unsigned char)val);
764             // Set NF
765         } else if(c == charcode_0){
766             // Setup Menu
767             setup_menu();
768         } else if(c == charcode_d){
769             // Call userband
770             input_userband();
771         } else if(c == charcode_c){
772             // Set userband
773             set_userband();
774         } else if(c == charcode_e){
775             toggle_amfm();
776         }
777        _CLS();
778        _LOCATE(0,0);
779 }
780