OSDN Git Service

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