OSDN Git Service

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