OSDN Git Service

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