OSDN Git Service

[UI][v2.0] Add support of roltaly-enbcoder.
[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
34 #if defined(__SDCC)
35 #include <sdcc-lib.h>
36 #include <pic18fregs.h> /* ONLY FOR PIC18x */
37 #include <delay.h>
38 #else
39 #include <xc.h>
40 #endif
41
42 #include <signal.h>
43
44 #include "iodef.h"
45 #include "idle.h"
46 #include "i2c_io.h"
47 #include "akc6955.h"
48 #include "lcd_acm1602.h"
49 #include "ui.h"
50 #include "eeprom.h"
51 #include "ioports.h"
52 #include "menu.h"
53 #include "power.h"
54 #include "adc_int.h"
55 #include "i2c_eeprom.h"
56 #include "backlight.h"
57 #include "rencoder.h"
58
59 /*
60  * Config words.
61  */
62 #if defined(pic18f23k22) || defined(pic18f24k22) || defined(pic18f25k22) || defined(pic18f26k22)
63 //#pragma stack 0x200 256 // Set stack size to 256bytes.
64 #pragma config FOSC=INTIO67,BORV=190,BOREN=ON,PWRTEN=ON
65 #pragma config WDTEN=ON,WDTPS=32768
66 #pragma config PBADEN=OFF,MCLRE=EXTMCLR,STVREN=ON,LVP=OFF,DEBUG=ON,XINST=ON
67 //#pragma config PBADEN=OFF,MCLRE=EXTMCLR,STVREN=ON,LVP=OFF//,XINST=ON
68 #pragma config CP0=OFF,CP1=OFF,CPB=OFF,CPD=OFF
69 #pragma config WRT0=OFF,WRT1=OFF,WRTB=OFF,WRTC=OFF,WRTD=OFF
70 #pragma config EBTR0=OFF,EBTR1=OFF,EBTRB=OFF
71 #endif
72 // For 4xK20 or 2xK20 Series
73 #if defined(pic18f43k20) || defined(pic18f44k20) || defined(pic18f45k20) || defined(pic18f46k20) || \
74     defined(pic18f23k20) || defined(pic18f24k20) || defined(pic18f25k20) || defined(pic18f26k20) || \
75     defined(_18F43K20)  || defined(_18F44K20)  || defined(_18F45K20)  || defined(_18F46K20)  || \
76     defined(_18F23K20)  || defined(_18F24K20)  || defined(_18F25K20)  || defined(_18F26K20) 
77
78 #ifdef __SDCC
79 #pragma stack 0x200 256
80 #endif
81
82 #pragma config FOSC=HS,FCMEN=ON,PWRT=ON,BOREN=NOSLP,BORV=27, \
83                WDTEN=ON,WDTPS=32768,PBADEN=OFF,HFOFST=OFF,LPT1OSC=OFF, \
84                MCLRE=ON,STVREN=ON,DEBUG=ON, \
85                XINST=OFF
86 #endif
87 /*
88  * Statuses
89   */
90 unsigned char stereoflag;
91 unsigned char tuneflag;
92 unsigned char cnrlevel;
93 int diffstat;
94 unsigned int batlevel_6955;
95 unsigned int battlevel;
96 unsigned char ui_idlekey;
97 unsigned char ui_idlepad;
98
99 int recv_signal;
100 unsigned char pollkeybuf[33];
101
102 //#define _LCD_DEBUG 1
103 #ifdef __XC
104 void TMR0_handler(void)
105 #else
106 SIGHANDLER(TMR0_handler)
107 #endif
108 {
109
110    // Stop timer0
111    T0CONbits.TMR0ON = 0;
112
113    // Clear interrupt flag
114 //   INTCONbits.TMR0IF = 0;
115    INTCONbits.TMR0IE = 0;;
116
117    return;
118 }
119 /*
120  * Interrupt wake up every 1ms.
121  */
122 #ifdef __XC
123 void TMR1_Handler(void)
124 #else
125 SIGHANDLER(TMR1_Handler)
126 #endif
127 {
128     rencoder_count();
129 //    rencoder_restart();
130    T1CON = 0b10110100;// RD16, T1RUN=0, 1/32 fOSC, TNR1CS=0, TMR1ON=0;
131    TMR1H = 63036 >> 8; // Tick = 4us, Count = 2500
132    TMR1L = 63036 & 255;
133    PIR1bits.TMR1IF = 0;
134    PIE1bits.TMR1IE = 1;
135    IPR1bits.TMR1IP = 1;
136    T1CONbits.TMR1ON = 1;
137 }
138
139 #ifdef __XC
140 void EXINT_Handler(void)
141 #else
142 SIGHANDLER(EXINT_Handler)
143 #endif
144 {
145     INTCONbits.INT0IE = 0;
146     INTCONbits.INT0IF = 0;
147     INTCON3bits.INT1IF = 0;
148     INTCON3bits.INT2IF = 0;
149     INTCON3bits.INT1IE = 0;
150     INTCON3bits.INT2IE = 0;
151
152 }
153 #ifdef __XC
154 void RBIF_handler(void)
155 #else
156 SIGHANDLER(RBIF_handler)
157 #endif
158 {
159     power_on_inthook();
160 //    if(chk_powerbutton(0, 0) != 0) { // If pressed on
161 //      power_off(1); //
162 //    }
163 }
164 #ifdef __XC
165 void  EEPROM_handler(void)
166 #else
167 SIGHANDLER(EEPROM_handler)
168 #endif
169 {
170     PIR2bits.EEIF = 0;
171     EECON1bits.WREN = 0;
172 //    if(chk_powerbutton(0, 0) != 0) { // If pressed on
173 //      power_off(1); //
174 //    }
175 }
176
177 #ifdef __XC
178 void INADC_handler(void)
179 #else
180 SIGHANDLER(INADC_handler)
181 #endif
182 {
183 //    unsigned int a;
184 //    a = polladc();
185 //    if(a != 0xffff) {
186 //        battlevel = adc_rawtobatt(a);
187 //    }
188     PIR1bits.ADIF = 0;
189 }
190 #ifdef __XC
191 void I2C_handler(void)
192 #else
193 SIGHANDLER(I2C_handler)
194 #endif
195 {
196     PIR1bits.SSPIF = 0;
197 }
198 #ifdef __XC
199 void I2CBus_handler(void)
200 #else
201 SIGHANDLER(I2CBus_handler)
202 #endif
203 {
204     PIR2bits.BCLIF = 0;
205 }
206
207
208
209 #ifdef __SDCC
210 DEF_INTLOW(intlow_handler)
211   DEF_HANDLER(SIG_TMR0, TMR0_handler)
212   DEF_HANDLER(SIG_INT0, EXINT_Handler)
213 //  DEF_HANDLER(SIG_TMR1, I2C_handler)
214 END_DEF
215
216 DEF_INTHIGH(inthigh_handler)
217  DEF_HANDLER(SIG_RBIF, RBIF_handler)
218  DEF_HANDLER(SIG_EEIF, EEPROM_handler)
219  DEF_HANDLER(SIG_TMR1, TMR1_Handler)
220  DEF_HANDLER(SIG_INT1, EXINT_Handler)
221  DEF_HANDLER(SIG_INT2, EXINT_Handler)
222  DEF_HANDLER(SIG_AD, INADC_handler)
223   //DEF_HANDLER(SIG_SSP, I2C_handler)
224   //DEF_HANDLER(SIG_BCOL, I2CBus_handler)
225 END_DEF
226 #else
227 void interrupt low_priority intlow_handler(void)
228 {
229     if(INTCONbits.TMR0IF) TMR0_handler();
230     if(INTCONbits.INT0IF) EXINT_Handler();
231 }
232
233 void interrupt high_priority inthigh_handler(void)
234 {
235     if(INTCONbits.RBIF) RBIF_handler();
236     if(PIR2bits.EEIF)   EEPROM_handler();
237     if(PIR1bits.TMR1IF) TMR1_Handler();
238    // if(INTCONbits.TMR0IF) TMR0_handler();
239 //    if(INTCON3bits.INT1IF) EXINT_Handler();
240 //    if(INTCON3bits.INT2IF) EXINT_Handler();
241     if(PIR1bits.ADIF) INADC_handler();
242
243 //    if(PIR1bits.SSPIF)    I2C_handler();
244 }
245
246 #ifdef __XC
247
248
249 #endif
250 #endif
251
252
253 void lowbatt(void)
254 {
255 //    _CLS();
256 //    idle_time_ms(100);
257     printhelp_2lines("Low battery X)", "Press key to suspend");
258     shutdown(1);
259 }
260
261 int main(void)
262 {
263     unsigned char c;
264     unsigned char pbutton;
265     unsigned char reset_status;
266     unsigned char p;
267     unsigned char lvcount = 0;
268     unsigned char dispf = 0xff;
269     unsigned char i;    
270
271     OSCCON =  (0x80 & 0b11111100) | 0b00111000;
272 //    OSCCON =  (0x80 & 0b11111100) | 0b00110010; // 8MHz 
273     idle_init();
274     keyin_init();
275     keyin_ioinit();
276     i2c1_init();
277     reset_status = chk_reset();
278     idle_time_ms(300); // Wait for setup.
279     WDTCONbits.SWDTEN = 0; // WDT OFF.
280     switch(reset_status){
281         case RESET_MCLR:
282         case RESET_BOR:
283             shutdown(0); // Save and halt on BOR.
284             break;
285         case RESET_SOFTWARE: //
286             RCONbits.RI = 0;
287            pbutton = chk_powerbutton();
288             if(pbutton == 0) shutdown(0); // Not-Pressed power-button -> shutdown( not save).
289             break;
290         case RESET_POR:
291         case RESET_WDT:  // Workaround random reset.
292  //           shutdown(0);
293             break;
294         default:
295             break;
296     }
297     WDTCONbits.SWDTEN = 1; // WDT ON.
298     power_on(1);
299     //intadc_init();
300     set_powerlamp(1);
301     valinit();
302     acm1602_init(LCD_I2CADDR, 1); //Init LCD
303     lcd_setbacklight(0xff, 255);
304     /* Check EEPROM */
305     check_eeprom();
306   /* Push default parameters to AKC6955*/
307     setup_akc6955();
308     _CLS();
309     //_LOCATE(0,0);
310     _PUTCHAR(' ');
311     update_status();
312     update_display();
313     ClrWdt();
314     ui_idlekey = setup.ui_idlecount / 92;
315     ui_idlepad = setup.ui_idlecount % 23;
316     rencoder_start();
317     do {
318
319 #if 1
320         if(battlevel < 340) { // 3.4V
321                 lvcount++;
322                 if(lvcount > 4) {
323                     if(dispf == 0) {
324                         acm1602_resume(LCD_I2CADDR);
325                         dispf = 0xff;
326                      }
327                     lowbatt(); //Zap 4Times on LowVoltage.
328                 }
329             } else {
330                 lvcount = 0;
331             }
332 #endif
333         /* Main routine*/
334
335         
336         for(i = 0; i < 4; i++) {
337            c = pollkey_single_timeout(ui_idlekey, 1); // 23*41 = 943ms
338            p = 0;
339             if(c != charcode_null) {
340                 ClrWdt();
341                 if(dispf == 0) {
342                     acm1602_resume(LCD_I2CADDR);
343                     dispf = 0xff;
344                 }
345                 rencoder_stop();
346                 setfreq_updown(c);
347                 update_status();
348                 update_display();
349                 rencoder_start();
350             }
351             if(renc_dir == RENC_LEFT) {
352                akc6955_down_freq(renc_count);
353                rencoder_init();
354             } else if(renc_dir == RENC_RIGHT) {
355                akc6955_up_freq(renc_count);
356                rencoder_init();
357             }
358             ClrWdt();
359          }
360          update_status();
361          dispf = backlight_dec(dispf); 
362          if(dispf != 0)  update_display();
363          if(ui_idlepad != 0) idle_time_ms(ui_idlepad);
364          ClrWdt();
365     } while(1);
366 }
367