summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
Diffstat (limited to 'apps')
-rw-r--r--apps/plugins/battery_bench.c339
1 files changed, 339 insertions, 0 deletions
diff --git a/apps/plugins/battery_bench.c b/apps/plugins/battery_bench.c
new file mode 100644
index 0000000000..3eebb44d8f
--- /dev/null
+++ b/apps/plugins/battery_bench.c
@@ -0,0 +1,339 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 *
11 * Copyright (C) 2006 Alexander Spyridakis, Hristo Kovachev
12 *
13 * All files in this archive are subject to the GNU General Public License.
14 * See the file COPYING in the source tree root for full license agreement.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20#ifndef SIMULATOR /* not for the simulator */
21
22#include "plugin.h"
23PLUGIN_HEADER
24
25#define BATTERY_LOG "/battery_bench.txt"
26#define BUF_SIZE 16000
27#define DISK_SPINDOWN_TIMEOUT 3600
28
29#define EV_EXIT 1337
30
31#if CONFIG_KEYPAD == RECORDER_PAD
32#define BATTERY_ON BUTTON_ON
33#define BATTERY_OFF BUTTON_OFF
34
35#elif CONFIG_KEYPAD == ONDIO_PAD
36#define BATTERY_ON BUTTON_RIGHT
37#define BATTERY_OFF BUTTON_OFF
38
39#elif CONFIG_KEYPAD == PLAYER_PAD
40#define BATTERY_ON BUTTON_ON
41#define BATTERY_OFF BUTTON_STOP
42
43#elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
44 (CONFIG_KEYPAD == IRIVER_H300_PAD)
45
46#define BATTERY_ON BUTTON_ON
47#define BATTERY_RC_ON BUTTON_RC_ON
48
49#define BATTERY_OFF BUTTON_OFF
50#define BATTERY_RC_OFF BUTTON_RC_STOP
51#endif
52
53
54/***************** Plugin Entry Point *****************/
55static struct plugin_api* rb;
56int main(void);
57void exit_tsr(void);
58void thread(void);
59
60enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
61{
62 (void)parameter;
63 rb = api;
64
65 return main();
66}
67
68struct
69{
70 int id;
71 bool ended;
72} s_thread;
73
74/* Struct for battery information */
75struct batt_info
76{
77 int ticks, level, eta;
78 unsigned int voltage;
79};
80
81struct event_queue thread_q;
82
83void exit_tsr(void)
84{
85 rb->queue_post(&thread_q, EV_EXIT, NULL);
86 while (!s_thread.ended)
87 rb->yield();
88 /* remove the thread's queue from the broadcast list */
89 rb->queue_delete(&thread_q);
90}
91
92#define HMS(x) (x)/3600,((x)%3600)/60,((x)%3600)%60
93void thread(void)
94{
95 bool got_info = false, timeflag = false, in_usb_mode = false;
96 int fd, buffelements, tick = 1, i = 0, skipped = 0, exit = 0;
97 int fst = 0, lst = 0; /* first and last skipped tick */
98 unsigned int last_voltage = 0;
99 long sleep_time;
100
101 struct event ev;
102
103 struct batt_info bat[buffelements = (BUF_SIZE / sizeof(struct batt_info))];
104
105 sleep_time = (rb->global_settings->disk_spindown > 1) ?
106 (rb->global_settings->disk_spindown - 1) * HZ : 5 * HZ;
107
108 do
109 {
110 if(!in_usb_mode && got_info &&
111 (exit || timeflag || rb->ata_disk_is_active()) )
112 {
113 int last, secs, j, temp = skipped;
114
115 fd = rb->open(BATTERY_LOG, O_RDWR | O_CREAT | O_APPEND);
116 if(fd < 0)
117 exit = 1;
118 else
119 {
120 do
121 {
122 if(skipped)
123 {
124 last = buffelements;
125 fst /= HZ;
126 lst /= HZ;
127 rb->fdprintf(fd,"-Skipped %d measurements from "
128 "%02d:%02d:%02d to %02d:%02d:%02d-\n",skipped,
129 HMS(fst),HMS(lst));
130 skipped = 0;
131 }
132 else
133 {
134 last = i;
135 i = 0;
136 }
137
138 for(j = i; j < last; j++)
139 {
140 secs = bat[j].ticks/HZ;
141 rb->fdprintf(fd,
142 "%02d:%02d:%02d, %05d, %03d%%, "
143 "%02d:%02d, %04d, %04d\n",
144 HMS(secs), secs, bat[j].level,
145 bat[j].eta / 60, bat[j].eta % 60,
146 bat[j].voltage * 10, temp + 1 + (j-i));
147 if(!j % 100 && !j) /* yield() at every 100 writes */
148 rb->yield();
149 }
150 temp += j - i;
151
152 }while(i != 0);
153
154 rb->close(fd);
155 tick = *rb->current_tick;
156 got_info = false;
157 timeflag = false;
158 }
159 }
160 else
161 {
162 if(!rb->pcm_is_playing() &&
163 (*rb->current_tick - tick) > DISK_SPINDOWN_TIMEOUT * HZ)
164 timeflag = true;
165
166 if(last_voltage != rb->battery_voltage())
167 {
168 if(i == buffelements)
169 {
170 if(!skipped++)
171 fst = bat[0].ticks;
172 i = 0;
173 }
174 else if(skipped)
175 {
176 skipped++;
177 lst = bat[i].ticks;
178 }
179 bat[i].ticks = *rb->current_tick;
180 bat[i].level = rb->battery_level();
181 bat[i].eta = rb->battery_time();
182 last_voltage = bat[i++].voltage = rb->battery_voltage();
183 got_info = true;
184 }
185
186 }
187
188 if(exit)
189 {
190 if(exit == 2)
191 rb->splash(HZ,true,"Exiting battery_bench...");
192 s_thread.ended = true;
193 rb->remove_thread(s_thread.id);
194 rb->yield(); /* exit the thread, this yield() won't return */
195 }
196
197 rb->queue_wait_w_tmo(&thread_q, &ev, sleep_time);
198 switch (ev.id)
199 {
200 case SYS_USB_CONNECTED:
201 in_usb_mode = true;
202 rb->usb_acknowledge(SYS_USB_CONNECTED_ACK);
203 break;
204 case SYS_USB_DISCONNECTED:
205 in_usb_mode = false;
206 rb->usb_acknowledge(SYS_USB_DISCONNECTED_ACK);
207 break;
208 case SYS_POWEROFF:
209 exit = 1;
210 break;
211 case EV_EXIT:
212 exit = 2;
213 break;
214 }
215 } while (1);
216
217}
218
219int main(void)
220{
221 int stacksize, button, fd;
222 bool on = false;
223 void* stack;
224
225
226 rb->lcd_clear_display();
227
228#ifdef HAVE_LCD_BITMAP
229 int strwdt, strhgt;
230
231 rb->lcd_setfont(FONT_SYSFIXED);
232
233 rb->lcd_getstringsize("Battery Benchmark", &strwdt, &strhgt);
234 rb->lcd_putsxy((LCD_WIDTH - strwdt)/2, strhgt, "Battery Benchmark");
235
236 rb->lcd_getstringsize("Check /battery_bench.txt", &strwdt, &strhgt);
237 rb->lcd_putsxy((LCD_WIDTH - strwdt)/2,strhgt * 3,
238 "Check /battery_bench.txt");
239 rb->lcd_getstringsize("file for more info.", &strwdt, &strhgt);
240 rb->lcd_putsxy((LCD_WIDTH - strwdt)/2, strhgt * 4, "file for more info.");
241 rb->lcd_getstringsize("Play to start, OFF to quit", &strwdt, &strhgt);
242 rb->lcd_putsxy((LCD_WIDTH - strwdt)/2, strhgt * 5,
243 "PLAY to start, OFF to quit");
244
245 rb->lcd_update();
246
247#else
248 rb->lcd_puts_scroll(0, 1, "Battery Benchmark");
249 rb->lcd_puts_scroll(0, 2, "PLAY to start, OFF to quit");
250#endif
251
252 do
253 {
254 button = rb->button_get(true);
255 switch(button)
256 {
257 case BATTERY_ON:
258#ifdef BATTERY_RC_ON
259 case BATTERY_RC_ON:
260#endif
261 on = true;
262 break;
263 case BATTERY_OFF:
264#ifdef BATTERY_RC_OFF
265 case BATTERY_RC_OFF:
266#endif
267 return PLUGIN_OK;
268
269 default: if(rb->default_event_handler(button) == SYS_USB_CONNECTED)
270 return PLUGIN_USB_CONNECTED;
271 }
272 }while(!on);
273
274 stack = rb->plugin_get_buffer(&stacksize);
275 /* long align it and leave some space (200bytes) for vars */
276 stack = (void*)(((unsigned int)stack + 200) & ~3);
277
278 stacksize = (stacksize - 200) & ~3;
279 if (stacksize < BUF_SIZE)
280 {
281 rb->splash(HZ*2, true, "Out of memory");
282 return PLUGIN_ERROR;
283 }
284
285 fd = rb->open(BATTERY_LOG, O_RDONLY);
286 if(fd < 0)
287 {
288 fd = rb->open(BATTERY_LOG, O_RDWR | O_CREAT);
289 if(fd >= 0)
290 {
291 rb->fdprintf(fd,
292 "This plugin will log your battery performance in a\n"
293 "file (%s) every time the disk is accessed (or every hour).\n"
294 "To properly test your battery:\n"
295 "1) Select and playback an album. "
296 "(Be sure to be more than the player's buffer)\n"
297 "2) Set to repeat.\n"
298 "3) Let the player run completely out of battery.\n"
299 "4) Recharge and copy (or whatever you want) the txt file to "
300 "your computer.\n"
301 "Now you can make graphs with the data of the battery log.\n"
302 "Do not enter another plugin during the test or else the "
303 "logging activity will end.\n\n"
304 "P.S: You can decide how you will make your tests.\n"
305 "Just don't open another plugin to be sure that your log "
306 "will continue.\n"
307 "M/DA (Measurements per Disk Activity) shows how many times\n"
308 "data was logged in the buffer between Disk Activity.\n\n"
309 "Battery type: %d mAh Buffer Entries: %d\n"
310 " Time:, Seconds:, Level:, Time Left:, Voltage[mV]:,"
311 " M/DA:\n"
312 ,BATTERY_LOG,rb->global_settings->battery_capacity,
313 BUF_SIZE / sizeof(struct batt_info));
314 rb->close(fd);
315 }
316 else
317 {
318 rb->splash(HZ / 2, true, "Cannot create file!");
319 return PLUGIN_ERROR;
320 }
321 }
322 else
323 {
324 rb->close(fd);
325 fd = rb->open(BATTERY_LOG, O_RDWR | O_APPEND);
326 rb->fdprintf(fd, "\nFile already present. Resuming Benchmark\n");
327 rb->close(fd);
328 }
329
330 rb->queue_init(&thread_q); /* put the thread's queue in the bcast list */
331 rb->memset(&s_thread, 0, sizeof(s_thread)); /* zero the struct */
332 s_thread.id = rb->create_thread(thread, stack,
333 stacksize, "Battery Benchmark");
334 rb->plugin_tsr(exit_tsr);
335
336 return PLUGIN_OK;
337}
338
339#endif