CircleOS  1
power.c
Go to the documentation of this file.
1 /****************** COPYRIGHT (C) 2007-2013 KEOLABS S.A.S. ********************/
13 /******************************************************************************/
14 
15 /* Includes ------------------------------------------------------------------*/
16 #include "circle.h"
17 
19 
20 #define MAX_TIME_ON (60*5) //shutdown after 5mn when no activity
21 u8 PWR_BatteryLevel = 100;
22 
23 u16 PWR_CurrentVBat = 0;
24 counter_t PWR_ReferenceTime = -1;
25 enum ePowerState PWR_CurrentState = PWR_STATE_UNDEF;
26 
27 
28 /*******************************************************************************
29 *
30 * POWER_Handler
31 *
32 *******************************************************************************/
39 /******************************************************************************/
40 void POWER_Handler( void )
41 {
42  enum ePowerState new_state = PWR_STATE_UNDEF;
43  static enum ePowerState last_state = PWR_STATE_UNDEF;
44  static u32 last_time = 0;
45  static u16 MinBat = 0;
46  static s32 stacounter = 0;
47  static s32 stacounter2 = 0;
48 
49  // iToShutDown is a global flag to indicate that a shutdown has been requested
50  if ( iToShutDown )
51  {
52  while ( 1 )
53  {
55  }
56  }
57 
58  u32 time = RTC_GetCounter();
59 
60  if ( last_time == 0 ) // initialization
61  {
62  PWR_CurrentVBat = UTIL_GetBat();
63  }
64 
65  //
66  if ( time != last_time ) // once per second is enough for measurement
67  {
68  u16 vbat = UTIL_GetBat();
69 
70  // Filter on 8 values
71  PWR_CurrentVBat = ( ( PWR_CurrentVBat * 7 ) + vbat ) / 8;
72  }
73  else
74  return;
75 
76  // Power management
77  if ( ( time / 3 ) != ( last_time / 3 ) ) // once per 3 seconds is enough for changing the display/state
78  {
79  // Read the status of the battery charger FL120727
80  s32 flagsta = POWER_ReadStatus();
81 
82  switch ( flagsta )
83  {
84  case 1 : // Done : (green on and red off)
85  new_state = PWR_STATE_FULL;
86  PWR_BatteryLevel = 100;
87  break;
88  case 2 : // Battery is being charged : (green off and red on)
89  new_state = PWR_STATE_CHARGING;
90  PWR_BatteryLevel = 50;
91  break;
92  case 3 : // Power supplied by battery : (green off and red off) = normal mode
93  new_state = PWR_STATE_NORMAL;
94  PWR_BatteryLevel = 50;
95  break;
96  case 0 : // Battery is absent or dead : (green on and red on)
97  if ( PWR_CurrentVBat < NO_BAT_VOLTAGE )
98  {
99  // USB connected
100  new_state = PWR_STATE_NOBAT;
101  PWR_BatteryLevel = 100;
102  }
103  else
104  // Battery is dead
105  {
106  new_state = PWR_STATE_NORMAL;
107  PWR_BatteryLevel = 0;
108  }
109  break;
110  }
111 
112  // We change only when we have twice the same state
113  if ( new_state == last_state )
114  {
115  if ( new_state != PWR_CurrentState )
116  {
117  switch ( PWR_CurrentState )
118  {
119  case PWR_STATE_NORMAL:
120  case PWR_STATE_LOW:
121  case PWR_STATE_EMPTY:
122  if ( new_state == PWR_STATE_NORMAL )
123  break;
124  default:
125  PWR_CurrentState = new_state;
126  MinBat = PWR_CurrentVBat;
127  break;
128  }
129  }
130  }
131 
132  // Now manage the power level.
133  switch ( PWR_CurrentState )
134  {
135  case PWR_STATE_NORMAL:
136  if ( MinBat < BAT_LOW_VOLTAGE )
137  {
138  PWR_CurrentState = PWR_STATE_LOW;
139  }
140  case PWR_STATE_LOW:
141  if ( PWR_CurrentVBat < MinBat )
142  {
143  MinBat = ( PWR_CurrentVBat + MinBat ) / 2;
144  }
145  if ( MinBat < BAT_EMPTY_VOLTAGE )
146  {
147  PWR_CurrentState = PWR_STATE_EMPTY;
148  }
149  PWR_BatteryLevel = ( 100 * ( MinBat - BAT_EMPTY_VOLTAGE ) ) / ( BAT_FULL_VOLTAGE - BAT_EMPTY_VOLTAGE ) ;
150  if ( PWR_BatteryLevel > 100 )
151  {
152  PWR_BatteryLevel = 100 ;
153  }
154  else if ( PWR_BatteryLevel < 0 )
155  {
156  PWR_BatteryLevel = 0 ;
157  }
158  stacounter = 0;
159  break;
160 
161  case PWR_STATE_EMPTY:
162  // 15" filter before shutdown message
163  if ( stacounter2++ > 45 )
164  {
165  CurrentMenu = 0;
167  LCD_ClearAllScreen( RGB_BLACK );
169  DRAW_RestoreCharMagniCoeff();
170  DRAW_DisplayStringWithMode( 0, 90, " BATTERY LOW!!! ", ALL_SCREEN, INVERTED_TEXT, CENTER );
171  DRAW_DisplayStringWithMode( 0, 60, " Shutting down! ", ALL_SCREEN, INVERTED_TEXT, CENTER );
173  if ( stacounter++ > 4 )
174  {
175  SHUTDOWN_Action();
176  }
177  }
178  break;
179 
180  default:
181  break;
182 
183  } // switch ( PWR_CurrentState )
184 
185  last_state = new_state;
186 
187  } // if (( time / 3 ) != ( last_time / 3 ) )
188 
189  last_time = time;
190 
191 
192  if ( PWR_ReferenceTime != -1 )
193  {
194  counter_t On_Time = time - PWR_ReferenceTime;
195  if ( On_Time > MAX_TIME_ON )
196  {
197  if ( ( PWR_CurrentState != PWR_STATE_CHARGING ) && ( PWR_CurrentState != PWR_STATE_NOBAT ) )
198  {
199  SHUTDOWN_Action();
200  }
201  else
202  {
203  POWER_Set_Time();
204  }
205  }
206  }
207 
208 }
209 
210 /*******************************************************************************
211 *
212 * POWER_Reset_Time
213 *
214 *******************************************************************************/
222 /******************************************************************************/
223 void POWER_Reset_Time( void )
224 {
225  PWR_ReferenceTime = -1;
226 }
227 
228 /*******************************************************************************
229 *
230 * POWER_Set_Time
231 *
232 *******************************************************************************/
240 /******************************************************************************/
241 void POWER_Set_Time( void )
242 {
243  if ( PWR_ReferenceTime == -1 )
244  {
246  PWR_ReferenceTime = RTC_GetCounter();
247  }
248 }
249 
251 
252