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"
50 #if defined(pic18f23k22) || defined(pic18f24k22) || defined(pic18f25k22) || defined(pic18f26k22)
51 //#pragma stack 0x200 256 // Set stack size to 256bytes.
52 #pragma config FOSC=INTIO67,BORV=190,BOREN=ON,PWRTEN=ON
53 #pragma config WDTEN=ON,WDTPS=32768
54 #pragma config PBADEN=OFF,MCLRE=EXTMCLR,STVREN=ON,LVP=OFF,DEBUG=ON//,XINST=ON
55 //#pragma config PBADEN=OFF,MCLRE=EXTMCLR,STVREN=ON,LVP=OFF//,XINST=ON
56 #pragma config CP0=OFF,CP1=OFF,CPB=OFF,CPD=OFF
57 #pragma config WRT0=OFF,WRT1=OFF,WRTB=OFF,WRTC=OFF,WRTD=OFF
58 #pragma config EBTR0=OFF,EBTR1=OFF,EBTRB=OFF
60 // For 4xK20 or 2xK20 Series
61 #if defined(pic18f43k20) || defined(pic18f44k20) || defined(pic18f45k20) || defined(pic18f46k20) || \
62 defined(pic18f23k20) || defined(pic18f24k20) || defined(pic18f25k20) || defined(pic18f26k20)
64 #pragma stack 0x200 256
65 #pragma config FOSC=HS,FCMEN=ON,PWRT=ON,BOREN=ON,BORV=22
66 #pragma config WDTEN=ON,WDTPS=32768,PBADEN=OFF,HFOFST=ON,LPT1OSC=OFF,MCLRE=ON
67 #pragma config STVREN=ON,DEBUG=ON
68 //#pragma config CP0=OFF,CP1=OFF,CP2=OFF,CP3=OFF
69 //#pragma config CPB=OFF,CPD=OFF
70 //#pragma config WRT0=OFF,WRT1=OFF,WRT2=OFF,WRT3=OFF
71 //#pragma config WRTC=OFF,WRTB=OFF,WRTD=OFF
72 //#pragma config EBTR0=OFF,EBTR1=OFF,EBTR2=OFF,EBTR3=OFF,EBTRB=OFF
75 //#define _LCD_DEBUG 1
77 SIGHANDLER(TMR0_handler)
88 // Clear interrupt flag
90 tmr0f &= ~(_TMR0IF | _TMR0IE);
97 * Interrupt wake up every 1ms.
99 SIGHANDLER(TMR3_Handler)
101 if(statecount >= 8) statecount = 0;
102 readkey_io(statecount);
104 if(statecount > 7) readkey_compare(); // Compare and push to fifo.
110 DEF_INTLOW(intlow_handler)
111 DEF_HANDLER(SIG_TMR0, TMR0_handler)
112 // DEF_HANDLER(SIG_TMR3, TMR3_Handler)
118 unsigned char amband;
119 unsigned char fmband;
121 unsigned char am_mode3k;
122 unsigned char am_userbandnum;
123 unsigned char fm_userbandnum;
124 _userband_t am_usrbands[USER_BAND_NUM];
125 _userband_t fm_usrbands[USER_BAND_NUM];
127 unsigned char enter_mode;
128 unsigned char numeric_mode;
129 unsigned char menu_node;
131 unsigned int ui_idlecount;
132 unsigned char scanflag;
135 int backlight_counter;
136 unsigned char backlight_level;
137 unsigned char pollkeybuf[33];
140 unsigned int writeword_eeprom(unsigned int p, unsigned int *sum, unsigned int word)
143 if(eeprom_writebyte(p, word >> 8) == 0) return p; // Error
144 *sum = calcsum_byte(*sum, (word >> 8));
146 if(eeprom_writebyte(p, word & 0xff) == 0) return p+1; // Error
147 *sum = calcsum_byte(*sum, word & 0xff);
151 unsigned int writebyte_eeprom(unsigned int p, unsigned int *sum, unsigned char b)
154 if(eeprom_writebyte(p, b) == 0) return p; // Error
155 *sum = calcsum_byte(*sum, b);
159 void save_eeprom(void)
162 unsigned int sum = 0x0000;
166 writeword_eeprom(p, &sum, 0x1298);
169 writeword_eeprom(p, &sum, amfreq);
172 writeword_eeprom(p, &sum, fmfreq);
175 writebyte_eeprom(p, &sum, amband);
177 writebyte_eeprom(p, &sum, fmband);
179 writebyte_eeprom(p, &sum, fm);
181 writebyte_eeprom(p, &sum, am_mode3k);
183 writebyte_eeprom(p, &sum, am_userbandnum);
185 writebyte_eeprom(p, &sum, fm_userbandnum);
188 for(i = 0 ; i < USER_BAND_NUM; i++){
189 writebyte_eeprom(p, &sum, am_usrbands[i].mode3k);
190 writebyte_eeprom(p + 1, &sum, am_usrbands[i].start);
191 writebyte_eeprom(p + 2, &sum, am_usrbands[i].stop);
192 writeword_eeprom(p + 3, &sum, am_usrbands[i].freq);
195 for(i = 0 ; i < USER_BAND_NUM; i++){
196 writebyte_eeprom(p, &sum, fm_usrbands[i].mode3k);
197 writebyte_eeprom(p + 1, &sum, fm_usrbands[i].start);
198 writebyte_eeprom(p + 2, &sum, fm_usrbands[i].stop);
199 writeword_eeprom(p + 3, &sum, fm_usrbands[i].freq);
203 eeprom_writebyte(p, sum >> 8);
204 eeprom_writebyte(p + 1, sum & 0xff);
208 unsigned int readword_eeprom(unsigned int p, unsigned int *sum)
215 h = eeprom_readbyte(p);
216 *sum = calcsum_byte(*sum, h);
218 l = eeprom_readbyte(p + 1);
219 *sum = calcsum_byte(*sum, l);
225 unsigned char readbyte_eeprom(unsigned int p, unsigned int *sum)
231 b = eeprom_readbyte(p);
232 *sum = calcsum_byte(*sum, b);
238 unsigned char load_eeprom(void)
241 unsigned int sum = 0x0000;
246 magic = readword_eeprom(p, &sum);
247 if(magic != 0x1298) return 0x01; // NO MAGICWORD
250 amfreq = readword_eeprom(p, &sum);
253 fmfreq = readword_eeprom(p, &sum);
256 amband = readbyte_eeprom(p, &sum);
258 fmband = readbyte_eeprom(p, &sum);
260 fm = readbyte_eeprom(p, &sum);
262 am_mode3k = readbyte_eeprom(p, &sum);
264 am_userbandnum = readbyte_eeprom(p, &sum);
266 fm_userbandnum = readbyte_eeprom(p, &sum);
269 for(i = 0 ; i < USER_BAND_NUM; i++){
270 am_usrbands[i].mode3k = readbyte_eeprom(p, &sum);
271 am_usrbands[i].start = readbyte_eeprom(p + 1, &sum);
272 am_usrbands[i].stop = readbyte_eeprom(p + 2, &sum);
273 am_usrbands[i].freq = readword_eeprom(p + 3, &sum);
276 for(i = 0 ; i < USER_BAND_NUM; i++){
277 fm_usrbands[i].mode3k = readbyte_eeprom(p, &sum);
278 fm_usrbands[i].start = readbyte_eeprom(p + 1, &sum);
279 fm_usrbands[i].stop = readbyte_eeprom(p + 2, &sum);
280 fm_usrbands[i].freq = readword_eeprom(p + 3, &sum);
284 magic = (eeprom_readbyte(p) << 8) + eeprom_readbyte(p+1);
287 if(sum != magic) return 0x00;
293 void update_status(void)
296 recv_signal = akc6955_read_level();
298 fmfreq = akc6955_get_freq();
300 amfreq = akc6955_get_freq();
307 void update_display(void)
312 print_numeric_nosupress(recv_signal, 3);
316 if(fmband < AKC6955_BAND_TV1) {
318 _PUTCHAR('1' + (fmband & 7));
320 } else if(fmband < AKC6955_BAND_FMUSER){
322 _PUTCHAR('1' + fmband - AKC6955_BAND_TV1);
328 if(amband == AKC6955_BAND_LW) {
330 } else if(amband <AKC6955_BAND_SW1) { //MW
332 _PUTCHAR('1' + amband - AKC6955_BAND_MW1);
334 } else if(amband <AKC6955_BAND_SW10) { //MW
336 _PUTCHAR('1' + amband - AKC6955_BAND_SW1);
338 } else if(amband < AKC6955_BAND_AMUSER) { //MW
340 _PUTCHAR('0' + amband - AKC6955_BAND_SW10);
342 } else if(amband == AKC6955_BAND_MW4){
351 int freq_lo = fmfreq % 100;
352 int freq_hi = fmfreq / 100;
353 print_numeric_nosupress(freq_hi, 3);
355 print_numeric_nosupress(freq_lo, 2);
358 print_numeric_nosupress(amfreq, 5);
371 void setfreq_updown(unsigned char ctlword)
374 case charcode_8: // Change band
377 if(amband > 18) amband = 0;
378 // amfreq = akc6955_setfreq(amfreq)
379 // akc6955_set_amband(amband);
380 _AKC6955_WAIT_62_5MS(); // 62.5ms
381 // amband = akc6955_get_amband();
382 // amfreq = akc6955_get_freq();
385 if(fmband > 7) fmband = 0;
386 // amfreq = akc6955_setfreq(amfreq)
387 // akc6955_set_fmband(fmband);
388 _AKC6955_WAIT_62_5MS(); // 62.5ms
389 // fmband = akc6955_get_fmband();
390 // fmfreq = akc6955_get_freq();
393 case charcode_2: // Change band
396 if(amband == 0) amband = 18;
397 if(amband >= 18) amband = 18;
398 // amfreq = akc6955_setfreq(amfreq)
399 // akc6955_set_amband(amband);
400 _AKC6955_WAIT_62_5MS(); // 62.5ms
401 // amband = akc6955_get_amband();
402 // amfreq = akc6955_get_freq();
405 if(fmband == 0) fmband = 7;
406 if(fmband >= 7) fmband = 7;
407 // amfreq = akc6955_setfreq(amfreq)
408 // akc6955_set_fmband(fmband);
409 _AKC6955_WAIT_62_5MS(); // 62.5ms
410 // fmband = akc6955_get_fmband();
411 // fmfreq = akc6955_get_freq();
414 case charcode_4: // Down Freq;
417 // fmfreq = akc6955_down_freq(10); // DOWN 100KHz
420 // amfreq = akc6955_down_freq(10); // DOWN 10KHz
423 case charcode_6: // Down Freq;
426 // fmfreq = akc6955_up_freq(10); // UP 100KHz
429 // amfreq = akc6955_up_freq(10); // UP 10KHz
432 case charcode_9: // Down Fast;
435 // fmfreq = akc6955_down_freq(50); // DOWN 500KHz
438 // amfreq = akc6955_down_freq(50); // DOWN 50KHz
441 case charcode_7: // Down Fast;
444 // fmfreq = akc6955_up_freq(50); // UP 100KHz
447 // amfreq = akc6955_up_freq(50); // UP 10KHz
450 case charcode_1: // Down Slow;
453 // fmfreq = akc6955_down_freq(5); // DOWN 50KHz
456 // amfreq = akc6955_down_freq(5); // DOWN 50KHz
459 case charcode_3: // Down Slow;
462 // fmfreq = akc6955_up_freq(5); // UP 50KHz
465 // amfreq = akc6955_up_freq(5); // UP 5KHz
468 case charcode_0: // Step
475 // amfreq = akc6955_mode3k(am_mode3k);
478 case charcode_a: // Toggle FM
490 case charcode_e: // Backlight ON/OFF
491 if(backlight_counter > 0) {
492 backlight_counter = 0;
494 backlight_counter = backlight_long;
512 static void setdefault(void)
516 fmfreq = 8000; // 10KHz order.
517 amband = AKC6955_BAND_MW2;
518 fmband = AKC6955_BAND_FM2;
524 for(i = 0; i < 4; i++){
525 am_usrbands[i].start = 0x19;
526 am_usrbands[i].stop = 0x32;
528 for(i = 0; i < 4; i++){
529 fm_usrbands[i].start = 0x19;
530 fm_usrbands[i].stop = 0x32;
539 unsigned int sum = 0;
543 unsigned char power_flag;
545 // OSCCON = (_IDLEN & 0b11111100) | 0b00111000;
552 _AKC6955_WAIT_125_0MS(); // Wait 125ms
556 backlight_long = 256;
557 backlight_counter = backlight_long;
558 backlight_level = 255;
559 ui_idlecount = 65535 - 7182/4 + 1; // 0.25Sec
561 acm1602_init(0xa0, 1); //Init LCD
562 _AKC6955_WAIT_125_0MS(); // Wait 125ms
563 _LOCATE(0,0); // It's BAD-KNOWHOW, but needs AKIZUKI'S LCD :(
566 printstr("Hello;-)");
567 lcd_setbacklight(0xff, 100);
568 // PORTD |= _LCDPORT_CONT_RS;
575 set_powerlamp(i & 1);
577 // idle(65536 - 7182/10 + 1);
578 c = pollkeys(pollkeybuf, 60, 1); // Poll about 600ms
582 for(sp = 0; sp < c; sp++) _PUTCHAR(pollkeybuf[sp] + '0');
591 switch(load_eeprom()) {
592 case 0x01: // No magic-word
593 idle(65535-7128*2+1);
597 printstr("EEPROM FORMATTING");
599 printstr("Press any key");
600 c = pollkey_single();
603 printstr("Formatting...");
604 // format_eeprom(2,200);
605 // writeword_eeprom(0, &sum, 0x1298);
609 printstr("Save defaults");
613 case 0x00: // Checksum error
614 idle(65535-7128*2+1);
617 printstr("X-) Sum Error");
619 printstr("Press any key to format");
620 c = pollkey_single();
623 printstr("Formatting...");
624 format_eeprom(2,250);
625 writeword_eeprom(0, &sum, 0x1298);
628 printstr("Save defaults");
632 case 0xff: // Success
634 default: // Unknown error
640 /* Push default parameters to AKC6955*/
643 akc6955_chg_fm(fm); // Set to AM
644 akc6955_set_amband(amband);
645 akc6955_set_freq(amfreq); // Dummy, TBS (954KHz)
646 akc6955_set_power(0xff); // Power ON
664 c = pollkeys(pollkeybuf, 60, 1);
667 setfreq_updown(pollkeybuf[p]);
671 // Check battery (include idle?)
672 // Read AKJC6955's status
677 if(backlight_counter > 0) {
679 lcd_setbacklight(0xff, backlight_level); // Turn ON
681 lcd_setbacklight(0x00, 0); // Turn OFF
683 // idle(ui_idlecount);