OSDN Git Service

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