3 * Config & Main routine.
4 * Copyright (C) 2013-06-10 K.Ohta <whatisthis.sowhat ai gmail.com>
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.
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,
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.
34 #include <pic18fregs.h> /* ONLY FOR PIC18x */
42 #include "lcd_acm1602.h"
48 #if defined(pic18f23k22) || defined(pic18f24k22) || defined(pic18f25k22) || defined(pic18f26k22)
49 #pragma stack 0x200 256 // Set stack size to 256bytes.
50 #pragma config FOSC=INTIO67,BORV=190,BOREN=ON,PWRTEN=ON
51 #pragma config WDTEN=ON,WDTPS=32768
52 #pragma config PBADEN=OFF,MCLRE=EXTMCLR,STVREN=ON,LVP=OFF,DEBUG=ON//,XINST=ON
53 #pragma config CP0=OFF,CP1=OFF,CPB=OFF,CPD=OFF
54 #pragma config WRT0=OFF,WRT1=OFF,WRTB=OFF,WRTC=OFF,WRTD=OFF
55 #pragma config EBTR0=OFF,EBTR1=OFF,EBTRB=OFF
57 // For 4xK20 or 2xK20 Series
58 #if defined(pic18f43k20) || defined(pic18f44k20) || defined(pic18f45k20) || defined(pic18f46k20) || \
59 defined(pic18f23k20) || defined(pic18f24k20) || defined(pic18f25k20) || defined(pic18f26k20)
60 #pragma stack 0x200 256
61 #pragma config FOSC=INTIO67,FCMEN=ON,PWRT=ON,BOREN=ON,BORV=22
62 #pragma config WDTEN=ON,WDTPS=32768,PBADEN=OFF,LPT1OSC=ON,MCLRE=ON
63 #pragma config STVREN=ON,DEBUG=ON
64 #pragma config CP0=OFF,CP1=OFF,CP2=OFF,CP3=OFF
65 #pragma config CPB=OFF,CPD=OFF
66 #pragma config WRT0=OFF,WRT1=OFF,WRT2=OFF,WRT3=OFF
67 #pragma config WRTC=OFF,WRTB=OFF,WRTD=OFF
68 #pragma config EBTR0=OFF,EBTR1=OFF,EBTR2=OFF,EBTR3=OFF,EBTRB=OFF
71 //#define _LCD_DEBUG 1
73 SIGHANDLER(TMR0_handler)
86 // Clear interrupt flag
95 DEF_INTLOW(intlow_handler)
96 DEF_HANDLER(SIG_TMR0, TMR0_handler)
102 unsigned char amband;
103 unsigned char fmband;
105 unsigned char am_mode3k;
106 unsigned char am_userbandnum;
107 unsigned char fm_userbandnum;
109 unsigned char mode3k; // mode3k if am
114 #define USER_BAND_NUM 4
115 _userband_t am_usrbands[USER_BAND_NUM];
116 _userband_t fm_usrbands[USER_BAND_NUM];
118 unsigned char enter_mode;
119 unsigned char numeric_mode;
120 unsigned char menu_node;
122 unsigned char help_flag;
126 unsigned int ui_idlecount;
129 int backlight_counter;
130 unsigned char backlight_level;
134 void toggle_amfm(void)
140 akc6955_set_amband(amband);
141 akc6955_set_freq(amfreq);
147 akc6955_set_fmband(fmband);
148 akc6955_set_freq(fmfreq);
153 void update_display(void)
157 if(fmband < AKC6955_BAND_TV1) {
159 _PUTCHAR('1' + (fmband & 7));
160 } else if(fmband < AKC6955_BAND_FMUSER){
162 _PUTCHAR('1' + fmband - AKC6955_BAND_TV1);
168 if(amband == AKC6955_BAND_LW) {
170 } else if(amband <AKC6955_BAND_SW1) { //MW
172 _PUTCHAR('1' + amband - AKC6955_BAND_MW1);
173 } else if(amband < AKC6955_BAND_AMUSER) { //MW
175 _PUTCHAR('1' + amband - AKC6955_BAND_SW1);
176 } else if(amband == AKC6955_BAND_MW4){
190 int freq_lo = fmfreq % 100;
191 int freq_hi = fmfreq / 100;
192 print_numeric(freq_hi, 0xff);
194 print_numeric(freq_lo, 0xff);
196 print_numeric(amfreq, 0xff);
201 print_numeric(recv_signal, 0xff);
205 void setfreq_direct(void)
212 printstr("Set Freq:FM");
214 val = read_numeric(val, 5, 7, 1);
216 akc6955_set_freq(val);
218 fmfreq = akc6955_get_freq();
222 printstr("Set Freq:AM");
224 val = read_numeric(val, 5, 7, 1);
226 akc6955_set_freq(val);
228 amfreq = akc6955_get_freq();
232 void setband_direct(void)
238 printstr("Set Band:FM");
240 band = read_numeric(band, 2, 7, 1);
241 akc6955_set_fmband(band);
244 fmfreq = akc6955_get_freq();
246 printstr("Set Band:AM");
247 band = amband & 0x1f;
248 band = read_numeric(band, 2, 7, 1);
249 akc6955_set_amband(band);
252 amfreq = akc6955_get_freq();
256 void call_userband(unsigned char num)
260 if(num >= USER_BAND_NUM) return;
262 freq = fm_usrbands[num].freq;
263 ch = ((freq - 3000) / 25) * 10;
264 akc6955_set_userband(fm_usrbands[num].start, fm_usrbands[num].stop, ch,
265 fm_usrbands[num].mode3k);
268 if(am_usrbands[num].mode3k != 0) p = 3;
269 freq = am_usrbands[num].freq;
271 akc6955_set_userband(am_usrbands[num].start, am_usrbands[num].stop, ch,
272 am_usrbands[num].mode3k);
276 void set_userband(void)
278 unsigned int from,to;
281 unsigned char mode3k;
282 unsigned int input_flag;
287 printstr("User ch:");
289 input_flag = readkey_compare();
291 } while(input_flag == 0);
294 if(c > charcode_0) return;
295 if(c < charcode_1) return;
296 if(c == charcode_0) {
299 c = c - charcode_1 + 1;
301 if(c >= USER_BAND_NUM) return;
303 from = fm_usrbands[c].start * 80 + 3000; // 32*25/10
304 to = fm_usrbands[c].stop * 80 + 3000;
308 print_numeric_nosupress(c, 1);
310 from = read_numeric(from, 5, 7, 1);
314 print_numeric_nosupress(c, 1);
316 to = read_numeric(to, 5, 7, 1);
317 fm_usrbands[c].start = (from - 3000) / 80;
318 fm_usrbands[c].stop = (to - 3000) / 80;
319 fm_usrbands[c].freq = from * 80 + 3000;
322 mode3k = am_usrbands[c].mode3k;
324 if(mode3k == 0) p = 160; // 5*32
325 from = am_usrbands[c].start * p;
326 to = am_usrbands[c].stop * p;
330 print_numeric_nosupress(c, 1);
333 printstr("0=3k 1=5k");
335 input_flag = readkey_compare();
337 } while(input_flag == 0);
338 cc = pop_keyinfifo();
340 if(cc == charcode_0){
343 } else if(cc = charcode_1) {
350 print_numeric_nosupress(c, 1);
352 from = read_numeric(from, 5, 7, 1);
356 print_numeric_nosupress(c, 1);
358 to = read_numeric(to, 5, 7, 1);
359 am_usrbands[c].start = from / p;
360 am_usrbands[c].stop = to / p;
361 am_usrbands[c].mode3k = mode3k;
362 am_usrbands[c].freq = from * p;
368 void input_userband(void)
371 unsigned char input_flag;
375 printstr("User Band");
379 input_flag = readkey_compare();
381 } while(input_flag == 0);
384 if((c >= charcode_a) && (c <= charcode_f)){
387 if(c == charcode_0) {
396 c = c - charcode_1 + 1;
397 if(c < USER_BAND_NUM) {
416 unsigned int input_flag;
419 printstr("Menu:F=HELP");
421 printstr("A=CANCEL");
424 input_flag = readkey_compare();
426 } while(input_flag == 0);
429 if((c < charcode_1) || ( c >charcode_s3)) {
435 } else if(c == charcode_a){
438 } else if(c == charcode_1){
442 akc6955_set_amband(amband);
443 akc6955_set_freq(amfreq);
445 } else if(c == charcode_2){
449 } else if(c == charcode_3){
453 } else if(c == charcode_4){
457 akc6955_set_fmband(fmband);
458 akc6955_set_freq(fmfreq);
460 } else if(c == charcode_5){
463 } else if(c == charcode_6){
466 } else if(c == charcode_7){
469 } else if(c == charcode_8){
472 } else if(c == charcode_9){
475 } else if(c == charcode_0){
478 } else if(c == charcode_b){
482 } else if(c == charcode_c){
486 } else if(c == charcode_d){
489 } else if(c == charcode_e){
497 void setfreq_updown(unsigned char ctlword)
502 case charcode_8: // Change band
505 if(amband > 18) amband = 0;
506 // amfreq = akc6955_setfreq(amfreq)
507 akc6955_set_amband(amband);
508 _AKC6955_WAIT_62_5MS(); // 62.5ms
509 amband = akc6955_get_amband();
510 amfreq = akc6955_get_freq();
513 if(fmband > 7) fmband = 0;
514 // amfreq = akc6955_setfreq(amfreq)
515 akc6955_set_fmband(fmband);
516 _AKC6955_WAIT_62_5MS(); // 62.5ms
517 fmband = akc6955_get_fmband();
518 fmfreq = akc6955_get_freq();
521 case charcode_2: // Change band
524 if(amband == 0) amband = 18;
525 if(amband >= 18) amband = 18;
526 // amfreq = akc6955_setfreq(amfreq)
527 akc6955_set_amband(amband);
528 _AKC6955_WAIT_62_5MS(); // 62.5ms
529 amband = akc6955_get_amband();
530 amfreq = akc6955_get_freq();
533 if(fmband == 0) fmband = 7;
534 if(fmband >= 7) fmband = 7;
535 // amfreq = akc6955_setfreq(amfreq)
536 akc6955_set_fmband(fmband);
537 _AKC6955_WAIT_62_5MS(); // 62.5ms
538 fmband = akc6955_get_fmband();
539 fmfreq = akc6955_get_freq();
542 case charcode_4: // Down Freq;
544 fmfreq = akc6955_down_freq(10); // DOWN 100KHz
546 amfreq = akc6955_down_freq(10); // DOWN 10KHz
549 case charcode_6: // Down Freq;
551 fmfreq = akc6955_up_freq(10); // UP 100KHz
553 amfreq = akc6955_up_freq(10); // UP 10KHz
556 case charcode_7: // Down Fast;
558 fmfreq = akc6955_down_freq(50); // DOWN 500KHz
560 amfreq = akc6955_down_freq(50); // DOWN 50KHz
563 case charcode_9: // Down Fast;
565 fmfreq = akc6955_up_freq(50); // UP 100KHz
567 amfreq = akc6955_up_freq(50); // UP 10KHz
570 case charcode_1: // Down Slow;
572 fmfreq = akc6955_down_freq(5); // DOWN 50KHz
574 amfreq = akc6955_down_freq(5); // DOWN 50KHz
577 case charcode_3: // Down Slow;
579 fmfreq = akc6955_up_freq(5); // UP 50KHz
581 amfreq = akc6955_up_freq(5); // UP 5KHz
584 case charcode_0: // Step
591 amfreq = akc6955_mode3k(am_mode3k);
594 case charcode_a: // Toggle FM
605 case charcode_e: // Backlight ON
606 backlight_counter = backlight_long;
622 unsigned char input_flag;
625 unsigned char power_flag;
633 _AKC6955_WAIT_125_0MS(); // Wait 125ms
637 backlight_long = 256;
638 backlight_counter = backlight_long;
639 backlight_level = 255;
640 ui_idlecount = 0xf800;
642 acm1602_init(0xa0, 1); //Init LCD
643 // _AKC6955_WAIT_125_0MS(); // Wait 125ms
645 printstr("Hello;-)");
650 fmfreq = 8000; // 10KHz order.
651 amband = AKC6955_BAND_MW2;
652 fmband = AKC6955_BAND_FM2;
658 for(i = 0; i < 4; i++){
659 am_usrbands[i].start = 0x19;
660 am_usrbands[i].stop = 0x32;
662 for(i = 0; i < 4; i++){
663 fm_usrbands[i].start = 0x19;
664 fm_usrbands[i].stop = 0x32;
668 /* Push default parameters to AKC6955*/
671 akc6955_chg_fm(fm); // Set to AM
672 akc6955_set_amband(amband);
673 akc6955_set_freq(amfreq); // Dummy, TBS (954KHz)
674 akc6955_set_power(0xff); // Power ON
684 input_flag = readkey_compare();
686 readchar = pop_keyinfifo();
687 if((readchar >= charcode_1) && (readchar <= charcode_f)) {
688 setfreq_updown(readchar);
694 recv_signal = akc6955_read_level();
696 fmfreq = akc6955_get_freq();
698 amfreq = akc6955_get_freq();
701 // Check battery (include idle?)
702 // Read AKJC6955's status
706 if(backlight_counter > 0) {
708 set_backlight(0xff, backlight_level); // Turn ON
710 set_backlight(0x00, 0); // Turn OFF
713 if(power_flag != 0x00) {
718 setsignal_tune(power_flag);