root/RF_BT_Tail/Power.c

Revision 244, 6.7 kB (checked in by phil, 4 years ago)

added initial Tail Source Package

Line 
1 // File: Power.c
2 //------------------------------------------------------------------------------
3 // Author: Giovanni de Sanctis
4 // Email: info@lateral-technologies.com
5 //------------------------------------------------------------------------------
6 // Date: Dec 2018
7 // Pushbutton, onboard LEDs and other power related functions
8 //------------------------------------------------------------------------------
9
10 #include "Power.h"
11 #include "mcc_generated_files/mcc.h"
12 #include "LEDs.h"
13 #include "Servos.h"
14
15 #define T_OFF                           2                         //Power button hold time in 0.5sec
16 #define T_TICK                          20                        //20ms
17 #define T_TIMER_ISR                     100                       //100ms
18
19 //Battery low threshold assuming 2:1 voltage divider (1023*4.8V/2/3.3)
20 #define ADC_THR(x)                      (155u*x/20u)  //1023/3.3V*5*v/2 (5cells,v=cell voltage in (volt*100)
21
22 #define THR_BATT_ZERO           ADC_THR(80u)  //minimum realistic voltage
23 #define THR_BATT_B0                     ADC_THR(124u) //0 bars, critical
24 #define THR_BATT_B1                     ADC_THR(126u) //1 bar  > 20%
25 #define THR_BATT_B2                     ADC_THR(128u) //2 bars > 50%
26 #define THR_BATT_B3                     ADC_THR(130u) //3 bars > 80%
27 #define THR_BATT_B4                     ADC_THR(132u) //4 fully charged
28 #define THR_BATT_MIN            THR_BATT_B1
29
30
31 //NOTE:Timed battery reading has now been disabled.
32 //  the <battery> variable is updated only if the app requests a battery reading
33 //  so the red LED will start blinking only if the app reads a low battery level
34
35 //Check the battery every 900*0.1s=90s
36 //#define TIMEOUT_CHECK_BATT  900                 
37 //#define TIMEOUT_CHECK_BATT0   100               //Time out for the first battery read
38
39 //Power down if not connected for 1200*0.1=120s
40 #define TIMEOUT_CONNECT         1200
41
42 uint32_t redPattern;            //Stores the pattern for the red LED
43 uint32_t bluePattern;           //Stores the pattern for the blue LED
44 uint32_t patternPtr;            //current bit pointer;
45
46 //uint16_t battTimer;                   //Timer counter to refresh the battery reading
47 uint16_t connectTimer;          //Timer counter to power down if not connected
48
49 uint16_t battery;                       //Last battery reading
50 uint8_t  battBars;                      //battery bars, from 0 to 4
51
52 uint8_t  btConnected;           //>0 if BT module is connected
53 uint8_t  tick;                          //enabled every 20ms;
54 uint8_t  countTick;                     //decremented every timer interrupt.
55 uint8_t  countTimerISR;         //decremented every timer interrupt.
56 uint8_t  poweringOff;           //1 to request shut down
57
58 void ioISR();
59
60 //Called after reset to hold the LDO's enable pin high
61 void powerBootstrap()
62 {
63   IO_POW_SetDigitalOutput();
64   IO_POW_SetHigh();
65
66   btConnected=0;                                //Assume not connected
67   battery=0x3FF;                                //Safe value for battery level
68   battBars=4;
69  
70   //battTimer=TIMEOUT_CHECK_BATT0;//Reset battery timer to enable 1st ADC reading
71   //connectTimer=TIMEOUT_CONNECT;       //Reset connect timer
72  
73   poweringOff = 0;                              //We're not shutting down yet
74  
75   //Light up the LED while the power button is pressed
76   while(CMP1_GetOutputStatus()==0)
77   {
78         IO_LED_RED_N_SetLow();
79         __delay_ms(500);
80   }
81   IO_LED_RED_N_SetHigh();
82  
83   TMR0_SetInterruptHandler(ioISR);
84 }
85
86 void shutDown()
87 {
88   poweringOff=1;
89 }
90
91 uint8_t checkPowerButton()
92 {
93   uint8_t count=0;
94  
95   if (CMP1_GetOutputStatus()==0 || poweringOff)
96   {
97         // Disable the Global Interrupts to stop blinking
98         INTERRUPT_GlobalInterruptDisable();
99         IO_LED_BLUE_N_SetHigh();                        //Turns Off blue LED
100        
101         while(CMP1_GetOutputStatus()==0)
102         {
103           if (count<=T_OFF)
104           {
105                 IO_LED_RED_N_SetLow();
106       }
107           else
108           {
109                 stopLEDs();
110                 stopServos();
111           }
112           __delay_ms(250);
113           IO_LED_RED_N_SetHigh();
114           __delay_ms(250);
115           ++count;
116         }
117        
118         //If power button was pressed for more than T_OFF/2 seconds
119         // then turn power off
120         if (count>T_OFF || poweringOff) IO_POW_SetLow();
121         // Re-Enable the Global Interrupts
122     INTERRUPT_GlobalInterruptEnable();
123   }
124   return 0;
125 }
126
127 void setBluePattern(uint32_t pattern)
128 {
129   //patternPtr=0x00000001;
130   if (!pattern) LED_BLUE_Off();
131   bluePattern=pattern;
132 }
133
134 //Updates the LED patterns; called in Timer1 every 0.1s
135 void ioISR()
136 {
137   countTick--;
138   if (countTick==0)
139   {
140         countTick=T_TICK;
141         tick=1;
142   }
143   countTimerISR--;
144   if (countTimerISR) return;
145   countTimerISR=T_TIMER_ISR;
146   uint8_t status=IO_STA_GetValue();
147  
148  
149   if (status^btConnected)
150   {
151         btConnected = status;
152         if (status) bluePattern=LED_BLUE_CNNCTD;
153         else bluePattern=LED_BLUE_ADVERT;
154   }
155   else
156   {
157         if (!btConnected)
158         {
159           connectTimer--;
160           //Timeout connection to BT
161           if (connectTimer==0) poweringOff=1;
162         }
163         else connectTimer=TIMEOUT_CONNECT;
164   }
165  
166   if (isBattLow())      redPattern=LED_RED_BATT;
167   else                          redPattern=LED_RED_OFF;
168  
169   patternPtr<<=1;
170   if (patternPtr==0) patternPtr=0x00000001;
171   if (redPattern)
172   {
173     if (redPattern & patternPtr) LED_RED_On();
174     else LED_RED_Off();
175   }
176   if (bluePattern)
177   {
178     if (bluePattern & patternPtr) LED_BLUE_On();
179     else LED_BLUE_Off();
180   }
181   //if (battTimer) --battTimer;
182 }
183
184 //Waits 20mS (for servo timing)
185 void wait20ms()
186 {
187   tick=0;
188   while(tick==0);
189 }
190
191
192 //Returns the battery voltage in fractions of 2.048V, i.e. 0x00=0V, 0xFF=2V
193 //the lsb indicates wheather the voltage is above a set threshold THR_BATT
194 //if lsb=0 then the voltage is below the threshold.
195 //The battery voltage depends on the voltage divider between battery and ADC in.
196 uint16_t getBatt()
197 {
198   uint16_t reading;
199    
200   if (poweringOff) return battery;                      //If shutting down then exit 
201   //If servos are running then don't read new value (it would be skewed)
202   if (isServoOn()) return battery;
203
204   IO_PWM_LEDS_SetHigh();
205   IO_PWM_LEDS_SetDigitalOutput();
206  
207   //Unlock peripheral select
208   PPSLOCK=0x55;                                                 //Magic sequence
209   PPSLOCK=0xAA;
210   PPSLOCK=0x00;                                                 //Reset PPSLOCKED bit
211  
212   RB7PPS = 0x00;                                                //RB7->LATB7  (detaches the out from the PWM3 preripheral)
213   __delay_us(160);                                              //Allow parasitic caps to charge
214   reading=ADC1_GetConversion(ADC_BATT); //Get ADC value
215   RB7PPS = 0x05;                                                //RB7->PWM3:PWM3OUT (reattaches PWM3)
216   //Re-lock peripheral select
217   PPSLOCK=0x55;                                                 //Magic sequence
218   PPSLOCK=0xAA;
219   PPSLOCK=0x01;                                                 //Set PPSLOCKED bit
220  
221   //Make sure we read a meaningful voltage before updating
222   if (reading>THR_BATT_ZERO) battery=reading;
223  
224   if (battery>=THR_BATT_B4) battBars=4;
225   else if (battery>=THR_BATT_B3) battBars=3;
226   else if (battery>=THR_BATT_B2) battBars=2;
227   else if (battery>=THR_BATT_B1) battBars=1;
228   else
229   {
230         battBars=0;
231         //shutDown();                           //Battery critical, shut down to prevent damage
232   }
233   return battery;
234 }
235
236 //Returns the battery charge remaining, expressed in 'bars', from 0 to 4
237 uint8_t getBattBars()
238 {
239   getBatt();
240   return battBars;
241 }
242
243
244 //Returns 1 if battery voltage is below threshold
245 uint8_t isBattLow()
246 {
247   //getBatt();
248   return (uint8_t)(battery<THR_BATT_MIN);
249 }
Note: See TracBrowser for help on using the browser.