Remove leftover backslash from macro conversion in FRACTMUL_SHL
[maemo-rb.git] / apps / debug_menu.c
blobb557f46dc30d0044507b3962128afbdea01e762b
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2002 Heikki Hannikainen
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
22 #include "config.h"
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <stdbool.h>
26 #include <string.h>
27 #include "lcd.h"
28 #include "menu.h"
29 #include "debug_menu.h"
30 #include "kernel.h"
31 #include "structec.h"
32 #include "action.h"
33 #include "debug.h"
34 #include "thread.h"
35 #include "powermgmt.h"
36 #include "system.h"
37 #include "font.h"
38 #include "audio.h"
39 #include "mp3_playback.h"
40 #include "settings.h"
41 #include "list.h"
42 #include "statusbar.h"
43 #include "dir.h"
44 #include "panic.h"
45 #include "screens.h"
46 #include "misc.h"
47 #include "splash.h"
48 #include "dircache.h"
49 #include "viewport.h"
50 #ifdef HAVE_TAGCACHE
51 #include "tagcache.h"
52 #endif
53 #include "lcd-remote.h"
54 #include "crc32.h"
55 #include "logf.h"
56 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
57 #include "disk.h"
58 #include "adc.h"
59 #include "power.h"
60 #include "usb.h"
61 #include "rtc.h"
62 #include "storage.h"
63 #include "fat.h"
64 #include "eeprom_24cxx.h"
65 #if (CONFIG_STORAGE & STORAGE_MMC) || (CONFIG_STORAGE & STORAGE_SD)
66 #include "sdmmc.h"
67 #endif
68 #if (CONFIG_STORAGE & STORAGE_ATA)
69 #include "ata.h"
70 #endif
71 #if CONFIG_TUNER
72 #include "tuner.h"
73 #include "radio.h"
74 #endif
75 #endif
77 #ifdef HAVE_LCD_BITMAP
78 #include "scrollbar.h"
79 #include "peakmeter.h"
80 #endif
81 #include "logfdisp.h"
82 #if CONFIG_CODEC == SWCODEC
83 #include "pcmbuf.h"
84 #include "buffering.h"
85 #include "playback.h"
86 #if defined(HAVE_SPDIF_OUT) || defined(HAVE_SPDIF_IN)
87 #include "spdif.h"
88 #endif
89 #endif
90 #ifdef IRIVER_H300_SERIES
91 #include "pcf50606.h" /* for pcf50606_read */
92 #endif
93 #ifdef IAUDIO_X5
94 #include "ds2411.h"
95 #endif
96 #include "hwcompat.h"
97 #include "button.h"
98 #if CONFIG_RTC == RTC_PCF50605
99 #include "pcf50605.h"
100 #endif
101 #include "appevents.h"
102 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
103 #include "debug-target.h"
104 #endif
106 #if defined(SANSA_E200) || defined(SANSA_C200) || defined(PHILIPS_SA9200) \
107 || (CONFIG_CPU == AS3525 && defined(CONFIG_CHARGING)) \
108 || CONFIG_CPU == AS3525v2
109 #include "ascodec.h"
110 #include "as3514.h"
111 #endif
113 #ifdef IPOD_NANO2G
114 #include "pmu-target.h"
115 #endif
117 #ifdef HAVE_USBSTACK
118 #include "usb_core.h"
119 #endif
121 #if defined(IPOD_ACCESSORY_PROTOCOL)
122 #include "iap.h"
123 #endif
125 /*---------------------------------------------------*/
126 /* SPECIAL DEBUG STUFF */
127 /*---------------------------------------------------*/
128 extern struct thread_entry threads[MAXTHREADS];
130 static char thread_status_char(unsigned status)
132 static const char thread_status_chars[THREAD_NUM_STATES+1] =
134 [0 ... THREAD_NUM_STATES] = '?',
135 [STATE_RUNNING] = 'R',
136 [STATE_BLOCKED] = 'B',
137 [STATE_SLEEPING] = 'S',
138 [STATE_BLOCKED_W_TMO] = 'T',
139 [STATE_FROZEN] = 'F',
140 [STATE_KILLED] = 'K',
143 if (status > THREAD_NUM_STATES)
144 status = THREAD_NUM_STATES;
146 return thread_status_chars[status];
149 static const char* threads_getname(int selected_item, void *data,
150 char *buffer, size_t buffer_len)
152 (void)data;
153 struct thread_entry *thread;
154 char name[32];
156 #if NUM_CORES > 1
157 if (selected_item < (int)NUM_CORES)
159 snprintf(buffer, buffer_len, "Idle (%d): %2d%%", selected_item,
160 idle_stack_usage(selected_item));
161 return buffer;
164 selected_item -= NUM_CORES;
165 #endif
167 thread = &threads[selected_item];
169 if (thread->state == STATE_KILLED)
171 snprintf(buffer, buffer_len, "%2d: ---", selected_item);
172 return buffer;
175 thread_get_name(name, 32, thread);
177 snprintf(buffer, buffer_len,
178 "%2d: " IF_COP("(%d) ") "%c%c " IF_PRIO("%d %d ") "%2d%% %s",
179 selected_item,
180 IF_COP(thread->core,)
181 #ifdef HAVE_SCHEDULER_BOOSTCTRL
182 (thread->cpu_boost) ? '+' :
183 #endif
184 ((thread->state == STATE_RUNNING) ? '*' : ' '),
185 thread_status_char(thread->state),
186 IF_PRIO(thread->base_priority, thread->priority, )
187 thread_stack_usage(thread), name);
189 return buffer;
192 static int dbg_threads_action_callback(int action, struct gui_synclist *lists)
194 (void)lists;
195 #ifdef ROCKBOX_HAS_LOGF
196 if (action == ACTION_STD_OK)
198 int selpos = gui_synclist_get_sel_pos(lists);
199 #if NUM_CORES > 1
200 if (selpos >= NUM_CORES)
201 remove_thread(threads[selpos - NUM_CORES].id);
202 #else
203 remove_thread(threads[selpos].id);
204 #endif
205 return ACTION_REDRAW;
207 #endif /* ROCKBOX_HAS_LOGF */
208 if (action == ACTION_NONE)
209 action = ACTION_REDRAW;
210 return action;
212 /* Test code!!! */
213 static bool dbg_os(void)
215 struct simplelist_info info;
216 simplelist_info_init(&info, IF_COP("Core and ") "Stack usage:",
217 #if NUM_CORES == 1
218 MAXTHREADS,
219 #else
220 MAXTHREADS+NUM_CORES,
221 #endif
222 NULL);
223 #ifndef ROCKBOX_HAS_LOGF
224 info.hide_selection = true;
225 info.scroll_all = true;
226 #endif
227 info.action_callback = dbg_threads_action_callback;
228 info.get_name = threads_getname;
229 return simplelist_show_list(&info);
232 #ifdef HAVE_LCD_BITMAP
233 #if CONFIG_CODEC != SWCODEC
234 #ifndef SIMULATOR
235 static bool dbg_audio_thread(void)
237 struct audio_debug d;
239 lcd_setfont(FONT_SYSFIXED);
241 while(1)
243 if (action_userabort(HZ/5))
244 return false;
246 audio_get_debugdata(&d);
248 lcd_clear_display();
250 lcd_putsf(0, 0, "read: %x", d.audiobuf_read);
251 lcd_putsf(0, 1, "write: %x", d.audiobuf_write);
252 lcd_putsf(0, 2, "swap: %x", d.audiobuf_swapwrite);
253 lcd_putsf(0, 3, "playing: %d", d.playing);
254 lcd_putsf(0, 4, "playable: %x", d.playable_space);
255 lcd_putsf(0, 5, "unswapped: %x", d.unswapped_space);
257 /* Playable space left */
258 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, 6*8, 112, 4, d.audiobuflen, 0,
259 d.playable_space, HORIZONTAL);
261 /* Show the watermark limit */
262 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, 6*8+4, 112, 4, d.audiobuflen, 0,
263 d.low_watermark_level, HORIZONTAL);
265 lcd_putsf(0, 7, "wm: %x - %x",
266 d.low_watermark_level, d.lowest_watermark_level);
268 lcd_update();
270 lcd_setfont(FONT_UI);
271 return false;
273 #endif /* !SIMULATOR */
274 #else /* CONFIG_CODEC == SWCODEC */
275 static unsigned int ticks, freq_sum;
276 #ifndef CPU_MULTI_FREQUENCY
277 static unsigned int boost_ticks;
278 #endif
280 static void dbg_audio_task(void)
282 #ifdef CPUFREQ_NORMAL
283 #ifndef CPU_MULTI_FREQUENCY
284 if(FREQ > CPUFREQ_NORMAL)
285 boost_ticks++;
286 #endif
287 freq_sum += FREQ/1000000; /* in MHz */
288 #endif
289 ticks++;
292 static bool dbg_buffering_thread(void)
294 int button;
295 int line, i;
296 bool done = false;
297 size_t bufused;
298 size_t bufsize = pcmbuf_get_bufsize();
299 int pcmbufdescs = pcmbuf_descs();
300 struct buffering_debug d;
301 size_t filebuflen = audio_get_filebuflen();
302 /* This is a size_t, but call it a long so it puts a - when it's bad. */
304 #ifndef CPU_MULTI_FREQUENCY
305 boost_ticks = 0;
306 #endif
307 ticks = freq_sum = 0;
309 tick_add_task(dbg_audio_task);
311 FOR_NB_SCREENS(i)
312 screens[i].setfont(FONT_SYSFIXED);
314 while(!done)
316 button = get_action(CONTEXT_STD,HZ/5);
317 switch(button)
319 case ACTION_STD_NEXT:
320 audio_next();
321 break;
322 case ACTION_STD_PREV:
323 audio_prev();
324 break;
325 case ACTION_STD_CANCEL:
326 done = true;
327 break;
330 buffering_get_debugdata(&d);
331 bufused = bufsize - pcmbuf_free();
333 FOR_NB_SCREENS(i)
335 line = 0;
336 screens[i].clear_display();
339 screens[i].putsf(0, line++, "pcm: %6ld/%ld", (long) bufused, (long) bufsize);
341 gui_scrollbar_draw(&screens[i],0, line*8, screens[i].lcdwidth, 6,
342 bufsize, 0, bufused, HORIZONTAL);
343 line++;
345 screens[i].putsf(0, line++, "alloc: %6ld/%ld", audio_filebufused(),
346 (long) filebuflen);
348 #if LCD_HEIGHT > 80 || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_HEIGHT > 80)
349 if (screens[i].lcdheight > 80)
351 gui_scrollbar_draw(&screens[i],0, line*8, screens[i].lcdwidth, 6,
352 filebuflen, 0, audio_filebufused(), HORIZONTAL);
353 line++;
355 screens[i].putsf(0, line++, "real: %6ld/%ld", (long)d.buffered_data,
356 (long)filebuflen);
358 gui_scrollbar_draw(&screens[i],0, line*8, screens[i].lcdwidth, 6,
359 filebuflen, 0, (long)d.buffered_data, HORIZONTAL);
360 line++;
362 #endif
364 screens[i].putsf(0, line++, "usefl: %6ld/%ld", (long)(d.useful_data),
365 (long)filebuflen);
367 #if LCD_HEIGHT > 80 || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_HEIGHT > 80)
368 if (screens[i].lcdheight > 80)
370 gui_scrollbar_draw(&screens[i],0, line*8, screens[i].lcdwidth, 6,
371 filebuflen, 0, d.useful_data, HORIZONTAL);
372 line++;
374 #endif
376 screens[i].putsf(0, line++, "data_rem: %ld", (long)d.data_rem);
378 screens[i].putsf(0, line++, "track count: %2d", audio_track_count());
380 screens[i].putsf(0, line++, "handle count: %d", (int)d.num_handles);
382 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
383 screens[i].putsf(0, line++, "cpu freq: %3dMHz",
384 (int)((FREQ + 500000) / 1000000));
385 #endif
387 if (ticks > 0)
389 int avgclock = freq_sum * 10 / ticks; /* in 100 kHz */
390 #ifdef CPU_MULTI_FREQUENCY
391 int boostquota = (avgclock * 100 - CPUFREQ_NORMAL/1000) /
392 ((CPUFREQ_MAX - CPUFREQ_NORMAL) / 1000000); /* in 0.1 % */
393 #else
394 int boostquota = boost_ticks * 1000 / ticks; /* in 0.1 % */
395 #endif
396 screens[i].putsf(0, line++, "boost:%3d.%d%% (%d.%dMHz)",
397 boostquota/10, boostquota%10, avgclock/10, avgclock%10);
400 screens[i].putsf(0, line++, "pcmbufdesc: %2d/%2d",
401 pcmbuf_used_descs(), pcmbufdescs);
402 screens[i].putsf(0, line++, "watermark: %6d",
403 (int)(d.watermark));
405 screens[i].update();
409 tick_remove_task(dbg_audio_task);
411 FOR_NB_SCREENS(i)
412 screens[i].setfont(FONT_UI);
414 return false;
416 #endif /* CONFIG_CODEC */
417 #endif /* HAVE_LCD_BITMAP */
419 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
420 static const char* dbg_partitions_getname(int selected_item, void *data,
421 char *buffer, size_t buffer_len)
423 (void)data;
424 int partition = selected_item/2;
425 struct partinfo* p = disk_partinfo(partition);
426 if (selected_item%2)
428 snprintf(buffer, buffer_len, " T:%x %ld MB", p->type, p->size / ( 2048 / ( SECTOR_SIZE / 512 )));
430 else
432 snprintf(buffer, buffer_len, "P%d: S:%lx", partition, p->start);
434 return buffer;
437 bool dbg_partitions(void)
439 struct simplelist_info info;
440 simplelist_info_init(&info, "Partition Info", 4, NULL);
441 info.selection_size = 2;
442 info.hide_selection = true;
443 info.scroll_all = true;
444 info.get_name = dbg_partitions_getname;
445 return simplelist_show_list(&info);
447 #endif /* PLATFORM_NATIVE */
449 #if defined(CPU_COLDFIRE) && defined(HAVE_SPDIF_OUT)
450 static bool dbg_spdif(void)
452 int line;
453 unsigned int control;
454 int x;
455 char *s;
456 int category;
457 int generation;
458 unsigned int interruptstat;
459 bool valnogood, symbolerr, parityerr;
460 bool done = false;
461 bool spdif_src_on;
462 int spdif_source = spdif_get_output_source(&spdif_src_on);
463 spdif_set_output_source(AUDIO_SRC_SPDIF IF_SPDIF_POWER_(, true));
465 lcd_clear_display();
466 lcd_setfont(FONT_SYSFIXED);
468 #ifdef HAVE_SPDIF_POWER
469 spdif_power_enable(true); /* We need SPDIF power for both sending & receiving */
470 #endif
472 while (!done)
474 line = 0;
476 control = EBU1RCVCCHANNEL1;
477 interruptstat = INTERRUPTSTAT;
478 INTERRUPTCLEAR = 0x03c00000;
480 valnogood = (interruptstat & 0x01000000)?true:false;
481 symbolerr = (interruptstat & 0x00800000)?true:false;
482 parityerr = (interruptstat & 0x00400000)?true:false;
484 lcd_putsf(0, line++, "Val: %s Sym: %s Par: %s",
485 valnogood?"--":"OK",
486 symbolerr?"--":"OK",
487 parityerr?"--":"OK");
489 lcd_putsf(0, line++, "Status word: %08x", (int)control);
491 line++;
493 x = control >> 31;
494 lcd_putsf(0, line++, "PRO: %d (%s)",
495 x, x?"Professional":"Consumer");
497 x = (control >> 30) & 1;
498 lcd_putsf(0, line++, "Audio: %d (%s)",
499 x, x?"Non-PCM":"PCM");
501 x = (control >> 29) & 1;
502 lcd_putsf(0, line++, "Copy: %d (%s)",
503 x, x?"Permitted":"Inhibited");
505 x = (control >> 27) & 7;
506 switch(x)
508 case 0:
509 s = "None";
510 break;
511 case 1:
512 s = "50/15us";
513 break;
514 default:
515 s = "Reserved";
516 break;
518 lcd_putsf(0, line++, "Preemphasis: %d (%s)", x, s);
520 x = (control >> 24) & 3;
521 lcd_putsf(0, line++, "Mode: %d", x);
523 category = (control >> 17) & 127;
524 switch(category)
526 case 0x00:
527 s = "General";
528 break;
529 case 0x40:
530 s = "Audio CD";
531 break;
532 default:
533 s = "Unknown";
535 lcd_putsf(0, line++, "Category: 0x%02x (%s)", category, s);
537 x = (control >> 16) & 1;
538 generation = x;
539 if(((category & 0x70) == 0x10) ||
540 ((category & 0x70) == 0x40) ||
541 ((category & 0x78) == 0x38))
543 generation = !generation;
545 lcd_putsf(0, line++, "Generation: %d (%s)",
546 x, generation?"Original":"No ind.");
548 x = (control >> 12) & 15;
549 lcd_putsf(0, line++, "Source: %d", x);
552 x = (control >> 8) & 15;
553 switch(x)
555 case 0:
556 s = "Unspecified";
557 break;
558 case 8:
559 s = "A (Left)";
560 break;
561 case 4:
562 s = "B (Right)";
563 break;
564 default:
565 s = "";
566 break;
568 lcd_putsf(0, line++, "Channel: %d (%s)", x, s);
570 x = (control >> 4) & 15;
571 switch(x)
573 case 0:
574 s = "44.1kHz";
575 break;
576 case 0x4:
577 s = "48kHz";
578 break;
579 case 0xc:
580 s = "32kHz";
581 break;
583 lcd_putsf(0, line++, "Frequency: %d (%s)", x, s);
585 x = (control >> 2) & 3;
586 lcd_putsf(0, line++, "Clock accuracy: %d", x);
587 line++;
589 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
590 lcd_putsf(0, line++, "Measured freq: %ldHz",
591 spdif_measure_frequency());
592 #endif
594 lcd_update();
596 if (action_userabort(HZ/10))
597 break;
600 spdif_set_output_source(spdif_source IF_SPDIF_POWER_(, spdif_src_on));
602 #ifdef HAVE_SPDIF_POWER
603 spdif_power_enable(global_settings.spdif_enable);
604 #endif
606 lcd_setfont(FONT_UI);
607 return false;
609 #endif /* CPU_COLDFIRE */
611 #if (CONFIG_RTC == RTC_PCF50605) && (CONFIG_PLATFORM & PLATFORM_NATIVE)
612 static bool dbg_pcf(void)
614 int line;
616 #ifdef HAVE_LCD_BITMAP
617 lcd_setfont(FONT_SYSFIXED);
618 #endif
619 lcd_clear_display();
621 while(1)
623 line = 0;
625 lcd_putsf(0, line++, "DCDC1: %02x", pcf50605_read(0x1b));
626 lcd_putsf(0, line++, "DCDC2: %02x", pcf50605_read(0x1c));
627 lcd_putsf(0, line++, "DCDC3: %02x", pcf50605_read(0x1d));
628 lcd_putsf(0, line++, "DCDC4: %02x", pcf50605_read(0x1e));
629 lcd_putsf(0, line++, "DCDEC1: %02x", pcf50605_read(0x1f));
630 lcd_putsf(0, line++, "DCDEC2: %02x", pcf50605_read(0x20));
631 lcd_putsf(0, line++, "DCUDC1: %02x", pcf50605_read(0x21));
632 lcd_putsf(0, line++, "DCUDC2: %02x", pcf50605_read(0x22));
633 lcd_putsf(0, line++, "IOREGC: %02x", pcf50605_read(0x23));
634 lcd_putsf(0, line++, "D1REGC: %02x", pcf50605_read(0x24));
635 lcd_putsf(0, line++, "D2REGC: %02x", pcf50605_read(0x25));
636 lcd_putsf(0, line++, "D3REGC: %02x", pcf50605_read(0x26));
637 lcd_putsf(0, line++, "LPREG1: %02x", pcf50605_read(0x27));
638 lcd_update();
639 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
641 lcd_setfont(FONT_UI);
642 return false;
646 lcd_setfont(FONT_UI);
647 return false;
649 #endif
651 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
652 static bool dbg_cpufreq(void)
654 int line;
655 int button;
657 #ifdef HAVE_LCD_BITMAP
658 lcd_setfont(FONT_SYSFIXED);
659 #endif
660 lcd_clear_display();
662 while(1)
664 line = 0;
666 lcd_putsf(0, line++, "Frequency: %ld", FREQ);
667 lcd_putsf(0, line++, "boost_counter: %d", get_cpu_boost_counter());
669 lcd_update();
670 button = get_action(CONTEXT_STD,HZ/10);
672 switch(button)
674 case ACTION_STD_PREV:
675 cpu_boost(true);
676 break;
678 case ACTION_STD_NEXT:
679 cpu_boost(false);
680 break;
682 case ACTION_STD_OK:
683 while (get_cpu_boost_counter() > 0)
684 cpu_boost(false);
685 set_cpu_frequency(CPUFREQ_DEFAULT);
686 break;
688 case ACTION_STD_CANCEL:
689 lcd_setfont(FONT_UI);
690 return false;
693 lcd_setfont(FONT_UI);
694 return false;
696 #endif /* HAVE_ADJUSTABLE_CPU_FREQ */
698 #if defined(HAVE_TSC2100) && (CONFIG_PLATFORM & PLATFORM_NATIVE)
699 #include "tsc2100.h"
700 static const char* tsc2100_debug_getname(int selected_item, void * data,
701 char *buffer, size_t buffer_len)
703 int *page = (int*)data;
704 bool reserved = false;
705 switch (*page)
707 case 0:
708 if ((selected_item > 0x0a) ||
709 (selected_item == 0x04) ||
710 (selected_item == 0x08))
711 reserved = true;
712 break;
713 case 1:
714 if ((selected_item > 0x05) ||
715 (selected_item == 0x02))
716 reserved = true;
717 break;
718 case 2:
719 if (selected_item > 0x1e)
720 reserved = true;
721 break;
723 if (reserved)
724 snprintf(buffer, buffer_len, "%02x: RSVD", selected_item);
725 else
726 snprintf(buffer, buffer_len, "%02x: %04x", selected_item,
727 tsc2100_readreg(*page, selected_item)&0xffff);
728 return buffer;
730 static int tsc2100debug_action_callback(int action, struct gui_synclist *lists)
732 int *page = (int*)lists->data;
733 if (action == ACTION_STD_OK)
735 *page = (*page+1)%3;
736 snprintf(lists->title, 32,
737 "tsc2100 registers - Page %d", *page);
738 return ACTION_REDRAW;
740 return action;
742 static bool tsc2100_debug(void)
744 int page = 0;
745 char title[32] = "tsc2100 registers - Page 0";
746 struct simplelist_info info;
747 simplelist_info_init(&info, title, 32, &page);
748 info.timeout = HZ/100;
749 info.get_name = tsc2100_debug_getname;
750 info.action_callback= tsc2100debug_action_callback;
751 return simplelist_show_list(&info);
753 #endif
754 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
755 #ifdef HAVE_LCD_BITMAP
757 * view_battery() shows a automatically scaled graph of the battery voltage
758 * over time. Usable for estimating battery life / charging rate.
759 * The power_history array is updated in power_thread of powermgmt.c.
762 #define BAT_LAST_VAL MIN(LCD_WIDTH, POWER_HISTORY_LEN)
763 #define BAT_YSPACE (LCD_HEIGHT - 20)
766 static bool view_battery(void)
768 int view = 0;
769 int i, x, y, y1, y2, grid, graph;
770 unsigned short maxv, minv;
772 lcd_setfont(FONT_SYSFIXED);
774 while(1)
776 lcd_clear_display();
777 switch (view) {
778 case 0: /* voltage history graph */
779 /* Find maximum and minimum voltage for scaling */
780 minv = power_history[0];
781 maxv = minv + 1;
782 for (i = 1; i < BAT_LAST_VAL && power_history[i]; i++) {
783 if (power_history[i] > maxv)
784 maxv = power_history[i];
785 if (power_history[i] < minv)
786 minv = power_history[i];
789 /* adjust grid scale */
790 if ((maxv - minv) > 50)
791 grid = 50;
792 else
793 grid = 5;
795 /* print header */
796 lcd_putsf(0, 0, "battery %d.%03dV", power_history[0] / 1000,
797 power_history[0] % 1000);
798 lcd_putsf(0, 1, "%d.%03d-%d.%03dV (%2dmV)",
799 minv / 1000, minv % 1000, maxv / 1000, maxv % 1000,
800 grid);
802 i = 1;
803 while ((y = (minv - (minv % grid)+i*grid)) < maxv)
805 graph = ((y-minv)*BAT_YSPACE)/(maxv-minv);
806 graph = LCD_HEIGHT-1 - graph;
808 /* draw dotted horizontal grid line */
809 for (x=0; x<LCD_WIDTH;x=x+2)
810 lcd_drawpixel(x,graph);
812 i++;
815 x = 0;
816 /* draw plot of power history
817 * skip empty entries
819 for (i = BAT_LAST_VAL - 1; i > 0; i--)
821 if (power_history[i] && power_history[i-1])
823 y1 = (power_history[i] - minv) * BAT_YSPACE /
824 (maxv - minv);
825 y1 = MIN(MAX(LCD_HEIGHT-1 - y1, 20),
826 LCD_HEIGHT-1);
827 y2 = (power_history[i-1] - minv) * BAT_YSPACE /
828 (maxv - minv);
829 y2 = MIN(MAX(LCD_HEIGHT-1 - y2, 20),
830 LCD_HEIGHT-1);
832 lcd_set_drawmode(DRMODE_SOLID);
834 /* make line thicker */
835 lcd_drawline(((x*LCD_WIDTH)/(BAT_LAST_VAL)),
836 y1,
837 (((x+1)*LCD_WIDTH)/(BAT_LAST_VAL)),
838 y2);
839 lcd_drawline(((x*LCD_WIDTH)/(BAT_LAST_VAL))+1,
840 y1+1,
841 (((x+1)*LCD_WIDTH)/(BAT_LAST_VAL))+1,
842 y2+1);
843 x++;
846 break;
848 case 1: /* status: */
849 #if CONFIG_CHARGING >= CHARGING_MONITOR
850 lcd_putsf(0, 0, "Pwr status: %s",
851 charging_state() ? "charging" : "discharging");
852 #else
853 lcd_puts(0, 0, "Power status:");
854 #endif
855 battery_read_info(&y, NULL);
856 lcd_putsf(0, 1, "Battery: %d.%03d V", y / 1000, y % 1000);
857 #ifdef ADC_EXT_POWER
858 y = (adc_read(ADC_EXT_POWER) * EXT_SCALE_FACTOR) / 1000;
859 lcd_putsf(0, 2, "External: %d.%03d V", y / 1000, y % 1000);
860 #endif
861 #if CONFIG_CHARGING
862 #if defined ARCHOS_RECORDER
863 lcd_putsf(0, 3, "Chgr: %s %s",
864 charger_inserted() ? "present" : "absent",
865 charger_enabled() ? "on" : "off");
866 lcd_putsf(0, 5, "short delta: %d", short_delta);
867 lcd_putsf(0, 6, "long delta: %d", long_delta);
868 lcd_puts(0, 7, power_message);
869 lcd_putsf(0, 8, "USB Inserted: %s",
870 usb_inserted() ? "yes" : "no");
871 #elif defined IPOD_NANO || defined IPOD_VIDEO
872 int usb_pwr = (GPIOL_INPUT_VAL & 0x10)?true:false;
873 int ext_pwr = (GPIOL_INPUT_VAL & 0x08)?false:true;
874 int dock = (GPIOA_INPUT_VAL & 0x10)?true:false;
875 int charging = (GPIOB_INPUT_VAL & 0x01)?false:true;
876 int headphone= (GPIOA_INPUT_VAL & 0x80)?true:false;
878 lcd_putsf(0, 3, "USB pwr: %s",
879 usb_pwr ? "present" : "absent");
880 lcd_putsf(0, 4, "EXT pwr: %s",
881 ext_pwr ? "present" : "absent");
882 lcd_putsf(0, 5, "Battery: %s",
883 charging ? "charging" : (usb_pwr||ext_pwr) ? "charged" : "discharging");
884 lcd_putsf(0, 6, "Dock mode: %s",
885 dock ? "enabled" : "disabled");
886 lcd_putsf(0, 7, "Headphone: %s",
887 headphone ? "connected" : "disconnected");
888 #ifdef IPOD_VIDEO
889 if(probed_ramsize == 64)
890 x = (adc_read(ADC_4066_ISTAT) * 2400) / (1024 * 2);
891 else
892 x = (adc_read(ADC_4066_ISTAT) * 2400) / (1024 * 3);
893 lcd_putsf(0, 8, "Ibat: %d mA", x);
894 lcd_putsf(0, 9, "Vbat * Ibat: %d mW", x * y / 1000);
895 #endif
896 #elif defined TOSHIBA_GIGABEAT_S
897 int line = 3;
898 unsigned int st;
900 static const unsigned char * const chrgstate_strings[] =
902 "Disabled",
903 "Error",
904 "Discharging",
905 "Precharge",
906 "Constant Voltage",
907 "Constant Current",
908 "<unknown>",
911 lcd_putsf(0, line++, "Charger: %s",
912 charger_inserted() ? "present" : "absent");
914 st = power_input_status() &
915 (POWER_INPUT_CHARGER | POWER_INPUT_BATTERY);
916 lcd_putsf(0, line++, "%s%s",
917 (st & POWER_INPUT_MAIN_CHARGER) ? " Main" : "",
918 (st & POWER_INPUT_USB_CHARGER) ? " USB" : "");
920 y = ARRAYLEN(chrgstate_strings) - 1;
922 switch (charge_state)
924 case CHARGE_STATE_DISABLED: y--;
925 case CHARGE_STATE_ERROR: y--;
926 case DISCHARGING: y--;
927 case TRICKLE: y--;
928 case TOPOFF: y--;
929 case CHARGING: y--;
930 default:;
933 lcd_putsf(0, line++, "State: %s", chrgstate_strings[y]);
935 lcd_putsf(0, line++, "Battery Switch: %s",
936 (st & POWER_INPUT_BATTERY) ? "On" : "Off");
938 y = chrgraw_adc_voltage();
939 lcd_putsf(0, line++, "CHRGRAW: %d.%03d V",
940 y / 1000, y % 1000);
942 y = application_supply_adc_voltage();
943 lcd_putsf(0, line++, "BP : %d.%03d V",
944 y / 1000, y % 1000);
946 y = battery_adc_charge_current();
947 if (y < 0) x = '-', y = -y;
948 else x = ' ';
949 lcd_putsf(0, line++, "CHRGISN:%c%d mA", x, y);
951 y = cccv_regulator_dissipation();
952 lcd_putsf(0, line++, "P CCCV : %d mW", y);
954 y = battery_charge_current();
955 if (y < 0) x = '-', y = -y;
956 else x = ' ';
957 lcd_putsf(0, line++, "I Charge:%c%d mA", x, y);
959 y = battery_adc_temp();
961 if (y != INT_MIN) {
962 lcd_putsf(0, line++, "T Battery: %dC (%dF)", y,
963 (9*y + 160) / 5);
964 } else {
965 /* Conversion disabled */
966 lcd_puts(0, line++, "T Battery: ?");
969 #elif defined(SANSA_E200) || defined(SANSA_C200) || CONFIG_CPU == AS3525 || \
970 CONFIG_CPU == AS3525v2
971 static const char * const chrgstate_strings[] =
973 [CHARGE_STATE_DISABLED - CHARGE_STATE_DISABLED]= "Disabled",
974 [CHARGE_STATE_ERROR - CHARGE_STATE_DISABLED] = "Error",
975 [DISCHARGING - CHARGE_STATE_DISABLED] = "Discharging",
976 [CHARGING - CHARGE_STATE_DISABLED] = "Charging",
978 const char *str = NULL;
980 lcd_putsf(0, 3, "Charger: %s",
981 charger_inserted() ? "present" : "absent");
983 y = charge_state - CHARGE_STATE_DISABLED;
984 if ((unsigned)y < ARRAYLEN(chrgstate_strings))
985 str = chrgstate_strings[y];
987 lcd_putsf(0, 4, "State: %s",
988 str ? str : "<unknown>");
990 lcd_putsf(0, 5, "CHARGER: %02X", ascodec_read_charger());
991 #elif defined(IPOD_NANO2G)
992 y = pmu_read_battery_voltage();
993 lcd_putsf(17, 1, "RAW: %d.%03d V", y / 1000, y % 1000);
994 y = pmu_read_battery_current();
995 lcd_putsf(0, 2, "Battery current: %d mA", y);
996 lcd_putsf(0, 3, "PWRCON: %08x %08x", PWRCON, PWRCONEXT);
997 lcd_putsf(0, 4, "CLKCON: %08x %03x %03x", CLKCON, CLKCON2, CLKCON3);
998 lcd_putsf(0, 5, "PLL: %06x %06x %06x", PLL0PMS, PLL1PMS, PLL2PMS);
999 x = pmu_read(0x1b) & 0xf;
1000 y = pmu_read(0x1a) * 25 + 625;
1001 lcd_putsf(0, 6, "AUTO: %x / %d mV", x, y);
1002 x = pmu_read(0x1f) & 0xf;
1003 y = pmu_read(0x1e) * 25 + 625;
1004 lcd_putsf(0, 7, "DOWN1: %x / %d mV", x, y);
1005 x = pmu_read(0x23) & 0xf;
1006 y = pmu_read(0x22) * 25 + 625;
1007 lcd_putsf(0, 8, "DOWN2: %x / %d mV", x, y);
1008 x = pmu_read(0x27) & 0xf;
1009 y = pmu_read(0x26) * 100 + 900;
1010 lcd_putsf(0, 9, "MEMLDO: %x / %d mV", x, y);
1011 for (i = 0; i < 6; i++)
1013 x = pmu_read(0x2e + (i << 1)) & 0xf;
1014 y = pmu_read(0x2d + (i << 1)) * 100 + 900;
1015 lcd_putsf(0, 10 + i, "LDO%d: %x / %d mV", i + 1, x, y);
1017 #else
1018 lcd_putsf(0, 3, "Charger: %s",
1019 charger_inserted() ? "present" : "absent");
1020 #endif /* target type */
1021 #endif /* CONFIG_CHARGING */
1022 break;
1024 case 2: /* voltage deltas: */
1025 lcd_puts(0, 0, "Voltage deltas:");
1027 for (i = 0; i <= 6; i++) {
1028 y = power_history[i] - power_history[i+1];
1029 lcd_putsf(0, i+1, "-%d min: %s%d.%03d V", i,
1030 (y < 0) ? "-" : "", ((y < 0) ? y * -1 : y) / 1000,
1031 ((y < 0) ? y * -1 : y ) % 1000);
1033 break;
1035 case 3: /* remaining time estimation: */
1037 #ifdef ARCHOS_RECORDER
1038 lcd_putsf(0, 0, "charge_state: %d", charge_state);
1040 lcd_putsf(0, 1, "Cycle time: %d m", powermgmt_last_cycle_startstop_min);
1042 lcd_putsf(0, 2, "Lvl@cyc st: %d%%", powermgmt_last_cycle_level);
1044 lcd_putsf(0, 3, "P=%2d I=%2d", pid_p, pid_i);
1046 lcd_putsf(0, 4, "Trickle sec: %d/60", trickle_sec);
1047 #endif /* ARCHOS_RECORDER */
1049 lcd_putsf(0, 5, "Last PwrHist: %d.%03dV",
1050 power_history[0] / 1000,
1051 power_history[0] % 1000);
1053 lcd_putsf(0, 6, "battery level: %d%%", battery_level());
1055 lcd_putsf(0, 7, "Est. remain: %d m", battery_time());
1056 break;
1059 lcd_update();
1061 switch(get_action(CONTEXT_STD,HZ/2))
1063 case ACTION_STD_PREV:
1064 if (view)
1065 view--;
1066 break;
1068 case ACTION_STD_NEXT:
1069 if (view < 3)
1070 view++;
1071 break;
1073 case ACTION_STD_CANCEL:
1074 lcd_setfont(FONT_UI);
1075 return false;
1078 lcd_setfont(FONT_UI);
1079 return false;
1082 #endif /* HAVE_LCD_BITMAP */
1083 #endif
1085 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
1086 #if (CONFIG_STORAGE & STORAGE_MMC) || (CONFIG_STORAGE & STORAGE_SD)
1088 #if (CONFIG_STORAGE & STORAGE_MMC)
1089 #define CARDTYPE "MMC"
1090 #elif (CONFIG_STORAGE & STORAGE_SD)
1091 #define CARDTYPE "microSD"
1092 #endif
1094 static int disk_callback(int btn, struct gui_synclist *lists)
1096 tCardInfo *card;
1097 int *cardnum = (int*)lists->data;
1098 unsigned char card_name[6];
1099 unsigned char pbuf[32];
1100 char *title = lists->title;
1101 static const unsigned char i_vmin[] = { 0, 1, 5, 10, 25, 35, 60, 100 };
1102 static const unsigned char i_vmax[] = { 1, 5, 10, 25, 35, 45, 80, 200 };
1103 static const unsigned char * const kbit_units[] = { "kBit/s", "MBit/s", "GBit/s" };
1104 static const unsigned char * const nsec_units[] = { "ns", "µs", "ms" };
1105 #if (CONFIG_STORAGE & STORAGE_MMC)
1106 static const char * const mmc_spec_vers[] = { "1.0-1.2", "1.4", "2.0-2.2",
1107 "3.1-3.31", "4.0" };
1108 #endif
1110 if ((btn == ACTION_STD_OK) || (btn == SYS_FS_CHANGED) || (btn == ACTION_REDRAW))
1112 #ifdef HAVE_HOTSWAP
1113 if (btn == ACTION_STD_OK)
1115 *cardnum ^= 0x1; /* change cards */
1117 #endif
1119 simplelist_set_line_count(0);
1121 card = card_get_info(*cardnum);
1123 if (card->initialized > 0)
1125 unsigned i;
1126 for (i=0; i<sizeof(card_name); i++)
1128 card_name[i] = card_extract_bits(card->cid, (103-8*i), 8);
1130 strlcpy(card_name, card_name, sizeof(card_name));
1131 simplelist_addline(SIMPLELIST_ADD_LINE,
1132 "%s Rev %d.%d", card_name,
1133 (int) card_extract_bits(card->cid, 63, 4),
1134 (int) card_extract_bits(card->cid, 59, 4));
1135 simplelist_addline(SIMPLELIST_ADD_LINE,
1136 "Prod: %d/%d",
1137 #if (CONFIG_STORAGE & STORAGE_SD)
1138 (int) card_extract_bits(card->cid, 11, 4),
1139 (int) card_extract_bits(card->cid, 19, 8) + 2000
1140 #elif (CONFIG_STORAGE & STORAGE_MMC)
1141 (int) card_extract_bits(card->cid, 15, 4),
1142 (int) card_extract_bits(card->cid, 11, 4) + 1997
1143 #endif
1145 simplelist_addline(SIMPLELIST_ADD_LINE,
1146 #if (CONFIG_STORAGE & STORAGE_SD)
1147 "Ser#: 0x%08lx",
1148 card_extract_bits(card->cid, 55, 32)
1149 #elif (CONFIG_STORAGE & STORAGE_MMC)
1150 "Ser#: 0x%04lx",
1151 card_extract_bits(card->cid, 47, 16)
1152 #endif
1155 simplelist_addline(SIMPLELIST_ADD_LINE, "M=%02x, "
1156 #if (CONFIG_STORAGE & STORAGE_SD)
1157 "O=%c%c",
1158 (int) card_extract_bits(card->cid, 127, 8),
1159 card_extract_bits(card->cid, 119, 8),
1160 card_extract_bits(card->cid, 111, 8)
1161 #elif (CONFIG_STORAGE & STORAGE_MMC)
1162 "O=%04x",
1163 (int) card_extract_bits(card->cid, 127, 8),
1164 (int) card_extract_bits(card->cid, 119, 16)
1165 #endif
1168 #if (CONFIG_STORAGE & STORAGE_MMC)
1169 int temp = card_extract_bits(card->csd, 125, 4);
1170 simplelist_addline(SIMPLELIST_ADD_LINE,
1171 "MMC v%s", temp < 5 ?
1172 mmc_spec_vers[temp] : "?.?");
1173 #endif
1174 simplelist_addline(SIMPLELIST_ADD_LINE,
1175 "Blocks: 0x%08lx", card->numblocks);
1176 output_dyn_value(pbuf, sizeof pbuf, card->speed / 1000,
1177 kbit_units, false);
1178 simplelist_addline(SIMPLELIST_ADD_LINE,
1179 "Speed: %s", pbuf);
1180 output_dyn_value(pbuf, sizeof pbuf, card->taac,
1181 nsec_units, false);
1182 simplelist_addline(SIMPLELIST_ADD_LINE,
1183 "Taac: %s", pbuf);
1184 simplelist_addline(SIMPLELIST_ADD_LINE,
1185 "Nsac: %d clk", card->nsac);
1186 simplelist_addline(SIMPLELIST_ADD_LINE,
1187 "R2W: *%d", card->r2w_factor);
1188 #if (CONFIG_STORAGE & STORAGE_SD)
1189 int csd_structure = card_extract_bits(card->csd, 127, 2);
1190 if (csd_structure == 0) /* CSD version 1.0 */
1191 #endif
1193 simplelist_addline(SIMPLELIST_ADD_LINE,
1194 "IRmax: %d..%d mA",
1195 i_vmin[card_extract_bits(card->csd, 61, 3)],
1196 i_vmax[card_extract_bits(card->csd, 58, 3)]);
1197 simplelist_addline(SIMPLELIST_ADD_LINE,
1198 "IWmax: %d..%d mA",
1199 i_vmin[card_extract_bits(card->csd, 55, 3)],
1200 i_vmax[card_extract_bits(card->csd, 52, 3)]);
1203 else if (card->initialized == 0)
1205 simplelist_addline(SIMPLELIST_ADD_LINE, "Not Found!");
1207 #if (CONFIG_STORAGE & STORAGE_SD)
1208 else /* card->initialized < 0 */
1210 simplelist_addline(SIMPLELIST_ADD_LINE, "Init Error! (%d)", card->initialized);
1212 #endif
1213 snprintf(title, 16, "[" CARDTYPE " %d]", *cardnum);
1214 gui_synclist_set_title(lists, title, Icon_NOICON);
1215 gui_synclist_set_nb_items(lists, simplelist_get_line_count());
1216 gui_synclist_select_item(lists, 0);
1217 btn = ACTION_REDRAW;
1219 return btn;
1221 #elif (CONFIG_STORAGE & STORAGE_ATA)
1222 static int disk_callback(int btn, struct gui_synclist *lists)
1224 (void)lists;
1225 int i;
1226 char buf[128];
1227 unsigned short* identify_info = ata_get_identify();
1228 bool timing_info_present = false;
1229 (void)btn;
1231 simplelist_set_line_count(0);
1233 for (i=0; i < 20; i++)
1234 ((unsigned short*)buf)[i]=htobe16(identify_info[i+27]);
1235 buf[40]=0;
1236 /* kill trailing space */
1237 for (i=39; i && buf[i]==' '; i--)
1238 buf[i] = 0;
1239 simplelist_addline(SIMPLELIST_ADD_LINE, "Model: %s", buf);
1240 for (i=0; i < 4; i++)
1241 ((unsigned short*)buf)[i]=htobe16(identify_info[i+23]);
1242 buf[8]=0;
1243 simplelist_addline(SIMPLELIST_ADD_LINE,
1244 "Firmware: %s", buf);
1245 snprintf(buf, sizeof buf, "%ld MB",
1246 ((unsigned long)identify_info[61] << 16 |
1247 (unsigned long)identify_info[60]) / 2048 );
1248 simplelist_addline(SIMPLELIST_ADD_LINE,
1249 "Size: %s", buf);
1250 unsigned long free;
1251 fat_size( IF_MV2(0,) NULL, &free );
1252 simplelist_addline(SIMPLELIST_ADD_LINE,
1253 "Free: %ld MB", free / 1024);
1254 simplelist_addline(SIMPLELIST_ADD_LINE,
1255 "Spinup time: %d ms", storage_spinup_time() * (1000/HZ));
1256 i = identify_info[83] & (1<<3);
1257 simplelist_addline(SIMPLELIST_ADD_LINE,
1258 "Power mgmt: %s", i ? "enabled" : "unsupported");
1259 i = identify_info[83] & (1<<9);
1260 simplelist_addline(SIMPLELIST_ADD_LINE,
1261 "Noise mgmt: %s", i ? "enabled" : "unsupported");
1262 i = identify_info[82] & (1<<6);
1263 simplelist_addline(SIMPLELIST_ADD_LINE,
1264 "Read-ahead: %s", i ? "enabled" : "unsupported");
1265 timing_info_present = identify_info[53] & (1<<1);
1266 if(timing_info_present) {
1267 char pio3[2], pio4[2];pio3[1] = 0;
1268 pio4[1] = 0;
1269 pio3[0] = (identify_info[64] & (1<<0)) ? '3' : 0;
1270 pio4[0] = (identify_info[64] & (1<<1)) ? '4' : 0;
1271 simplelist_addline(SIMPLELIST_ADD_LINE,
1272 "PIO modes: 0 1 2 %s %s", pio3, pio4);
1274 else {
1275 simplelist_addline(SIMPLELIST_ADD_LINE,
1276 "No PIO mode info");
1278 timing_info_present = identify_info[53] & (1<<1);
1279 if(timing_info_present) {
1280 simplelist_addline(SIMPLELIST_ADD_LINE,
1281 "Cycle times %dns/%dns",
1282 identify_info[67],
1283 identify_info[68] );
1284 } else {
1285 simplelist_addline(SIMPLELIST_ADD_LINE,
1286 "No timing info");
1288 int sector_size = 512;
1289 if((identify_info[106] & 0xe000) == 0x6000)
1290 sector_size *= BIT_N(identify_info[106] & 0x000f);
1291 simplelist_addline(SIMPLELIST_ADD_LINE,
1292 "Physical sector size: %d", sector_size);
1293 #ifdef HAVE_ATA_DMA
1294 if (identify_info[63] & (1<<0)) {
1295 char mdma0[2], mdma1[2], mdma2[2];
1296 mdma0[1] = mdma1[1] = mdma2[1] = 0;
1297 mdma0[0] = (identify_info[63] & (1<<0)) ? '0' : 0;
1298 mdma1[0] = (identify_info[63] & (1<<1)) ? '1' : 0;
1299 mdma2[0] = (identify_info[63] & (1<<2)) ? '2' : 0;
1300 simplelist_addline(SIMPLELIST_ADD_LINE,
1301 "MDMA modes: %s %s %s", mdma0, mdma1, mdma2);
1302 simplelist_addline(SIMPLELIST_ADD_LINE,
1303 "MDMA Cycle times %dns/%dns",
1304 identify_info[65],
1305 identify_info[66] );
1307 else {
1308 simplelist_addline(SIMPLELIST_ADD_LINE,
1309 "No MDMA mode info");
1311 if (identify_info[53] & (1<<2)) {
1312 char udma0[2], udma1[2], udma2[2], udma3[2], udma4[2], udma5[2], udma6[2];
1313 udma0[1] = udma1[1] = udma2[1] = udma3[1] = udma4[1] = udma5[1] = udma6[1] = 0;
1314 udma0[0] = (identify_info[88] & (1<<0)) ? '0' : 0;
1315 udma1[0] = (identify_info[88] & (1<<1)) ? '1' : 0;
1316 udma2[0] = (identify_info[88] & (1<<2)) ? '2' : 0;
1317 udma3[0] = (identify_info[88] & (1<<3)) ? '3' : 0;
1318 udma4[0] = (identify_info[88] & (1<<4)) ? '4' : 0;
1319 udma5[0] = (identify_info[88] & (1<<5)) ? '5' : 0;
1320 udma6[0] = (identify_info[88] & (1<<6)) ? '6' : 0;
1321 simplelist_addline(SIMPLELIST_ADD_LINE,
1322 "UDMA modes: %s %s %s %s %s %s %s", udma0, udma1, udma2,
1323 udma3, udma4, udma5, udma6);
1325 else {
1326 simplelist_addline(SIMPLELIST_ADD_LINE,
1327 "No UDMA mode info");
1329 #endif /* HAVE_ATA_DMA */
1330 timing_info_present = identify_info[53] & (1<<1);
1331 if(timing_info_present) {
1332 i = identify_info[49] & (1<<11);
1333 simplelist_addline(SIMPLELIST_ADD_LINE,
1334 "IORDY support: %s", i ? "yes" : "no");
1335 i = identify_info[49] & (1<<10);
1336 simplelist_addline(SIMPLELIST_ADD_LINE,
1337 "IORDY disable: %s", i ? "yes" : "no");
1338 } else {
1339 simplelist_addline(SIMPLELIST_ADD_LINE,
1340 "No timing info");
1342 simplelist_addline(SIMPLELIST_ADD_LINE,
1343 "Cluster size: %d bytes", fat_get_cluster_size(IF_MV(0)));
1344 #ifdef HAVE_ATA_DMA
1345 i = ata_get_dma_mode();
1346 if (i == 0) {
1347 simplelist_addline(SIMPLELIST_ADD_LINE,
1348 "DMA not enabled");
1349 } else {
1350 simplelist_addline(SIMPLELIST_ADD_LINE,
1351 "DMA mode: %s %c",
1352 (i & 0x40) ? "UDMA" : "MDMA",
1353 '0' + (i & 7));
1355 #endif /* HAVE_ATA_DMA */
1356 return btn;
1358 #else /* No SD, MMC or ATA */
1359 static int disk_callback(int btn, struct gui_synclist *lists)
1361 (void)btn;
1362 (void)lists;
1363 struct storage_info info;
1364 storage_get_info(0,&info);
1365 simplelist_addline(SIMPLELIST_ADD_LINE, "Vendor: %s", info.vendor);
1366 simplelist_addline(SIMPLELIST_ADD_LINE, "Model: %s", info.product);
1367 simplelist_addline(SIMPLELIST_ADD_LINE, "Firmware: %s", info.revision);
1368 simplelist_addline(SIMPLELIST_ADD_LINE,
1369 "Size: %ld MB", info.num_sectors*(info.sector_size/512)/2024);
1370 unsigned long free;
1371 fat_size( IF_MV2(0,) NULL, &free );
1372 simplelist_addline(SIMPLELIST_ADD_LINE,
1373 "Free: %ld MB", free / 1024);
1374 simplelist_addline(SIMPLELIST_ADD_LINE,
1375 "Cluster size: %d bytes", fat_get_cluster_size(IF_MV(0)));
1376 return btn;
1378 #endif
1380 #if (CONFIG_STORAGE & STORAGE_ATA)
1381 static bool dbg_identify_info(void)
1383 int fd = creat("/identify_info.bin", 0666);
1384 if(fd >= 0)
1386 #ifdef ROCKBOX_LITTLE_ENDIAN
1387 ecwrite(fd, ata_get_identify(), SECTOR_SIZE/2, "s", true);
1388 #else
1389 write(fd, ata_get_identify(), SECTOR_SIZE);
1390 #endif
1391 close(fd);
1393 return false;
1395 #endif
1397 static bool dbg_disk_info(void)
1399 struct simplelist_info info;
1400 simplelist_info_init(&info, "Disk Info", 1, NULL);
1401 #if (CONFIG_STORAGE & STORAGE_MMC) || (CONFIG_STORAGE & STORAGE_SD)
1402 char title[16];
1403 int card = 0;
1404 info.callback_data = (void*)&card;
1405 info.title = title;
1406 #endif
1407 info.action_callback = disk_callback;
1408 info.hide_selection = true;
1409 info.scroll_all = true;
1410 return simplelist_show_list(&info);
1412 #endif /* PLATFORM_NATIVE */
1414 #ifdef HAVE_DIRCACHE
1415 static int dircache_callback(int btn, struct gui_synclist *lists)
1417 (void)btn; (void)lists;
1418 simplelist_set_line_count(0);
1419 simplelist_addline(SIMPLELIST_ADD_LINE, "Cache initialized: %s",
1420 dircache_is_enabled() ? "Yes" : "No");
1421 simplelist_addline(SIMPLELIST_ADD_LINE, "Cache size: %d B",
1422 dircache_get_cache_size());
1423 simplelist_addline(SIMPLELIST_ADD_LINE, "Last size: %d B",
1424 global_status.dircache_size);
1425 simplelist_addline(SIMPLELIST_ADD_LINE, "Limit: %d B",
1426 DIRCACHE_LIMIT);
1427 simplelist_addline(SIMPLELIST_ADD_LINE, "Reserve: %d/%d B",
1428 dircache_get_reserve_used(), DIRCACHE_RESERVE);
1429 simplelist_addline(SIMPLELIST_ADD_LINE, "Scanning took: %d s",
1430 dircache_get_build_ticks() / HZ);
1431 simplelist_addline(SIMPLELIST_ADD_LINE, "Entry count: %d",
1432 dircache_get_entry_count());
1433 return btn;
1436 static bool dbg_dircache_info(void)
1438 struct simplelist_info info;
1439 simplelist_info_init(&info, "Dircache Info", 7, NULL);
1440 info.action_callback = dircache_callback;
1441 info.hide_selection = true;
1442 info.scroll_all = true;
1443 return simplelist_show_list(&info);
1446 #endif /* HAVE_DIRCACHE */
1448 #ifdef HAVE_TAGCACHE
1449 static int database_callback(int btn, struct gui_synclist *lists)
1451 (void)lists;
1452 struct tagcache_stat *stat = tagcache_get_stat();
1453 static bool synced = false;
1455 simplelist_set_line_count(0);
1457 simplelist_addline(SIMPLELIST_ADD_LINE, "Initialized: %s",
1458 stat->initialized ? "Yes" : "No");
1459 simplelist_addline(SIMPLELIST_ADD_LINE, "DB Ready: %s",
1460 stat->ready ? "Yes" : "No");
1461 simplelist_addline(SIMPLELIST_ADD_LINE, "RAM Cache: %s",
1462 stat->ramcache ? "Yes" : "No");
1463 simplelist_addline(SIMPLELIST_ADD_LINE, "RAM: %d/%d B",
1464 stat->ramcache_used, stat->ramcache_allocated);
1465 simplelist_addline(SIMPLELIST_ADD_LINE, "Progress: %d%% (%d entries)",
1466 stat->progress, stat->processed_entries);
1467 simplelist_addline(SIMPLELIST_ADD_LINE, "Curfile: %s",
1468 stat->curentry ? stat->curentry : "---");
1469 simplelist_addline(SIMPLELIST_ADD_LINE, "Commit step: %d",
1470 stat->commit_step);
1471 simplelist_addline(SIMPLELIST_ADD_LINE, "Commit delayed: %s",
1472 stat->commit_delayed ? "Yes" : "No");
1474 simplelist_addline(SIMPLELIST_ADD_LINE, "Queue length: %d",
1475 stat->queue_length);
1477 if (synced)
1479 synced = false;
1480 tagcache_screensync_event();
1483 if (!btn && stat->curentry)
1485 synced = true;
1486 return ACTION_REDRAW;
1489 if (btn == ACTION_STD_CANCEL)
1490 tagcache_screensync_enable(false);
1492 return btn;
1494 static bool dbg_tagcache_info(void)
1496 struct simplelist_info info;
1497 simplelist_info_init(&info, "Database Info", 8, NULL);
1498 info.action_callback = database_callback;
1499 info.hide_selection = true;
1500 info.scroll_all = true;
1502 /* Don't do nonblock here, must give enough processing time
1503 for tagcache thread. */
1504 /* info.timeout = TIMEOUT_NOBLOCK; */
1505 info.timeout = 1;
1506 tagcache_screensync_enable(true);
1507 return simplelist_show_list(&info);
1509 #endif
1511 #if CONFIG_CPU == SH7034
1512 static bool dbg_save_roms(void)
1514 int fd;
1515 int oldmode = system_memory_guard(MEMGUARD_NONE);
1517 fd = creat("/internal_rom_0000-FFFF.bin", 0666);
1518 if(fd >= 0)
1520 write(fd, (void *)0, 0x10000);
1521 close(fd);
1524 fd = creat("/internal_rom_2000000-203FFFF.bin", 0666);
1525 if(fd >= 0)
1527 write(fd, (void *)0x2000000, 0x40000);
1528 close(fd);
1531 system_memory_guard(oldmode);
1532 return false;
1534 #elif defined CPU_COLDFIRE
1535 static bool dbg_save_roms(void)
1537 int fd;
1538 int oldmode = system_memory_guard(MEMGUARD_NONE);
1540 #if defined(IRIVER_H100_SERIES)
1541 fd = creat("/internal_rom_000000-1FFFFF.bin", 0666);
1542 #elif defined(IRIVER_H300_SERIES)
1543 fd = creat("/internal_rom_000000-3FFFFF.bin", 0666);
1544 #elif defined(IAUDIO_X5) || defined(IAUDIO_M5) || defined(IAUDIO_M3)
1545 fd = creat("/internal_rom_000000-3FFFFF.bin", 0666);
1546 #elif defined(MPIO_HD200) || defined(MPIO_HD300)
1547 fd = creat("/internal_rom_000000-1FFFFF.bin", 0666);
1548 #endif
1549 if(fd >= 0)
1551 write(fd, (void *)0, FLASH_SIZE);
1552 close(fd);
1554 system_memory_guard(oldmode);
1556 #ifdef HAVE_EEPROM
1557 fd = creat("/internal_eeprom.bin", 0666);
1558 if (fd >= 0)
1560 int old_irq_level;
1561 char buf[EEPROM_SIZE];
1562 int err;
1564 old_irq_level = disable_irq_save();
1566 err = eeprom_24cxx_read(0, buf, sizeof buf);
1568 restore_irq(old_irq_level);
1570 if (err)
1571 splashf(HZ*3, "Eeprom read failure (%d)", err);
1572 else
1574 write(fd, buf, sizeof buf);
1577 close(fd);
1579 #endif
1581 return false;
1583 #elif defined(CPU_PP) && !(CONFIG_STORAGE & STORAGE_SD)
1584 static bool dbg_save_roms(void)
1586 int fd;
1588 fd = creat("/internal_rom_000000-0FFFFF.bin", 0666);
1589 if(fd >= 0)
1591 write(fd, (void *)0x20000000, FLASH_SIZE);
1592 close(fd);
1595 return false;
1597 #elif CONFIG_CPU == IMX31L
1598 static bool dbg_save_roms(void)
1600 int fd;
1602 fd = creat("/flash_rom_A0000000-A01FFFFF.bin", 0666);
1603 if (fd >= 0)
1605 write(fd, (void*)0xa0000000, FLASH_SIZE);
1606 close(fd);
1609 return false;
1611 #elif defined(CPU_TCC780X)
1612 static bool dbg_save_roms(void)
1614 int fd;
1616 fd = creat("/eeprom_E0000000-E0001FFF.bin", 0666);
1617 if (fd >= 0)
1619 write(fd, (void*)0xe0000000, 0x2000);
1620 close(fd);
1623 return false;
1625 #endif /* CPU */
1627 #ifndef SIMULATOR
1628 #if CONFIG_TUNER
1630 #ifdef CONFIG_TUNER_MULTI
1631 static int tuner_type = 0;
1632 #define IF_TUNER_TYPE(type) if(tuner_type==type)
1633 #else
1634 #define IF_TUNER_TYPE(type)
1635 #endif
1637 static int radio_callback(int btn, struct gui_synclist *lists)
1639 (void)lists;
1640 if (btn == ACTION_STD_CANCEL)
1641 return btn;
1642 simplelist_set_line_count(1);
1644 #if (CONFIG_TUNER & LV24020LP)
1645 simplelist_addline(SIMPLELIST_ADD_LINE,
1646 "CTRL_STAT: %02X", lv24020lp_get(LV24020LP_CTRL_STAT) );
1647 simplelist_addline(SIMPLELIST_ADD_LINE,
1648 "RADIO_STAT: %02X", lv24020lp_get(LV24020LP_REG_STAT) );
1649 simplelist_addline(SIMPLELIST_ADD_LINE,
1650 "MSS_FM: %d kHz", lv24020lp_get(LV24020LP_MSS_FM) );
1651 simplelist_addline(SIMPLELIST_ADD_LINE,
1652 "MSS_IF: %d Hz", lv24020lp_get(LV24020LP_MSS_IF) );
1653 simplelist_addline(SIMPLELIST_ADD_LINE,
1654 "MSS_SD: %d Hz", lv24020lp_get(LV24020LP_MSS_SD) );
1655 simplelist_addline(SIMPLELIST_ADD_LINE,
1656 "if_set: %d Hz", lv24020lp_get(LV24020LP_IF_SET) );
1657 simplelist_addline(SIMPLELIST_ADD_LINE,
1658 "sd_set: %d Hz", lv24020lp_get(LV24020LP_SD_SET) );
1659 #endif /* LV24020LP */
1660 #if (CONFIG_TUNER & S1A0903X01)
1661 simplelist_addline(SIMPLELIST_ADD_LINE,
1662 "Samsung regs: %08X", s1a0903x01_get(RADIO_ALL));
1663 /* This one doesn't return dynamic data atm */
1664 #endif /* S1A0903X01 */
1665 #if (CONFIG_TUNER & TEA5767)
1666 struct tea5767_dbg_info nfo;
1667 tea5767_dbg_info(&nfo);
1668 simplelist_addline(SIMPLELIST_ADD_LINE, "Philips regs:");
1669 simplelist_addline(SIMPLELIST_ADD_LINE,
1670 " Read: %02X %02X %02X %02X %02X",
1671 (unsigned)nfo.read_regs[0], (unsigned)nfo.read_regs[1],
1672 (unsigned)nfo.read_regs[2], (unsigned)nfo.read_regs[3],
1673 (unsigned)nfo.read_regs[4]);
1674 simplelist_addline(SIMPLELIST_ADD_LINE,
1675 " Write: %02X %02X %02X %02X %02X",
1676 (unsigned)nfo.write_regs[0], (unsigned)nfo.write_regs[1],
1677 (unsigned)nfo.write_regs[2], (unsigned)nfo.write_regs[3],
1678 (unsigned)nfo.write_regs[4]);
1679 #endif /* TEA5767 */
1680 #if (CONFIG_TUNER & SI4700)
1681 IF_TUNER_TYPE(SI4700)
1683 struct si4700_dbg_info nfo;
1684 int i;
1685 si4700_dbg_info(&nfo);
1686 simplelist_addline(SIMPLELIST_ADD_LINE, "SI4700 regs:");
1687 for (i = 0; i < 16; i += 4) {
1688 simplelist_addline(SIMPLELIST_ADD_LINE,"%02X: %04X %04X %04X %04X",
1689 i, nfo.regs[i], nfo.regs[i+1], nfo.regs[i+2], nfo.regs[i+3]);
1692 #endif /* SI4700 */
1693 #if (CONFIG_TUNER & RDA5802)
1694 IF_TUNER_TYPE(RDA5802)
1696 struct rda5802_dbg_info nfo;
1697 int i;
1698 rda5802_dbg_info(&nfo);
1699 simplelist_addline(SIMPLELIST_ADD_LINE, "RDA5802 regs:");
1700 for (i = 0; i < 16; i += 4) {
1701 simplelist_addline(SIMPLELIST_ADD_LINE,"%02X: %04X %04X %04X %04X",
1702 i, nfo.regs[i], nfo.regs[i+1], nfo.regs[i+2], nfo.regs[i+3]);
1705 #endif /* RDA55802 */
1706 return ACTION_REDRAW;
1708 static bool dbg_fm_radio(void)
1710 struct simplelist_info info;
1711 #ifdef CONFIG_TUNER_MULTI
1712 tuner_type = tuner_detect_type();
1713 #endif
1714 info.scroll_all = true;
1715 simplelist_info_init(&info, "FM Radio", 1, NULL);
1716 simplelist_set_line_count(0);
1717 simplelist_addline(SIMPLELIST_ADD_LINE, "HW detected: %s",
1718 radio_hardware_present() ? "yes" : "no");
1720 info.action_callback = radio_hardware_present()?radio_callback : NULL;
1721 info.hide_selection = true;
1722 return simplelist_show_list(&info);
1724 #endif /* CONFIG_TUNER */
1725 #endif /* !SIMULATOR */
1727 #ifdef HAVE_LCD_BITMAP
1728 extern bool do_screendump_instead_of_usb;
1730 static bool dbg_screendump(void)
1732 do_screendump_instead_of_usb = !do_screendump_instead_of_usb;
1733 splashf(HZ, "Screendump %s",
1734 do_screendump_instead_of_usb?"enabled":"disabled");
1735 return false;
1737 #endif /* HAVE_LCD_BITMAP */
1739 extern bool write_metadata_log;
1741 static bool dbg_metadatalog(void)
1743 write_metadata_log = !write_metadata_log;
1744 splashf(HZ, "Metadata log %s",
1745 write_metadata_log?"enabled":"disabled");
1746 return false;
1749 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
1750 static bool dbg_set_memory_guard(void)
1752 static const struct opt_items names[MAXMEMGUARD] = {
1753 { "None", -1 },
1754 { "Flash ROM writes", -1 },
1755 { "Zero area (all)", -1 }
1757 int mode = system_memory_guard(MEMGUARD_KEEP);
1759 set_option( "Catch mem accesses", &mode, INT, names, MAXMEMGUARD, NULL);
1760 system_memory_guard(mode);
1762 return false;
1764 #endif /* CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) */
1766 #if defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS)
1767 static bool dbg_write_eeprom(void)
1769 int fd;
1770 int rc;
1771 int old_irq_level;
1772 char buf[EEPROM_SIZE];
1773 int err;
1775 fd = open("/internal_eeprom.bin", O_RDONLY);
1777 if (fd >= 0)
1779 rc = read(fd, buf, EEPROM_SIZE);
1781 if(rc == EEPROM_SIZE)
1783 old_irq_level = disable_irq_save();
1785 err = eeprom_24cxx_write(0, buf, sizeof buf);
1786 if (err)
1787 splashf(HZ*3, "Eeprom write failure (%d)", err);
1788 else
1789 splash(HZ*3, "Eeprom written successfully");
1791 restore_irq(old_irq_level);
1793 else
1795 splashf(HZ*3, "File read error (%d)",rc);
1797 close(fd);
1799 else
1801 splash(HZ*3, "Failed to open 'internal_eeprom.bin'");
1804 return false;
1806 #endif /* defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS) */
1807 #ifdef CPU_BOOST_LOGGING
1808 static bool cpu_boost_log(void)
1810 int i = 0,j=0;
1811 int count = cpu_boost_log_getcount();
1812 int lines = LCD_HEIGHT/SYSFONT_HEIGHT;
1813 char *str;
1814 bool done;
1815 lcd_setfont(FONT_SYSFIXED);
1816 str = cpu_boost_log_getlog_first();
1817 while (i < count)
1819 lcd_clear_display();
1820 for(j=0; j<lines; j++,i++)
1822 if (!str)
1823 str = cpu_boost_log_getlog_next();
1824 if (str)
1826 if(strlen(str) > LCD_WIDTH/SYSFONT_WIDTH)
1827 lcd_puts_scroll(0, j, str);
1828 else
1829 lcd_puts(0, j,str);
1831 str = NULL;
1833 lcd_update();
1834 done = false;
1835 while (!done)
1837 switch(get_action(CONTEXT_STD,TIMEOUT_BLOCK))
1839 case ACTION_STD_OK:
1840 case ACTION_STD_PREV:
1841 case ACTION_STD_NEXT:
1842 done = true;
1843 break;
1844 case ACTION_STD_CANCEL:
1845 i = count;
1846 done = true;
1847 break;
1851 lcd_stop_scroll();
1852 get_action(CONTEXT_STD,TIMEOUT_BLOCK);
1853 lcd_setfont(FONT_UI);
1854 return false;
1856 #endif
1858 #if (defined(HAVE_WHEEL_ACCELERATION) && (CONFIG_KEYPAD==IPOD_4G_PAD) \
1859 && !defined(IPOD_MINI) && !defined(SIMULATOR))
1860 extern bool wheel_is_touched;
1861 extern int old_wheel_value;
1862 extern int new_wheel_value;
1863 extern int wheel_delta;
1864 extern unsigned int accumulated_wheel_delta;
1865 extern unsigned int wheel_velocity;
1867 static bool dbg_scrollwheel(void)
1869 unsigned int speed;
1871 lcd_setfont(FONT_SYSFIXED);
1873 while (1)
1875 if (action_userabort(HZ/10))
1876 break;
1878 lcd_clear_display();
1880 /* show internal variables of scrollwheel driver */
1881 lcd_putsf(0, 0, "wheel touched: %s", (wheel_is_touched) ? "true" : "false");
1882 lcd_putsf(0, 1, "new position: %2d", new_wheel_value);
1883 lcd_putsf(0, 2, "old position: %2d", old_wheel_value);
1884 lcd_putsf(0, 3, "wheel delta: %2d", wheel_delta);
1885 lcd_putsf(0, 4, "accumulated delta: %2d", accumulated_wheel_delta);
1886 lcd_putsf(0, 5, "velo [deg/s]: %4d", (int)wheel_velocity);
1888 /* show effective accelerated scrollspeed */
1889 speed = button_apply_acceleration( (1<<31)|(1<<24)|wheel_velocity);
1890 lcd_putsf(0, 6, "accel. speed: %4d", speed);
1892 lcd_update();
1894 lcd_setfont(FONT_UI);
1895 return false;
1897 #endif
1899 #if defined (HAVE_USBSTACK)
1901 #if defined(ROCKBOX_HAS_LOGF) && defined(USB_ENABLE_SERIAL)
1902 static bool toggle_usb_core_driver(int driver, char *msg)
1904 bool enabled = !usb_core_driver_enabled(driver);
1906 usb_core_enable_driver(driver,enabled);
1907 splashf(HZ, "%s %s", msg, enabled?"enabled":"disabled");
1909 return false;
1912 static bool toggle_usb_serial(void)
1914 return toggle_usb_core_driver(USB_DRIVER_SERIAL,"USB Serial");
1916 #endif
1918 #endif
1920 #if CONFIG_USBOTG == USBOTG_ISP1583
1921 extern int dbg_usb_num_items(void);
1922 extern const char* dbg_usb_item(int selected_item, void *data,
1923 char *buffer, size_t buffer_len);
1925 static int isp1583_action_callback(int action, struct gui_synclist *lists)
1927 (void)lists;
1928 if (action == ACTION_NONE)
1929 action = ACTION_REDRAW;
1930 return action;
1933 static bool dbg_isp1583(void)
1935 struct simplelist_info isp1583;
1936 isp1583.scroll_all = true;
1937 simplelist_info_init(&isp1583, "ISP1583", dbg_usb_num_items(), NULL);
1938 isp1583.timeout = HZ/100;
1939 isp1583.hide_selection = true;
1940 isp1583.get_name = dbg_usb_item;
1941 isp1583.action_callback = isp1583_action_callback;
1942 return simplelist_show_list(&isp1583);
1944 #endif
1946 #if defined(CREATIVE_ZVx) && !defined(SIMULATOR)
1947 extern int pic_dbg_num_items(void);
1948 extern const char* pic_dbg_item(int selected_item, void *data,
1949 char *buffer, size_t buffer_len);
1951 static int pic_action_callback(int action, struct gui_synclist *lists)
1953 (void)lists;
1954 if (action == ACTION_NONE)
1955 action = ACTION_REDRAW;
1956 return action;
1959 static bool dbg_pic(void)
1961 struct simplelist_info pic;
1962 pic.scroll_all = true;
1963 simplelist_info_init(&pic, "PIC", pic_dbg_num_items(), NULL);
1964 pic.timeout = HZ/100;
1965 pic.hide_selection = true;
1966 pic.get_name = pic_dbg_item;
1967 pic.action_callback = pic_action_callback;
1968 return simplelist_show_list(&pic);
1970 #endif
1973 /****** The menu *********/
1974 struct the_menu_item {
1975 unsigned char *desc; /* string or ID */
1976 bool (*function) (void); /* return true if USB was connected */
1978 static const struct the_menu_item menuitems[] = {
1979 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || \
1980 (defined(CPU_PP) && !(CONFIG_STORAGE & STORAGE_SD)) || \
1981 CONFIG_CPU == IMX31L || defined(CPU_TCC780X)
1982 { "Dump ROM contents", dbg_save_roms },
1983 #endif
1984 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || defined(CPU_PP) \
1985 || CONFIG_CPU == S3C2440 || CONFIG_CPU == IMX31L || CONFIG_CPU == AS3525 \
1986 || CONFIG_CPU == DM320 || defined(CPU_S5L870X) || CONFIG_CPU == AS3525v2
1987 { "View I/O ports", dbg_ports },
1988 #endif
1989 #if (CONFIG_RTC == RTC_PCF50605) && (CONFIG_PLATFORM & PLATFORM_NATIVE)
1990 { "View PCF registers", dbg_pcf },
1991 #endif
1992 #if defined(HAVE_TSC2100) && (CONFIG_PLATFORM & PLATFORM_NATIVE)
1993 { "TSC2100 debug", tsc2100_debug },
1994 #endif
1995 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
1996 { "CPU frequency", dbg_cpufreq },
1997 #endif
1998 #if CONFIG_CPU == IMX31L
1999 { "DVFS/DPTC", __dbg_dvfs_dptc },
2000 #endif
2001 #if defined(IRIVER_H100_SERIES) && !defined(SIMULATOR)
2002 { "S/PDIF analyzer", dbg_spdif },
2003 #endif
2004 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
2005 { "Catch mem accesses", dbg_set_memory_guard },
2006 #endif
2007 { "View OS stacks", dbg_os },
2008 #ifdef HAVE_LCD_BITMAP
2009 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
2010 { "View battery", view_battery },
2011 #endif
2012 { "Screendump", dbg_screendump },
2013 #endif
2014 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
2015 { "View HW info", dbg_hw_info },
2016 #endif
2017 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
2018 { "View partitions", dbg_partitions },
2019 #endif
2020 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
2021 { "View disk info", dbg_disk_info },
2022 #if (CONFIG_STORAGE & STORAGE_ATA)
2023 { "Dump ATA identify info", dbg_identify_info},
2024 #endif
2025 #endif
2026 { "Metadata log", dbg_metadatalog },
2027 #ifdef HAVE_DIRCACHE
2028 { "View dircache info", dbg_dircache_info },
2029 #endif
2030 #ifdef HAVE_TAGCACHE
2031 { "View database info", dbg_tagcache_info },
2032 #endif
2033 #ifdef HAVE_LCD_BITMAP
2034 #if CONFIG_CODEC == SWCODEC
2035 { "View buffering thread", dbg_buffering_thread },
2036 #elif !defined(SIMULATOR)
2037 { "View audio thread", dbg_audio_thread },
2038 #endif
2039 #ifdef PM_DEBUG
2040 { "pm histogram", peak_meter_histogram},
2041 #endif /* PM_DEBUG */
2042 #endif /* HAVE_LCD_BITMAP */
2043 #ifndef SIMULATOR
2044 #if CONFIG_TUNER
2045 { "FM Radio", dbg_fm_radio },
2046 #endif
2047 #endif
2048 #if defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS)
2049 { "Write back EEPROM", dbg_write_eeprom },
2050 #endif
2051 #if CONFIG_USBOTG == USBOTG_ISP1583
2052 { "View ISP1583 info", dbg_isp1583 },
2053 #endif
2054 #if defined(CREATIVE_ZVx) && !defined(SIMULATOR)
2055 { "View PIC info", dbg_pic },
2056 #endif
2057 #ifdef ROCKBOX_HAS_LOGF
2058 {"Show Log File", logfdisplay },
2059 {"Dump Log File", logfdump },
2060 #endif
2061 #if defined(HAVE_USBSTACK)
2062 #if defined(ROCKBOX_HAS_LOGF) && defined(USB_ENABLE_SERIAL)
2063 {"USB Serial driver (logf)", toggle_usb_serial },
2064 #endif
2065 #endif /* HAVE_USBSTACK */
2066 #ifdef CPU_BOOST_LOGGING
2067 {"cpu_boost log",cpu_boost_log},
2068 #endif
2069 #if (defined(HAVE_WHEEL_ACCELERATION) && (CONFIG_KEYPAD==IPOD_4G_PAD) \
2070 && !defined(IPOD_MINI) && !defined(SIMULATOR))
2071 {"Debug scrollwheel", dbg_scrollwheel },
2072 #endif
2074 static int menu_action_callback(int btn, struct gui_synclist *lists)
2076 int i;
2077 if (btn == ACTION_STD_OK)
2079 FOR_NB_SCREENS(i)
2080 viewportmanager_theme_enable(i, false, NULL);
2081 menuitems[gui_synclist_get_sel_pos(lists)].function();
2082 btn = ACTION_REDRAW;
2083 FOR_NB_SCREENS(i)
2084 viewportmanager_theme_undo(i, false);
2086 return btn;
2089 static const char* dbg_menu_getname(int item, void * data,
2090 char *buffer, size_t buffer_len)
2092 (void)data; (void)buffer; (void)buffer_len;
2093 return menuitems[item].desc;
2096 bool debug_menu(void)
2098 struct simplelist_info info;
2100 simplelist_info_init(&info, "Debug Menu", ARRAYLEN(menuitems), NULL);
2101 info.action_callback = menu_action_callback;
2102 info.get_name = dbg_menu_getname;
2103 return simplelist_show_list(&info);