Prepare new maemo release
[maemo-rb.git] / apps / debug_menu.c
blobc4291879c30aa7123e82ab0f29da4e5db9f1efd1
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 "lang.h"
29 #include "menu.h"
30 #include "debug_menu.h"
31 #include "kernel.h"
32 #include "structec.h"
33 #include "action.h"
34 #include "debug.h"
35 #include "thread.h"
36 #include "powermgmt.h"
37 #include "system.h"
38 #include "font.h"
39 #include "audio.h"
40 #include "mp3_playback.h"
41 #include "settings.h"
42 #include "list.h"
43 #include "statusbar.h"
44 #include "dir.h"
45 #include "panic.h"
46 #include "screens.h"
47 #include "misc.h"
48 #include "splash.h"
49 #include "shortcuts.h"
50 #include "dircache.h"
51 #include "viewport.h"
52 #ifdef HAVE_TAGCACHE
53 #include "tagcache.h"
54 #endif
55 #ifdef HAVE_REMOTE_LCD
56 #include "lcd-remote.h"
57 #endif
58 #include "crc32.h"
59 #include "logf.h"
60 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
61 #include "disk.h"
62 #include "adc.h"
63 #include "usb.h"
64 #include "rtc.h"
65 #include "storage.h"
66 #include "fat.h"
67 #include "eeprom_24cxx.h"
68 #if (CONFIG_STORAGE & STORAGE_MMC) || (CONFIG_STORAGE & STORAGE_SD)
69 #include "sdmmc.h"
70 #endif
71 #if (CONFIG_STORAGE & STORAGE_ATA)
72 #include "ata.h"
73 #endif
74 #if CONFIG_TUNER
75 #include "tuner.h"
76 #include "radio.h"
77 #endif
78 #endif
79 #include "power.h"
81 #if defined(SAMSUNG_YPR0) && defined(CONFIG_TUNER)
82 #include "tuner.h"
83 #include "radio.h"
84 #endif
86 #ifdef HAVE_LCD_BITMAP
87 #include "scrollbar.h"
88 #include "peakmeter.h"
89 #include "skin_engine/skin_engine.h"
90 #endif
91 #include "logfdisp.h"
92 #include "core_alloc.h"
93 #if CONFIG_CODEC == SWCODEC
94 #include "pcmbuf.h"
95 #include "buffering.h"
96 #include "playback.h"
97 #if defined(HAVE_SPDIF_OUT) || defined(HAVE_SPDIF_IN)
98 #include "spdif.h"
99 #endif
100 #endif
101 #ifdef IRIVER_H300_SERIES
102 #include "pcf50606.h" /* for pcf50606_read */
103 #endif
104 #ifdef IAUDIO_X5
105 #include "ds2411.h"
106 #endif
107 #include "hwcompat.h"
108 #include "button.h"
109 #if CONFIG_RTC == RTC_PCF50605
110 #include "pcf50605.h"
111 #endif
112 #include "appevents.h"
114 #if defined(HAVE_AS3514) && defined(CONFIG_CHARGING)
115 #include "ascodec.h"
116 #endif
118 #ifdef IPOD_NANO2G
119 #include "pmu-target.h"
120 #endif
122 #ifdef HAVE_USBSTACK
123 #include "usb_core.h"
124 #endif
126 #if defined(IPOD_ACCESSORY_PROTOCOL)
127 #include "iap.h"
128 #endif
130 #ifdef HAVE_RDS_CAP
131 #include "rds.h"
132 #endif
134 /*---------------------------------------------------*/
135 /* SPECIAL DEBUG STUFF */
136 /*---------------------------------------------------*/
137 extern struct thread_entry threads[MAXTHREADS];
139 static char thread_status_char(unsigned status)
141 static const char thread_status_chars[THREAD_NUM_STATES+1] =
143 [0 ... THREAD_NUM_STATES] = '?',
144 [STATE_RUNNING] = 'R',
145 [STATE_BLOCKED] = 'B',
146 [STATE_SLEEPING] = 'S',
147 [STATE_BLOCKED_W_TMO] = 'T',
148 [STATE_FROZEN] = 'F',
149 [STATE_KILLED] = 'K',
152 if (status > THREAD_NUM_STATES)
153 status = THREAD_NUM_STATES;
155 return thread_status_chars[status];
158 static const char* threads_getname(int selected_item, void *data,
159 char *buffer, size_t buffer_len)
161 (void)data;
162 struct thread_entry *thread;
163 char name[32];
165 #if NUM_CORES > 1
166 if (selected_item < (int)NUM_CORES)
168 snprintf(buffer, buffer_len, "Idle (%d): %2d%%", selected_item,
169 idle_stack_usage(selected_item));
170 return buffer;
173 selected_item -= NUM_CORES;
174 #endif
176 thread = &threads[selected_item];
178 if (thread->state == STATE_KILLED)
180 snprintf(buffer, buffer_len, "%2d: ---", selected_item);
181 return buffer;
184 thread_get_name(name, 32, thread);
186 snprintf(buffer, buffer_len,
187 "%2d: " IF_COP("(%d) ") "%c%c " IF_PRIO("%d %d ") "%2d%% %s",
188 selected_item,
189 IF_COP(thread->core,)
190 #ifdef HAVE_SCHEDULER_BOOSTCTRL
191 (thread->cpu_boost) ? '+' :
192 #endif
193 ((thread->state == STATE_RUNNING) ? '*' : ' '),
194 thread_status_char(thread->state),
195 IF_PRIO(thread->base_priority, thread->priority, )
196 thread_stack_usage(thread), name);
198 return buffer;
201 static int dbg_threads_action_callback(int action, struct gui_synclist *lists)
203 (void)lists;
204 #ifdef ROCKBOX_HAS_LOGF
205 if (action == ACTION_STD_OK)
207 int selpos = gui_synclist_get_sel_pos(lists);
208 #if NUM_CORES > 1
209 if (selpos >= NUM_CORES)
210 remove_thread(threads[selpos - NUM_CORES].id);
211 #else
212 remove_thread(threads[selpos].id);
213 #endif
214 return ACTION_REDRAW;
216 #endif /* ROCKBOX_HAS_LOGF */
217 if (action == ACTION_NONE)
218 action = ACTION_REDRAW;
219 return action;
221 /* Test code!!! */
222 static bool dbg_os(void)
224 struct simplelist_info info;
225 simplelist_info_init(&info, IF_COP("Core and ") "Stack usage:",
226 #if NUM_CORES == 1
227 MAXTHREADS,
228 #else
229 MAXTHREADS+NUM_CORES,
230 #endif
231 NULL);
232 #ifndef ROCKBOX_HAS_LOGF
233 info.hide_selection = true;
234 info.scroll_all = true;
235 #endif
236 info.action_callback = dbg_threads_action_callback;
237 info.get_name = threads_getname;
238 return simplelist_show_list(&info);
241 #ifdef __linux__
242 #include "cpuinfo-linux.h"
244 #define MAX_STATES 16
245 static struct time_state states[MAX_STATES];
247 static const char* get_cpuinfo(int selected_item, void *data,
248 char *buffer, size_t buffer_len)
250 (void)data;(void)buffer_len;
251 const char* text;
252 long time, diff;
253 struct cpuusage us;
254 static struct cpuusage last_us;
255 int state_count = *(int*)data;
257 if (cpuusage_linux(&us) != 0)
258 return NULL;
260 switch(selected_item)
262 case 0:
263 diff = abs(last_us.usage - us.usage);
264 sprintf(buffer, "Usage: %ld.%02ld%% (%c %ld.%02ld)",
265 us.usage/100, us.usage%100,
266 (us.usage >= last_us.usage) ? '+':'-',
267 diff/100, diff%100);
268 last_us.usage = us.usage;
269 return buffer;
270 case 1:
271 text = "User";
272 time = us.utime;
273 diff = us.utime - last_us.utime;
274 last_us.utime = us.utime;
275 break;
276 case 2:
277 text = "Sys";
278 time = us.stime;
279 diff = us.stime - last_us.stime;
280 last_us.stime = us.stime;
281 break;
282 case 3:
283 text = "Real";
284 time = us.rtime;
285 diff = us.rtime - last_us.rtime;
286 last_us.rtime = us.rtime;
287 break;
288 case 4:
289 return "*** Per CPU freq stats ***";
290 default:
292 int cpu = (selected_item - 5) / (state_count + 1);
293 int cpu_line = (selected_item - 5) % (state_count + 1);
294 int freq1 = frequency_linux(cpu, false);
295 int freq2 = frequency_linux(cpu, true);
296 if (cpu_line == 0)
298 sprintf(buffer, " CPU%d: Cur/Scal freq: %d/%d MHz", cpu,
299 freq1 > 0 ? freq1/1000 : -1,
300 freq2 > 0 ? freq2/1000 : -1);
302 else
304 cpustatetimes_linux(cpu, states, ARRAYLEN(states));
305 snprintf(buffer, buffer_len, " %ld %ld",
306 states[cpu_line-1].frequency,
307 states[cpu_line-1].time);
309 return buffer;
312 sprintf(buffer, "%s: %ld.%02lds (+ %ld.%02ld)", text,
313 time / us.hz, time % us.hz,
314 diff / us.hz, diff % us.hz);
315 return buffer;
318 static int cpuinfo_cb(int action, struct gui_synclist *lists)
320 (void)lists;
321 if (action == ACTION_NONE)
322 action = ACTION_REDRAW;
323 return action;
326 static bool dbg_cpuinfo(void)
328 struct simplelist_info info;
329 int cpu_count = MAX(cpucount_linux(), 1);
330 int state_count = cpustatetimes_linux(0, states, ARRAYLEN(states));
331 printf("%s(): %d %d\n", __func__, cpu_count, state_count);
332 simplelist_info_init(&info, "CPU info:", 5 + cpu_count*(state_count+1), &state_count);
333 info.get_name = get_cpuinfo;
334 info.action_callback = cpuinfo_cb;
335 info.timeout = HZ;
336 info.hide_selection = true;
337 info.scroll_all = true;
338 return simplelist_show_list(&info);
341 #endif
343 #ifdef HAVE_LCD_BITMAP
344 #if CONFIG_CODEC != SWCODEC
345 #ifndef SIMULATOR
346 static bool dbg_audio_thread(void)
348 struct audio_debug d;
350 lcd_setfont(FONT_SYSFIXED);
352 while(1)
354 if (action_userabort(HZ/5))
355 return false;
357 audio_get_debugdata(&d);
359 lcd_clear_display();
361 lcd_putsf(0, 0, "read: %x", d.audiobuf_read);
362 lcd_putsf(0, 1, "write: %x", d.audiobuf_write);
363 lcd_putsf(0, 2, "swap: %x", d.audiobuf_swapwrite);
364 lcd_putsf(0, 3, "playing: %d", d.playing);
365 lcd_putsf(0, 4, "playable: %x", d.playable_space);
366 lcd_putsf(0, 5, "unswapped: %x", d.unswapped_space);
368 /* Playable space left */
369 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, 6*8, 112, 4, d.audiobuflen, 0,
370 d.playable_space, HORIZONTAL);
372 /* Show the watermark limit */
373 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, 6*8+4, 112, 4, d.audiobuflen, 0,
374 d.low_watermark_level, HORIZONTAL);
376 lcd_putsf(0, 7, "wm: %x - %x",
377 d.low_watermark_level, d.lowest_watermark_level);
379 lcd_update();
381 lcd_setfont(FONT_UI);
382 return false;
384 #endif /* !SIMULATOR */
385 #else /* CONFIG_CODEC == SWCODEC */
386 static unsigned int ticks, freq_sum;
387 #ifndef CPU_MULTI_FREQUENCY
388 static unsigned int boost_ticks;
389 #endif
391 static void dbg_audio_task(void)
393 #ifdef CPUFREQ_NORMAL
394 #ifndef CPU_MULTI_FREQUENCY
395 if(FREQ > CPUFREQ_NORMAL)
396 boost_ticks++;
397 #endif
398 freq_sum += FREQ/1000000; /* in MHz */
399 #endif
400 ticks++;
403 static bool dbg_buffering_thread(void)
405 int button;
406 int line;
407 bool done = false;
408 size_t bufused;
409 size_t bufsize = pcmbuf_get_bufsize();
410 int pcmbufdescs = pcmbuf_descs();
411 struct buffering_debug d;
412 size_t filebuflen = audio_get_filebuflen();
413 /* This is a size_t, but call it a long so it puts a - when it's bad. */
415 #ifndef CPU_MULTI_FREQUENCY
416 boost_ticks = 0;
417 #endif
418 ticks = freq_sum = 0;
420 tick_add_task(dbg_audio_task);
422 FOR_NB_SCREENS(i)
423 screens[i].setfont(FONT_SYSFIXED);
425 while(!done)
427 button = get_action(CONTEXT_STD,HZ/5);
428 switch(button)
430 case ACTION_STD_NEXT:
431 audio_next();
432 break;
433 case ACTION_STD_PREV:
434 audio_prev();
435 break;
436 case ACTION_STD_CANCEL:
437 done = true;
438 break;
441 buffering_get_debugdata(&d);
442 bufused = bufsize - pcmbuf_free();
444 FOR_NB_SCREENS(i)
446 line = 0;
447 screens[i].clear_display();
450 screens[i].putsf(0, line++, "pcm: %6ld/%ld", (long) bufused, (long) bufsize);
452 gui_scrollbar_draw(&screens[i],0, line*8, screens[i].lcdwidth, 6,
453 bufsize, 0, bufused, HORIZONTAL);
454 line++;
456 screens[i].putsf(0, line++, "alloc: %6ld/%ld", audio_filebufused(),
457 (long) filebuflen);
459 #if LCD_HEIGHT > 80 || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_HEIGHT > 80)
460 if (screens[i].lcdheight > 80)
462 gui_scrollbar_draw(&screens[i],0, line*8, screens[i].lcdwidth, 6,
463 filebuflen, 0, audio_filebufused(), HORIZONTAL);
464 line++;
466 screens[i].putsf(0, line++, "real: %6ld/%ld", (long)d.buffered_data,
467 (long)filebuflen);
469 gui_scrollbar_draw(&screens[i],0, line*8, screens[i].lcdwidth, 6,
470 filebuflen, 0, (long)d.buffered_data, HORIZONTAL);
471 line++;
473 #endif
475 screens[i].putsf(0, line++, "usefl: %6ld/%ld", (long)(d.useful_data),
476 (long)filebuflen);
478 #if LCD_HEIGHT > 80 || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_HEIGHT > 80)
479 if (screens[i].lcdheight > 80)
481 gui_scrollbar_draw(&screens[i],0, line*8, screens[i].lcdwidth, 6,
482 filebuflen, 0, d.useful_data, HORIZONTAL);
483 line++;
485 #endif
487 screens[i].putsf(0, line++, "data_rem: %ld", (long)d.data_rem);
489 screens[i].putsf(0, line++, "track count: %2d", audio_track_count());
491 screens[i].putsf(0, line++, "handle count: %d", (int)d.num_handles);
493 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
494 screens[i].putsf(0, line++, "cpu freq: %3dMHz",
495 (int)((FREQ + 500000) / 1000000));
496 #endif
498 if (ticks > 0)
500 int avgclock = freq_sum * 10 / ticks; /* in 100 kHz */
501 #ifdef CPU_MULTI_FREQUENCY
502 int boostquota = (avgclock * 100 - CPUFREQ_NORMAL/1000) /
503 ((CPUFREQ_MAX - CPUFREQ_NORMAL) / 1000000); /* in 0.1 % */
504 #else
505 int boostquota = boost_ticks * 1000 / ticks; /* in 0.1 % */
506 #endif
507 screens[i].putsf(0, line++, "boost:%3d.%d%% (%d.%dMHz)",
508 boostquota/10, boostquota%10, avgclock/10, avgclock%10);
511 screens[i].putsf(0, line++, "pcmbufdesc: %2d/%2d",
512 pcmbuf_used_descs(), pcmbufdescs);
513 screens[i].putsf(0, line++, "watermark: %6d",
514 (int)(d.watermark));
516 screens[i].update();
520 tick_remove_task(dbg_audio_task);
522 FOR_NB_SCREENS(i)
523 screens[i].setfont(FONT_UI);
525 return false;
527 #endif /* CONFIG_CODEC */
528 #endif /* HAVE_LCD_BITMAP */
530 static const char* bf_getname(int selected_item, void *data,
531 char *buffer, size_t buffer_len)
533 (void)data;
534 core_print_block_at(selected_item, buffer, buffer_len);
535 return buffer;
538 static int bf_action_cb(int action, struct gui_synclist* list)
540 if (action == ACTION_STD_OK)
542 if (gui_synclist_get_sel_pos(list) == 0 && core_test_free())
544 splash(HZ, "Freed test handle. New alloc should trigger compact");
546 else
548 splash(HZ/1, "Attempting a 64k allocation");
549 int handle = core_alloc("test", 64<<10);
550 splash(HZ/2, (handle > 0) ? "Success":"Fail");
551 /* for some reason simplelist doesn't allow adding items here if
552 * info.get_name is given, so use normal list api */
553 gui_synclist_set_nb_items(list, core_get_num_blocks());
554 if (handle > 0)
555 core_free(handle);
557 action = ACTION_REDRAW;
559 return action;
562 static bool dbg_buflib_allocs(void)
564 struct simplelist_info info;
565 simplelist_info_init(&info, "mem allocs", core_get_num_blocks(), NULL);
566 info.get_name = bf_getname;
567 info.action_callback = bf_action_cb;
568 info.timeout = HZ;
569 return simplelist_show_list(&info);
572 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
573 static const char* dbg_partitions_getname(int selected_item, void *data,
574 char *buffer, size_t buffer_len)
576 (void)data;
577 int partition = selected_item/2;
578 struct partinfo* p = disk_partinfo(partition);
579 if (selected_item%2)
581 snprintf(buffer, buffer_len, " T:%x %ld MB", p->type, p->size / ( 2048 / ( SECTOR_SIZE / 512 )));
583 else
585 snprintf(buffer, buffer_len, "P%d: S:%lx", partition, p->start);
587 return buffer;
590 static bool dbg_partitions(void)
592 struct simplelist_info info;
593 simplelist_info_init(&info, "Partition Info", 4, NULL);
594 info.selection_size = 2;
595 info.hide_selection = true;
596 info.scroll_all = true;
597 info.get_name = dbg_partitions_getname;
598 return simplelist_show_list(&info);
600 #endif /* PLATFORM_NATIVE */
602 #if defined(CPU_COLDFIRE) && defined(HAVE_SPDIF_OUT)
603 static bool dbg_spdif(void)
605 int line;
606 unsigned int control;
607 int x;
608 char *s;
609 int category;
610 int generation;
611 unsigned int interruptstat;
612 bool valnogood, symbolerr, parityerr;
613 bool done = false;
614 bool spdif_src_on;
615 int spdif_source = spdif_get_output_source(&spdif_src_on);
616 spdif_set_output_source(AUDIO_SRC_SPDIF IF_SPDIF_POWER_(, true));
618 lcd_clear_display();
619 lcd_setfont(FONT_SYSFIXED);
621 #ifdef HAVE_SPDIF_POWER
622 spdif_power_enable(true); /* We need SPDIF power for both sending & receiving */
623 #endif
625 while (!done)
627 line = 0;
629 control = EBU1RCVCCHANNEL1;
630 interruptstat = INTERRUPTSTAT;
631 INTERRUPTCLEAR = 0x03c00000;
633 valnogood = (interruptstat & 0x01000000)?true:false;
634 symbolerr = (interruptstat & 0x00800000)?true:false;
635 parityerr = (interruptstat & 0x00400000)?true:false;
637 lcd_putsf(0, line++, "Val: %s Sym: %s Par: %s",
638 valnogood?"--":"OK",
639 symbolerr?"--":"OK",
640 parityerr?"--":"OK");
642 lcd_putsf(0, line++, "Status word: %08x", (int)control);
644 line++;
646 x = control >> 31;
647 lcd_putsf(0, line++, "PRO: %d (%s)",
648 x, x?"Professional":"Consumer");
650 x = (control >> 30) & 1;
651 lcd_putsf(0, line++, "Audio: %d (%s)",
652 x, x?"Non-PCM":"PCM");
654 x = (control >> 29) & 1;
655 lcd_putsf(0, line++, "Copy: %d (%s)",
656 x, x?"Permitted":"Inhibited");
658 x = (control >> 27) & 7;
659 switch(x)
661 case 0:
662 s = "None";
663 break;
664 case 1:
665 s = "50/15us";
666 break;
667 default:
668 s = "Reserved";
669 break;
671 lcd_putsf(0, line++, "Preemphasis: %d (%s)", x, s);
673 x = (control >> 24) & 3;
674 lcd_putsf(0, line++, "Mode: %d", x);
676 category = (control >> 17) & 127;
677 switch(category)
679 case 0x00:
680 s = "General";
681 break;
682 case 0x40:
683 s = "Audio CD";
684 break;
685 default:
686 s = "Unknown";
688 lcd_putsf(0, line++, "Category: 0x%02x (%s)", category, s);
690 x = (control >> 16) & 1;
691 generation = x;
692 if(((category & 0x70) == 0x10) ||
693 ((category & 0x70) == 0x40) ||
694 ((category & 0x78) == 0x38))
696 generation = !generation;
698 lcd_putsf(0, line++, "Generation: %d (%s)",
699 x, generation?"Original":"No ind.");
701 x = (control >> 12) & 15;
702 lcd_putsf(0, line++, "Source: %d", x);
705 x = (control >> 8) & 15;
706 switch(x)
708 case 0:
709 s = "Unspecified";
710 break;
711 case 8:
712 s = "A (Left)";
713 break;
714 case 4:
715 s = "B (Right)";
716 break;
717 default:
718 s = "";
719 break;
721 lcd_putsf(0, line++, "Channel: %d (%s)", x, s);
723 x = (control >> 4) & 15;
724 switch(x)
726 case 0:
727 s = "44.1kHz";
728 break;
729 case 0x4:
730 s = "48kHz";
731 break;
732 case 0xc:
733 s = "32kHz";
734 break;
736 lcd_putsf(0, line++, "Frequency: %d (%s)", x, s);
738 x = (control >> 2) & 3;
739 lcd_putsf(0, line++, "Clock accuracy: %d", x);
740 line++;
742 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
743 lcd_putsf(0, line++, "Measured freq: %ldHz",
744 spdif_measure_frequency());
745 #endif
747 lcd_update();
749 if (action_userabort(HZ/10))
750 break;
753 spdif_set_output_source(spdif_source IF_SPDIF_POWER_(, spdif_src_on));
755 #ifdef HAVE_SPDIF_POWER
756 spdif_power_enable(global_settings.spdif_enable);
757 #endif
759 lcd_setfont(FONT_UI);
760 return false;
762 #endif /* CPU_COLDFIRE */
764 #if (CONFIG_RTC == RTC_PCF50605) && (CONFIG_PLATFORM & PLATFORM_NATIVE)
765 static bool dbg_pcf(void)
767 int line;
769 #ifdef HAVE_LCD_BITMAP
770 lcd_setfont(FONT_SYSFIXED);
771 #endif
772 lcd_clear_display();
774 while(1)
776 line = 0;
778 lcd_putsf(0, line++, "DCDC1: %02x", pcf50605_read(0x1b));
779 lcd_putsf(0, line++, "DCDC2: %02x", pcf50605_read(0x1c));
780 lcd_putsf(0, line++, "DCDC3: %02x", pcf50605_read(0x1d));
781 lcd_putsf(0, line++, "DCDC4: %02x", pcf50605_read(0x1e));
782 lcd_putsf(0, line++, "DCDEC1: %02x", pcf50605_read(0x1f));
783 lcd_putsf(0, line++, "DCDEC2: %02x", pcf50605_read(0x20));
784 lcd_putsf(0, line++, "DCUDC1: %02x", pcf50605_read(0x21));
785 lcd_putsf(0, line++, "DCUDC2: %02x", pcf50605_read(0x22));
786 lcd_putsf(0, line++, "IOREGC: %02x", pcf50605_read(0x23));
787 lcd_putsf(0, line++, "D1REGC: %02x", pcf50605_read(0x24));
788 lcd_putsf(0, line++, "D2REGC: %02x", pcf50605_read(0x25));
789 lcd_putsf(0, line++, "D3REGC: %02x", pcf50605_read(0x26));
790 lcd_putsf(0, line++, "LPREG1: %02x", pcf50605_read(0x27));
791 lcd_update();
792 if (action_userabort(HZ/10))
794 lcd_setfont(FONT_UI);
795 return false;
799 lcd_setfont(FONT_UI);
800 return false;
802 #endif
804 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
805 static bool dbg_cpufreq(void)
807 int line;
808 int button;
810 #ifdef HAVE_LCD_BITMAP
811 lcd_setfont(FONT_SYSFIXED);
812 #endif
813 lcd_clear_display();
815 while(1)
817 line = 0;
819 lcd_putsf(0, line++, "Frequency: %ld", FREQ);
820 lcd_putsf(0, line++, "boost_counter: %d", get_cpu_boost_counter());
822 lcd_update();
823 button = get_action(CONTEXT_STD,HZ/10);
825 switch(button)
827 case ACTION_STD_PREV:
828 cpu_boost(true);
829 break;
831 case ACTION_STD_NEXT:
832 cpu_boost(false);
833 break;
835 case ACTION_STD_OK:
836 while (get_cpu_boost_counter() > 0)
837 cpu_boost(false);
838 set_cpu_frequency(CPUFREQ_DEFAULT);
839 break;
841 case ACTION_STD_CANCEL:
842 lcd_setfont(FONT_UI);
843 return false;
846 lcd_setfont(FONT_UI);
847 return false;
849 #endif /* HAVE_ADJUSTABLE_CPU_FREQ */
851 #if defined(HAVE_TSC2100) && (CONFIG_PLATFORM & PLATFORM_NATIVE)
852 #include "tsc2100.h"
853 static const char* tsc2100_debug_getname(int selected_item, void * data,
854 char *buffer, size_t buffer_len)
856 int *page = (int*)data;
857 bool reserved = false;
858 switch (*page)
860 case 0:
861 if ((selected_item > 0x0a) ||
862 (selected_item == 0x04) ||
863 (selected_item == 0x08))
864 reserved = true;
865 break;
866 case 1:
867 if ((selected_item > 0x05) ||
868 (selected_item == 0x02))
869 reserved = true;
870 break;
871 case 2:
872 if (selected_item > 0x1e)
873 reserved = true;
874 break;
876 if (reserved)
877 snprintf(buffer, buffer_len, "%02x: RSVD", selected_item);
878 else
879 snprintf(buffer, buffer_len, "%02x: %04x", selected_item,
880 tsc2100_readreg(*page, selected_item)&0xffff);
881 return buffer;
883 static int tsc2100debug_action_callback(int action, struct gui_synclist *lists)
885 int *page = (int*)lists->data;
886 if (action == ACTION_STD_OK)
888 *page = (*page+1)%3;
889 snprintf(lists->title, 32,
890 "tsc2100 registers - Page %d", *page);
891 return ACTION_REDRAW;
893 return action;
895 static bool tsc2100_debug(void)
897 int page = 0;
898 char title[32] = "tsc2100 registers - Page 0";
899 struct simplelist_info info;
900 simplelist_info_init(&info, title, 32, &page);
901 info.timeout = HZ/100;
902 info.get_name = tsc2100_debug_getname;
903 info.action_callback= tsc2100debug_action_callback;
904 return simplelist_show_list(&info);
906 #endif
907 #if (CONFIG_BATTERY_MEASURE != 0) && defined(HAVE_LCD_BITMAP) && !defined(SIMULATOR)
909 * view_battery() shows a automatically scaled graph of the battery voltage
910 * over time. Usable for estimating battery life / charging rate.
911 * The power_history array is updated in power_thread of powermgmt.c.
914 #define BAT_LAST_VAL MIN(LCD_WIDTH, POWER_HISTORY_LEN)
915 #define BAT_TSPACE 20
916 #define BAT_YSPACE (LCD_HEIGHT - BAT_TSPACE)
919 static bool view_battery(void)
921 int view = 0;
922 int i, x, y, z, y1, y2, grid, graph;
923 unsigned short maxv, minv;
925 lcd_setfont(FONT_SYSFIXED);
927 while(1)
929 lcd_clear_display();
930 switch (view) {
931 case 0: /* voltage history graph */
932 /* Find maximum and minimum voltage for scaling */
933 minv = power_history[0];
934 maxv = minv + 1;
935 for (i = 1; i < BAT_LAST_VAL && power_history[i]; i++) {
936 if (power_history[i] > maxv)
937 maxv = power_history[i];
938 if (power_history[i] < minv)
939 minv = power_history[i];
941 /* print header */
942 #if (CONFIG_BATTERY_MEASURE & VOLTAGE_MEASURE)
943 /* adjust grid scale */
944 if ((maxv - minv) > 50)
945 grid = 50;
946 else
947 grid = 5;
949 lcd_putsf(0, 0, "battery %d.%03dV", power_history[0] / 1000,
950 power_history[0] % 1000);
951 lcd_putsf(0, 1, "%d.%03d-%d.%03dV (%2dmV)",
952 minv / 1000, minv % 1000, maxv / 1000, maxv % 1000,
953 grid);
954 #elif (CONFIG_BATTERY_MEASURE & PERCENTAGE_MEASURE)
955 /* adjust grid scale */
956 if ((maxv - minv) > 10)
957 grid = 10;
958 else
959 grid = 1;
960 lcd_putsf(0, 0, "battery %d%%", power_history[0]);
961 lcd_putsf(0, 1, "%d%%-%d%% (%d %%)", minv, maxv, grid);
962 #endif
964 i = 1;
965 while ((y = (minv - (minv % grid)+i*grid)) < maxv)
967 graph = ((y-minv)*BAT_YSPACE)/(maxv-minv);
968 graph = LCD_HEIGHT-1 - graph;
970 /* draw dotted horizontal grid line */
971 for (x=0; x<LCD_WIDTH;x=x+2)
972 lcd_drawpixel(x,graph);
974 i++;
977 x = 0;
978 /* draw plot of power history
979 * skip empty entries
981 for (i = BAT_LAST_VAL - 1; i > 0; i--)
983 if (power_history[i] && power_history[i-1])
985 y1 = (power_history[i] - minv) * BAT_YSPACE /
986 (maxv - minv);
987 y1 = MIN(MAX(LCD_HEIGHT-1 - y1, BAT_TSPACE),
988 LCD_HEIGHT-1);
989 y2 = (power_history[i-1] - minv) * BAT_YSPACE /
990 (maxv - minv);
991 y2 = MIN(MAX(LCD_HEIGHT-1 - y2, BAT_TSPACE),
992 LCD_HEIGHT-1);
994 lcd_set_drawmode(DRMODE_SOLID);
996 /* make line thicker */
997 lcd_drawline(((x*LCD_WIDTH)/(BAT_LAST_VAL)),
998 y1,
999 (((x+1)*LCD_WIDTH)/(BAT_LAST_VAL)),
1000 y2);
1001 lcd_drawline(((x*LCD_WIDTH)/(BAT_LAST_VAL))+1,
1002 y1+1,
1003 (((x+1)*LCD_WIDTH)/(BAT_LAST_VAL))+1,
1004 y2+1);
1005 x++;
1008 break;
1010 case 1: /* status: */
1011 #if CONFIG_CHARGING >= CHARGING_MONITOR
1012 lcd_putsf(0, 0, "Pwr status: %s",
1013 charging_state() ? "charging" : "discharging");
1014 #else
1015 lcd_puts(0, 0, "Power status: unknown");
1016 #endif
1017 battery_read_info(&y, &z);
1018 if (y > 0)
1019 lcd_putsf(0, 1, "Battery: %d.%03d V (%d %%)", y / 1000, y % 1000, z);
1020 else if (z > 0)
1021 lcd_putsf(0, 1, "Battery: %d %%", z);
1022 #ifdef ADC_EXT_POWER
1023 y = (adc_read(ADC_EXT_POWER) * EXT_SCALE_FACTOR) / 1000;
1024 lcd_putsf(0, 2, "External: %d.%03d V", y / 1000, y % 1000);
1025 #endif
1026 #if CONFIG_CHARGING
1027 #if defined ARCHOS_RECORDER
1028 lcd_putsf(0, 3, "Chgr: %s %s",
1029 charger_inserted() ? "present" : "absent",
1030 charger_enabled() ? "on" : "off");
1031 lcd_putsf(0, 5, "short delta: %d", short_delta);
1032 lcd_putsf(0, 6, "long delta: %d", long_delta);
1033 lcd_puts(0, 7, power_message);
1034 lcd_putsf(0, 8, "USB Inserted: %s",
1035 usb_inserted() ? "yes" : "no");
1036 #elif defined IPOD_NANO || defined IPOD_VIDEO
1037 int usb_pwr = (GPIOL_INPUT_VAL & 0x10)?true:false;
1038 int ext_pwr = (GPIOL_INPUT_VAL & 0x08)?false:true;
1039 int dock = (GPIOA_INPUT_VAL & 0x10)?true:false;
1040 int charging = (GPIOB_INPUT_VAL & 0x01)?false:true;
1041 int headphone= (GPIOA_INPUT_VAL & 0x80)?true:false;
1043 lcd_putsf(0, 3, "USB pwr: %s",
1044 usb_pwr ? "present" : "absent");
1045 lcd_putsf(0, 4, "EXT pwr: %s",
1046 ext_pwr ? "present" : "absent");
1047 lcd_putsf(0, 5, "Battery: %s",
1048 charging ? "charging" : (usb_pwr||ext_pwr) ? "charged" : "discharging");
1049 lcd_putsf(0, 6, "Dock mode: %s",
1050 dock ? "enabled" : "disabled");
1051 lcd_putsf(0, 7, "Headphone: %s",
1052 headphone ? "connected" : "disconnected");
1053 #ifdef IPOD_VIDEO
1054 if(probed_ramsize == 64)
1055 x = (adc_read(ADC_4066_ISTAT) * 2400) / (1024 * 2);
1056 else
1057 #endif
1058 x = (adc_read(ADC_4066_ISTAT) * 2400) / (1024 * 3);
1059 lcd_putsf(0, 8, "Ibat: %d mA", x);
1060 lcd_putsf(0, 9, "Vbat * Ibat: %d mW", x * y / 1000);
1061 #elif defined TOSHIBA_GIGABEAT_S
1062 int line = 3;
1063 unsigned int st;
1065 static const unsigned char * const chrgstate_strings[] =
1067 "Disabled",
1068 "Error",
1069 "Discharging",
1070 "Precharge",
1071 "Constant Voltage",
1072 "Constant Current",
1073 "<unknown>",
1076 lcd_putsf(0, line++, "Charger: %s",
1077 charger_inserted() ? "present" : "absent");
1079 st = power_input_status() &
1080 (POWER_INPUT_CHARGER | POWER_INPUT_BATTERY);
1081 lcd_putsf(0, line++, "%s%s",
1082 (st & POWER_INPUT_MAIN_CHARGER) ? " Main" : "",
1083 (st & POWER_INPUT_USB_CHARGER) ? " USB" : "");
1085 y = ARRAYLEN(chrgstate_strings) - 1;
1087 switch (charge_state)
1089 case CHARGE_STATE_DISABLED: y--;
1090 case CHARGE_STATE_ERROR: y--;
1091 case DISCHARGING: y--;
1092 case TRICKLE: y--;
1093 case TOPOFF: y--;
1094 case CHARGING: y--;
1095 default:;
1098 lcd_putsf(0, line++, "State: %s", chrgstate_strings[y]);
1100 lcd_putsf(0, line++, "Battery Switch: %s",
1101 (st & POWER_INPUT_BATTERY) ? "On" : "Off");
1103 y = chrgraw_adc_voltage();
1104 lcd_putsf(0, line++, "CHRGRAW: %d.%03d V",
1105 y / 1000, y % 1000);
1107 y = application_supply_adc_voltage();
1108 lcd_putsf(0, line++, "BP : %d.%03d V",
1109 y / 1000, y % 1000);
1111 y = battery_adc_charge_current();
1112 if (y < 0) x = '-', y = -y;
1113 else x = ' ';
1114 lcd_putsf(0, line++, "CHRGISN:%c%d mA", x, y);
1116 y = cccv_regulator_dissipation();
1117 lcd_putsf(0, line++, "P CCCV : %d mW", y);
1119 y = battery_charge_current();
1120 if (y < 0) x = '-', y = -y;
1121 else x = ' ';
1122 lcd_putsf(0, line++, "I Charge:%c%d mA", x, y);
1124 y = battery_adc_temp();
1126 if (y != INT_MIN) {
1127 lcd_putsf(0, line++, "T Battery: %dC (%dF)", y,
1128 (9*y + 160) / 5);
1129 } else {
1130 /* Conversion disabled */
1131 lcd_puts(0, line++, "T Battery: ?");
1134 #elif defined(HAVE_AS3514) && defined(CONFIG_CHARGING)
1135 static const char * const chrgstate_strings[] =
1137 [CHARGE_STATE_DISABLED - CHARGE_STATE_DISABLED]= "Disabled",
1138 [CHARGE_STATE_ERROR - CHARGE_STATE_DISABLED] = "Error",
1139 [DISCHARGING - CHARGE_STATE_DISABLED] = "Discharging",
1140 [CHARGING - CHARGE_STATE_DISABLED] = "Charging",
1142 const char *str = NULL;
1144 lcd_putsf(0, 3, "Charger: %s",
1145 charger_inserted() ? "present" : "absent");
1147 y = charge_state - CHARGE_STATE_DISABLED;
1148 if ((unsigned)y < ARRAYLEN(chrgstate_strings))
1149 str = chrgstate_strings[y];
1151 lcd_putsf(0, 4, "State: %s",
1152 str ? str : "<unknown>");
1154 lcd_putsf(0, 5, "CHARGER: %02X", ascodec_read_charger());
1155 #elif defined(IPOD_NANO2G)
1156 y = pmu_read_battery_voltage();
1157 lcd_putsf(17, 1, "RAW: %d.%03d V", y / 1000, y % 1000);
1158 y = pmu_read_battery_current();
1159 lcd_putsf(0, 2, "Battery current: %d mA", y);
1160 lcd_putsf(0, 3, "PWRCON: %08x %08x", PWRCON, PWRCONEXT);
1161 lcd_putsf(0, 4, "CLKCON: %08x %03x %03x", CLKCON, CLKCON2, CLKCON3);
1162 lcd_putsf(0, 5, "PLL: %06x %06x %06x", PLL0PMS, PLL1PMS, PLL2PMS);
1163 x = pmu_read(0x1b) & 0xf;
1164 y = pmu_read(0x1a) * 25 + 625;
1165 lcd_putsf(0, 6, "AUTO: %x / %d mV", x, y);
1166 x = pmu_read(0x1f) & 0xf;
1167 y = pmu_read(0x1e) * 25 + 625;
1168 lcd_putsf(0, 7, "DOWN1: %x / %d mV", x, y);
1169 x = pmu_read(0x23) & 0xf;
1170 y = pmu_read(0x22) * 25 + 625;
1171 lcd_putsf(0, 8, "DOWN2: %x / %d mV", x, y);
1172 x = pmu_read(0x27) & 0xf;
1173 y = pmu_read(0x26) * 100 + 900;
1174 lcd_putsf(0, 9, "MEMLDO: %x / %d mV", x, y);
1175 for (i = 0; i < 6; i++)
1177 x = pmu_read(0x2e + (i << 1)) & 0xf;
1178 y = pmu_read(0x2d + (i << 1)) * 100 + 900;
1179 lcd_putsf(0, 10 + i, "LDO%d: %x / %d mV", i + 1, x, y);
1181 #else
1182 lcd_putsf(0, 3, "Charger: %s",
1183 charger_inserted() ? "present" : "absent");
1184 #endif /* target type */
1185 #endif /* CONFIG_CHARGING */
1186 break;
1187 case 2: /* voltage deltas: */
1188 #if (CONFIG_BATTERY_MEASURE & VOLTAGE_MEASURE)
1189 lcd_puts(0, 0, "Voltage deltas:");
1190 for (i = 0; i < POWER_HISTORY_LEN-1; i++) {
1191 y = power_history[i] - power_history[i+1];
1192 lcd_putsf(0, i+1, "-%d min: %c%d.%03d V", i,
1193 (y < 0) ? '-' : ' ', ((y < 0) ? y * -1 : y) / 1000,
1194 ((y < 0) ? y * -1 : y ) % 1000);
1196 #elif (CONFIG_BATTERY_MEASURE & PERCENTAGE_MEASURE)
1197 lcd_puts(0, 0, "Percentage deltas:");
1198 for (i = 0; i < POWER_HISTORY_LEN-1; i++) {
1199 y = power_history[i] - power_history[i+1];
1200 lcd_putsf(0, i+1, "-%d min: %c%d%%", i,
1201 (y < 0) ? '-' : ' ', ((y < 0) ? y * -1 : y));
1203 #endif
1204 break;
1206 case 3: /* remaining time estimation: */
1208 #ifdef ARCHOS_RECORDER
1209 lcd_putsf(0, 0, "charge_state: %d", charge_state);
1211 lcd_putsf(0, 1, "Cycle time: %d m", powermgmt_last_cycle_startstop_min);
1213 lcd_putsf(0, 2, "Lvl@cyc st: %d%%", powermgmt_last_cycle_level);
1215 lcd_putsf(0, 3, "P=%2d I=%2d", pid_p, pid_i);
1217 lcd_putsf(0, 4, "Trickle sec: %d/60", trickle_sec);
1218 #endif /* ARCHOS_RECORDER */
1220 #if (CONFIG_BATTERY_MEASURE & VOLTAGE_MEASURE)
1221 lcd_putsf(0, 5, "Last PwrHist: %d.%03dV",
1222 power_history[0] / 1000,
1223 power_history[0] % 1000);
1224 #endif
1226 lcd_putsf(0, 6, "battery level: %d%%", battery_level());
1228 int time_left = battery_time();
1229 if (time_left >= 0)
1230 lcd_putsf(0, 7, "Est. remain: %d m", time_left);
1231 else
1232 lcd_puts(0, 7, "Estimation n/a");
1233 break;
1236 lcd_update();
1238 switch(get_action(CONTEXT_STD,HZ/2))
1240 case ACTION_STD_PREV:
1241 if (view)
1242 view--;
1243 break;
1245 case ACTION_STD_NEXT:
1246 if (view < 3)
1247 view++;
1248 break;
1250 case ACTION_STD_CANCEL:
1251 lcd_setfont(FONT_UI);
1252 return false;
1255 lcd_setfont(FONT_UI);
1256 return false;
1259 #endif /* (CONFIG_BATTERY_MEASURE != 0) && HAVE_LCD_BITMAP */
1261 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
1262 #if (CONFIG_STORAGE & STORAGE_MMC) || (CONFIG_STORAGE & STORAGE_SD)
1264 #if (CONFIG_STORAGE & STORAGE_MMC)
1265 #define CARDTYPE "MMC"
1266 #elif (CONFIG_STORAGE & STORAGE_SD)
1267 #define CARDTYPE "microSD"
1268 #endif
1270 static int disk_callback(int btn, struct gui_synclist *lists)
1272 tCardInfo *card;
1273 int *cardnum = (int*)lists->data;
1274 unsigned char card_name[6];
1275 unsigned char pbuf[32];
1276 char *title = lists->title;
1277 static const unsigned char i_vmin[] = { 0, 1, 5, 10, 25, 35, 60, 100 };
1278 static const unsigned char i_vmax[] = { 1, 5, 10, 25, 35, 45, 80, 200 };
1279 static const unsigned char * const kbit_units[] = { "kBit/s", "MBit/s", "GBit/s" };
1280 static const unsigned char * const nsec_units[] = { "ns", "µs", "ms" };
1281 #if (CONFIG_STORAGE & STORAGE_MMC)
1282 static const char * const mmc_spec_vers[] = { "1.0-1.2", "1.4", "2.0-2.2",
1283 "3.1-3.31", "4.0" };
1284 #endif
1286 if ((btn == ACTION_STD_OK) || (btn == SYS_FS_CHANGED) || (btn == ACTION_REDRAW))
1288 #ifdef HAVE_HOTSWAP
1289 if (btn == ACTION_STD_OK)
1291 *cardnum ^= 0x1; /* change cards */
1293 #endif
1295 simplelist_set_line_count(0);
1297 card = card_get_info(*cardnum);
1299 if (card->initialized > 0)
1301 unsigned i;
1302 for (i=0; i<sizeof(card_name); i++)
1304 card_name[i] = card_extract_bits(card->cid, (103-8*i), 8);
1306 strlcpy(card_name, card_name, sizeof(card_name));
1307 simplelist_addline(
1308 "%s Rev %d.%d", card_name,
1309 (int) card_extract_bits(card->cid, 63, 4),
1310 (int) card_extract_bits(card->cid, 59, 4));
1311 simplelist_addline(
1312 "Prod: %d/%d",
1313 #if (CONFIG_STORAGE & STORAGE_SD)
1314 (int) card_extract_bits(card->cid, 11, 4),
1315 (int) card_extract_bits(card->cid, 19, 8) + 2000
1316 #elif (CONFIG_STORAGE & STORAGE_MMC)
1317 (int) card_extract_bits(card->cid, 15, 4),
1318 (int) card_extract_bits(card->cid, 11, 4) + 1997
1319 #endif
1321 simplelist_addline(
1322 #if (CONFIG_STORAGE & STORAGE_SD)
1323 "Ser#: 0x%08lx",
1324 card_extract_bits(card->cid, 55, 32)
1325 #elif (CONFIG_STORAGE & STORAGE_MMC)
1326 "Ser#: 0x%04lx",
1327 card_extract_bits(card->cid, 47, 16)
1328 #endif
1331 simplelist_addline("M=%02x, "
1332 #if (CONFIG_STORAGE & STORAGE_SD)
1333 "O=%c%c",
1334 (int) card_extract_bits(card->cid, 127, 8),
1335 card_extract_bits(card->cid, 119, 8),
1336 card_extract_bits(card->cid, 111, 8)
1337 #elif (CONFIG_STORAGE & STORAGE_MMC)
1338 "O=%04x",
1339 (int) card_extract_bits(card->cid, 127, 8),
1340 (int) card_extract_bits(card->cid, 119, 16)
1341 #endif
1344 #if (CONFIG_STORAGE & STORAGE_MMC)
1345 int temp = card_extract_bits(card->csd, 125, 4);
1346 simplelist_addline(
1347 "MMC v%s", temp < 5 ?
1348 mmc_spec_vers[temp] : "?.?");
1349 #endif
1350 simplelist_addline(
1351 "Blocks: 0x%08lx", card->numblocks);
1352 output_dyn_value(pbuf, sizeof pbuf, card->speed / 1000,
1353 kbit_units, false);
1354 simplelist_addline(
1355 "Speed: %s", pbuf);
1356 output_dyn_value(pbuf, sizeof pbuf, card->taac,
1357 nsec_units, false);
1358 simplelist_addline(
1359 "Taac: %s", pbuf);
1360 simplelist_addline(
1361 "Nsac: %d clk", card->nsac);
1362 simplelist_addline(
1363 "R2W: *%d", card->r2w_factor);
1364 #if (CONFIG_STORAGE & STORAGE_SD)
1365 int csd_structure = card_extract_bits(card->csd, 127, 2);
1366 if (csd_structure == 0) /* CSD version 1.0 */
1367 #endif
1369 simplelist_addline(
1370 "IRmax: %d..%d mA",
1371 i_vmin[card_extract_bits(card->csd, 61, 3)],
1372 i_vmax[card_extract_bits(card->csd, 58, 3)]);
1373 simplelist_addline(
1374 "IWmax: %d..%d mA",
1375 i_vmin[card_extract_bits(card->csd, 55, 3)],
1376 i_vmax[card_extract_bits(card->csd, 52, 3)]);
1379 else if (card->initialized == 0)
1381 simplelist_addline("Not Found!");
1383 #if (CONFIG_STORAGE & STORAGE_SD)
1384 else /* card->initialized < 0 */
1386 simplelist_addline("Init Error! (%d)", card->initialized);
1388 #endif
1389 snprintf(title, 16, "[" CARDTYPE " %d]", *cardnum);
1390 gui_synclist_set_title(lists, title, Icon_NOICON);
1391 gui_synclist_set_nb_items(lists, simplelist_get_line_count());
1392 gui_synclist_select_item(lists, 0);
1393 btn = ACTION_REDRAW;
1395 return btn;
1397 #elif (CONFIG_STORAGE & STORAGE_ATA)
1398 static int disk_callback(int btn, struct gui_synclist *lists)
1400 (void)lists;
1401 int i;
1402 char buf[128];
1403 unsigned short* identify_info = ata_get_identify();
1404 bool timing_info_present = false;
1405 (void)btn;
1407 simplelist_set_line_count(0);
1409 for (i=0; i < 20; i++)
1410 ((unsigned short*)buf)[i]=htobe16(identify_info[i+27]);
1411 buf[40]=0;
1412 /* kill trailing space */
1413 for (i=39; i && buf[i]==' '; i--)
1414 buf[i] = 0;
1415 simplelist_addline("Model: %s", buf);
1416 for (i=0; i < 4; i++)
1417 ((unsigned short*)buf)[i]=htobe16(identify_info[i+23]);
1418 buf[8]=0;
1419 simplelist_addline(
1420 "Firmware: %s", buf);
1421 snprintf(buf, sizeof buf, "%ld MB",
1422 ((unsigned long)identify_info[61] << 16 |
1423 (unsigned long)identify_info[60]) / 2048 );
1424 simplelist_addline(
1425 "Size: %s", buf);
1426 unsigned long free;
1427 fat_size( IF_MV2(0,) NULL, &free );
1428 simplelist_addline(
1429 "Free: %ld MB", free / 1024);
1430 simplelist_addline(
1431 "Spinup time: %d ms", storage_spinup_time() * (1000/HZ));
1432 i = identify_info[83] & (1<<3);
1433 simplelist_addline(
1434 "Power mgmt: %s", i ? "enabled" : "unsupported");
1435 i = identify_info[83] & (1<<9);
1436 simplelist_addline(
1437 "Noise mgmt: %s", i ? "enabled" : "unsupported");
1438 i = identify_info[82] & (1<<6);
1439 simplelist_addline(
1440 "Read-ahead: %s", i ? "enabled" : "unsupported");
1441 timing_info_present = identify_info[53] & (1<<1);
1442 if(timing_info_present) {
1443 char pio3[2], pio4[2];pio3[1] = 0;
1444 pio4[1] = 0;
1445 pio3[0] = (identify_info[64] & (1<<0)) ? '3' : 0;
1446 pio4[0] = (identify_info[64] & (1<<1)) ? '4' : 0;
1447 simplelist_addline(
1448 "PIO modes: 0 1 2 %s %s", pio3, pio4);
1450 else {
1451 simplelist_addline(
1452 "No PIO mode info");
1454 timing_info_present = identify_info[53] & (1<<1);
1455 if(timing_info_present) {
1456 simplelist_addline(
1457 "Cycle times %dns/%dns",
1458 identify_info[67],
1459 identify_info[68] );
1460 } else {
1461 simplelist_addline(
1462 "No timing info");
1464 int sector_size = 512;
1465 if((identify_info[106] & 0xe000) == 0x6000)
1466 sector_size *= BIT_N(identify_info[106] & 0x000f);
1467 simplelist_addline(
1468 "Physical sector size: %d", sector_size);
1469 #ifdef HAVE_ATA_DMA
1470 if (identify_info[63] & (1<<0)) {
1471 char mdma0[2], mdma1[2], mdma2[2];
1472 mdma0[1] = mdma1[1] = mdma2[1] = 0;
1473 mdma0[0] = (identify_info[63] & (1<<0)) ? '0' : 0;
1474 mdma1[0] = (identify_info[63] & (1<<1)) ? '1' : 0;
1475 mdma2[0] = (identify_info[63] & (1<<2)) ? '2' : 0;
1476 simplelist_addline(
1477 "MDMA modes: %s %s %s", mdma0, mdma1, mdma2);
1478 simplelist_addline(
1479 "MDMA Cycle times %dns/%dns",
1480 identify_info[65],
1481 identify_info[66] );
1483 else {
1484 simplelist_addline(
1485 "No MDMA mode info");
1487 if (identify_info[53] & (1<<2)) {
1488 char udma0[2], udma1[2], udma2[2], udma3[2], udma4[2], udma5[2], udma6[2];
1489 udma0[1] = udma1[1] = udma2[1] = udma3[1] = udma4[1] = udma5[1] = udma6[1] = 0;
1490 udma0[0] = (identify_info[88] & (1<<0)) ? '0' : 0;
1491 udma1[0] = (identify_info[88] & (1<<1)) ? '1' : 0;
1492 udma2[0] = (identify_info[88] & (1<<2)) ? '2' : 0;
1493 udma3[0] = (identify_info[88] & (1<<3)) ? '3' : 0;
1494 udma4[0] = (identify_info[88] & (1<<4)) ? '4' : 0;
1495 udma5[0] = (identify_info[88] & (1<<5)) ? '5' : 0;
1496 udma6[0] = (identify_info[88] & (1<<6)) ? '6' : 0;
1497 simplelist_addline(
1498 "UDMA modes: %s %s %s %s %s %s %s", udma0, udma1, udma2,
1499 udma3, udma4, udma5, udma6);
1501 else {
1502 simplelist_addline(
1503 "No UDMA mode info");
1505 #endif /* HAVE_ATA_DMA */
1506 timing_info_present = identify_info[53] & (1<<1);
1507 if(timing_info_present) {
1508 i = identify_info[49] & (1<<11);
1509 simplelist_addline(
1510 "IORDY support: %s", i ? "yes" : "no");
1511 i = identify_info[49] & (1<<10);
1512 simplelist_addline(
1513 "IORDY disable: %s", i ? "yes" : "no");
1514 } else {
1515 simplelist_addline(
1516 "No timing info");
1518 simplelist_addline(
1519 "Cluster size: %d bytes", fat_get_cluster_size(IF_MV(0)));
1520 #ifdef HAVE_ATA_DMA
1521 i = ata_get_dma_mode();
1522 if (i == 0) {
1523 simplelist_addline(
1524 "DMA not enabled");
1525 } else {
1526 simplelist_addline(
1527 "DMA mode: %s %c",
1528 (i & 0x40) ? "UDMA" : "MDMA",
1529 '0' + (i & 7));
1531 #endif /* HAVE_ATA_DMA */
1532 return btn;
1534 #else /* No SD, MMC or ATA */
1535 static int disk_callback(int btn, struct gui_synclist *lists)
1537 (void)lists;
1538 struct storage_info info;
1539 storage_get_info(0,&info);
1540 simplelist_addline("Vendor: %s", info.vendor);
1541 simplelist_addline("Model: %s", info.product);
1542 simplelist_addline("Firmware: %s", info.revision);
1543 simplelist_addline(
1544 "Size: %ld MB", info.num_sectors*(info.sector_size/512)/2024);
1545 unsigned long free;
1546 fat_size( IF_MV2(0,) NULL, &free );
1547 simplelist_addline(
1548 "Free: %ld MB", free / 1024);
1549 simplelist_addline(
1550 "Cluster size: %d bytes", fat_get_cluster_size(IF_MV(0)));
1551 return btn;
1553 #endif
1555 #if (CONFIG_STORAGE & STORAGE_ATA)
1556 static bool dbg_identify_info(void)
1558 int fd = creat("/identify_info.bin", 0666);
1559 if(fd >= 0)
1561 #ifdef ROCKBOX_LITTLE_ENDIAN
1562 ecwrite(fd, ata_get_identify(), SECTOR_SIZE/2, "s", true);
1563 #else
1564 write(fd, ata_get_identify(), SECTOR_SIZE);
1565 #endif
1566 close(fd);
1568 return false;
1570 #endif
1572 static bool dbg_disk_info(void)
1574 struct simplelist_info info;
1575 simplelist_info_init(&info, "Disk Info", 1, NULL);
1576 #if (CONFIG_STORAGE & STORAGE_MMC) || (CONFIG_STORAGE & STORAGE_SD)
1577 char title[16];
1578 int card = 0;
1579 info.callback_data = (void*)&card;
1580 info.title = title;
1581 #endif
1582 info.action_callback = disk_callback;
1583 info.hide_selection = true;
1584 info.scroll_all = true;
1585 return simplelist_show_list(&info);
1587 #endif /* PLATFORM_NATIVE */
1589 #ifdef HAVE_DIRCACHE
1590 static int dircache_callback(int btn, struct gui_synclist *lists)
1592 (void)lists;
1593 simplelist_set_line_count(0);
1594 simplelist_addline("Cache initialized: %s",
1595 dircache_is_enabled() ? "Yes" : "No");
1596 simplelist_addline("Cache size: %d B",
1597 dircache_get_cache_size());
1598 simplelist_addline("Last size: %d B",
1599 global_status.dircache_size);
1600 simplelist_addline("Limit: %d B",
1601 DIRCACHE_LIMIT);
1602 simplelist_addline("Reserve: %d/%d B",
1603 dircache_get_reserve_used(), DIRCACHE_RESERVE);
1604 simplelist_addline("Scanning took: %d s",
1605 dircache_get_build_ticks() / HZ);
1606 simplelist_addline("Entry count: %d",
1607 dircache_get_entry_count());
1608 return btn;
1611 static bool dbg_dircache_info(void)
1613 struct simplelist_info info;
1614 simplelist_info_init(&info, "Dircache Info", 7, NULL);
1615 info.action_callback = dircache_callback;
1616 info.hide_selection = true;
1617 info.scroll_all = true;
1618 return simplelist_show_list(&info);
1621 #endif /* HAVE_DIRCACHE */
1623 #ifdef HAVE_TAGCACHE
1624 static int database_callback(int btn, struct gui_synclist *lists)
1626 (void)lists;
1627 struct tagcache_stat *stat = tagcache_get_stat();
1628 static bool synced = false;
1630 simplelist_set_line_count(0);
1632 simplelist_addline("Initialized: %s",
1633 stat->initialized ? "Yes" : "No");
1634 simplelist_addline("DB Ready: %s",
1635 stat->ready ? "Yes" : "No");
1636 simplelist_addline("RAM Cache: %s",
1637 stat->ramcache ? "Yes" : "No");
1638 simplelist_addline("RAM: %d/%d B",
1639 stat->ramcache_used, stat->ramcache_allocated);
1640 simplelist_addline("Progress: %d%% (%d entries)",
1641 stat->progress, stat->processed_entries);
1642 simplelist_addline("Curfile: %s",
1643 stat->curentry ? stat->curentry : "---");
1644 simplelist_addline("Commit step: %d",
1645 stat->commit_step);
1646 simplelist_addline("Commit delayed: %s",
1647 stat->commit_delayed ? "Yes" : "No");
1649 simplelist_addline("Queue length: %d",
1650 stat->queue_length);
1652 if (synced)
1654 synced = false;
1655 tagcache_screensync_event();
1658 if (!btn && stat->curentry)
1660 synced = true;
1661 return ACTION_REDRAW;
1664 if (btn == ACTION_STD_CANCEL)
1665 tagcache_screensync_enable(false);
1667 return btn;
1669 static bool dbg_tagcache_info(void)
1671 struct simplelist_info info;
1672 simplelist_info_init(&info, "Database Info", 8, NULL);
1673 info.action_callback = database_callback;
1674 info.hide_selection = true;
1675 info.scroll_all = true;
1677 /* Don't do nonblock here, must give enough processing time
1678 for tagcache thread. */
1679 /* info.timeout = TIMEOUT_NOBLOCK; */
1680 info.timeout = 1;
1681 tagcache_screensync_enable(true);
1682 return simplelist_show_list(&info);
1684 #endif
1686 #if CONFIG_CPU == SH7034
1687 static bool dbg_save_roms(void)
1689 int fd;
1690 int oldmode = system_memory_guard(MEMGUARD_NONE);
1692 fd = creat("/internal_rom_0000-FFFF.bin", 0666);
1693 if(fd >= 0)
1695 write(fd, (void *)0, 0x10000);
1696 close(fd);
1699 fd = creat("/internal_rom_2000000-203FFFF.bin", 0666);
1700 if(fd >= 0)
1702 write(fd, (void *)0x2000000, 0x40000);
1703 close(fd);
1706 system_memory_guard(oldmode);
1707 return false;
1709 #elif defined CPU_COLDFIRE
1710 static bool dbg_save_roms(void)
1712 int fd;
1713 int oldmode = system_memory_guard(MEMGUARD_NONE);
1715 #if defined(IRIVER_H100_SERIES)
1716 fd = creat("/internal_rom_000000-1FFFFF.bin", 0666);
1717 #elif defined(IRIVER_H300_SERIES)
1718 fd = creat("/internal_rom_000000-3FFFFF.bin", 0666);
1719 #elif defined(IAUDIO_X5) || defined(IAUDIO_M5) || defined(IAUDIO_M3)
1720 fd = creat("/internal_rom_000000-3FFFFF.bin", 0666);
1721 #elif defined(MPIO_HD200) || defined(MPIO_HD300)
1722 fd = creat("/internal_rom_000000-1FFFFF.bin", 0666);
1723 #endif
1724 if(fd >= 0)
1726 write(fd, (void *)0, FLASH_SIZE);
1727 close(fd);
1729 system_memory_guard(oldmode);
1731 #ifdef HAVE_EEPROM
1732 fd = creat("/internal_eeprom.bin", 0666);
1733 if (fd >= 0)
1735 int old_irq_level;
1736 char buf[EEPROM_SIZE];
1737 int err;
1739 old_irq_level = disable_irq_save();
1741 err = eeprom_24cxx_read(0, buf, sizeof buf);
1743 restore_irq(old_irq_level);
1745 if (err)
1746 splashf(HZ*3, "Eeprom read failure (%d)", err);
1747 else
1749 write(fd, buf, sizeof buf);
1752 close(fd);
1754 #endif
1756 return false;
1758 #elif defined(CPU_PP) && !(CONFIG_STORAGE & STORAGE_SD)
1759 static bool dbg_save_roms(void)
1761 int fd = creat("/internal_rom_000000-0FFFFF.bin", 0666);
1762 if(fd >= 0)
1764 write(fd, (void *)0x20000000, FLASH_SIZE);
1765 close(fd);
1768 return false;
1770 #elif CONFIG_CPU == AS3525v2 || CONFIG_CPU == AS3525
1771 static bool dbg_save_roms(void)
1773 int fd = creat("/rom.bin", 0666);
1774 if(fd >= 0)
1776 write(fd, (void *)0x80000000, 0x20000);
1777 close(fd);
1780 return false;
1782 #elif CONFIG_CPU == IMX31L
1783 bool __dbg_dvfs_dptc(void);
1784 static bool dbg_save_roms(void)
1786 int fd = creat("/flash_rom_A0000000-A01FFFFF.bin", 0666);
1787 if (fd >= 0)
1789 write(fd, (void*)0xa0000000, FLASH_SIZE);
1790 close(fd);
1793 return false;
1795 #elif defined(CPU_TCC780X)
1796 static bool dbg_save_roms(void)
1798 int fd = creat("/eeprom_E0000000-E0001FFF.bin", 0666);
1799 if (fd >= 0)
1801 write(fd, (void*)0xe0000000, 0x2000);
1802 close(fd);
1805 return false;
1807 #elif CONFIG_CPU == RK27XX
1808 static bool dbg_save_roms(void)
1810 char buf[0x200];
1812 int fd = creat("/rom.bin", 0666);
1813 if(fd < 0)
1814 return false;
1816 for(int addr = 0; addr < 0x2000; addr += sizeof(buf))
1818 int old_irq = disable_irq_save();
1820 /* map rom at 0 */
1821 SCU_REMAP = 0;
1822 commit_discard_idcache();
1824 /* copy rom */
1825 memcpy((void *)buf, (void *)addr, sizeof(buf));
1827 /* map iram back at 0 */
1828 SCU_REMAP = 0xdeadbeef;
1829 commit_discard_idcache();
1831 restore_irq(old_irq);
1833 write(fd, (void *)buf, sizeof(buf));
1835 close(fd);
1837 return false;
1839 #endif /* CPU */
1841 #ifndef SIMULATOR
1842 #if CONFIG_TUNER
1844 #ifdef CONFIG_TUNER_MULTI
1845 static int tuner_type = 0;
1846 #define IF_TUNER_TYPE(type) if(tuner_type==type)
1847 #else
1848 #define IF_TUNER_TYPE(type)
1849 #endif
1851 static int radio_callback(int btn, struct gui_synclist *lists)
1853 (void)lists;
1854 if (btn == ACTION_STD_CANCEL)
1855 return btn;
1856 simplelist_set_line_count(1);
1858 #if (CONFIG_TUNER & LV24020LP)
1859 simplelist_addline(
1860 "CTRL_STAT: %02X", lv24020lp_get(LV24020LP_CTRL_STAT) );
1861 simplelist_addline(
1862 "RADIO_STAT: %02X", lv24020lp_get(LV24020LP_REG_STAT) );
1863 simplelist_addline(
1864 "MSS_FM: %d kHz", lv24020lp_get(LV24020LP_MSS_FM) );
1865 simplelist_addline(
1866 "MSS_IF: %d Hz", lv24020lp_get(LV24020LP_MSS_IF) );
1867 simplelist_addline(
1868 "MSS_SD: %d Hz", lv24020lp_get(LV24020LP_MSS_SD) );
1869 simplelist_addline(
1870 "if_set: %d Hz", lv24020lp_get(LV24020LP_IF_SET) );
1871 simplelist_addline(
1872 "sd_set: %d Hz", lv24020lp_get(LV24020LP_SD_SET) );
1873 #endif /* LV24020LP */
1874 #if (CONFIG_TUNER & S1A0903X01)
1875 simplelist_addline(
1876 "Samsung regs: %08X", s1a0903x01_get(RADIO_ALL));
1877 /* This one doesn't return dynamic data atm */
1878 #endif /* S1A0903X01 */
1879 #if (CONFIG_TUNER & TEA5767)
1880 struct tea5767_dbg_info nfo;
1881 tea5767_dbg_info(&nfo);
1882 simplelist_addline("Philips regs:");
1883 simplelist_addline(
1884 " Read: %02X %02X %02X %02X %02X",
1885 (unsigned)nfo.read_regs[0], (unsigned)nfo.read_regs[1],
1886 (unsigned)nfo.read_regs[2], (unsigned)nfo.read_regs[3],
1887 (unsigned)nfo.read_regs[4]);
1888 simplelist_addline(
1889 " Write: %02X %02X %02X %02X %02X",
1890 (unsigned)nfo.write_regs[0], (unsigned)nfo.write_regs[1],
1891 (unsigned)nfo.write_regs[2], (unsigned)nfo.write_regs[3],
1892 (unsigned)nfo.write_regs[4]);
1893 #endif /* TEA5767 */
1894 #if (CONFIG_TUNER & SI4700)
1895 IF_TUNER_TYPE(SI4700)
1897 struct si4700_dbg_info nfo;
1898 si4700_dbg_info(&nfo);
1899 simplelist_addline("SI4700 regs:");
1900 for (int i = 0; i < 16; i += 4) {
1901 simplelist_addline("%02X: %04X %04X %04X %04X",
1902 i, nfo.regs[i], nfo.regs[i+1], nfo.regs[i+2], nfo.regs[i+3]);
1905 #endif /* SI4700 */
1906 #if (CONFIG_TUNER & RDA5802)
1907 IF_TUNER_TYPE(RDA5802)
1909 struct rda5802_dbg_info nfo;
1910 rda5802_dbg_info(&nfo);
1911 simplelist_addline("RDA5802 regs:");
1912 for (int i = 0; i < 16; i += 4) {
1913 simplelist_addline("%02X: %04X %04X %04X %04X",
1914 i, nfo.regs[i], nfo.regs[i+1], nfo.regs[i+2], nfo.regs[i+3]);
1917 #endif /* RDA55802 */
1918 #if (CONFIG_TUNER & STFM1000)
1919 IF_TUNER_TYPE(STFM1000)
1921 struct stfm1000_dbg_info nfo;
1922 stfm1000_dbg_info(&nfo);
1923 simplelist_addline("STFM1000 regs:");
1924 simplelist_addline("chipid: 0x%x", nfo.chipid);
1926 #endif /* STFM1000 */
1928 #ifdef HAVE_RDS_CAP
1929 simplelist_addline("PI:%04X PS:'%8s'",
1930 rds_get_pi(), rds_get_ps());
1931 simplelist_addline("RT:%s",
1932 rds_get_rt());
1933 time_t seconds = rds_get_ct();
1934 struct tm* time = gmtime(&seconds);
1935 simplelist_addline(
1936 "CT:%4d-%02d-%02d %02d:%02d",
1937 time->tm_year + 1900, time->tm_mon + 1, time->tm_mday,
1938 time->tm_hour, time->tm_min, time->tm_sec);
1939 #endif
1940 return ACTION_REDRAW;
1942 static bool dbg_fm_radio(void)
1944 struct simplelist_info info;
1945 #ifdef CONFIG_TUNER_MULTI
1946 tuner_type = tuner_detect_type();
1947 #endif
1948 info.scroll_all = true;
1949 simplelist_info_init(&info, "FM Radio", 1, NULL);
1950 simplelist_set_line_count(0);
1951 simplelist_addline("HW detected: %s",
1952 radio_hardware_present() ? "yes" : "no");
1954 info.action_callback = radio_hardware_present()?radio_callback : NULL;
1955 info.hide_selection = true;
1956 return simplelist_show_list(&info);
1958 #endif /* CONFIG_TUNER */
1959 #endif /* !SIMULATOR */
1961 #if defined(HAVE_LCD_BITMAP) && !defined(APPLICATION)
1962 extern bool do_screendump_instead_of_usb;
1964 static bool dbg_screendump(void)
1966 do_screendump_instead_of_usb = !do_screendump_instead_of_usb;
1967 splashf(HZ, "Screendump %sabled", do_screendump_instead_of_usb?"en":"dis");
1968 return false;
1970 #endif /* HAVE_LCD_BITMAP */
1972 extern bool write_metadata_log;
1974 static bool dbg_metadatalog(void)
1976 write_metadata_log = !write_metadata_log;
1977 splashf(HZ, "Metadata log %sabled", write_metadata_log ? "en" : "dis");
1978 return false;
1981 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
1982 static bool dbg_set_memory_guard(void)
1984 static const struct opt_items names[MAXMEMGUARD] = {
1985 { "None", -1 },
1986 { "Flash ROM writes", -1 },
1987 { "Zero area (all)", -1 }
1989 int mode = system_memory_guard(MEMGUARD_KEEP);
1991 set_option( "Catch mem accesses", &mode, INT, names, MAXMEMGUARD, NULL);
1992 system_memory_guard(mode);
1994 return false;
1996 #endif /* CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) */
1998 #if defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS)
1999 static bool dbg_write_eeprom(void)
2001 int fd = open("/internal_eeprom.bin", O_RDONLY);
2003 if (fd >= 0)
2005 char buf[EEPROM_SIZE];
2006 int rc = read(fd, buf, EEPROM_SIZE);
2008 if(rc == EEPROM_SIZE)
2010 int old_irq_level = disable_irq_save();
2012 int err = eeprom_24cxx_write(0, buf, sizeof buf);
2013 if (err)
2014 splashf(HZ*3, "Eeprom write failure (%d)", err);
2015 else
2016 splash(HZ*3, "Eeprom written successfully");
2018 restore_irq(old_irq_level);
2020 else
2022 splashf(HZ*3, "File read error (%d)",rc);
2024 close(fd);
2026 else
2028 splash(HZ*3, "Failed to open 'internal_eeprom.bin'");
2031 return false;
2033 #endif /* defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS) */
2034 #ifdef CPU_BOOST_LOGGING
2035 static bool cpu_boost_log(void)
2037 int count = cpu_boost_log_getcount();
2038 char *str = cpu_boost_log_getlog_first();
2039 bool done;
2040 lcd_setfont(FONT_SYSFIXED);
2041 for (int i = 0; i < count ;)
2043 lcd_clear_display();
2044 for(int j=0; j<LCD_HEIGHT/SYSFONT_HEIGHT; j++,i++)
2046 if (!str)
2047 str = cpu_boost_log_getlog_next();
2048 if (str)
2050 if(strlen(str) > LCD_WIDTH/SYSFONT_WIDTH)
2051 lcd_puts_scroll(0, j, str);
2052 else
2053 lcd_puts(0, j,str);
2055 str = NULL;
2057 lcd_update();
2058 done = false;
2059 while (!done)
2061 switch(get_action(CONTEXT_STD,TIMEOUT_BLOCK))
2063 case ACTION_STD_OK:
2064 case ACTION_STD_PREV:
2065 case ACTION_STD_NEXT:
2066 done = true;
2067 break;
2068 case ACTION_STD_CANCEL:
2069 i = count;
2070 done = true;
2071 break;
2075 lcd_stop_scroll();
2076 get_action(CONTEXT_STD,TIMEOUT_BLOCK);
2077 lcd_setfont(FONT_UI);
2078 return false;
2080 #endif
2082 #if (defined(HAVE_WHEEL_ACCELERATION) && (CONFIG_KEYPAD==IPOD_4G_PAD) \
2083 && !defined(IPOD_MINI) && !defined(SIMULATOR))
2084 extern bool wheel_is_touched;
2085 extern int old_wheel_value;
2086 extern int new_wheel_value;
2087 extern int wheel_delta;
2088 extern unsigned int accumulated_wheel_delta;
2089 extern unsigned int wheel_velocity;
2091 static bool dbg_scrollwheel(void)
2093 lcd_setfont(FONT_SYSFIXED);
2095 while (1)
2097 if (action_userabort(HZ/10))
2098 break;
2100 lcd_clear_display();
2102 /* show internal variables of scrollwheel driver */
2103 lcd_putsf(0, 0, "wheel touched: %s", (wheel_is_touched) ? "true" : "false");
2104 lcd_putsf(0, 1, "new position: %2d", new_wheel_value);
2105 lcd_putsf(0, 2, "old position: %2d", old_wheel_value);
2106 lcd_putsf(0, 3, "wheel delta: %2d", wheel_delta);
2107 lcd_putsf(0, 4, "accumulated delta: %2d", accumulated_wheel_delta);
2108 lcd_putsf(0, 5, "velo [deg/s]: %4d", (int)wheel_velocity);
2110 /* show effective accelerated scrollspeed */
2111 lcd_putsf(0, 6, "accel. speed: %4d",
2112 button_apply_acceleration((1<<31)|(1<<24)|wheel_velocity) );
2114 lcd_update();
2116 lcd_setfont(FONT_UI);
2117 return false;
2119 #endif
2121 #ifdef HAVE_USBSTACK
2122 #if defined(ROCKBOX_HAS_LOGF) && defined(USB_ENABLE_SERIAL)
2123 static bool toggle_usb_serial(void)
2125 bool enabled = !usb_core_driver_enabled(USB_DRIVER_SERIAL);
2127 usb_core_enable_driver(USB_DRIVER_SERIAL, enabled);
2128 splashf(HZ, "USB Serial %sabled", enabled ? "en" : "dis");
2130 return false;
2132 #endif
2133 #endif
2135 #if CONFIG_USBOTG == USBOTG_ISP1583
2136 extern int dbg_usb_num_items(void);
2137 extern const char* dbg_usb_item(int selected_item, void *data,
2138 char *buffer, size_t buffer_len);
2140 static int isp1583_action_callback(int action, struct gui_synclist *lists)
2142 (void)lists;
2143 if (action == ACTION_NONE)
2144 action = ACTION_REDRAW;
2145 return action;
2148 static bool dbg_isp1583(void)
2150 struct simplelist_info isp1583;
2151 isp1583.scroll_all = true;
2152 simplelist_info_init(&isp1583, "ISP1583", dbg_usb_num_items(), NULL);
2153 isp1583.timeout = HZ/100;
2154 isp1583.hide_selection = true;
2155 isp1583.get_name = dbg_usb_item;
2156 isp1583.action_callback = isp1583_action_callback;
2157 return simplelist_show_list(&isp1583);
2159 #endif
2161 #if defined(CREATIVE_ZVx) && !defined(SIMULATOR)
2162 extern int pic_dbg_num_items(void);
2163 extern const char* pic_dbg_item(int selected_item, void *data,
2164 char *buffer, size_t buffer_len);
2166 static int pic_action_callback(int action, struct gui_synclist *lists)
2168 (void)lists;
2169 if (action == ACTION_NONE)
2170 action = ACTION_REDRAW;
2171 return action;
2174 static bool dbg_pic(void)
2176 struct simplelist_info pic;
2177 pic.scroll_all = true;
2178 simplelist_info_init(&pic, "PIC", pic_dbg_num_items(), NULL);
2179 pic.timeout = HZ/100;
2180 pic.hide_selection = true;
2181 pic.get_name = pic_dbg_item;
2182 pic.action_callback = pic_action_callback;
2183 return simplelist_show_list(&pic);
2185 #endif
2187 #ifdef HAVE_LCD_BITMAP
2188 static bool dbg_skin_engine(void)
2190 struct simplelist_info info;
2191 int i, total = 0;
2192 #if defined(HAVE_BACKDROP_IMAGE)
2193 int ref_count;
2194 char *path;
2195 size_t bytes;
2196 int path_prefix_len = strlen(ROCKBOX_DIR "/wps/");
2197 #endif
2198 simplelist_info_init(&info, "Skin engine usage", 0, NULL);
2199 simplelist_set_line_count(0);
2200 info.hide_selection = true;
2201 FOR_NB_SCREENS(j) {
2202 #if NB_SCREENS > 1
2203 simplelist_addline("%s display:",
2204 j == 0 ? "Main" : "Remote");
2205 #endif
2206 for (i = 0; i < skin_get_num_skins(); i++) {
2207 struct skin_stats *stats = skin_get_stats(i, j);
2208 if (stats->buflib_handles)
2210 simplelist_addline("Skin ID: %d, %d allocations",
2211 i, stats->buflib_handles);
2212 simplelist_addline("\tskin: %d bytes",
2213 stats->tree_size);
2214 simplelist_addline("\tImages: %d bytes",
2215 stats->images_size);
2216 simplelist_addline("\tTotal: %d bytes",
2217 stats->tree_size + stats->images_size);
2218 total += stats->tree_size + stats->images_size;
2222 simplelist_addline("Skin total usage: %d bytes", total);
2223 #if defined(HAVE_BACKDROP_IMAGE)
2224 simplelist_addline("Backdrop Images:");
2225 i = 0;
2226 while (skin_backdrop_get_debug(i++, &path, &ref_count, &bytes)) {
2227 if (ref_count > 0) {
2229 if (!strncasecmp(path, ROCKBOX_DIR "/wps/", path_prefix_len))
2230 path += path_prefix_len;
2231 simplelist_addline("%s", path);
2232 simplelist_addline("\tref_count: %d", ref_count);
2233 simplelist_addline("\tsize: %d", bytes);
2234 total += bytes;
2237 simplelist_addline("Total usage: %d bytes", total);
2238 #endif
2239 return simplelist_show_list(&info);
2241 #endif
2244 /****** The menu *********/
2245 static const struct {
2246 unsigned char *desc; /* string or ID */
2247 bool (*function) (void); /* return true if USB was connected */
2248 } menuitems[] = {
2249 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || \
2250 (defined(CPU_PP) && !(CONFIG_STORAGE & STORAGE_SD)) || \
2251 CONFIG_CPU == IMX31L || defined(CPU_TCC780X) || CONFIG_CPU == AS3525v2 || \
2252 CONFIG_CPU == AS3525 || CONFIG_CPU == RK27XX
2253 { "Dump ROM contents", dbg_save_roms },
2254 #endif
2255 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || defined(CPU_PP) \
2256 || CONFIG_CPU == S3C2440 || CONFIG_CPU == IMX31L || CONFIG_CPU == AS3525 \
2257 || CONFIG_CPU == DM320 || defined(CPU_S5L870X) || CONFIG_CPU == AS3525v2 \
2258 || CONFIG_CPU == RK27XX
2259 { "View I/O ports", dbg_ports },
2260 #endif
2261 #if (CONFIG_RTC == RTC_PCF50605) && (CONFIG_PLATFORM & PLATFORM_NATIVE)
2262 { "View PCF registers", dbg_pcf },
2263 #endif
2264 #if defined(HAVE_TSC2100) && (CONFIG_PLATFORM & PLATFORM_NATIVE)
2265 { "TSC2100 debug", tsc2100_debug },
2266 #endif
2267 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
2268 { "CPU frequency", dbg_cpufreq },
2269 #endif
2270 #if CONFIG_CPU == IMX31L
2271 { "DVFS/DPTC", __dbg_dvfs_dptc },
2272 #endif
2273 #if defined(IRIVER_H100_SERIES) && !defined(SIMULATOR)
2274 { "S/PDIF analyzer", dbg_spdif },
2275 #endif
2276 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
2277 { "Catch mem accesses", dbg_set_memory_guard },
2278 #endif
2279 { "View OS stacks", dbg_os },
2280 #ifdef __linux__
2281 { "View CPU stats", dbg_cpuinfo },
2282 #endif
2283 #ifdef HAVE_LCD_BITMAP
2284 #if (CONFIG_BATTERY_MEASURE != 0) && !defined(SIMULATOR)
2285 { "View battery", view_battery },
2286 #endif
2287 #ifndef APPLICATION
2288 { "Screendump", dbg_screendump },
2289 #endif
2290 { "Skin Engine Ram usage", dbg_skin_engine },
2291 #endif
2292 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
2293 { "View HW info", dbg_hw_info },
2294 #endif
2295 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
2296 { "View partitions", dbg_partitions },
2297 #endif
2298 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
2299 { "View disk info", dbg_disk_info },
2300 #if (CONFIG_STORAGE & STORAGE_ATA)
2301 { "Dump ATA identify info", dbg_identify_info},
2302 #endif
2303 #endif
2304 { "Metadata log", dbg_metadatalog },
2305 #ifdef HAVE_DIRCACHE
2306 { "View dircache info", dbg_dircache_info },
2307 #endif
2308 #ifdef HAVE_TAGCACHE
2309 { "View database info", dbg_tagcache_info },
2310 #endif
2311 #ifdef HAVE_LCD_BITMAP
2312 #if CONFIG_CODEC == SWCODEC
2313 { "View buffering thread", dbg_buffering_thread },
2314 #elif !defined(SIMULATOR)
2315 { "View audio thread", dbg_audio_thread },
2316 #endif
2317 #ifdef PM_DEBUG
2318 { "pm histogram", peak_meter_histogram},
2319 #endif /* PM_DEBUG */
2320 #endif /* HAVE_LCD_BITMAP */
2321 { "View buflib allocs", dbg_buflib_allocs },
2322 #ifndef SIMULATOR
2323 #if CONFIG_TUNER
2324 { "FM Radio", dbg_fm_radio },
2325 #endif
2326 #endif
2327 #if defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS)
2328 { "Write back EEPROM", dbg_write_eeprom },
2329 #endif
2330 #if CONFIG_USBOTG == USBOTG_ISP1583
2331 { "View ISP1583 info", dbg_isp1583 },
2332 #endif
2333 #if defined(CREATIVE_ZVx) && !defined(SIMULATOR)
2334 { "View PIC info", dbg_pic },
2335 #endif
2336 #ifdef ROCKBOX_HAS_LOGF
2337 {"Show Log File", logfdisplay },
2338 {"Dump Log File", logfdump },
2339 #endif
2340 #if defined(HAVE_USBSTACK)
2341 #if defined(ROCKBOX_HAS_LOGF) && defined(USB_ENABLE_SERIAL)
2342 {"USB Serial driver (logf)", toggle_usb_serial },
2343 #endif
2344 #endif /* HAVE_USBSTACK */
2345 #ifdef CPU_BOOST_LOGGING
2346 {"cpu_boost log",cpu_boost_log},
2347 #endif
2348 #if (defined(HAVE_WHEEL_ACCELERATION) && (CONFIG_KEYPAD==IPOD_4G_PAD) \
2349 && !defined(IPOD_MINI) && !defined(SIMULATOR))
2350 {"Debug scrollwheel", dbg_scrollwheel },
2351 #endif
2354 static int menu_action_callback(int btn, struct gui_synclist *lists)
2356 int selection = gui_synclist_get_sel_pos(lists);
2357 if (btn == ACTION_STD_OK)
2359 FOR_NB_SCREENS(i)
2360 viewportmanager_theme_enable(i, false, NULL);
2361 menuitems[selection].function();
2362 btn = ACTION_REDRAW;
2363 FOR_NB_SCREENS(i)
2364 viewportmanager_theme_undo(i, false);
2366 else if (btn == ACTION_STD_CONTEXT)
2368 MENUITEM_STRINGLIST(menu_items, "Debug Menu", NULL, ID2P(LANG_ADD_TO_FAVES));
2369 if (do_menu(&menu_items, NULL, NULL, false) == 0)
2370 shortcuts_add(SHORTCUT_DEBUGITEM, menuitems[selection].desc);
2371 return ACTION_STD_CANCEL;
2373 return btn;
2376 static const char* menu_get_name(int item, void * data,
2377 char *buffer, size_t buffer_len)
2379 (void)data; (void)buffer; (void)buffer_len;
2380 return menuitems[item].desc;
2383 bool debug_menu(void)
2385 struct simplelist_info info;
2387 simplelist_info_init(&info, "Debug Menu", ARRAYLEN(menuitems), NULL);
2388 info.action_callback = menu_action_callback;
2389 info.get_name = menu_get_name;
2390 return simplelist_show_list(&info);
2393 bool run_debug_screen(char* screen)
2395 for (unsigned i=0; i<ARRAYLEN(menuitems); i++)
2396 if (!strcmp(screen, menuitems[i].desc))
2398 FOR_NB_SCREENS(j)
2399 viewportmanager_theme_enable(j, false, NULL);
2400 menuitems[i].function();
2401 FOR_NB_SCREENS(j)
2402 viewportmanager_theme_undo(j, false);
2403 return true;
2406 return false;