Fix off-by-one buffer error
[maemo-rb.git] / apps / debug_menu.c
blobe96b8c553f623d1fefe4310fad945455cabee39f
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 #include "core_alloc.h"
83 #if CONFIG_CODEC == SWCODEC
84 #include "pcmbuf.h"
85 #include "buffering.h"
86 #include "playback.h"
87 #if defined(HAVE_SPDIF_OUT) || defined(HAVE_SPDIF_IN)
88 #include "spdif.h"
89 #endif
90 #endif
91 #ifdef IRIVER_H300_SERIES
92 #include "pcf50606.h" /* for pcf50606_read */
93 #endif
94 #ifdef IAUDIO_X5
95 #include "ds2411.h"
96 #endif
97 #include "hwcompat.h"
98 #include "button.h"
99 #if CONFIG_RTC == RTC_PCF50605
100 #include "pcf50605.h"
101 #endif
102 #include "appevents.h"
103 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
104 #include "debug-target.h"
105 #endif
107 #if defined(SANSA_E200) || defined(SANSA_C200) || defined(PHILIPS_SA9200) \
108 || (CONFIG_CPU == AS3525 && defined(CONFIG_CHARGING)) \
109 || CONFIG_CPU == AS3525v2
110 #include "ascodec.h"
111 #include "as3514.h"
112 #endif
114 #ifdef IPOD_NANO2G
115 #include "pmu-target.h"
116 #endif
118 #ifdef HAVE_USBSTACK
119 #include "usb_core.h"
120 #endif
122 #if defined(IPOD_ACCESSORY_PROTOCOL)
123 #include "iap.h"
124 #endif
126 /*---------------------------------------------------*/
127 /* SPECIAL DEBUG STUFF */
128 /*---------------------------------------------------*/
129 extern struct thread_entry threads[MAXTHREADS];
131 static char thread_status_char(unsigned status)
133 static const char thread_status_chars[THREAD_NUM_STATES+1] =
135 [0 ... THREAD_NUM_STATES] = '?',
136 [STATE_RUNNING] = 'R',
137 [STATE_BLOCKED] = 'B',
138 [STATE_SLEEPING] = 'S',
139 [STATE_BLOCKED_W_TMO] = 'T',
140 [STATE_FROZEN] = 'F',
141 [STATE_KILLED] = 'K',
144 if (status > THREAD_NUM_STATES)
145 status = THREAD_NUM_STATES;
147 return thread_status_chars[status];
150 static const char* threads_getname(int selected_item, void *data,
151 char *buffer, size_t buffer_len)
153 (void)data;
154 struct thread_entry *thread;
155 char name[32];
157 #if NUM_CORES > 1
158 if (selected_item < (int)NUM_CORES)
160 snprintf(buffer, buffer_len, "Idle (%d): %2d%%", selected_item,
161 idle_stack_usage(selected_item));
162 return buffer;
165 selected_item -= NUM_CORES;
166 #endif
168 thread = &threads[selected_item];
170 if (thread->state == STATE_KILLED)
172 snprintf(buffer, buffer_len, "%2d: ---", selected_item);
173 return buffer;
176 thread_get_name(name, 32, thread);
178 snprintf(buffer, buffer_len,
179 "%2d: " IF_COP("(%d) ") "%c%c " IF_PRIO("%d %d ") "%2d%% %s",
180 selected_item,
181 IF_COP(thread->core,)
182 #ifdef HAVE_SCHEDULER_BOOSTCTRL
183 (thread->cpu_boost) ? '+' :
184 #endif
185 ((thread->state == STATE_RUNNING) ? '*' : ' '),
186 thread_status_char(thread->state),
187 IF_PRIO(thread->base_priority, thread->priority, )
188 thread_stack_usage(thread), name);
190 return buffer;
193 static int dbg_threads_action_callback(int action, struct gui_synclist *lists)
195 (void)lists;
196 #ifdef ROCKBOX_HAS_LOGF
197 if (action == ACTION_STD_OK)
199 int selpos = gui_synclist_get_sel_pos(lists);
200 #if NUM_CORES > 1
201 if (selpos >= NUM_CORES)
202 remove_thread(threads[selpos - NUM_CORES].id);
203 #else
204 remove_thread(threads[selpos].id);
205 #endif
206 return ACTION_REDRAW;
208 #endif /* ROCKBOX_HAS_LOGF */
209 if (action == ACTION_NONE)
210 action = ACTION_REDRAW;
211 return action;
213 /* Test code!!! */
214 static bool dbg_os(void)
216 struct simplelist_info info;
217 simplelist_info_init(&info, IF_COP("Core and ") "Stack usage:",
218 #if NUM_CORES == 1
219 MAXTHREADS,
220 #else
221 MAXTHREADS+NUM_CORES,
222 #endif
223 NULL);
224 #ifndef ROCKBOX_HAS_LOGF
225 info.hide_selection = true;
226 info.scroll_all = true;
227 #endif
228 info.action_callback = dbg_threads_action_callback;
229 info.get_name = threads_getname;
230 return simplelist_show_list(&info);
233 #ifdef HAVE_LCD_BITMAP
234 #if CONFIG_CODEC != SWCODEC
235 #ifndef SIMULATOR
236 static bool dbg_audio_thread(void)
238 struct audio_debug d;
240 lcd_setfont(FONT_SYSFIXED);
242 while(1)
244 if (action_userabort(HZ/5))
245 return false;
247 audio_get_debugdata(&d);
249 lcd_clear_display();
251 lcd_putsf(0, 0, "read: %x", d.audiobuf_read);
252 lcd_putsf(0, 1, "write: %x", d.audiobuf_write);
253 lcd_putsf(0, 2, "swap: %x", d.audiobuf_swapwrite);
254 lcd_putsf(0, 3, "playing: %d", d.playing);
255 lcd_putsf(0, 4, "playable: %x", d.playable_space);
256 lcd_putsf(0, 5, "unswapped: %x", d.unswapped_space);
258 /* Playable space left */
259 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, 6*8, 112, 4, d.audiobuflen, 0,
260 d.playable_space, HORIZONTAL);
262 /* Show the watermark limit */
263 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, 6*8+4, 112, 4, d.audiobuflen, 0,
264 d.low_watermark_level, HORIZONTAL);
266 lcd_putsf(0, 7, "wm: %x - %x",
267 d.low_watermark_level, d.lowest_watermark_level);
269 lcd_update();
271 lcd_setfont(FONT_UI);
272 return false;
274 #endif /* !SIMULATOR */
275 #else /* CONFIG_CODEC == SWCODEC */
276 static unsigned int ticks, freq_sum;
277 #ifndef CPU_MULTI_FREQUENCY
278 static unsigned int boost_ticks;
279 #endif
281 static void dbg_audio_task(void)
283 #ifdef CPUFREQ_NORMAL
284 #ifndef CPU_MULTI_FREQUENCY
285 if(FREQ > CPUFREQ_NORMAL)
286 boost_ticks++;
287 #endif
288 freq_sum += FREQ/1000000; /* in MHz */
289 #endif
290 ticks++;
293 static bool dbg_buffering_thread(void)
295 int button;
296 int line, i;
297 bool done = false;
298 size_t bufused;
299 size_t bufsize = pcmbuf_get_bufsize();
300 int pcmbufdescs = pcmbuf_descs();
301 struct buffering_debug d;
302 size_t filebuflen = audio_get_filebuflen();
303 /* This is a size_t, but call it a long so it puts a - when it's bad. */
305 #ifndef CPU_MULTI_FREQUENCY
306 boost_ticks = 0;
307 #endif
308 ticks = freq_sum = 0;
310 tick_add_task(dbg_audio_task);
312 FOR_NB_SCREENS(i)
313 screens[i].setfont(FONT_SYSFIXED);
315 while(!done)
317 button = get_action(CONTEXT_STD,HZ/5);
318 switch(button)
320 case ACTION_STD_NEXT:
321 audio_next();
322 break;
323 case ACTION_STD_PREV:
324 audio_prev();
325 break;
326 case ACTION_STD_CANCEL:
327 done = true;
328 break;
331 buffering_get_debugdata(&d);
332 bufused = bufsize - pcmbuf_free();
334 FOR_NB_SCREENS(i)
336 line = 0;
337 screens[i].clear_display();
340 screens[i].putsf(0, line++, "pcm: %6ld/%ld", (long) bufused, (long) bufsize);
342 gui_scrollbar_draw(&screens[i],0, line*8, screens[i].lcdwidth, 6,
343 bufsize, 0, bufused, HORIZONTAL);
344 line++;
346 screens[i].putsf(0, line++, "alloc: %6ld/%ld", audio_filebufused(),
347 (long) filebuflen);
349 #if LCD_HEIGHT > 80 || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_HEIGHT > 80)
350 if (screens[i].lcdheight > 80)
352 gui_scrollbar_draw(&screens[i],0, line*8, screens[i].lcdwidth, 6,
353 filebuflen, 0, audio_filebufused(), HORIZONTAL);
354 line++;
356 screens[i].putsf(0, line++, "real: %6ld/%ld", (long)d.buffered_data,
357 (long)filebuflen);
359 gui_scrollbar_draw(&screens[i],0, line*8, screens[i].lcdwidth, 6,
360 filebuflen, 0, (long)d.buffered_data, HORIZONTAL);
361 line++;
363 #endif
365 screens[i].putsf(0, line++, "usefl: %6ld/%ld", (long)(d.useful_data),
366 (long)filebuflen);
368 #if LCD_HEIGHT > 80 || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_HEIGHT > 80)
369 if (screens[i].lcdheight > 80)
371 gui_scrollbar_draw(&screens[i],0, line*8, screens[i].lcdwidth, 6,
372 filebuflen, 0, d.useful_data, HORIZONTAL);
373 line++;
375 #endif
377 screens[i].putsf(0, line++, "data_rem: %ld", (long)d.data_rem);
379 screens[i].putsf(0, line++, "track count: %2d", audio_track_count());
381 screens[i].putsf(0, line++, "handle count: %d", (int)d.num_handles);
383 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
384 screens[i].putsf(0, line++, "cpu freq: %3dMHz",
385 (int)((FREQ + 500000) / 1000000));
386 #endif
388 if (ticks > 0)
390 int avgclock = freq_sum * 10 / ticks; /* in 100 kHz */
391 #ifdef CPU_MULTI_FREQUENCY
392 int boostquota = (avgclock * 100 - CPUFREQ_NORMAL/1000) /
393 ((CPUFREQ_MAX - CPUFREQ_NORMAL) / 1000000); /* in 0.1 % */
394 #else
395 int boostquota = boost_ticks * 1000 / ticks; /* in 0.1 % */
396 #endif
397 screens[i].putsf(0, line++, "boost:%3d.%d%% (%d.%dMHz)",
398 boostquota/10, boostquota%10, avgclock/10, avgclock%10);
401 screens[i].putsf(0, line++, "pcmbufdesc: %2d/%2d",
402 pcmbuf_used_descs(), pcmbufdescs);
403 screens[i].putsf(0, line++, "watermark: %6d",
404 (int)(d.watermark));
406 screens[i].update();
410 tick_remove_task(dbg_audio_task);
412 FOR_NB_SCREENS(i)
413 screens[i].setfont(FONT_UI);
415 return false;
417 #endif /* CONFIG_CODEC */
418 #endif /* HAVE_LCD_BITMAP */
420 static const char* bf_getname(int selected_item, void *data,
421 char *buffer, size_t buffer_len)
423 (void)data;
424 core_print_block_at(selected_item, buffer, buffer_len);
425 return buffer;
428 static int bf_action_cb(int action, struct gui_synclist* list)
430 if (action == ACTION_STD_OK)
432 if (gui_synclist_get_sel_pos(list) == 0 && core_test_free())
434 splash(HZ, "Freed test handle. New alloc should trigger compact");
436 else
438 splash(HZ/1, "Attempting a 64k allocation");
439 int handle = core_alloc("test", 64<<10);
440 splash(HZ/2, (handle > 0) ? "Success":"Fail");
441 /* for some reason simplelist doesn't allow adding items here if
442 * info.get_name is given, so use normal list api */
443 gui_synclist_set_nb_items(list, core_get_num_blocks());
444 if (handle > 0)
445 core_free(handle);
447 action = ACTION_REDRAW;
449 else if (action == ACTION_NONE)
450 action = ACTION_REDRAW;
451 return action;
454 static bool dbg_buflib_allocs(void)
456 struct simplelist_info info;
457 simplelist_info_init(&info, "mem allocs", core_get_num_blocks(), NULL);
458 info.get_name = bf_getname;
459 info.action_callback = bf_action_cb;
460 info.timeout = TIMEOUT_BLOCK;
461 return simplelist_show_list(&info);
464 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
465 static const char* dbg_partitions_getname(int selected_item, void *data,
466 char *buffer, size_t buffer_len)
468 (void)data;
469 int partition = selected_item/2;
470 struct partinfo* p = disk_partinfo(partition);
471 if (selected_item%2)
473 snprintf(buffer, buffer_len, " T:%x %ld MB", p->type, p->size / ( 2048 / ( SECTOR_SIZE / 512 )));
475 else
477 snprintf(buffer, buffer_len, "P%d: S:%lx", partition, p->start);
479 return buffer;
482 bool dbg_partitions(void)
484 struct simplelist_info info;
485 simplelist_info_init(&info, "Partition Info", 4, NULL);
486 info.selection_size = 2;
487 info.hide_selection = true;
488 info.scroll_all = true;
489 info.get_name = dbg_partitions_getname;
490 return simplelist_show_list(&info);
492 #endif /* PLATFORM_NATIVE */
494 #if defined(CPU_COLDFIRE) && defined(HAVE_SPDIF_OUT)
495 static bool dbg_spdif(void)
497 int line;
498 unsigned int control;
499 int x;
500 char *s;
501 int category;
502 int generation;
503 unsigned int interruptstat;
504 bool valnogood, symbolerr, parityerr;
505 bool done = false;
506 bool spdif_src_on;
507 int spdif_source = spdif_get_output_source(&spdif_src_on);
508 spdif_set_output_source(AUDIO_SRC_SPDIF IF_SPDIF_POWER_(, true));
510 lcd_clear_display();
511 lcd_setfont(FONT_SYSFIXED);
513 #ifdef HAVE_SPDIF_POWER
514 spdif_power_enable(true); /* We need SPDIF power for both sending & receiving */
515 #endif
517 while (!done)
519 line = 0;
521 control = EBU1RCVCCHANNEL1;
522 interruptstat = INTERRUPTSTAT;
523 INTERRUPTCLEAR = 0x03c00000;
525 valnogood = (interruptstat & 0x01000000)?true:false;
526 symbolerr = (interruptstat & 0x00800000)?true:false;
527 parityerr = (interruptstat & 0x00400000)?true:false;
529 lcd_putsf(0, line++, "Val: %s Sym: %s Par: %s",
530 valnogood?"--":"OK",
531 symbolerr?"--":"OK",
532 parityerr?"--":"OK");
534 lcd_putsf(0, line++, "Status word: %08x", (int)control);
536 line++;
538 x = control >> 31;
539 lcd_putsf(0, line++, "PRO: %d (%s)",
540 x, x?"Professional":"Consumer");
542 x = (control >> 30) & 1;
543 lcd_putsf(0, line++, "Audio: %d (%s)",
544 x, x?"Non-PCM":"PCM");
546 x = (control >> 29) & 1;
547 lcd_putsf(0, line++, "Copy: %d (%s)",
548 x, x?"Permitted":"Inhibited");
550 x = (control >> 27) & 7;
551 switch(x)
553 case 0:
554 s = "None";
555 break;
556 case 1:
557 s = "50/15us";
558 break;
559 default:
560 s = "Reserved";
561 break;
563 lcd_putsf(0, line++, "Preemphasis: %d (%s)", x, s);
565 x = (control >> 24) & 3;
566 lcd_putsf(0, line++, "Mode: %d", x);
568 category = (control >> 17) & 127;
569 switch(category)
571 case 0x00:
572 s = "General";
573 break;
574 case 0x40:
575 s = "Audio CD";
576 break;
577 default:
578 s = "Unknown";
580 lcd_putsf(0, line++, "Category: 0x%02x (%s)", category, s);
582 x = (control >> 16) & 1;
583 generation = x;
584 if(((category & 0x70) == 0x10) ||
585 ((category & 0x70) == 0x40) ||
586 ((category & 0x78) == 0x38))
588 generation = !generation;
590 lcd_putsf(0, line++, "Generation: %d (%s)",
591 x, generation?"Original":"No ind.");
593 x = (control >> 12) & 15;
594 lcd_putsf(0, line++, "Source: %d", x);
597 x = (control >> 8) & 15;
598 switch(x)
600 case 0:
601 s = "Unspecified";
602 break;
603 case 8:
604 s = "A (Left)";
605 break;
606 case 4:
607 s = "B (Right)";
608 break;
609 default:
610 s = "";
611 break;
613 lcd_putsf(0, line++, "Channel: %d (%s)", x, s);
615 x = (control >> 4) & 15;
616 switch(x)
618 case 0:
619 s = "44.1kHz";
620 break;
621 case 0x4:
622 s = "48kHz";
623 break;
624 case 0xc:
625 s = "32kHz";
626 break;
628 lcd_putsf(0, line++, "Frequency: %d (%s)", x, s);
630 x = (control >> 2) & 3;
631 lcd_putsf(0, line++, "Clock accuracy: %d", x);
632 line++;
634 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
635 lcd_putsf(0, line++, "Measured freq: %ldHz",
636 spdif_measure_frequency());
637 #endif
639 lcd_update();
641 if (action_userabort(HZ/10))
642 break;
645 spdif_set_output_source(spdif_source IF_SPDIF_POWER_(, spdif_src_on));
647 #ifdef HAVE_SPDIF_POWER
648 spdif_power_enable(global_settings.spdif_enable);
649 #endif
651 lcd_setfont(FONT_UI);
652 return false;
654 #endif /* CPU_COLDFIRE */
656 #if (CONFIG_RTC == RTC_PCF50605) && (CONFIG_PLATFORM & PLATFORM_NATIVE)
657 static bool dbg_pcf(void)
659 int line;
661 #ifdef HAVE_LCD_BITMAP
662 lcd_setfont(FONT_SYSFIXED);
663 #endif
664 lcd_clear_display();
666 while(1)
668 line = 0;
670 lcd_putsf(0, line++, "DCDC1: %02x", pcf50605_read(0x1b));
671 lcd_putsf(0, line++, "DCDC2: %02x", pcf50605_read(0x1c));
672 lcd_putsf(0, line++, "DCDC3: %02x", pcf50605_read(0x1d));
673 lcd_putsf(0, line++, "DCDC4: %02x", pcf50605_read(0x1e));
674 lcd_putsf(0, line++, "DCDEC1: %02x", pcf50605_read(0x1f));
675 lcd_putsf(0, line++, "DCDEC2: %02x", pcf50605_read(0x20));
676 lcd_putsf(0, line++, "DCUDC1: %02x", pcf50605_read(0x21));
677 lcd_putsf(0, line++, "DCUDC2: %02x", pcf50605_read(0x22));
678 lcd_putsf(0, line++, "IOREGC: %02x", pcf50605_read(0x23));
679 lcd_putsf(0, line++, "D1REGC: %02x", pcf50605_read(0x24));
680 lcd_putsf(0, line++, "D2REGC: %02x", pcf50605_read(0x25));
681 lcd_putsf(0, line++, "D3REGC: %02x", pcf50605_read(0x26));
682 lcd_putsf(0, line++, "LPREG1: %02x", pcf50605_read(0x27));
683 lcd_update();
684 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
686 lcd_setfont(FONT_UI);
687 return false;
691 lcd_setfont(FONT_UI);
692 return false;
694 #endif
696 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
697 static bool dbg_cpufreq(void)
699 int line;
700 int button;
702 #ifdef HAVE_LCD_BITMAP
703 lcd_setfont(FONT_SYSFIXED);
704 #endif
705 lcd_clear_display();
707 while(1)
709 line = 0;
711 lcd_putsf(0, line++, "Frequency: %ld", FREQ);
712 lcd_putsf(0, line++, "boost_counter: %d", get_cpu_boost_counter());
714 lcd_update();
715 button = get_action(CONTEXT_STD,HZ/10);
717 switch(button)
719 case ACTION_STD_PREV:
720 cpu_boost(true);
721 break;
723 case ACTION_STD_NEXT:
724 cpu_boost(false);
725 break;
727 case ACTION_STD_OK:
728 while (get_cpu_boost_counter() > 0)
729 cpu_boost(false);
730 set_cpu_frequency(CPUFREQ_DEFAULT);
731 break;
733 case ACTION_STD_CANCEL:
734 lcd_setfont(FONT_UI);
735 return false;
738 lcd_setfont(FONT_UI);
739 return false;
741 #endif /* HAVE_ADJUSTABLE_CPU_FREQ */
743 #if defined(HAVE_TSC2100) && (CONFIG_PLATFORM & PLATFORM_NATIVE)
744 #include "tsc2100.h"
745 static const char* tsc2100_debug_getname(int selected_item, void * data,
746 char *buffer, size_t buffer_len)
748 int *page = (int*)data;
749 bool reserved = false;
750 switch (*page)
752 case 0:
753 if ((selected_item > 0x0a) ||
754 (selected_item == 0x04) ||
755 (selected_item == 0x08))
756 reserved = true;
757 break;
758 case 1:
759 if ((selected_item > 0x05) ||
760 (selected_item == 0x02))
761 reserved = true;
762 break;
763 case 2:
764 if (selected_item > 0x1e)
765 reserved = true;
766 break;
768 if (reserved)
769 snprintf(buffer, buffer_len, "%02x: RSVD", selected_item);
770 else
771 snprintf(buffer, buffer_len, "%02x: %04x", selected_item,
772 tsc2100_readreg(*page, selected_item)&0xffff);
773 return buffer;
775 static int tsc2100debug_action_callback(int action, struct gui_synclist *lists)
777 int *page = (int*)lists->data;
778 if (action == ACTION_STD_OK)
780 *page = (*page+1)%3;
781 snprintf(lists->title, 32,
782 "tsc2100 registers - Page %d", *page);
783 return ACTION_REDRAW;
785 return action;
787 static bool tsc2100_debug(void)
789 int page = 0;
790 char title[32] = "tsc2100 registers - Page 0";
791 struct simplelist_info info;
792 simplelist_info_init(&info, title, 32, &page);
793 info.timeout = HZ/100;
794 info.get_name = tsc2100_debug_getname;
795 info.action_callback= tsc2100debug_action_callback;
796 return simplelist_show_list(&info);
798 #endif
799 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
800 #ifdef HAVE_LCD_BITMAP
802 * view_battery() shows a automatically scaled graph of the battery voltage
803 * over time. Usable for estimating battery life / charging rate.
804 * The power_history array is updated in power_thread of powermgmt.c.
807 #define BAT_LAST_VAL MIN(LCD_WIDTH, POWER_HISTORY_LEN)
808 #define BAT_YSPACE (LCD_HEIGHT - 20)
811 static bool view_battery(void)
813 int view = 0;
814 int i, x, y, y1, y2, grid, graph;
815 unsigned short maxv, minv;
817 lcd_setfont(FONT_SYSFIXED);
819 while(1)
821 lcd_clear_display();
822 switch (view) {
823 case 0: /* voltage history graph */
824 /* Find maximum and minimum voltage for scaling */
825 minv = power_history[0];
826 maxv = minv + 1;
827 for (i = 1; i < BAT_LAST_VAL && power_history[i]; i++) {
828 if (power_history[i] > maxv)
829 maxv = power_history[i];
830 if (power_history[i] < minv)
831 minv = power_history[i];
834 /* adjust grid scale */
835 if ((maxv - minv) > 50)
836 grid = 50;
837 else
838 grid = 5;
840 /* print header */
841 lcd_putsf(0, 0, "battery %d.%03dV", power_history[0] / 1000,
842 power_history[0] % 1000);
843 lcd_putsf(0, 1, "%d.%03d-%d.%03dV (%2dmV)",
844 minv / 1000, minv % 1000, maxv / 1000, maxv % 1000,
845 grid);
847 i = 1;
848 while ((y = (minv - (minv % grid)+i*grid)) < maxv)
850 graph = ((y-minv)*BAT_YSPACE)/(maxv-minv);
851 graph = LCD_HEIGHT-1 - graph;
853 /* draw dotted horizontal grid line */
854 for (x=0; x<LCD_WIDTH;x=x+2)
855 lcd_drawpixel(x,graph);
857 i++;
860 x = 0;
861 /* draw plot of power history
862 * skip empty entries
864 for (i = BAT_LAST_VAL - 1; i > 0; i--)
866 if (power_history[i] && power_history[i-1])
868 y1 = (power_history[i] - minv) * BAT_YSPACE /
869 (maxv - minv);
870 y1 = MIN(MAX(LCD_HEIGHT-1 - y1, 20),
871 LCD_HEIGHT-1);
872 y2 = (power_history[i-1] - minv) * BAT_YSPACE /
873 (maxv - minv);
874 y2 = MIN(MAX(LCD_HEIGHT-1 - y2, 20),
875 LCD_HEIGHT-1);
877 lcd_set_drawmode(DRMODE_SOLID);
879 /* make line thicker */
880 lcd_drawline(((x*LCD_WIDTH)/(BAT_LAST_VAL)),
881 y1,
882 (((x+1)*LCD_WIDTH)/(BAT_LAST_VAL)),
883 y2);
884 lcd_drawline(((x*LCD_WIDTH)/(BAT_LAST_VAL))+1,
885 y1+1,
886 (((x+1)*LCD_WIDTH)/(BAT_LAST_VAL))+1,
887 y2+1);
888 x++;
891 break;
893 case 1: /* status: */
894 #if CONFIG_CHARGING >= CHARGING_MONITOR
895 lcd_putsf(0, 0, "Pwr status: %s",
896 charging_state() ? "charging" : "discharging");
897 #else
898 lcd_puts(0, 0, "Power status:");
899 #endif
900 battery_read_info(&y, NULL);
901 lcd_putsf(0, 1, "Battery: %d.%03d V", y / 1000, y % 1000);
902 #ifdef ADC_EXT_POWER
903 y = (adc_read(ADC_EXT_POWER) * EXT_SCALE_FACTOR) / 1000;
904 lcd_putsf(0, 2, "External: %d.%03d V", y / 1000, y % 1000);
905 #endif
906 #if CONFIG_CHARGING
907 #if defined ARCHOS_RECORDER
908 lcd_putsf(0, 3, "Chgr: %s %s",
909 charger_inserted() ? "present" : "absent",
910 charger_enabled() ? "on" : "off");
911 lcd_putsf(0, 5, "short delta: %d", short_delta);
912 lcd_putsf(0, 6, "long delta: %d", long_delta);
913 lcd_puts(0, 7, power_message);
914 lcd_putsf(0, 8, "USB Inserted: %s",
915 usb_inserted() ? "yes" : "no");
916 #elif defined IPOD_NANO || defined IPOD_VIDEO
917 int usb_pwr = (GPIOL_INPUT_VAL & 0x10)?true:false;
918 int ext_pwr = (GPIOL_INPUT_VAL & 0x08)?false:true;
919 int dock = (GPIOA_INPUT_VAL & 0x10)?true:false;
920 int charging = (GPIOB_INPUT_VAL & 0x01)?false:true;
921 int headphone= (GPIOA_INPUT_VAL & 0x80)?true:false;
923 lcd_putsf(0, 3, "USB pwr: %s",
924 usb_pwr ? "present" : "absent");
925 lcd_putsf(0, 4, "EXT pwr: %s",
926 ext_pwr ? "present" : "absent");
927 lcd_putsf(0, 5, "Battery: %s",
928 charging ? "charging" : (usb_pwr||ext_pwr) ? "charged" : "discharging");
929 lcd_putsf(0, 6, "Dock mode: %s",
930 dock ? "enabled" : "disabled");
931 lcd_putsf(0, 7, "Headphone: %s",
932 headphone ? "connected" : "disconnected");
933 #ifdef IPOD_VIDEO
934 if(probed_ramsize == 64)
935 x = (adc_read(ADC_4066_ISTAT) * 2400) / (1024 * 2);
936 else
937 #endif
938 x = (adc_read(ADC_4066_ISTAT) * 2400) / (1024 * 3);
939 lcd_putsf(0, 8, "Ibat: %d mA", x);
940 lcd_putsf(0, 9, "Vbat * Ibat: %d mW", x * y / 1000);
941 #elif defined TOSHIBA_GIGABEAT_S
942 int line = 3;
943 unsigned int st;
945 static const unsigned char * const chrgstate_strings[] =
947 "Disabled",
948 "Error",
949 "Discharging",
950 "Precharge",
951 "Constant Voltage",
952 "Constant Current",
953 "<unknown>",
956 lcd_putsf(0, line++, "Charger: %s",
957 charger_inserted() ? "present" : "absent");
959 st = power_input_status() &
960 (POWER_INPUT_CHARGER | POWER_INPUT_BATTERY);
961 lcd_putsf(0, line++, "%s%s",
962 (st & POWER_INPUT_MAIN_CHARGER) ? " Main" : "",
963 (st & POWER_INPUT_USB_CHARGER) ? " USB" : "");
965 y = ARRAYLEN(chrgstate_strings) - 1;
967 switch (charge_state)
969 case CHARGE_STATE_DISABLED: y--;
970 case CHARGE_STATE_ERROR: y--;
971 case DISCHARGING: y--;
972 case TRICKLE: y--;
973 case TOPOFF: y--;
974 case CHARGING: y--;
975 default:;
978 lcd_putsf(0, line++, "State: %s", chrgstate_strings[y]);
980 lcd_putsf(0, line++, "Battery Switch: %s",
981 (st & POWER_INPUT_BATTERY) ? "On" : "Off");
983 y = chrgraw_adc_voltage();
984 lcd_putsf(0, line++, "CHRGRAW: %d.%03d V",
985 y / 1000, y % 1000);
987 y = application_supply_adc_voltage();
988 lcd_putsf(0, line++, "BP : %d.%03d V",
989 y / 1000, y % 1000);
991 y = battery_adc_charge_current();
992 if (y < 0) x = '-', y = -y;
993 else x = ' ';
994 lcd_putsf(0, line++, "CHRGISN:%c%d mA", x, y);
996 y = cccv_regulator_dissipation();
997 lcd_putsf(0, line++, "P CCCV : %d mW", y);
999 y = battery_charge_current();
1000 if (y < 0) x = '-', y = -y;
1001 else x = ' ';
1002 lcd_putsf(0, line++, "I Charge:%c%d mA", x, y);
1004 y = battery_adc_temp();
1006 if (y != INT_MIN) {
1007 lcd_putsf(0, line++, "T Battery: %dC (%dF)", y,
1008 (9*y + 160) / 5);
1009 } else {
1010 /* Conversion disabled */
1011 lcd_puts(0, line++, "T Battery: ?");
1014 #elif defined(SANSA_E200) || defined(SANSA_C200) || CONFIG_CPU == AS3525 || \
1015 CONFIG_CPU == AS3525v2
1016 static const char * const chrgstate_strings[] =
1018 [CHARGE_STATE_DISABLED - CHARGE_STATE_DISABLED]= "Disabled",
1019 [CHARGE_STATE_ERROR - CHARGE_STATE_DISABLED] = "Error",
1020 [DISCHARGING - CHARGE_STATE_DISABLED] = "Discharging",
1021 [CHARGING - CHARGE_STATE_DISABLED] = "Charging",
1023 const char *str = NULL;
1025 lcd_putsf(0, 3, "Charger: %s",
1026 charger_inserted() ? "present" : "absent");
1028 y = charge_state - CHARGE_STATE_DISABLED;
1029 if ((unsigned)y < ARRAYLEN(chrgstate_strings))
1030 str = chrgstate_strings[y];
1032 lcd_putsf(0, 4, "State: %s",
1033 str ? str : "<unknown>");
1035 lcd_putsf(0, 5, "CHARGER: %02X", ascodec_read_charger());
1036 #elif defined(IPOD_NANO2G)
1037 y = pmu_read_battery_voltage();
1038 lcd_putsf(17, 1, "RAW: %d.%03d V", y / 1000, y % 1000);
1039 y = pmu_read_battery_current();
1040 lcd_putsf(0, 2, "Battery current: %d mA", y);
1041 lcd_putsf(0, 3, "PWRCON: %08x %08x", PWRCON, PWRCONEXT);
1042 lcd_putsf(0, 4, "CLKCON: %08x %03x %03x", CLKCON, CLKCON2, CLKCON3);
1043 lcd_putsf(0, 5, "PLL: %06x %06x %06x", PLL0PMS, PLL1PMS, PLL2PMS);
1044 x = pmu_read(0x1b) & 0xf;
1045 y = pmu_read(0x1a) * 25 + 625;
1046 lcd_putsf(0, 6, "AUTO: %x / %d mV", x, y);
1047 x = pmu_read(0x1f) & 0xf;
1048 y = pmu_read(0x1e) * 25 + 625;
1049 lcd_putsf(0, 7, "DOWN1: %x / %d mV", x, y);
1050 x = pmu_read(0x23) & 0xf;
1051 y = pmu_read(0x22) * 25 + 625;
1052 lcd_putsf(0, 8, "DOWN2: %x / %d mV", x, y);
1053 x = pmu_read(0x27) & 0xf;
1054 y = pmu_read(0x26) * 100 + 900;
1055 lcd_putsf(0, 9, "MEMLDO: %x / %d mV", x, y);
1056 for (i = 0; i < 6; i++)
1058 x = pmu_read(0x2e + (i << 1)) & 0xf;
1059 y = pmu_read(0x2d + (i << 1)) * 100 + 900;
1060 lcd_putsf(0, 10 + i, "LDO%d: %x / %d mV", i + 1, x, y);
1062 #else
1063 lcd_putsf(0, 3, "Charger: %s",
1064 charger_inserted() ? "present" : "absent");
1065 #endif /* target type */
1066 #endif /* CONFIG_CHARGING */
1067 break;
1069 case 2: /* voltage deltas: */
1070 lcd_puts(0, 0, "Voltage deltas:");
1072 for (i = 0; i <= 6; i++) {
1073 y = power_history[i] - power_history[i+1];
1074 lcd_putsf(0, i+1, "-%d min: %s%d.%03d V", i,
1075 (y < 0) ? "-" : "", ((y < 0) ? y * -1 : y) / 1000,
1076 ((y < 0) ? y * -1 : y ) % 1000);
1078 break;
1080 case 3: /* remaining time estimation: */
1082 #ifdef ARCHOS_RECORDER
1083 lcd_putsf(0, 0, "charge_state: %d", charge_state);
1085 lcd_putsf(0, 1, "Cycle time: %d m", powermgmt_last_cycle_startstop_min);
1087 lcd_putsf(0, 2, "Lvl@cyc st: %d%%", powermgmt_last_cycle_level);
1089 lcd_putsf(0, 3, "P=%2d I=%2d", pid_p, pid_i);
1091 lcd_putsf(0, 4, "Trickle sec: %d/60", trickle_sec);
1092 #endif /* ARCHOS_RECORDER */
1094 lcd_putsf(0, 5, "Last PwrHist: %d.%03dV",
1095 power_history[0] / 1000,
1096 power_history[0] % 1000);
1098 lcd_putsf(0, 6, "battery level: %d%%", battery_level());
1100 lcd_putsf(0, 7, "Est. remain: %d m", battery_time());
1101 break;
1104 lcd_update();
1106 switch(get_action(CONTEXT_STD,HZ/2))
1108 case ACTION_STD_PREV:
1109 if (view)
1110 view--;
1111 break;
1113 case ACTION_STD_NEXT:
1114 if (view < 3)
1115 view++;
1116 break;
1118 case ACTION_STD_CANCEL:
1119 lcd_setfont(FONT_UI);
1120 return false;
1123 lcd_setfont(FONT_UI);
1124 return false;
1127 #endif /* HAVE_LCD_BITMAP */
1128 #endif
1130 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
1131 #if (CONFIG_STORAGE & STORAGE_MMC) || (CONFIG_STORAGE & STORAGE_SD)
1133 #if (CONFIG_STORAGE & STORAGE_MMC)
1134 #define CARDTYPE "MMC"
1135 #elif (CONFIG_STORAGE & STORAGE_SD)
1136 #define CARDTYPE "microSD"
1137 #endif
1139 static int disk_callback(int btn, struct gui_synclist *lists)
1141 tCardInfo *card;
1142 int *cardnum = (int*)lists->data;
1143 unsigned char card_name[6];
1144 unsigned char pbuf[32];
1145 char *title = lists->title;
1146 static const unsigned char i_vmin[] = { 0, 1, 5, 10, 25, 35, 60, 100 };
1147 static const unsigned char i_vmax[] = { 1, 5, 10, 25, 35, 45, 80, 200 };
1148 static const unsigned char * const kbit_units[] = { "kBit/s", "MBit/s", "GBit/s" };
1149 static const unsigned char * const nsec_units[] = { "ns", "µs", "ms" };
1150 #if (CONFIG_STORAGE & STORAGE_MMC)
1151 static const char * const mmc_spec_vers[] = { "1.0-1.2", "1.4", "2.0-2.2",
1152 "3.1-3.31", "4.0" };
1153 #endif
1155 if ((btn == ACTION_STD_OK) || (btn == SYS_FS_CHANGED) || (btn == ACTION_REDRAW))
1157 #ifdef HAVE_HOTSWAP
1158 if (btn == ACTION_STD_OK)
1160 *cardnum ^= 0x1; /* change cards */
1162 #endif
1164 simplelist_set_line_count(0);
1166 card = card_get_info(*cardnum);
1168 if (card->initialized > 0)
1170 unsigned i;
1171 for (i=0; i<sizeof(card_name); i++)
1173 card_name[i] = card_extract_bits(card->cid, (103-8*i), 8);
1175 strlcpy(card_name, card_name, sizeof(card_name));
1176 simplelist_addline(SIMPLELIST_ADD_LINE,
1177 "%s Rev %d.%d", card_name,
1178 (int) card_extract_bits(card->cid, 63, 4),
1179 (int) card_extract_bits(card->cid, 59, 4));
1180 simplelist_addline(SIMPLELIST_ADD_LINE,
1181 "Prod: %d/%d",
1182 #if (CONFIG_STORAGE & STORAGE_SD)
1183 (int) card_extract_bits(card->cid, 11, 4),
1184 (int) card_extract_bits(card->cid, 19, 8) + 2000
1185 #elif (CONFIG_STORAGE & STORAGE_MMC)
1186 (int) card_extract_bits(card->cid, 15, 4),
1187 (int) card_extract_bits(card->cid, 11, 4) + 1997
1188 #endif
1190 simplelist_addline(SIMPLELIST_ADD_LINE,
1191 #if (CONFIG_STORAGE & STORAGE_SD)
1192 "Ser#: 0x%08lx",
1193 card_extract_bits(card->cid, 55, 32)
1194 #elif (CONFIG_STORAGE & STORAGE_MMC)
1195 "Ser#: 0x%04lx",
1196 card_extract_bits(card->cid, 47, 16)
1197 #endif
1200 simplelist_addline(SIMPLELIST_ADD_LINE, "M=%02x, "
1201 #if (CONFIG_STORAGE & STORAGE_SD)
1202 "O=%c%c",
1203 (int) card_extract_bits(card->cid, 127, 8),
1204 card_extract_bits(card->cid, 119, 8),
1205 card_extract_bits(card->cid, 111, 8)
1206 #elif (CONFIG_STORAGE & STORAGE_MMC)
1207 "O=%04x",
1208 (int) card_extract_bits(card->cid, 127, 8),
1209 (int) card_extract_bits(card->cid, 119, 16)
1210 #endif
1213 #if (CONFIG_STORAGE & STORAGE_MMC)
1214 int temp = card_extract_bits(card->csd, 125, 4);
1215 simplelist_addline(SIMPLELIST_ADD_LINE,
1216 "MMC v%s", temp < 5 ?
1217 mmc_spec_vers[temp] : "?.?");
1218 #endif
1219 simplelist_addline(SIMPLELIST_ADD_LINE,
1220 "Blocks: 0x%08lx", card->numblocks);
1221 output_dyn_value(pbuf, sizeof pbuf, card->speed / 1000,
1222 kbit_units, false);
1223 simplelist_addline(SIMPLELIST_ADD_LINE,
1224 "Speed: %s", pbuf);
1225 output_dyn_value(pbuf, sizeof pbuf, card->taac,
1226 nsec_units, false);
1227 simplelist_addline(SIMPLELIST_ADD_LINE,
1228 "Taac: %s", pbuf);
1229 simplelist_addline(SIMPLELIST_ADD_LINE,
1230 "Nsac: %d clk", card->nsac);
1231 simplelist_addline(SIMPLELIST_ADD_LINE,
1232 "R2W: *%d", card->r2w_factor);
1233 #if (CONFIG_STORAGE & STORAGE_SD)
1234 int csd_structure = card_extract_bits(card->csd, 127, 2);
1235 if (csd_structure == 0) /* CSD version 1.0 */
1236 #endif
1238 simplelist_addline(SIMPLELIST_ADD_LINE,
1239 "IRmax: %d..%d mA",
1240 i_vmin[card_extract_bits(card->csd, 61, 3)],
1241 i_vmax[card_extract_bits(card->csd, 58, 3)]);
1242 simplelist_addline(SIMPLELIST_ADD_LINE,
1243 "IWmax: %d..%d mA",
1244 i_vmin[card_extract_bits(card->csd, 55, 3)],
1245 i_vmax[card_extract_bits(card->csd, 52, 3)]);
1248 else if (card->initialized == 0)
1250 simplelist_addline(SIMPLELIST_ADD_LINE, "Not Found!");
1252 #if (CONFIG_STORAGE & STORAGE_SD)
1253 else /* card->initialized < 0 */
1255 simplelist_addline(SIMPLELIST_ADD_LINE, "Init Error! (%d)", card->initialized);
1257 #endif
1258 snprintf(title, 16, "[" CARDTYPE " %d]", *cardnum);
1259 gui_synclist_set_title(lists, title, Icon_NOICON);
1260 gui_synclist_set_nb_items(lists, simplelist_get_line_count());
1261 gui_synclist_select_item(lists, 0);
1262 btn = ACTION_REDRAW;
1264 return btn;
1266 #elif (CONFIG_STORAGE & STORAGE_ATA)
1267 static int disk_callback(int btn, struct gui_synclist *lists)
1269 (void)lists;
1270 int i;
1271 char buf[128];
1272 unsigned short* identify_info = ata_get_identify();
1273 bool timing_info_present = false;
1274 (void)btn;
1276 simplelist_set_line_count(0);
1278 for (i=0; i < 20; i++)
1279 ((unsigned short*)buf)[i]=htobe16(identify_info[i+27]);
1280 buf[40]=0;
1281 /* kill trailing space */
1282 for (i=39; i && buf[i]==' '; i--)
1283 buf[i] = 0;
1284 simplelist_addline(SIMPLELIST_ADD_LINE, "Model: %s", buf);
1285 for (i=0; i < 4; i++)
1286 ((unsigned short*)buf)[i]=htobe16(identify_info[i+23]);
1287 buf[8]=0;
1288 simplelist_addline(SIMPLELIST_ADD_LINE,
1289 "Firmware: %s", buf);
1290 snprintf(buf, sizeof buf, "%ld MB",
1291 ((unsigned long)identify_info[61] << 16 |
1292 (unsigned long)identify_info[60]) / 2048 );
1293 simplelist_addline(SIMPLELIST_ADD_LINE,
1294 "Size: %s", buf);
1295 unsigned long free;
1296 fat_size( IF_MV2(0,) NULL, &free );
1297 simplelist_addline(SIMPLELIST_ADD_LINE,
1298 "Free: %ld MB", free / 1024);
1299 simplelist_addline(SIMPLELIST_ADD_LINE,
1300 "Spinup time: %d ms", storage_spinup_time() * (1000/HZ));
1301 i = identify_info[83] & (1<<3);
1302 simplelist_addline(SIMPLELIST_ADD_LINE,
1303 "Power mgmt: %s", i ? "enabled" : "unsupported");
1304 i = identify_info[83] & (1<<9);
1305 simplelist_addline(SIMPLELIST_ADD_LINE,
1306 "Noise mgmt: %s", i ? "enabled" : "unsupported");
1307 i = identify_info[82] & (1<<6);
1308 simplelist_addline(SIMPLELIST_ADD_LINE,
1309 "Read-ahead: %s", i ? "enabled" : "unsupported");
1310 timing_info_present = identify_info[53] & (1<<1);
1311 if(timing_info_present) {
1312 char pio3[2], pio4[2];pio3[1] = 0;
1313 pio4[1] = 0;
1314 pio3[0] = (identify_info[64] & (1<<0)) ? '3' : 0;
1315 pio4[0] = (identify_info[64] & (1<<1)) ? '4' : 0;
1316 simplelist_addline(SIMPLELIST_ADD_LINE,
1317 "PIO modes: 0 1 2 %s %s", pio3, pio4);
1319 else {
1320 simplelist_addline(SIMPLELIST_ADD_LINE,
1321 "No PIO mode info");
1323 timing_info_present = identify_info[53] & (1<<1);
1324 if(timing_info_present) {
1325 simplelist_addline(SIMPLELIST_ADD_LINE,
1326 "Cycle times %dns/%dns",
1327 identify_info[67],
1328 identify_info[68] );
1329 } else {
1330 simplelist_addline(SIMPLELIST_ADD_LINE,
1331 "No timing info");
1333 int sector_size = 512;
1334 if((identify_info[106] & 0xe000) == 0x6000)
1335 sector_size *= BIT_N(identify_info[106] & 0x000f);
1336 simplelist_addline(SIMPLELIST_ADD_LINE,
1337 "Physical sector size: %d", sector_size);
1338 #ifdef HAVE_ATA_DMA
1339 if (identify_info[63] & (1<<0)) {
1340 char mdma0[2], mdma1[2], mdma2[2];
1341 mdma0[1] = mdma1[1] = mdma2[1] = 0;
1342 mdma0[0] = (identify_info[63] & (1<<0)) ? '0' : 0;
1343 mdma1[0] = (identify_info[63] & (1<<1)) ? '1' : 0;
1344 mdma2[0] = (identify_info[63] & (1<<2)) ? '2' : 0;
1345 simplelist_addline(SIMPLELIST_ADD_LINE,
1346 "MDMA modes: %s %s %s", mdma0, mdma1, mdma2);
1347 simplelist_addline(SIMPLELIST_ADD_LINE,
1348 "MDMA Cycle times %dns/%dns",
1349 identify_info[65],
1350 identify_info[66] );
1352 else {
1353 simplelist_addline(SIMPLELIST_ADD_LINE,
1354 "No MDMA mode info");
1356 if (identify_info[53] & (1<<2)) {
1357 char udma0[2], udma1[2], udma2[2], udma3[2], udma4[2], udma5[2], udma6[2];
1358 udma0[1] = udma1[1] = udma2[1] = udma3[1] = udma4[1] = udma5[1] = udma6[1] = 0;
1359 udma0[0] = (identify_info[88] & (1<<0)) ? '0' : 0;
1360 udma1[0] = (identify_info[88] & (1<<1)) ? '1' : 0;
1361 udma2[0] = (identify_info[88] & (1<<2)) ? '2' : 0;
1362 udma3[0] = (identify_info[88] & (1<<3)) ? '3' : 0;
1363 udma4[0] = (identify_info[88] & (1<<4)) ? '4' : 0;
1364 udma5[0] = (identify_info[88] & (1<<5)) ? '5' : 0;
1365 udma6[0] = (identify_info[88] & (1<<6)) ? '6' : 0;
1366 simplelist_addline(SIMPLELIST_ADD_LINE,
1367 "UDMA modes: %s %s %s %s %s %s %s", udma0, udma1, udma2,
1368 udma3, udma4, udma5, udma6);
1370 else {
1371 simplelist_addline(SIMPLELIST_ADD_LINE,
1372 "No UDMA mode info");
1374 #endif /* HAVE_ATA_DMA */
1375 timing_info_present = identify_info[53] & (1<<1);
1376 if(timing_info_present) {
1377 i = identify_info[49] & (1<<11);
1378 simplelist_addline(SIMPLELIST_ADD_LINE,
1379 "IORDY support: %s", i ? "yes" : "no");
1380 i = identify_info[49] & (1<<10);
1381 simplelist_addline(SIMPLELIST_ADD_LINE,
1382 "IORDY disable: %s", i ? "yes" : "no");
1383 } else {
1384 simplelist_addline(SIMPLELIST_ADD_LINE,
1385 "No timing info");
1387 simplelist_addline(SIMPLELIST_ADD_LINE,
1388 "Cluster size: %d bytes", fat_get_cluster_size(IF_MV(0)));
1389 #ifdef HAVE_ATA_DMA
1390 i = ata_get_dma_mode();
1391 if (i == 0) {
1392 simplelist_addline(SIMPLELIST_ADD_LINE,
1393 "DMA not enabled");
1394 } else {
1395 simplelist_addline(SIMPLELIST_ADD_LINE,
1396 "DMA mode: %s %c",
1397 (i & 0x40) ? "UDMA" : "MDMA",
1398 '0' + (i & 7));
1400 #endif /* HAVE_ATA_DMA */
1401 return btn;
1403 #else /* No SD, MMC or ATA */
1404 static int disk_callback(int btn, struct gui_synclist *lists)
1406 (void)btn;
1407 (void)lists;
1408 struct storage_info info;
1409 storage_get_info(0,&info);
1410 simplelist_addline(SIMPLELIST_ADD_LINE, "Vendor: %s", info.vendor);
1411 simplelist_addline(SIMPLELIST_ADD_LINE, "Model: %s", info.product);
1412 simplelist_addline(SIMPLELIST_ADD_LINE, "Firmware: %s", info.revision);
1413 simplelist_addline(SIMPLELIST_ADD_LINE,
1414 "Size: %ld MB", info.num_sectors*(info.sector_size/512)/2024);
1415 unsigned long free;
1416 fat_size( IF_MV2(0,) NULL, &free );
1417 simplelist_addline(SIMPLELIST_ADD_LINE,
1418 "Free: %ld MB", free / 1024);
1419 simplelist_addline(SIMPLELIST_ADD_LINE,
1420 "Cluster size: %d bytes", fat_get_cluster_size(IF_MV(0)));
1421 return btn;
1423 #endif
1425 #if (CONFIG_STORAGE & STORAGE_ATA)
1426 static bool dbg_identify_info(void)
1428 int fd = creat("/identify_info.bin", 0666);
1429 if(fd >= 0)
1431 #ifdef ROCKBOX_LITTLE_ENDIAN
1432 ecwrite(fd, ata_get_identify(), SECTOR_SIZE/2, "s", true);
1433 #else
1434 write(fd, ata_get_identify(), SECTOR_SIZE);
1435 #endif
1436 close(fd);
1438 return false;
1440 #endif
1442 static bool dbg_disk_info(void)
1444 struct simplelist_info info;
1445 simplelist_info_init(&info, "Disk Info", 1, NULL);
1446 #if (CONFIG_STORAGE & STORAGE_MMC) || (CONFIG_STORAGE & STORAGE_SD)
1447 char title[16];
1448 int card = 0;
1449 info.callback_data = (void*)&card;
1450 info.title = title;
1451 #endif
1452 info.action_callback = disk_callback;
1453 info.hide_selection = true;
1454 info.scroll_all = true;
1455 return simplelist_show_list(&info);
1457 #endif /* PLATFORM_NATIVE */
1459 #ifdef HAVE_DIRCACHE
1460 static int dircache_callback(int btn, struct gui_synclist *lists)
1462 (void)btn; (void)lists;
1463 simplelist_set_line_count(0);
1464 simplelist_addline(SIMPLELIST_ADD_LINE, "Cache initialized: %s",
1465 dircache_is_enabled() ? "Yes" : "No");
1466 simplelist_addline(SIMPLELIST_ADD_LINE, "Cache size: %d B",
1467 dircache_get_cache_size());
1468 simplelist_addline(SIMPLELIST_ADD_LINE, "Last size: %d B",
1469 global_status.dircache_size);
1470 simplelist_addline(SIMPLELIST_ADD_LINE, "Limit: %d B",
1471 DIRCACHE_LIMIT);
1472 simplelist_addline(SIMPLELIST_ADD_LINE, "Reserve: %d/%d B",
1473 dircache_get_reserve_used(), DIRCACHE_RESERVE);
1474 simplelist_addline(SIMPLELIST_ADD_LINE, "Scanning took: %d s",
1475 dircache_get_build_ticks() / HZ);
1476 simplelist_addline(SIMPLELIST_ADD_LINE, "Entry count: %d",
1477 dircache_get_entry_count());
1478 return btn;
1481 static bool dbg_dircache_info(void)
1483 struct simplelist_info info;
1484 simplelist_info_init(&info, "Dircache Info", 7, NULL);
1485 info.action_callback = dircache_callback;
1486 info.hide_selection = true;
1487 info.scroll_all = true;
1488 return simplelist_show_list(&info);
1491 #endif /* HAVE_DIRCACHE */
1493 #ifdef HAVE_TAGCACHE
1494 static int database_callback(int btn, struct gui_synclist *lists)
1496 (void)lists;
1497 struct tagcache_stat *stat = tagcache_get_stat();
1498 static bool synced = false;
1500 simplelist_set_line_count(0);
1502 simplelist_addline(SIMPLELIST_ADD_LINE, "Initialized: %s",
1503 stat->initialized ? "Yes" : "No");
1504 simplelist_addline(SIMPLELIST_ADD_LINE, "DB Ready: %s",
1505 stat->ready ? "Yes" : "No");
1506 simplelist_addline(SIMPLELIST_ADD_LINE, "RAM Cache: %s",
1507 stat->ramcache ? "Yes" : "No");
1508 simplelist_addline(SIMPLELIST_ADD_LINE, "RAM: %d/%d B",
1509 stat->ramcache_used, stat->ramcache_allocated);
1510 simplelist_addline(SIMPLELIST_ADD_LINE, "Progress: %d%% (%d entries)",
1511 stat->progress, stat->processed_entries);
1512 simplelist_addline(SIMPLELIST_ADD_LINE, "Curfile: %s",
1513 stat->curentry ? stat->curentry : "---");
1514 simplelist_addline(SIMPLELIST_ADD_LINE, "Commit step: %d",
1515 stat->commit_step);
1516 simplelist_addline(SIMPLELIST_ADD_LINE, "Commit delayed: %s",
1517 stat->commit_delayed ? "Yes" : "No");
1519 simplelist_addline(SIMPLELIST_ADD_LINE, "Queue length: %d",
1520 stat->queue_length);
1522 if (synced)
1524 synced = false;
1525 tagcache_screensync_event();
1528 if (!btn && stat->curentry)
1530 synced = true;
1531 return ACTION_REDRAW;
1534 if (btn == ACTION_STD_CANCEL)
1535 tagcache_screensync_enable(false);
1537 return btn;
1539 static bool dbg_tagcache_info(void)
1541 struct simplelist_info info;
1542 simplelist_info_init(&info, "Database Info", 8, NULL);
1543 info.action_callback = database_callback;
1544 info.hide_selection = true;
1545 info.scroll_all = true;
1547 /* Don't do nonblock here, must give enough processing time
1548 for tagcache thread. */
1549 /* info.timeout = TIMEOUT_NOBLOCK; */
1550 info.timeout = 1;
1551 tagcache_screensync_enable(true);
1552 return simplelist_show_list(&info);
1554 #endif
1556 #if CONFIG_CPU == SH7034
1557 static bool dbg_save_roms(void)
1559 int fd;
1560 int oldmode = system_memory_guard(MEMGUARD_NONE);
1562 fd = creat("/internal_rom_0000-FFFF.bin", 0666);
1563 if(fd >= 0)
1565 write(fd, (void *)0, 0x10000);
1566 close(fd);
1569 fd = creat("/internal_rom_2000000-203FFFF.bin", 0666);
1570 if(fd >= 0)
1572 write(fd, (void *)0x2000000, 0x40000);
1573 close(fd);
1576 system_memory_guard(oldmode);
1577 return false;
1579 #elif defined CPU_COLDFIRE
1580 static bool dbg_save_roms(void)
1582 int fd;
1583 int oldmode = system_memory_guard(MEMGUARD_NONE);
1585 #if defined(IRIVER_H100_SERIES)
1586 fd = creat("/internal_rom_000000-1FFFFF.bin", 0666);
1587 #elif defined(IRIVER_H300_SERIES)
1588 fd = creat("/internal_rom_000000-3FFFFF.bin", 0666);
1589 #elif defined(IAUDIO_X5) || defined(IAUDIO_M5) || defined(IAUDIO_M3)
1590 fd = creat("/internal_rom_000000-3FFFFF.bin", 0666);
1591 #elif defined(MPIO_HD200) || defined(MPIO_HD300)
1592 fd = creat("/internal_rom_000000-1FFFFF.bin", 0666);
1593 #endif
1594 if(fd >= 0)
1596 write(fd, (void *)0, FLASH_SIZE);
1597 close(fd);
1599 system_memory_guard(oldmode);
1601 #ifdef HAVE_EEPROM
1602 fd = creat("/internal_eeprom.bin", 0666);
1603 if (fd >= 0)
1605 int old_irq_level;
1606 char buf[EEPROM_SIZE];
1607 int err;
1609 old_irq_level = disable_irq_save();
1611 err = eeprom_24cxx_read(0, buf, sizeof buf);
1613 restore_irq(old_irq_level);
1615 if (err)
1616 splashf(HZ*3, "Eeprom read failure (%d)", err);
1617 else
1619 write(fd, buf, sizeof buf);
1622 close(fd);
1624 #endif
1626 return false;
1628 #elif defined(CPU_PP) && !(CONFIG_STORAGE & STORAGE_SD)
1629 static bool dbg_save_roms(void)
1631 int fd;
1633 fd = creat("/internal_rom_000000-0FFFFF.bin", 0666);
1634 if(fd >= 0)
1636 write(fd, (void *)0x20000000, FLASH_SIZE);
1637 close(fd);
1640 return false;
1642 #elif CONFIG_CPU == IMX31L
1643 static bool dbg_save_roms(void)
1645 int fd;
1647 fd = creat("/flash_rom_A0000000-A01FFFFF.bin", 0666);
1648 if (fd >= 0)
1650 write(fd, (void*)0xa0000000, FLASH_SIZE);
1651 close(fd);
1654 return false;
1656 #elif defined(CPU_TCC780X)
1657 static bool dbg_save_roms(void)
1659 int fd;
1661 fd = creat("/eeprom_E0000000-E0001FFF.bin", 0666);
1662 if (fd >= 0)
1664 write(fd, (void*)0xe0000000, 0x2000);
1665 close(fd);
1668 return false;
1670 #endif /* CPU */
1672 #ifndef SIMULATOR
1673 #if CONFIG_TUNER
1675 #ifdef CONFIG_TUNER_MULTI
1676 static int tuner_type = 0;
1677 #define IF_TUNER_TYPE(type) if(tuner_type==type)
1678 #else
1679 #define IF_TUNER_TYPE(type)
1680 #endif
1682 static int radio_callback(int btn, struct gui_synclist *lists)
1684 (void)lists;
1685 if (btn == ACTION_STD_CANCEL)
1686 return btn;
1687 simplelist_set_line_count(1);
1689 #if (CONFIG_TUNER & LV24020LP)
1690 simplelist_addline(SIMPLELIST_ADD_LINE,
1691 "CTRL_STAT: %02X", lv24020lp_get(LV24020LP_CTRL_STAT) );
1692 simplelist_addline(SIMPLELIST_ADD_LINE,
1693 "RADIO_STAT: %02X", lv24020lp_get(LV24020LP_REG_STAT) );
1694 simplelist_addline(SIMPLELIST_ADD_LINE,
1695 "MSS_FM: %d kHz", lv24020lp_get(LV24020LP_MSS_FM) );
1696 simplelist_addline(SIMPLELIST_ADD_LINE,
1697 "MSS_IF: %d Hz", lv24020lp_get(LV24020LP_MSS_IF) );
1698 simplelist_addline(SIMPLELIST_ADD_LINE,
1699 "MSS_SD: %d Hz", lv24020lp_get(LV24020LP_MSS_SD) );
1700 simplelist_addline(SIMPLELIST_ADD_LINE,
1701 "if_set: %d Hz", lv24020lp_get(LV24020LP_IF_SET) );
1702 simplelist_addline(SIMPLELIST_ADD_LINE,
1703 "sd_set: %d Hz", lv24020lp_get(LV24020LP_SD_SET) );
1704 #endif /* LV24020LP */
1705 #if (CONFIG_TUNER & S1A0903X01)
1706 simplelist_addline(SIMPLELIST_ADD_LINE,
1707 "Samsung regs: %08X", s1a0903x01_get(RADIO_ALL));
1708 /* This one doesn't return dynamic data atm */
1709 #endif /* S1A0903X01 */
1710 #if (CONFIG_TUNER & TEA5767)
1711 struct tea5767_dbg_info nfo;
1712 tea5767_dbg_info(&nfo);
1713 simplelist_addline(SIMPLELIST_ADD_LINE, "Philips regs:");
1714 simplelist_addline(SIMPLELIST_ADD_LINE,
1715 " Read: %02X %02X %02X %02X %02X",
1716 (unsigned)nfo.read_regs[0], (unsigned)nfo.read_regs[1],
1717 (unsigned)nfo.read_regs[2], (unsigned)nfo.read_regs[3],
1718 (unsigned)nfo.read_regs[4]);
1719 simplelist_addline(SIMPLELIST_ADD_LINE,
1720 " Write: %02X %02X %02X %02X %02X",
1721 (unsigned)nfo.write_regs[0], (unsigned)nfo.write_regs[1],
1722 (unsigned)nfo.write_regs[2], (unsigned)nfo.write_regs[3],
1723 (unsigned)nfo.write_regs[4]);
1724 #endif /* TEA5767 */
1725 #if (CONFIG_TUNER & SI4700)
1726 IF_TUNER_TYPE(SI4700)
1728 struct si4700_dbg_info nfo;
1729 int i;
1730 si4700_dbg_info(&nfo);
1731 simplelist_addline(SIMPLELIST_ADD_LINE, "SI4700 regs:");
1732 for (i = 0; i < 16; i += 4) {
1733 simplelist_addline(SIMPLELIST_ADD_LINE,"%02X: %04X %04X %04X %04X",
1734 i, nfo.regs[i], nfo.regs[i+1], nfo.regs[i+2], nfo.regs[i+3]);
1737 #endif /* SI4700 */
1738 #if (CONFIG_TUNER & RDA5802)
1739 IF_TUNER_TYPE(RDA5802)
1741 struct rda5802_dbg_info nfo;
1742 int i;
1743 rda5802_dbg_info(&nfo);
1744 simplelist_addline(SIMPLELIST_ADD_LINE, "RDA5802 regs:");
1745 for (i = 0; i < 16; i += 4) {
1746 simplelist_addline(SIMPLELIST_ADD_LINE,"%02X: %04X %04X %04X %04X",
1747 i, nfo.regs[i], nfo.regs[i+1], nfo.regs[i+2], nfo.regs[i+3]);
1750 #endif /* RDA55802 */
1751 return ACTION_REDRAW;
1753 static bool dbg_fm_radio(void)
1755 struct simplelist_info info;
1756 #ifdef CONFIG_TUNER_MULTI
1757 tuner_type = tuner_detect_type();
1758 #endif
1759 info.scroll_all = true;
1760 simplelist_info_init(&info, "FM Radio", 1, NULL);
1761 simplelist_set_line_count(0);
1762 simplelist_addline(SIMPLELIST_ADD_LINE, "HW detected: %s",
1763 radio_hardware_present() ? "yes" : "no");
1765 info.action_callback = radio_hardware_present()?radio_callback : NULL;
1766 info.hide_selection = true;
1767 return simplelist_show_list(&info);
1769 #endif /* CONFIG_TUNER */
1770 #endif /* !SIMULATOR */
1772 #ifdef HAVE_LCD_BITMAP
1773 extern bool do_screendump_instead_of_usb;
1775 static bool dbg_screendump(void)
1777 do_screendump_instead_of_usb = !do_screendump_instead_of_usb;
1778 splashf(HZ, "Screendump %s",
1779 do_screendump_instead_of_usb?"enabled":"disabled");
1780 return false;
1782 #endif /* HAVE_LCD_BITMAP */
1784 extern bool write_metadata_log;
1786 static bool dbg_metadatalog(void)
1788 write_metadata_log = !write_metadata_log;
1789 splashf(HZ, "Metadata log %s",
1790 write_metadata_log?"enabled":"disabled");
1791 return false;
1794 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
1795 static bool dbg_set_memory_guard(void)
1797 static const struct opt_items names[MAXMEMGUARD] = {
1798 { "None", -1 },
1799 { "Flash ROM writes", -1 },
1800 { "Zero area (all)", -1 }
1802 int mode = system_memory_guard(MEMGUARD_KEEP);
1804 set_option( "Catch mem accesses", &mode, INT, names, MAXMEMGUARD, NULL);
1805 system_memory_guard(mode);
1807 return false;
1809 #endif /* CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) */
1811 #if defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS)
1812 static bool dbg_write_eeprom(void)
1814 int fd;
1815 int rc;
1816 int old_irq_level;
1817 char buf[EEPROM_SIZE];
1818 int err;
1820 fd = open("/internal_eeprom.bin", O_RDONLY);
1822 if (fd >= 0)
1824 rc = read(fd, buf, EEPROM_SIZE);
1826 if(rc == EEPROM_SIZE)
1828 old_irq_level = disable_irq_save();
1830 err = eeprom_24cxx_write(0, buf, sizeof buf);
1831 if (err)
1832 splashf(HZ*3, "Eeprom write failure (%d)", err);
1833 else
1834 splash(HZ*3, "Eeprom written successfully");
1836 restore_irq(old_irq_level);
1838 else
1840 splashf(HZ*3, "File read error (%d)",rc);
1842 close(fd);
1844 else
1846 splash(HZ*3, "Failed to open 'internal_eeprom.bin'");
1849 return false;
1851 #endif /* defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS) */
1852 #ifdef CPU_BOOST_LOGGING
1853 static bool cpu_boost_log(void)
1855 int i = 0,j=0;
1856 int count = cpu_boost_log_getcount();
1857 int lines = LCD_HEIGHT/SYSFONT_HEIGHT;
1858 char *str;
1859 bool done;
1860 lcd_setfont(FONT_SYSFIXED);
1861 str = cpu_boost_log_getlog_first();
1862 while (i < count)
1864 lcd_clear_display();
1865 for(j=0; j<lines; j++,i++)
1867 if (!str)
1868 str = cpu_boost_log_getlog_next();
1869 if (str)
1871 if(strlen(str) > LCD_WIDTH/SYSFONT_WIDTH)
1872 lcd_puts_scroll(0, j, str);
1873 else
1874 lcd_puts(0, j,str);
1876 str = NULL;
1878 lcd_update();
1879 done = false;
1880 while (!done)
1882 switch(get_action(CONTEXT_STD,TIMEOUT_BLOCK))
1884 case ACTION_STD_OK:
1885 case ACTION_STD_PREV:
1886 case ACTION_STD_NEXT:
1887 done = true;
1888 break;
1889 case ACTION_STD_CANCEL:
1890 i = count;
1891 done = true;
1892 break;
1896 lcd_stop_scroll();
1897 get_action(CONTEXT_STD,TIMEOUT_BLOCK);
1898 lcd_setfont(FONT_UI);
1899 return false;
1901 #endif
1903 #if (defined(HAVE_WHEEL_ACCELERATION) && (CONFIG_KEYPAD==IPOD_4G_PAD) \
1904 && !defined(IPOD_MINI) && !defined(SIMULATOR))
1905 extern bool wheel_is_touched;
1906 extern int old_wheel_value;
1907 extern int new_wheel_value;
1908 extern int wheel_delta;
1909 extern unsigned int accumulated_wheel_delta;
1910 extern unsigned int wheel_velocity;
1912 static bool dbg_scrollwheel(void)
1914 unsigned int speed;
1916 lcd_setfont(FONT_SYSFIXED);
1918 while (1)
1920 if (action_userabort(HZ/10))
1921 break;
1923 lcd_clear_display();
1925 /* show internal variables of scrollwheel driver */
1926 lcd_putsf(0, 0, "wheel touched: %s", (wheel_is_touched) ? "true" : "false");
1927 lcd_putsf(0, 1, "new position: %2d", new_wheel_value);
1928 lcd_putsf(0, 2, "old position: %2d", old_wheel_value);
1929 lcd_putsf(0, 3, "wheel delta: %2d", wheel_delta);
1930 lcd_putsf(0, 4, "accumulated delta: %2d", accumulated_wheel_delta);
1931 lcd_putsf(0, 5, "velo [deg/s]: %4d", (int)wheel_velocity);
1933 /* show effective accelerated scrollspeed */
1934 speed = button_apply_acceleration( (1<<31)|(1<<24)|wheel_velocity);
1935 lcd_putsf(0, 6, "accel. speed: %4d", speed);
1937 lcd_update();
1939 lcd_setfont(FONT_UI);
1940 return false;
1942 #endif
1944 #if defined (HAVE_USBSTACK)
1946 #if defined(ROCKBOX_HAS_LOGF) && defined(USB_ENABLE_SERIAL)
1947 static bool toggle_usb_core_driver(int driver, char *msg)
1949 bool enabled = !usb_core_driver_enabled(driver);
1951 usb_core_enable_driver(driver,enabled);
1952 splashf(HZ, "%s %s", msg, enabled?"enabled":"disabled");
1954 return false;
1957 static bool toggle_usb_serial(void)
1959 return toggle_usb_core_driver(USB_DRIVER_SERIAL,"USB Serial");
1961 #endif
1963 #endif
1965 #if CONFIG_USBOTG == USBOTG_ISP1583
1966 extern int dbg_usb_num_items(void);
1967 extern const char* dbg_usb_item(int selected_item, void *data,
1968 char *buffer, size_t buffer_len);
1970 static int isp1583_action_callback(int action, struct gui_synclist *lists)
1972 (void)lists;
1973 if (action == ACTION_NONE)
1974 action = ACTION_REDRAW;
1975 return action;
1978 static bool dbg_isp1583(void)
1980 struct simplelist_info isp1583;
1981 isp1583.scroll_all = true;
1982 simplelist_info_init(&isp1583, "ISP1583", dbg_usb_num_items(), NULL);
1983 isp1583.timeout = HZ/100;
1984 isp1583.hide_selection = true;
1985 isp1583.get_name = dbg_usb_item;
1986 isp1583.action_callback = isp1583_action_callback;
1987 return simplelist_show_list(&isp1583);
1989 #endif
1991 #if defined(CREATIVE_ZVx) && !defined(SIMULATOR)
1992 extern int pic_dbg_num_items(void);
1993 extern const char* pic_dbg_item(int selected_item, void *data,
1994 char *buffer, size_t buffer_len);
1996 static int pic_action_callback(int action, struct gui_synclist *lists)
1998 (void)lists;
1999 if (action == ACTION_NONE)
2000 action = ACTION_REDRAW;
2001 return action;
2004 static bool dbg_pic(void)
2006 struct simplelist_info pic;
2007 pic.scroll_all = true;
2008 simplelist_info_init(&pic, "PIC", pic_dbg_num_items(), NULL);
2009 pic.timeout = HZ/100;
2010 pic.hide_selection = true;
2011 pic.get_name = pic_dbg_item;
2012 pic.action_callback = pic_action_callback;
2013 return simplelist_show_list(&pic);
2015 #endif
2018 /****** The menu *********/
2019 struct the_menu_item {
2020 unsigned char *desc; /* string or ID */
2021 bool (*function) (void); /* return true if USB was connected */
2023 static const struct the_menu_item menuitems[] = {
2024 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || \
2025 (defined(CPU_PP) && !(CONFIG_STORAGE & STORAGE_SD)) || \
2026 CONFIG_CPU == IMX31L || defined(CPU_TCC780X)
2027 { "Dump ROM contents", dbg_save_roms },
2028 #endif
2029 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || defined(CPU_PP) \
2030 || CONFIG_CPU == S3C2440 || CONFIG_CPU == IMX31L || CONFIG_CPU == AS3525 \
2031 || CONFIG_CPU == DM320 || defined(CPU_S5L870X) || CONFIG_CPU == AS3525v2 \
2032 || CONFIG_CPU == RK27XX
2033 { "View I/O ports", dbg_ports },
2034 #endif
2035 #if (CONFIG_RTC == RTC_PCF50605) && (CONFIG_PLATFORM & PLATFORM_NATIVE)
2036 { "View PCF registers", dbg_pcf },
2037 #endif
2038 #if defined(HAVE_TSC2100) && (CONFIG_PLATFORM & PLATFORM_NATIVE)
2039 { "TSC2100 debug", tsc2100_debug },
2040 #endif
2041 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
2042 { "CPU frequency", dbg_cpufreq },
2043 #endif
2044 #if CONFIG_CPU == IMX31L
2045 { "DVFS/DPTC", __dbg_dvfs_dptc },
2046 #endif
2047 #if defined(IRIVER_H100_SERIES) && !defined(SIMULATOR)
2048 { "S/PDIF analyzer", dbg_spdif },
2049 #endif
2050 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
2051 { "Catch mem accesses", dbg_set_memory_guard },
2052 #endif
2053 { "View OS stacks", dbg_os },
2054 #ifdef HAVE_LCD_BITMAP
2055 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
2056 { "View battery", view_battery },
2057 #endif
2058 { "Screendump", dbg_screendump },
2059 #endif
2060 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
2061 { "View HW info", dbg_hw_info },
2062 #endif
2063 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
2064 { "View partitions", dbg_partitions },
2065 #endif
2066 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
2067 { "View disk info", dbg_disk_info },
2068 #if (CONFIG_STORAGE & STORAGE_ATA)
2069 { "Dump ATA identify info", dbg_identify_info},
2070 #endif
2071 #endif
2072 { "Metadata log", dbg_metadatalog },
2073 #ifdef HAVE_DIRCACHE
2074 { "View dircache info", dbg_dircache_info },
2075 #endif
2076 #ifdef HAVE_TAGCACHE
2077 { "View database info", dbg_tagcache_info },
2078 #endif
2079 #ifdef HAVE_LCD_BITMAP
2080 #if CONFIG_CODEC == SWCODEC
2081 { "View buffering thread", dbg_buffering_thread },
2082 #elif !defined(SIMULATOR)
2083 { "View audio thread", dbg_audio_thread },
2084 #endif
2085 #ifdef PM_DEBUG
2086 { "pm histogram", peak_meter_histogram},
2087 #endif /* PM_DEBUG */
2088 #endif /* HAVE_LCD_BITMAP */
2089 { "View buflib allocs", dbg_buflib_allocs },
2090 #ifndef SIMULATOR
2091 #if CONFIG_TUNER
2092 { "FM Radio", dbg_fm_radio },
2093 #endif
2094 #endif
2095 #if defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS)
2096 { "Write back EEPROM", dbg_write_eeprom },
2097 #endif
2098 #if CONFIG_USBOTG == USBOTG_ISP1583
2099 { "View ISP1583 info", dbg_isp1583 },
2100 #endif
2101 #if defined(CREATIVE_ZVx) && !defined(SIMULATOR)
2102 { "View PIC info", dbg_pic },
2103 #endif
2104 #ifdef ROCKBOX_HAS_LOGF
2105 {"Show Log File", logfdisplay },
2106 {"Dump Log File", logfdump },
2107 #endif
2108 #if defined(HAVE_USBSTACK)
2109 #if defined(ROCKBOX_HAS_LOGF) && defined(USB_ENABLE_SERIAL)
2110 {"USB Serial driver (logf)", toggle_usb_serial },
2111 #endif
2112 #endif /* HAVE_USBSTACK */
2113 #ifdef CPU_BOOST_LOGGING
2114 {"cpu_boost log",cpu_boost_log},
2115 #endif
2116 #if (defined(HAVE_WHEEL_ACCELERATION) && (CONFIG_KEYPAD==IPOD_4G_PAD) \
2117 && !defined(IPOD_MINI) && !defined(SIMULATOR))
2118 {"Debug scrollwheel", dbg_scrollwheel },
2119 #endif
2121 static int menu_action_callback(int btn, struct gui_synclist *lists)
2123 int i;
2124 if (btn == ACTION_STD_OK)
2126 FOR_NB_SCREENS(i)
2127 viewportmanager_theme_enable(i, false, NULL);
2128 menuitems[gui_synclist_get_sel_pos(lists)].function();
2129 btn = ACTION_REDRAW;
2130 FOR_NB_SCREENS(i)
2131 viewportmanager_theme_undo(i, false);
2133 return btn;
2136 static const char* dbg_menu_getname(int item, void * data,
2137 char *buffer, size_t buffer_len)
2139 (void)data; (void)buffer; (void)buffer_len;
2140 return menuitems[item].desc;
2143 bool debug_menu(void)
2145 struct simplelist_info info;
2147 simplelist_info_init(&info, "Debug Menu", ARRAYLEN(menuitems), NULL);
2148 info.action_callback = menu_action_callback;
2149 info.get_name = dbg_menu_getname;
2150 return simplelist_show_list(&info);