OSDN Git Service

[IO] Fix unstable of power button.
[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
56 /*
57  * Config words.
58  */
59 #if defined(pic18f23k22) || defined(pic18f24k22) || defined(pic18f25k22) || defined(pic18f26k22)
60 //#pragma stack 0x200 256 // Set stack size to 256bytes.
61 #pragma config FOSC=INTIO67,BORV=190,BOREN=ON,PWRTEN=ON
62 #pragma config WDTEN=ON,WDTPS=32768
63 #pragma config PBADEN=OFF,MCLRE=EXTMCLR,STVREN=ON,LVP=OFF,DEBUG=ON,XINST=ON
64 //#pragma config PBADEN=OFF,MCLRE=EXTMCLR,STVREN=ON,LVP=OFF//,XINST=ON
65 #pragma config CP0=OFF,CP1=OFF,CPB=OFF,CPD=OFF
66 #pragma config WRT0=OFF,WRT1=OFF,WRTB=OFF,WRTC=OFF,WRTD=OFF
67 #pragma config EBTR0=OFF,EBTR1=OFF,EBTRB=OFF
68 #endif
69 // For 4xK20 or 2xK20 Series
70 #if defined(pic18f43k20) || defined(pic18f44k20) || defined(pic18f45k20) || defined(pic18f46k20) || \
71     defined(pic18f23k20) || defined(pic18f24k20) || defined(pic18f25k20) || defined(pic18f26k20) || \
72     defined(_18F43K20)  || defined(_18F44K20)  || defined(_18F45K20)  || defined(_18F46K20)  || \
73     defined(_18F23K20)  || defined(_18F24K20)  || defined(_18F25K20)  || defined(_18F26K20) 
74
75 #ifdef __SDCC
76 #pragma stack 0x200 256
77 #endif
78
79 #pragma config FOSC=HS,FCMEN=ON,PWRT=ON,BOREN=NOSLP,BORV=27, \
80                WDTEN=ON,WDTPS=32768,PBADEN=OFF,HFOFST=OFF,LPT1OSC=OFF, \
81                MCLRE=ON,STVREN=ON,DEBUG=ON, \
82                XINST=OFF
83 #endif
84 /*
85  * Statuses
86   */
87 unsigned char stereoflag;
88 unsigned char tuneflag;
89 unsigned char cnrlevel;
90 int diffstat;
91 unsigned int batlevel_6955;
92 unsigned int battlevel;
93
94 int recv_signal;
95 int backlight_counter;
96 unsigned char backlight_level;
97 unsigned char pollkeybuf[33];
98
99 //#define _LCD_DEBUG 1
100 #ifdef __XC
101 void TMR0_handler(void)
102 #else
103 SIGHANDLER(TMR0_handler)
104 #endif
105 {
106
107    // Stop timer0
108    T0CONbits.TMR0ON = 0;
109
110    // Clear interrupt flag
111    INTCONbits.TMR0IF = 0;
112    INTCONbits.TMR0IE = 0;;
113
114    return;
115 }
116 /*
117  * Interrupt wake up every 1ms.
118  */
119 #ifdef __XC
120 void TMR3_Handler(void)
121 #else
122 SIGHANDLER(TMR3_Handler)
123 #endif
124 {
125     PIR2bits.TMR3IF  = 0;
126     PIE2bits.TMR3IE  = 0;
127     T3CONbits.TMR3ON = 0;
128 }
129
130 #ifdef __XC
131 void EXINT_Handler(void)
132 #else
133 SIGHANDLER(EXINT_Handler)
134 #endif
135 {
136     INTCONbits.INT0IE = 0;
137     INTCONbits.INT0IF = 0;
138     INTCON3bits.INT1IF = 0;
139     INTCON3bits.INT2IF = 0;
140     INTCON3bits.INT1IE = 0;
141     INTCON3bits.INT2IE = 0;
142
143 }
144 #ifdef __XC
145 void RBIF_handler(void)
146 #else
147 SIGHANDLER(RBIF_handler)
148 #endif
149 {
150     power_on_inthook();
151 //    if(chk_powerbutton(0, 0) != 0) { // If pressed on
152 //      power_off(1); //
153 //    }
154 }
155 #ifdef __XC
156 void  EEPROM_handler(void)
157 #else
158 SIGHANDLER(EEPROM_handler)
159 #endif
160 {
161     PIR2bits.EEIF = 0;
162     EECON1bits.WREN = 0;
163 //    if(chk_powerbutton(0, 0) != 0) { // If pressed on
164 //      power_off(1); //
165 //    }
166 }
167
168 #ifdef __XC
169 void INADC_handler(void)
170 #else
171 SIGHANDLER(INADC_handler)
172 #endif
173 {
174 //    unsigned int a;
175 //    a = polladc();
176 //    if(a != 0xffff) {
177 //        battlevel = adc_rawtobatt(a);
178 //    }
179     PIR1bits.ADIF = 0;
180 }
181 #ifdef __XC
182 void I2C_handler(void)
183 #else
184 SIGHANDLER(I2C_handler)
185 #endif
186 {
187     PIR1bits.SSPIF = 0;
188 }
189 #ifdef __XC
190 void I2CBus_handler(void)
191 #else
192 SIGHANDLER(I2CBus_handler)
193 #endif
194 {
195     PIR2bits.BCLIF = 0;
196 }
197
198
199
200 #ifdef __SDCC
201 DEF_INTLOW(intlow_handler)
202   DEF_HANDLER(SIG_TMR0, TMR0_handler)
203   DEF_HANDLER(SIG_INT0, EXINT_Handler)
204 //  DEF_HANDLER(SIG_TMR3, I2C_handler)
205 END_DEF
206
207 DEF_INTHIGH(inthigh_handler)
208  DEF_HANDLER(SIG_RBIF, RBIF_handler)
209  DEF_HANDLER(SIG_EEIF, EEPROM_handler)
210  DEF_HANDLER(SIG_TMR3, TMR3_Handler)
211  DEF_HANDLER(SIG_INT1, EXINT_Handler)
212  DEF_HANDLER(SIG_INT2, EXINT_Handler)
213  DEF_HANDLER(SIG_AD, INADC_handler)
214   //DEF_HANDLER(SIG_SSP, I2C_handler)
215   //DEF_HANDLER(SIG_BCOL, I2CBus_handler)
216 END_DEF
217 #else
218 void interrupt low_priority intlow_handler(void)
219 {
220     if(INTCONbits.TMR0IF) TMR0_handler();
221     if(INTCONbits.INT0IF) EXINT_Handler();
222 }
223
224 void interrupt high_priority inthigh_handler(void)
225 {
226     if(INTCONbits.RBIF) RBIF_handler();
227     if(PIR2bits.EEIF)   EEPROM_handler();
228     if(PIR2bits.TMR3IF) TMR3_Handler();
229     if(INTCONbits.TMR0IF) TMR0_handler();
230     if(INTCON3bits.INT1IF) EXINT_Handler();
231     if(INTCON3bits.INT2IF) EXINT_Handler();
232     if(PIR1bits.ADIF) INADC_handler();
233
234 //    if(PIR1bits.SSPIF)    I2C_handler();
235 }
236
237 #ifdef __XC
238
239
240 #endif
241 #endif
242
243
244 void lowbatt(void)
245 {
246 //    _CLS();
247 //    idle_time_ms(100);
248     printhelp_2lines("Low battery X)", "Press key to suspend");
249     shutdown(1);
250 }
251
252 int main(void)
253 {
254     unsigned char c;
255     unsigned int sum = 0;
256     unsigned char pbutton;
257     unsigned char reset_status;
258     unsigned char p;
259     
260     OSCCON =  (0x80 & 0b11111100) | 0b00111000;
261 //    OSCCON =  (0x80 & 0b11111100) | 0b00110010; // 8MHz 
262     idle_init();
263     keyin_init();
264     keyin_ioinit();
265     WDTCONbits.SWDTEN = 0; // WDT OFF.
266     reset_status = chk_reset();
267     idle_time_ms(300); // Wait for setup.
268     switch(reset_status){
269         case RESET_MCLR:
270         case RESET_WDT:  // Workaround random reset.
271         case RESET_BOR:
272             shutdown(0); // Save and halt on BOR.
273             break;
274         case RESET_SOFTWARE: //
275             RCONbits.RI = 0;
276             break;
277         default:
278             break;
279     }
280     WDTCONbits.SWDTEN = 1; // WDT ON.
281     i2c1_init();
282     power_on(1);
283     intadc_init();
284     set_powerlamp(1);
285 //    idle_time_ms(125);
286     valinit();
287
288     acm1602_init(0xa0, 1); //Init LCD
289 //    idle_time_ms(125);
290     _LOCATE(0,0);  // It's BAD-KNOWHOW, but needs AKIZUKI'S LCD :(
291     _PUTCHAR(' '); //
292     _LOCATE(0,1);
293     printstr("Hello;-)");
294     lcd_setbacklight(0xff, 255);
295     idle_time_ms(1000);
296     /* Check EEPROM */
297     check_eeprom();
298   /* Push default parameters to AKC6955*/
299     setup_akc6955();
300     _CLS();
301     _LOCATE(0,0);
302     _PUTCHAR(' ');
303     battlevel = 350;
304     update_status();
305     update_display();
306     ClrWdt();
307     lcd_setbacklight(0xff, 255);
308     do {
309             if(battlevel <= 340) { // 3.4V
310                lowbatt();
311             }
312         /* Main routine*/
313            c = pollkeys(pollkeybuf, 5, 1); // 23*10=135ms
314            p = 0;
315             while(c > 0) {
316                 ClrWdt();
317                 setfreq_updown(pollkeybuf[p]);
318                 c--;
319                  p++;
320             }
321 //       idle_time_ms(ui_idlecount);
322             _LOCATE(0,0);
323             pbutton = chk_powerbutton();
324             if(pbutton != 0) shutdown(1); // Button pressed.
325
326             if(backlight_counter > 0) {
327                 backlight_counter--;
328                 lcd_setbacklight(0xff, backlight_level); // Turn ON
329             } else {
330                 lcd_setbacklight(0x00, 0); // Turn OFF
331         }
332         ClrWdt();
333         update_status();
334         update_display();
335         ClrWdt();
336     } while(1);
337 }
338