OSDN Git Service

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