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"
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
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
73 //#define _LCD_DEBUG 1
75 SIGHANDLER(TMR0_handler)
88 // Clear interrupt flag
90 tmr0f &= ~(_TMR0IF | _TMR0IE);
97 DEF_INTLOW(intlow_handler)
98 DEF_HANDLER(SIG_TMR0, TMR0_handler)
104 unsigned char amband;
105 unsigned char fmband;
107 unsigned char am_mode3k;
108 unsigned char am_userbandnum;
109 unsigned char fm_userbandnum;
111 unsigned char mode3k; // mode3k if am
116 #define USER_BAND_NUM 4
117 _userband_t am_usrbands[USER_BAND_NUM];
118 _userband_t fm_usrbands[USER_BAND_NUM];
120 unsigned char enter_mode;
121 unsigned char numeric_mode;
122 unsigned char menu_node;
124 unsigned char help_flag;
128 unsigned int ui_idlecount;
129 unsigned char scanflag;
132 int backlight_counter;
133 unsigned char backlight_level;
135 unsigned int writeword_eeprom(unsigned int p, unsigned int *sum, unsigned int word)
137 if(eeprom_writebyte(p, word >> 8) == 0) return p; // Error
138 *sum = calcsum_byte(*sum, (word >> 8));
140 if(eeprom_writebyte(p, word & 0xff) == 0) return p+1; // Error
141 *sum = calcsum_byte(*sum, word & 0xff);
145 unsigned int writebyte_eeprom(unsigned int p, unsigned int *sum, unsigned char b)
147 if(eeprom_writebyte(p, b) == 0) return p; // Error
148 *sum = calcsum_byte(*sum, b);
152 void save_eeprom(void)
155 unsigned int sum = 0x0000;
159 writeword_eeprom(p, &sum, 0x1298);
162 writeword_eeprom(p, &sum, amfreq);
165 writeword_eeprom(p, &sum, fmfreq);
168 writebyte_eeprom(p, &sum, amband);
170 writebyte_eeprom(p, &sum, fmband);
172 writebyte_eeprom(p, &sum, fm);
174 writebyte_eeprom(p, &sum, am_mode3k);
176 writebyte_eeprom(p, &sum, am_userbandnum);
178 writebyte_eeprom(p, &sum, fm_userbandnum);
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);
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);
196 eeprom_writebyte(p, sum >> 8);
197 eeprom_writebyte(p + 1, sum & 0xff);
201 unsigned int readword_eeprom(unsigned int p, unsigned int *sum)
206 h = eeprom_readbyte(p);
207 *sum = calcsum_byte(*sum, h);
209 l = eeprom_readbyte(p + 1);
210 *sum = calcsum_byte(*sum, l);
216 unsigned char readbyte_eeprom(unsigned int p, unsigned int *sum)
220 b = eeprom_readbyte(p);
221 *sum = calcsum_byte(*sum, b);
227 unsigned char load_eeprom(void)
230 unsigned int sum = 0x0000;
235 magic = readword_eeprom(p, &sum);
236 if(magic != 0x1298) return 0x01; // NO MAGICWORD
239 amfreq = readword_eeprom(p, &sum);
242 fmfreq = readword_eeprom(p, &sum);
245 amband = readbyte_eeprom(p, &sum);
247 fmband = readbyte_eeprom(p, &sum);
249 fm = readbyte_eeprom(p, &sum);
251 am_mode3k = readbyte_eeprom(p, &sum);
253 am_userbandnum = readbyte_eeprom(p, &sum);
255 fm_userbandnum = readbyte_eeprom(p, &sum);
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);
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);
273 magic = (eeprom_readbyte(p) << 8) + eeprom_readbyte(p+1);
276 if(sum != magic) return 0x00;
281 void toggle_amfm(void)
287 akc6955_set_amband(amband);
288 akc6955_set_freq(amfreq);
294 akc6955_set_fmband(fmband);
295 akc6955_set_freq(fmfreq);
300 static void update_status(void)
303 recv_signal = akc6955_read_level();
305 fmfreq = akc6955_get_freq();
307 amfreq = akc6955_get_freq();
314 void set_volume(void)
318 void update_display(void)
322 if(fmband < AKC6955_BAND_TV1) {
324 _PUTCHAR('1' + (fmband & 7));
325 } else if(fmband < AKC6955_BAND_FMUSER){
327 _PUTCHAR('1' + fmband - AKC6955_BAND_TV1);
333 if(amband == AKC6955_BAND_LW) {
335 } else if(amband <AKC6955_BAND_SW1) { //MW
337 _PUTCHAR('1' + amband - AKC6955_BAND_MW1);
338 } else if(amband < AKC6955_BAND_AMUSER) { //MW
340 _PUTCHAR('1' + amband - AKC6955_BAND_SW1);
341 } else if(amband == AKC6955_BAND_MW4){
355 int freq_lo = fmfreq % 100;
356 int freq_hi = fmfreq / 100;
357 print_numeric(freq_hi, 0xff);
359 print_numeric(freq_lo, 0xff);
361 print_numeric(amfreq, 0xff);
366 print_numeric(recv_signal, 0xff);
371 unsigned char input_flag;
378 printstr("Scan A=ABORT");
380 printstr("U=6, D=4");
382 input_flag = readkey_compare();
384 } while(input_flag == 0);
387 akc6955_do_scan(0xff);
388 } else if(c == charcode_4){
396 input_flag = readkey_compare();
398 } while(input_flag == 0);
402 akc6955_abort_scan();
404 } else if(c == charcode_4){
405 akc6955_abort_scan();
408 } else if(c == charcode_6){
409 akc6955_abort_scan();
410 akc6955_do_scan(0xff);
413 if(akc6955_chk_donescan() != 0) break;
423 void setfreq_direct(void)
430 printstr("Set Freq:FM");
432 val = read_numeric(val, 5, 7, 1);
434 akc6955_set_freq(val);
438 printstr("Set Freq:AM");
440 val = read_numeric(val, 5, 7, 1);
442 akc6955_set_freq(val);
449 void setband_direct(void)
455 printstr("Set Band:FM");
457 band = read_numeric(band, 2, 7, 1);
458 akc6955_set_fmband(band);
462 printstr("Set Band:AM");
463 band = amband & 0x1f;
464 band = read_numeric(band, 2, 7, 1);
465 akc6955_set_amband(band);
473 void call_userband(unsigned char num)
477 if(num >= USER_BAND_NUM) return;
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);
485 if(am_usrbands[num].mode3k != 0) p = 3;
486 freq = am_usrbands[num].freq;
488 akc6955_set_userband(am_usrbands[num].start, am_usrbands[num].stop, ch,
489 am_usrbands[num].mode3k);
492 fmband = AKC6955_BAND_AMUSER;
494 amband = AKC6955_BAND_AMUSER;
501 void set_userband(void)
503 unsigned int from,to;
506 unsigned char mode3k;
507 unsigned int input_flag;
512 printstr("User ch:");
514 input_flag = readkey_compare();
516 } while(input_flag == 0);
519 if(c > charcode_0) return;
520 if(c < charcode_1) return;
521 if(c == charcode_0) {
524 c = c - charcode_1 + 1;
526 if(c >= USER_BAND_NUM) return;
528 from = fm_usrbands[c].start * 80 + 3000; // 32*25/10
529 to = fm_usrbands[c].stop * 80 + 3000;
533 print_numeric_nosupress(c, 1);
535 from = read_numeric(from, 5, 7, 1);
539 print_numeric_nosupress(c, 1);
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;
547 mode3k = am_usrbands[c].mode3k;
549 if(mode3k == 0) p = 160; // 5*32
550 from = am_usrbands[c].start * p;
551 to = am_usrbands[c].stop * p;
555 print_numeric_nosupress(c, 1);
558 printstr("0=3k 1=5k");
560 input_flag = readkey_compare();
562 } while(input_flag == 0);
563 cc = pop_keyinfifo();
565 if(cc == charcode_0){
568 } else if(cc = charcode_1) {
575 print_numeric_nosupress(c, 1);
577 from = read_numeric(from, 5, 7, 1);
581 print_numeric_nosupress(c, 1);
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;
593 void input_userband(void)
596 unsigned char input_flag;
600 printstr("User Band");
604 input_flag = readkey_compare();
606 } while(input_flag == 0);
609 if((c >= charcode_a) && (c <= charcode_f)){
612 if(c == charcode_0) {
621 c = c - charcode_1 + 1;
622 if(c < USER_BAND_NUM) {
641 unsigned int input_flag;
644 printstr("Menu:F=HELP");
646 printstr("A=CANCEL");
649 input_flag = readkey_compare();
651 } while(input_flag == 0);
654 if((c < charcode_1) || ( c >charcode_s3)) {
660 } else if(c == charcode_a){
663 } else if(c == charcode_1){
667 akc6955_set_amband(amband);
668 akc6955_set_freq(amfreq);
670 } else if(c == charcode_2){
674 } else if(c == charcode_3){
678 } else if(c == charcode_4){
682 akc6955_set_fmband(fmband);
683 akc6955_set_freq(fmfreq);
685 } else if(c == charcode_5){
688 } else if(c == charcode_6){
691 } else if(c == charcode_7){
694 } else if(c == charcode_8){
697 } else if(c == charcode_9){
700 } else if(c == charcode_0){
703 } else if(c == charcode_b){
707 } else if(c == charcode_c){
711 } else if(c == charcode_d){
714 } else if(c == charcode_e){
722 void setfreq_updown(unsigned char ctlword)
726 case charcode_8: // Change band
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();
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();
745 case charcode_2: // Change band
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();
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();
766 case charcode_4: // Down Freq;
768 fmfreq = akc6955_down_freq(10); // DOWN 100KHz
770 amfreq = akc6955_down_freq(10); // DOWN 10KHz
773 case charcode_6: // Down Freq;
775 fmfreq = akc6955_up_freq(10); // UP 100KHz
777 amfreq = akc6955_up_freq(10); // UP 10KHz
780 case charcode_7: // Down Fast;
782 fmfreq = akc6955_down_freq(50); // DOWN 500KHz
784 amfreq = akc6955_down_freq(50); // DOWN 50KHz
787 case charcode_9: // Down Fast;
789 fmfreq = akc6955_up_freq(50); // UP 100KHz
791 amfreq = akc6955_up_freq(50); // UP 10KHz
794 case charcode_1: // Down Slow;
796 fmfreq = akc6955_down_freq(5); // DOWN 50KHz
798 amfreq = akc6955_down_freq(5); // DOWN 50KHz
801 case charcode_3: // Down Slow;
803 fmfreq = akc6955_up_freq(5); // UP 50KHz
805 amfreq = akc6955_up_freq(5); // UP 5KHz
808 case charcode_0: // Step
815 amfreq = akc6955_mode3k(am_mode3k);
818 case charcode_a: // Toggle FM
830 case charcode_e: // Backlight ON/OFF
831 if(backlight_counter > 0) {
832 backlight_counter = 0;
834 backlight_counter = backlight_long;
848 static void setdefault(void)
852 fmfreq = 8000; // 10KHz order.
853 amband = AKC6955_BAND_MW2;
854 fmband = AKC6955_BAND_FM2;
860 for(i = 0; i < 4; i++){
861 am_usrbands[i].start = 0x19;
862 am_usrbands[i].stop = 0x32;
864 for(i = 0; i < 4; i++){
865 fm_usrbands[i].start = 0x19;
866 fm_usrbands[i].stop = 0x32;
875 unsigned char input_flag;
879 unsigned char power_flag;
881 // OSCCON = _IDLEN & 0b11111100;
889 // _AKC6955_WAIT_125_0MS(); // Wait 125ms
893 backlight_long = 256;
894 backlight_counter = backlight_long;
895 backlight_level = 255;
896 ui_idlecount = 0xf800;
898 acm1602_init(0xa0, 1); //Init LCD
899 // _AKC6955_WAIT_125_0MS(); // Wait 125ms
901 printstr("Hello;-)");
904 // LATDbits.LATD3 = 1;
912 // print_numeric_nosupress(i, 5);
914 // PORTDbits.RD3 = i & 1;
918 switch(load_eeprom()) {
919 case 0x01: // No magic-word
924 printstr("EEPROM FORMATTING");
926 printstr("Press any key");
928 input_flag = readkey_compare();
930 } while(input_flag == 0);
932 format_eeprom(0,254);
935 case 0x00: // Checksum error
939 printstr("X-) Sum Error");
941 printstr("Press any key to format");
943 input_flag = readkey_compare();
945 } while(input_flag == 0);
948 format_eeprom(0,254);
952 case 0xff: // Success
954 default: // Unknown error
960 /* Push default parameters to AKC6955*/
963 akc6955_chg_fm(fm); // Set to AM
964 akc6955_set_amband(amband);
965 akc6955_set_freq(amfreq); // Dummy, TBS (954KHz)
966 akc6955_set_power(0xff); // Power ON
978 input_flag = readkey_compare();
980 readchar = pop_keyinfifo();
981 if((readchar >= charcode_1) && (readchar <= charcode_f)) {
982 setfreq_updown(readchar);
987 // Check battery (include idle?)
988 // Read AKJC6955's status
993 if(backlight_counter > 0) {
995 set_backlight(0xff, backlight_level); // Turn ON
997 set_backlight(0x00, 0); // Turn OFF
1000 if(power_flag != 0x00) {
1005 setsignal_tune(power_flag);