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)
63 #pragma stack 0x200 256
64 #pragma config FOSC=HS,FCMEN=ON,PWRT=ON,BOREN=ON,BORV=22
65 #pragma config WDTEN=ON,WDTPS=32768,PBADEN=OFF,HFOFST=ON,LPT1OSC=OFF,MCLRE=ON
66 #pragma config STVREN=ON,DEBUG=ON
67 #pragma config CP0=OFF,CP1=OFF,CP2=OFF,CP3=OFF
68 #pragma config CPB=OFF,CPD=OFF
69 #pragma config WRT0=OFF,WRT1=OFF,WRT2=OFF,WRT3=OFF
70 #pragma config WRTC=OFF,WRTB=OFF,WRTD=OFF
71 #pragma config EBTR0=OFF,EBTR1=OFF,EBTR2=OFF,EBTR3=OFF,EBTRB=OFF
74 //#define _LCD_DEBUG 1
76 SIGHANDLER(TMR0_handler)
89 // Clear interrupt flag
91 tmr0f &= ~(_TMR0IF | _TMR0IE);
98 DEF_INTLOW(intlow_handler)
99 DEF_HANDLER(SIG_TMR0, TMR0_handler)
105 unsigned char amband;
106 unsigned char fmband;
108 unsigned char am_mode3k;
109 unsigned char am_userbandnum;
110 unsigned char fm_userbandnum;
112 unsigned char mode3k; // mode3k if am
117 #define USER_BAND_NUM 4
118 _userband_t am_usrbands[USER_BAND_NUM];
119 _userband_t fm_usrbands[USER_BAND_NUM];
121 unsigned char enter_mode;
122 unsigned char numeric_mode;
123 unsigned char menu_node;
125 unsigned char help_flag;
129 unsigned int ui_idlecount;
130 unsigned char scanflag;
133 int backlight_counter;
134 unsigned char backlight_level;
136 unsigned int writeword_eeprom(unsigned int p, unsigned int *sum, unsigned int word)
138 if(eeprom_writebyte(p, word >> 8) == 0) return p; // Error
139 *sum = calcsum_byte(*sum, (word >> 8));
141 if(eeprom_writebyte(p, word & 0xff) == 0) return p+1; // Error
142 *sum = calcsum_byte(*sum, word & 0xff);
146 unsigned int writebyte_eeprom(unsigned int p, unsigned int *sum, unsigned char b)
148 if(eeprom_writebyte(p, b) == 0) return p; // Error
149 *sum = calcsum_byte(*sum, b);
153 void save_eeprom(void)
156 unsigned int sum = 0x0000;
160 writeword_eeprom(p, &sum, 0x1298);
163 writeword_eeprom(p, &sum, amfreq);
166 writeword_eeprom(p, &sum, fmfreq);
169 writebyte_eeprom(p, &sum, amband);
171 writebyte_eeprom(p, &sum, fmband);
173 writebyte_eeprom(p, &sum, fm);
175 writebyte_eeprom(p, &sum, am_mode3k);
177 writebyte_eeprom(p, &sum, am_userbandnum);
179 writebyte_eeprom(p, &sum, fm_userbandnum);
182 for(i = 0 ; i < USER_BAND_NUM; i++){
183 writebyte_eeprom(p, &sum, am_usrbands[i].mode3k);
184 writebyte_eeprom(p + 1, &sum, am_usrbands[i].start);
185 writebyte_eeprom(p + 2, &sum, am_usrbands[i].stop);
186 writeword_eeprom(p + 3, &sum, am_usrbands[i].freq);
189 for(i = 0 ; i < USER_BAND_NUM; i++){
190 writebyte_eeprom(p, &sum, fm_usrbands[i].mode3k);
191 writebyte_eeprom(p + 1, &sum, fm_usrbands[i].start);
192 writebyte_eeprom(p + 2, &sum, fm_usrbands[i].stop);
193 writeword_eeprom(p + 3, &sum, fm_usrbands[i].freq);
197 eeprom_writebyte(p, sum >> 8);
198 eeprom_writebyte(p + 1, sum & 0xff);
202 unsigned int readword_eeprom(unsigned int p, unsigned int *sum)
207 h = eeprom_readbyte(p);
208 *sum = calcsum_byte(*sum, h);
210 l = eeprom_readbyte(p + 1);
211 *sum = calcsum_byte(*sum, l);
217 unsigned char readbyte_eeprom(unsigned int p, unsigned int *sum)
221 b = eeprom_readbyte(p);
222 *sum = calcsum_byte(*sum, b);
228 unsigned char load_eeprom(void)
231 unsigned int sum = 0x0000;
236 magic = readword_eeprom(p, &sum);
237 if(magic != 0x1298) return 0x01; // NO MAGICWORD
240 amfreq = readword_eeprom(p, &sum);
243 fmfreq = readword_eeprom(p, &sum);
246 amband = readbyte_eeprom(p, &sum);
248 fmband = readbyte_eeprom(p, &sum);
250 fm = readbyte_eeprom(p, &sum);
252 am_mode3k = readbyte_eeprom(p, &sum);
254 am_userbandnum = readbyte_eeprom(p, &sum);
256 fm_userbandnum = readbyte_eeprom(p, &sum);
259 for(i = 0 ; i < USER_BAND_NUM; i++){
260 am_usrbands[i].mode3k = readbyte_eeprom(p, &sum);
261 am_usrbands[i].start = readbyte_eeprom(p + 1, &sum);
262 am_usrbands[i].stop = readbyte_eeprom(p + 2, &sum);
263 am_usrbands[i].freq = readword_eeprom(p + 3, &sum);
266 for(i = 0 ; i < USER_BAND_NUM; i++){
267 fm_usrbands[i].mode3k = readbyte_eeprom(p, &sum);
268 fm_usrbands[i].start = readbyte_eeprom(p + 1, &sum);
269 fm_usrbands[i].stop = readbyte_eeprom(p + 2, &sum);
270 fm_usrbands[i].freq = readword_eeprom(p + 3, &sum);
274 magic = (eeprom_readbyte(p) << 8) + eeprom_readbyte(p+1);
277 if(sum != magic) return 0x00;
282 void toggle_amfm(void)
288 akc6955_set_amband(amband);
289 akc6955_set_freq(amfreq);
295 akc6955_set_fmband(fmband);
296 akc6955_set_freq(fmfreq);
301 static void update_status(void)
304 recv_signal = akc6955_read_level();
306 fmfreq = akc6955_get_freq();
308 amfreq = akc6955_get_freq();
315 void set_volume(void)
319 void update_display(void)
323 if(fmband < AKC6955_BAND_TV1) {
325 _PUTCHAR('1' + (fmband & 7));
326 } else if(fmband < AKC6955_BAND_FMUSER){
328 _PUTCHAR('1' + fmband - AKC6955_BAND_TV1);
334 if(amband == AKC6955_BAND_LW) {
336 } else if(amband <AKC6955_BAND_SW1) { //MW
338 _PUTCHAR('1' + amband - AKC6955_BAND_MW1);
339 } else if(amband < AKC6955_BAND_AMUSER) { //MW
341 _PUTCHAR('1' + amband - AKC6955_BAND_SW1);
342 } else if(amband == AKC6955_BAND_MW4){
356 int freq_lo = fmfreq % 100;
357 int freq_hi = fmfreq / 100;
358 print_numeric(freq_hi, 0xff);
360 print_numeric(freq_lo, 0xff);
362 print_numeric(amfreq, 0xff);
367 print_numeric(recv_signal, 0xff);
372 unsigned char input_flag;
379 printstr("Scan A=ABORT");
381 printstr("U=6, D=4");
383 input_flag = readkey_compare();
385 } while(input_flag == 0);
388 akc6955_do_scan(0xff);
389 } else if(c == charcode_4){
397 input_flag = readkey_compare();
399 } while(input_flag == 0);
403 akc6955_abort_scan();
405 } else if(c == charcode_4){
406 akc6955_abort_scan();
409 } else if(c == charcode_6){
410 akc6955_abort_scan();
411 akc6955_do_scan(0xff);
414 if(akc6955_chk_donescan() != 0) break;
424 void setfreq_direct(void)
431 printstr("Set Freq:FM");
433 val = read_numeric(val, 5, 7, 1);
435 akc6955_set_freq(val);
439 printstr("Set Freq:AM");
441 val = read_numeric(val, 5, 7, 1);
443 akc6955_set_freq(val);
450 void setband_direct(void)
456 printstr("Set Band:FM");
458 band = read_numeric(band, 2, 7, 1);
459 akc6955_set_fmband(band);
463 printstr("Set Band:AM");
464 band = amband & 0x1f;
465 band = read_numeric(band, 2, 7, 1);
466 akc6955_set_amband(band);
474 void call_userband(unsigned char num)
478 if(num >= USER_BAND_NUM) return;
480 freq = fm_usrbands[num].freq;
481 ch = ((freq - 3000) / 25) * 10;
482 akc6955_set_userband(fm_usrbands[num].start, fm_usrbands[num].stop, ch,
483 fm_usrbands[num].mode3k);
486 if(am_usrbands[num].mode3k != 0) p = 3;
487 freq = am_usrbands[num].freq;
489 akc6955_set_userband(am_usrbands[num].start, am_usrbands[num].stop, ch,
490 am_usrbands[num].mode3k);
493 fmband = AKC6955_BAND_AMUSER;
495 amband = AKC6955_BAND_AMUSER;
502 void set_userband(void)
504 unsigned int from,to;
507 unsigned char mode3k;
508 unsigned int input_flag;
513 printstr("User ch:");
515 input_flag = readkey_compare();
517 } while(input_flag == 0);
520 if(c > charcode_0) return;
521 if(c < charcode_1) return;
522 if(c == charcode_0) {
525 c = c - charcode_1 + 1;
527 if(c >= USER_BAND_NUM) return;
529 from = fm_usrbands[c].start * 80 + 3000; // 32*25/10
530 to = fm_usrbands[c].stop * 80 + 3000;
534 print_numeric_nosupress(c, 1);
536 from = read_numeric(from, 5, 7, 1);
540 print_numeric_nosupress(c, 1);
542 to = read_numeric(to, 5, 7, 1);
543 fm_usrbands[c].start = (from - 3000) / 80;
544 fm_usrbands[c].stop = (to - 3000) / 80;
545 fm_usrbands[c].freq = from * 80 + 3000;
548 mode3k = am_usrbands[c].mode3k;
550 if(mode3k == 0) p = 160; // 5*32
551 from = am_usrbands[c].start * p;
552 to = am_usrbands[c].stop * p;
556 print_numeric_nosupress(c, 1);
559 printstr("0=3k 1=5k");
561 input_flag = readkey_compare();
563 } while(input_flag == 0);
564 cc = pop_keyinfifo();
566 if(cc == charcode_0){
569 } else if(cc = charcode_1) {
576 print_numeric_nosupress(c, 1);
578 from = read_numeric(from, 5, 7, 1);
582 print_numeric_nosupress(c, 1);
584 to = read_numeric(to, 5, 7, 1);
585 am_usrbands[c].start = from / p;
586 am_usrbands[c].stop = to / p;
587 am_usrbands[c].mode3k = mode3k;
588 am_usrbands[c].freq = from * p;
594 void input_userband(void)
597 unsigned char input_flag;
601 printstr("User Band");
605 input_flag = readkey_compare();
607 } while(input_flag == 0);
610 if((c >= charcode_a) && (c <= charcode_f)){
613 if(c == charcode_0) {
622 c = c - charcode_1 + 1;
623 if(c < USER_BAND_NUM) {
642 unsigned int input_flag;
645 printstr("Menu:F=HELP");
647 printstr("A=CANCEL");
650 input_flag = readkey_compare();
652 } while(input_flag == 0);
655 if((c < charcode_1) || ( c >charcode_s3)) {
661 } else if(c == charcode_a){
664 } else if(c == charcode_1){
668 akc6955_set_amband(amband);
669 akc6955_set_freq(amfreq);
671 } else if(c == charcode_2){
675 } else if(c == charcode_3){
679 } else if(c == charcode_4){
683 akc6955_set_fmband(fmband);
684 akc6955_set_freq(fmfreq);
686 } else if(c == charcode_5){
689 } else if(c == charcode_6){
692 } else if(c == charcode_7){
695 } else if(c == charcode_8){
698 } else if(c == charcode_9){
701 } else if(c == charcode_0){
704 } else if(c == charcode_b){
708 } else if(c == charcode_c){
712 } else if(c == charcode_d){
715 } else if(c == charcode_e){
723 void setfreq_updown(unsigned char ctlword)
727 case charcode_8: // Change band
730 if(amband > 18) amband = 0;
731 // amfreq = akc6955_setfreq(amfreq)
732 akc6955_set_amband(amband);
733 _AKC6955_WAIT_62_5MS(); // 62.5ms
734 amband = akc6955_get_amband();
735 amfreq = akc6955_get_freq();
738 if(fmband > 7) fmband = 0;
739 // amfreq = akc6955_setfreq(amfreq)
740 akc6955_set_fmband(fmband);
741 _AKC6955_WAIT_62_5MS(); // 62.5ms
742 fmband = akc6955_get_fmband();
743 fmfreq = akc6955_get_freq();
746 case charcode_2: // Change band
749 if(amband == 0) amband = 18;
750 if(amband >= 18) amband = 18;
751 // amfreq = akc6955_setfreq(amfreq)
752 akc6955_set_amband(amband);
753 _AKC6955_WAIT_62_5MS(); // 62.5ms
754 amband = akc6955_get_amband();
755 amfreq = akc6955_get_freq();
758 if(fmband == 0) fmband = 7;
759 if(fmband >= 7) fmband = 7;
760 // amfreq = akc6955_setfreq(amfreq)
761 akc6955_set_fmband(fmband);
762 _AKC6955_WAIT_62_5MS(); // 62.5ms
763 fmband = akc6955_get_fmband();
764 fmfreq = akc6955_get_freq();
767 case charcode_4: // Down Freq;
769 fmfreq = akc6955_down_freq(10); // DOWN 100KHz
771 amfreq = akc6955_down_freq(10); // DOWN 10KHz
774 case charcode_6: // Down Freq;
776 fmfreq = akc6955_up_freq(10); // UP 100KHz
778 amfreq = akc6955_up_freq(10); // UP 10KHz
781 case charcode_7: // Down Fast;
783 fmfreq = akc6955_down_freq(50); // DOWN 500KHz
785 amfreq = akc6955_down_freq(50); // DOWN 50KHz
788 case charcode_9: // Down Fast;
790 fmfreq = akc6955_up_freq(50); // UP 100KHz
792 amfreq = akc6955_up_freq(50); // UP 10KHz
795 case charcode_1: // Down Slow;
797 fmfreq = akc6955_down_freq(5); // DOWN 50KHz
799 amfreq = akc6955_down_freq(5); // DOWN 50KHz
802 case charcode_3: // Down Slow;
804 fmfreq = akc6955_up_freq(5); // UP 50KHz
806 amfreq = akc6955_up_freq(5); // UP 5KHz
809 case charcode_0: // Step
816 amfreq = akc6955_mode3k(am_mode3k);
819 case charcode_a: // Toggle FM
831 case charcode_e: // Backlight ON/OFF
832 if(backlight_counter > 0) {
833 backlight_counter = 0;
835 backlight_counter = backlight_long;
849 static void setdefault(void)
853 fmfreq = 8000; // 10KHz order.
854 amband = AKC6955_BAND_MW2;
855 fmband = AKC6955_BAND_FM2;
861 for(i = 0; i < 4; i++){
862 am_usrbands[i].start = 0x19;
863 am_usrbands[i].stop = 0x32;
865 for(i = 0; i < 4; i++){
866 fm_usrbands[i].start = 0x19;
867 fm_usrbands[i].stop = 0x32;
876 unsigned char input_flag;
880 unsigned char power_flag;
882 // OSCCON = _IDLEN & 0b11111100;
890 _AKC6955_WAIT_125_0MS(); // Wait 125ms
894 backlight_long = 256;
895 backlight_counter = backlight_long;
896 backlight_level = 255;
897 ui_idlecount = 0xf800;
899 acm1602_init(0xa0, 1); //Init LCD
900 _AKC6955_WAIT_125_0MS(); // Wait 125ms
904 printstr("Hello;-)");
905 acm1602_setbacklight(0xff);
906 // PORTD |= _LCDPORT_CONT_RS;
913 print_numeric_nosupress(i, 5);
914 // print_numeric(i, 1);
915 // PORTDbits.RD3 = i & 1;
919 switch(load_eeprom()) {
920 case 0x01: // No magic-word
925 printstr("EEPROM FORMATTING");
927 printstr("Press any key");
929 input_flag = readkey_compare();
931 } while(input_flag == 0);
933 format_eeprom(0,254);
936 case 0x00: // Checksum error
940 printstr("X-) Sum Error");
942 printstr("Press any key to format");
944 input_flag = readkey_compare();
946 } while(input_flag == 0);
949 format_eeprom(0,254);
953 case 0xff: // Success
955 default: // Unknown error
961 /* Push default parameters to AKC6955*/
964 akc6955_chg_fm(fm); // Set to AM
965 akc6955_set_amband(amband);
966 akc6955_set_freq(amfreq); // Dummy, TBS (954KHz)
967 akc6955_set_power(0xff); // Power ON
979 input_flag = readkey_compare();
981 readchar = pop_keyinfifo();
982 if((readchar >= charcode_1) && (readchar <= charcode_f)) {
983 setfreq_updown(readchar);
988 // Check battery (include idle?)
989 // Read AKJC6955's status
994 if(backlight_counter > 0) {
996 set_backlight(0xff, backlight_level); // Turn ON
998 set_backlight(0x00, 0); // Turn OFF
1001 if(power_flag != 0x00) {
1006 setsignal_tune(power_flag);