OSDN Git Service

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