OSDN Git Service

98f1a57974a75eb09123c637fb38fe48f4d439a1
[openi2cradio/OpenI2CRadio.git] / power.c
1 /*
2  * OpenI2CRADIO
3  * Power switch.
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 "commondef.h"
30 #include "lcd_acm1602.h"
31 #include "power.h"
32
33 /*
34  * Detect reset condition.
35  */
36 unsigned char chk_reset(void)
37 {
38
39 #ifdef __SDCC
40     union {
41         __RCONbits_t b;
42         unsigned char byte;
43     } rcon;
44     union {
45         __STKPTRbits_t b;
46         unsigned char byte;
47     } stkptr;
48 #else
49     union {
50         RCONbits_t b;
51         unsigned char byte;
52     } rcon;
53     union {
54         STKPTRbits_t b;
55         unsigned char byte;
56     } stkptr;
57 #endif
58     rcon.byte = RCON;
59     stkptr.byte = STKPTR;
60     RCON |= 0b01010011; // SBOREN,*RI,*POR,*BOR = '1'.
61     if((rcon.b.POR ==0) && (rcon.b.BOR == 0)) {
62         return RESET_POR;
63     }
64
65     if(rcon.b.BOR == 0) return RESET_BOR;
66     if(rcon.b.RI == 0) return RESET_SOFTWARE;
67     if(rcon.b.TO == 0) return RESET_WDT;
68     if(rcon.b.PD == 0) return RESET_POWERDOWN;
69     if(stkptr.b.STKOVF == 1) return RESET_STACK_FULL;
70     if(stkptr.b.STKUNF == 1) return RESET_STACK_UNDER;
71     return RESET_MCLR;
72 }
73
74 void power_on_inthook(void)
75 {
76
77     IOCB = 0x00;
78     IOCB |= 0x10; // IOCB4 ONLY.
79 #ifdef __SDCC
80 //    INTCON &= ~(_RBIF | _RBIE);
81 //    INTCON |= _GIE;
82 //    INTCON |= (_GIE | _PEIE);
83     INTCONbits.RBIE = 0;
84     INTCONbits.RBIF = 0;
85     INTCONbits.GIE = 1;
86     INTCONbits.PEIE = 1;
87
88 #else
89     INTCON &= ~(_INTCON_RBIF_MASK | _INTCON_RBIE_MASK);
90 //    INTCON |= _GIE;
91     INTCON |= (_INTCON_GIE_MASK | _INTCON_PEIE_MASK);
92 #endif
93 }
94
95 void power_on(unsigned char f)
96 {
97     if(f == 0x00){
98         set_examp_mute(1);
99         idle_time_ms(200);
100         set_radiopower(0);
101     } else {
102         set_examp_mute(0);
103         idle_time_ms(100);
104         set_radiopower(1);
105     }
106 }
107
108 void rfamp_power(unsigned char b)
109 {
110     __bitops_t bx;
111     
112     bx.byte = b;
113     if(bx.b0) {
114         _RFAMP_SEL_B0 = 1;
115     } else {
116         _RFAMP_SEL_B0 = 0;
117     }
118     if(bx.b1) {
119         _RFAMP_SEL_B1 = 1;
120     } else {
121         _RFAMP_SEL_B1 = 0;
122     }
123
124 }
125
126 unsigned char chk_powerbutton(void)
127 {
128     unsigned char count = 0;
129     char i;
130     for(i = 0; i < 24; i++) {  // 10*32=320ms.
131         if(PORTBbits.RB4 == 0) count++;
132         _POWER_DELAY();
133         ClrWdt();
134     }
135     if(count > 15) {
136         return 0xff; // Pressed
137     }
138     return 0; // Not pressed
139 }
140
141 void shutdown(unsigned char save)
142 {
143     _CLS();
144     _LOCATE(0,0);
145 //    printstr("Bye...");
146     idle_time_ms(1500); // 1.5Sec
147     lcd_setbacklight(0, 0);
148     set_powerlamp(0);
149     _AM_STATLAMP = 0;
150     _FM_STATLAMP = 0;
151 //    _CLS();
152     acm1602_suspend(LCD_I2CADDR);
153     power_off(save);
154 }
155
156 void power_off(unsigned char save)
157 {
158     unsigned char sts;
159     if(save != 0) save_eeprom();
160     WDTCONbits.SWDTEN = 0; // Lame WDT OFF.
161
162     do {
163         IOCB = 0x00;
164         IOCB |= 0x10; // IOCB4 ONLY.
165         OSCCONbits.IDLEN = 0; // Not Idle.
166         INTCON2bits.RBIP = 1; // Priority = HIGH;
167         INTCONbits.RBIF = 0;
168         INTCONbits.GIE = 0;
169         INTCONbits.PEIE = 0;
170         INTCONbits.RBIE = 1;
171         power_on(0);
172         Sleep();
173         // Wake up
174         if(INTCONbits.RBIF == 1) {
175             sts = chk_powerbutton();
176         } else {
177             sts = 0;
178         }
179     } while(sts == 0);
180     INTCONbits.RBIF = 0;
181     INTCONbits.RBIE = 0;
182
183     INTCONbits.GIE = 1;
184     INTCONbits.PEIE = 1;
185
186     // Button pressed, software reset.
187     Reset();
188 }