OSDN Git Service

[UI] Change key assignment.
[openi2cradio/OpenI2CRadio.git] / main.c
1 /*
2  * OpenI2CRADIO
3  * Config & Main routine.
4  * Copyright (C) 2013-06-10 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 <stdarg.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <sdcc-lib.h>
34 #include <pic18fregs.h> /* ONLY FOR PIC18x */
35 #include <signal.h>
36 #include <delay.h>
37
38 #include "iodef.h"
39 #include "idle.h"
40 #include "i2c_io.h"
41 #include "akc6955.h"
42 #include "lcd_acm1602.h"
43 #include "ui.h"
44
45 /*
46  * Config words.
47  */
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
56 #endif
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
69 #endif
70
71 //#define _LCD_DEBUG 1
72
73 SIGHANDLER(TMR0_handler)
74 {
75    unsigned char tmr0f;
76    unsigned char t0con;
77
78    // Stop timer0
79    t0con = T0CON;
80    t0con &= ~_IDLEN;
81    T0CON = t0con;
82
83    // Read IOKEYS
84    readkey_io();
85
86    // Clear interrupt flag
87    tmr0f = INTCON;
88    tmr0f &= ~(_TMR0IF);
89    INTCON = tmr0f;
90
91    return;
92 }
93
94
95 DEF_INTLOW(intlow_handler)
96   DEF_HANDLER(SIG_TMR0, TMR0_handler)
97 END_DEF
98
99
100 unsigned int amfreq;
101 unsigned int fmfreq;
102 unsigned char amband;
103 unsigned char fmband;
104 unsigned char fm;
105 unsigned char am_mode3k;
106 unsigned char am_userbandnum;
107 unsigned char fm_userbandnum;
108 typedef struct {
109     unsigned char start;
110     unsigned char stop;
111 } _userband_t;
112
113 _userband_t am_usrbands[4];
114 _userband_t fm_usrbands[4];
115
116 unsigned char enter_mode;
117 unsigned char numeric_mode;
118 unsigned char menu_node;
119 int backlight_long;
120 unsigned char help_flag;
121 int help_line;
122 int help_section;
123 int ui_language;
124 unsigned int ui_idlecount;
125
126 int recv_signal;
127 int backlight_counter;
128 unsigned char backlight_level;
129
130
131
132 void toggle_amfm(void)
133 {
134     if(fm != 0){
135         fm = 0;
136 #ifndef _LCD_DEBUG
137         akc6955_chg_fm(fm);
138         akc6955_set_amband(amband);
139         akc6955_set_freq(amfreq);
140 #endif
141     } else {
142         fm = 0xff;
143 #ifndef _LCD_DEBUG
144         akc6955_chg_fm(fm);
145         akc6955_set_fmband(fmband);
146         akc6955_set_freq(fmfreq);
147 #endif
148     }
149 }
150
151 void update_display(void)
152 {
153     if(fm != 0){ // FM
154         _LOCATE(0,0);
155         if(fmband < AKC6955_BAND_TV1) {
156             printstr("FM");
157             _PUTCHAR('1' + (fmband & 7));
158         } else if(fmband < AKC6955_BAND_FMUSER){
159             printstr("TV");
160             _PUTCHAR('1' + fmband - AKC6955_BAND_TV1);
161         } else { // USER
162             printstr("FMUSR");
163         }
164     } else { // AM
165         _LOCATE(0,1);
166         if(amband == AKC6955_BAND_LW) {
167             printstr("LW");
168         } else if(amband <AKC6955_BAND_SW1) { //MW
169             printstr("MW");
170             _PUTCHAR('1' + amband - AKC6955_BAND_MW1);
171         } else if(amband < AKC6955_BAND_AMUSER) { //MW
172             printstr("SW");
173             _PUTCHAR('1' + amband - AKC6955_BAND_SW1);
174         } else if(amband == AKC6955_BAND_MW4){
175             printstr("MW4");
176         } else {
177             printstr("AMUSR");
178         }
179      }
180      _LOCATE(16-4 ,1);
181      if(fm != 0){
182          printstr("MHz");
183      } else {
184          printstr("KHz");
185      }
186      _LOCATE(16-5, 1);
187      if(fm != 0){
188          int freq_lo = fmfreq % 100;
189          int freq_hi = fmfreq / 100;
190          print_numeric(freq_hi);
191          _PUTCHAR('.');
192          print_numeric(freq_lo);
193      } else {
194          print_numeric(amfreq);
195      }
196      // Signal
197      _LOCATE(0, 0);
198      printstr("S=");
199      print_numeric(recv_signal);
200 }
201
202
203 void setfreq_updown(unsigned char ctlword)
204 {
205 #ifndef _LCD_DEBUG
206     switch(ctlword){
207         case charcode_8: // Change band
208             if(fm != 0){
209                 amband++;
210                 if(amband > 18) amband = 0;
211 //                amfreq = akc6955_setfreq(amfreq)
212                 akc6955_set_amband(amband);
213                 _AKC6955_WAIT_62_5MS(); // 62.5ms
214                 amband = akc6955_get_amband();
215                 amfreq = akc6955_get_freq();
216             } else {
217                 fmband++;
218                 if(fmband > 7) fmband = 0;
219 //                amfreq = akc6955_setfreq(amfreq)
220                 akc6955_set_fmband(fmband);
221                 _AKC6955_WAIT_62_5MS(); // 62.5ms
222                 fmband = akc6955_get_fmband();
223                 fmfreq = akc6955_get_freq();
224             }
225             break;
226         case charcode_2: // Change band
227             if(fm != 0){
228                 amband--;
229                 if(amband == 0) amband = 18;
230                 if(amband >= 18) amband = 18;
231 //                amfreq = akc6955_setfreq(amfreq)
232                 akc6955_set_amband(amband);
233                 _AKC6955_WAIT_62_5MS(); // 62.5ms
234                 amband = akc6955_get_amband();
235                 amfreq = akc6955_get_freq();
236             } else {
237                 fmband--;
238                 if(fmband == 0) fmband = 7;
239                 if(fmband >= 7) fmband = 7;
240 //                amfreq = akc6955_setfreq(amfreq)
241                 akc6955_set_fmband(fmband);
242                 _AKC6955_WAIT_62_5MS(); // 62.5ms
243                 fmband = akc6955_get_fmband();
244                 fmfreq = akc6955_get_freq();
245             }
246             break;
247         case charcode_4: // Down Freq;
248             if(fm != 0){
249                 fmfreq = akc6955_down_freq(10); // DOWN 100KHz
250             } else {
251                 amfreq = akc6955_down_freq(10); // DOWN 10KHz
252             }
253             break;
254         case charcode_6: // Down Freq;
255             if(fm != 0){
256                 fmfreq = akc6955_up_freq(10); // UP 100KHz
257             } else {
258                 amfreq = akc6955_up_freq(10); // UP 10KHz
259             }
260             break;
261         case charcode_7: // Down Fast;
262             if(fm != 0){
263                 fmfreq = akc6955_down_freq(50); // DOWN 500KHz
264             } else {
265                 amfreq = akc6955_down_freq(50); // DOWN 50KHz
266             }
267             break;
268         case charcode_9: // Down Fast;
269             if(fm != 0){
270                 fmfreq = akc6955_up_freq(50); // UP 100KHz
271             } else {
272                 amfreq = akc6955_up_freq(50); // UP 10KHz
273             }
274             break;
275         case charcode_1: // Down Slow;
276             if(fm != 0){
277                 fmfreq = akc6955_down_freq(5); // DOWN 50KHz
278             } else {
279                 amfreq = akc6955_down_freq(5); // DOWN 50KHz
280             }
281             break;
282         case charcode_3: // Down Slow;
283             if(fm != 0){
284                 fmfreq = akc6955_up_freq(5); // UP 50KHz
285             } else {
286                 amfreq = akc6955_up_freq(5); // UP 5KHz
287             }
288             break;
289         case charcode_0: // Step
290             if(fm == 0){
291                 if(am_mode3k == 0) {
292                     am_mode3k = 0xff;
293                 } else {
294                     am_mode3k = 0;
295                 }
296                 amfreq = akc6955_mode3k(am_mode3k);
297             }
298             break;
299         case charcode_a: // Toggle FM
300             toggle_amfm();
301             break;
302         case charcode_b:
303             // Menu / cancel
304             break;
305         case charcode_c:
306             break;
307         case charcode_d:
308             // Delete
309             break;
310         case charcode_e: // Backlight ON
311             backlight_counter = backlight_long;
312             break;
313         case charcode_f:
314             // Toggle Numeric/Padkey(NO Numeric is not entered)
315             break;
316         default:
317             break;
318     }
319 #endif
320 }
321 /*
322  * 
323  */
324 int main(void)
325 {
326     char readchar;
327     unsigned char input_flag;
328     char i;
329 #ifdef _LCD_DEBUG
330     unsigned char power_flag;
331 #endif
332     keyin_init();
333     keyin_ioinit();
334     idle_init();
335
336     i2c1_init();
337
338     _AKC6955_WAIT_125_0MS(); // Wait 125ms
339 #ifdef _LCD_DEBUG
340     power_flag = 0xff;
341 #endif
342     backlight_long = 256;
343     backlight_counter = backlight_long;
344     backlight_level = 255;
345     ui_idlecount = 0xf800;
346
347     acm1602_init(0xa0, 1); //Init LCD
348 //    _AKC6955_WAIT_125_0MS(); // Wait 125ms
349     _LOCATE(0,0);
350     printstr("Hello;-)");
351
352     
353     // Init AKC6955
354     amfreq = 954;
355     fmfreq = 8000; // 10KHz order.
356     amband = AKC6955_BAND_MW2;
357     fmband = AKC6955_BAND_FM2;
358     am_mode3k = 0xff;
359     fm = 0;
360     recv_signal = 0;
361     am_userbandnum = 0;
362     fm_userbandnum = 0;
363     for(i = 0; i < 4; i++){
364         am_usrbands[i].start = 0x19;
365         am_usrbands[i].stop  = 0x32;
366     }
367     for(i = 0; i < 4; i++){
368         fm_usrbands[i].start = 0x19;
369         fm_usrbands[i].stop  = 0x32;
370     }
371
372     /* Check EEPROM */
373     /* Push default parameters to AKC6955*/
374
375 #ifndef _LCD_DEBUG
376     akc6955_chg_fm(fm); // Set to AM
377     akc6955_set_amband(amband);
378     akc6955_set_freq(amfreq); // Dummy, TBS (954KHz)
379     akc6955_set_power(0xff); // Power ON
380 #endif
381
382 #ifdef _LCD_DEBUG
383     idle(0xf000);
384 #else
385     idle(0xff00);
386 #endif
387     do {
388         /* Main routine*/
389         input_flag = readkey_compare();
390         if(input_flag != 0){
391             readchar = pop_keyinfifo();
392             switch(readchar) {
393                 // Top of input-tree.
394                 case charcode_s0:
395                     // Change FM/AM
396                     toggle_amfm();
397                     break;
398                 case charcode_s1:
399                     //
400                     backlight_counter = backlight_long;
401                     break;
402                 case charcode_s2:
403                     // ENTER
404                     break;
405                 case charcode_s3:
406                     // Reserve
407                     break;
408                 case charcode_null: // None
409                     break;
410                 default:
411                     // Numeric 0to9, or a to f.
412                     setfreq_updown(readchar);
413                     break;
414             }
415         }
416 #ifndef _LCD_DEBUG
417         recv_signal = akc6955_read_level();
418         if(fm != 0){
419             fmfreq = akc6955_get_freq();
420         } else {
421             amfreq = akc6955_get_freq();
422         }
423 #endif
424         // Check battery (include idle?)
425         // Read AKJC6955's status
426         // Putstring to LCD.
427
428         update_display();
429         if(backlight_counter > 0) {
430             backlight_counter--;
431             set_backlight(0xff, backlight_level); // Turn ON
432         } else {
433             set_backlight(0x00, 0); // Turn OFF
434         }
435 #ifdef _LCD_DEBUG
436         if(power_flag != 0x00) {
437             power_flag = 0x00;
438         } else {
439             power_flag = 0xff;
440         }
441         setsignal_tune(power_flag);
442 #endif
443         idle(ui_idlecount);
444     } while(1);
445 }
446