When building a static linux binary link libusb static.
[Rockbox.git] / apps / debug_menu.c
blobd1463c735316d5cfbf5307e5a409e8429e02e856
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2002 Heikki Hannikainen
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
20 #include "config.h"
21 #include <stdio.h>
22 #include <stdbool.h>
23 #include <string.h>
24 #include "lcd.h"
25 #include "menu.h"
26 #include "debug_menu.h"
27 #include "kernel.h"
28 #include "sprintf.h"
29 #include "action.h"
30 #include "debug.h"
31 #include "thread.h"
32 #include "powermgmt.h"
33 #include "system.h"
34 #include "font.h"
35 #include "audio.h"
36 #include "mp3_playback.h"
37 #include "settings.h"
38 #include "list.h"
39 #include "statusbar.h"
40 #include "dir.h"
41 #include "panic.h"
42 #include "screens.h"
43 #include "misc.h"
44 #include "splash.h"
45 #include "dircache.h"
46 #ifdef HAVE_TAGCACHE
47 #include "tagcache.h"
48 #endif
49 #include "lcd-remote.h"
50 #include "crc32.h"
51 #include "logf.h"
52 #ifndef SIMULATOR
53 #include "disk.h"
54 #include "adc.h"
55 #include "power.h"
56 #include "usb.h"
57 #include "rtc.h"
58 #include "ata.h"
59 #include "fat.h"
60 #include "mas.h"
61 #include "eeprom_24cxx.h"
62 #if defined(HAVE_MMC) || defined(HAVE_HOTSWAP)
63 #include "ata_mmc.h"
64 #endif
65 #if CONFIG_TUNER
66 #include "tuner.h"
67 #include "radio.h"
68 #endif
69 #endif
71 #ifdef HAVE_LCD_BITMAP
72 #include "scrollbar.h"
73 #include "peakmeter.h"
74 #endif
75 #include "logfdisp.h"
76 #if CONFIG_CODEC == SWCODEC
77 #include "pcmbuf.h"
78 #include "buffering.h"
79 #if defined(HAVE_SPDIF_OUT) || defined(HAVE_SPDIF_IN)
80 #include "spdif.h"
81 #endif
82 #endif
83 #ifdef IRIVER_H300_SERIES
84 #include "pcf50606.h" /* for pcf50606_read */
85 #endif
86 #ifdef IAUDIO_X5
87 #include "ds2411.h"
88 #endif
89 #include "hwcompat.h"
90 #include "button.h"
91 #if CONFIG_RTC == RTC_PCF50605
92 #include "pcf50605.h"
93 #endif
95 #if CONFIG_CPU == DM320 || CONFIG_CPU == S3C2440 || CONFIG_CPU == TCC7801
96 #include "debug-target.h"
97 #endif
99 /*---------------------------------------------------*/
100 /* SPECIAL DEBUG STUFF */
101 /*---------------------------------------------------*/
102 extern struct thread_entry threads[MAXTHREADS];
104 static char thread_status_char(unsigned status)
106 static const char thread_status_chars[THREAD_NUM_STATES+1] =
108 [0 ... THREAD_NUM_STATES] = '?',
109 [STATE_RUNNING] = 'R',
110 [STATE_BLOCKED] = 'B',
111 [STATE_SLEEPING] = 'S',
112 [STATE_BLOCKED_W_TMO] = 'T',
113 [STATE_FROZEN] = 'F',
114 [STATE_KILLED] = 'K',
117 #if NUM_CORES > 1
118 if (status == STATE_BUSY) /* Not a state index */
119 return '.';
120 #endif
122 if (status > THREAD_NUM_STATES)
123 status = THREAD_NUM_STATES;
125 return thread_status_chars[status];
128 static char* threads_getname(int selected_item, void * data, char *buffer)
130 (void)data;
131 struct thread_entry *thread;
132 char name[32];
134 #if NUM_CORES > 1
135 if (selected_item < (int)NUM_CORES)
137 snprintf(buffer, MAX_PATH, "Idle (%d): %2d%%", selected_item,
138 idle_stack_usage(selected_item));
139 return buffer;
142 selected_item -= NUM_CORES;
143 #endif
145 thread = &threads[selected_item];
147 if (thread->state == STATE_KILLED)
149 snprintf(buffer, MAX_PATH, "%2d: ---", selected_item);
150 return buffer;
153 thread_get_name(name, 32, thread);
155 snprintf(buffer, MAX_PATH,
156 "%2d: " IF_COP("(%d) ") "%c%c " IF_PRIO("%d ") "%2d%% %s",
157 selected_item,
158 IF_COP(thread->core,)
159 #ifdef HAVE_SCHEDULER_BOOSTCTRL
160 (thread->boosted) ? '+' :
161 #endif
162 ((thread->state == STATE_RUNNING) ? '*' : ' '),
163 thread_status_char(thread->state),
164 IF_PRIO(thread->priority,)
165 thread_stack_usage(thread), name);
167 return buffer;
169 static int dbg_threads_action_callback(int action, struct gui_synclist *lists)
171 (void)lists;
172 #ifdef ROCKBOX_HAS_LOGF
173 if (action == ACTION_STD_OK)
175 int selpos = gui_synclist_get_sel_pos(lists);
176 #if NUM_CORES > 1
177 if (selpos >= NUM_CORES)
178 remove_thread(&threads[selpos - NUM_CORES]);
179 #else
180 remove_thread(&threads[selpos]);
181 #endif
182 return ACTION_REDRAW;
184 #endif /* ROCKBOX_HAS_LOGF */
185 return action;
187 /* Test code!!! */
188 static bool dbg_os(void)
190 struct simplelist_info info;
191 simplelist_info_init(&info, IF_COP("Core and ") "Stack usage:",
192 #if NUM_CORES == 1
193 MAXTHREADS,
194 #else
195 MAXTHREADS+NUM_CORES,
196 #endif
197 NULL);
198 #ifndef ROCKBOX_HAS_LOGF
199 info.hide_selection = true;
200 #endif
201 info.action_callback = dbg_threads_action_callback;
202 info.get_name = threads_getname;
203 return simplelist_show_list(&info);
206 #ifdef HAVE_LCD_BITMAP
207 #if CONFIG_CODEC != SWCODEC
208 #ifndef SIMULATOR
209 static bool dbg_audio_thread(void)
211 char buf[32];
212 struct audio_debug d;
214 lcd_setmargins(0, 0);
215 lcd_setfont(FONT_SYSFIXED);
217 while(1)
219 if (action_userabort(HZ/5))
220 return false;
222 audio_get_debugdata(&d);
224 lcd_clear_display();
226 snprintf(buf, sizeof(buf), "read: %x", d.audiobuf_read);
227 lcd_puts(0, 0, buf);
228 snprintf(buf, sizeof(buf), "write: %x", d.audiobuf_write);
229 lcd_puts(0, 1, buf);
230 snprintf(buf, sizeof(buf), "swap: %x", d.audiobuf_swapwrite);
231 lcd_puts(0, 2, buf);
232 snprintf(buf, sizeof(buf), "playing: %d", d.playing);
233 lcd_puts(0, 3, buf);
234 snprintf(buf, sizeof(buf), "playable: %x", d.playable_space);
235 lcd_puts(0, 4, buf);
236 snprintf(buf, sizeof(buf), "unswapped: %x", d.unswapped_space);
237 lcd_puts(0, 5, buf);
239 /* Playable space left */
240 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, 6*8, 112, 4, d.audiobuflen, 0,
241 d.playable_space, HORIZONTAL);
243 /* Show the watermark limit */
244 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, 6*8+4, 112, 4, d.audiobuflen, 0,
245 d.low_watermark_level, HORIZONTAL);
247 snprintf(buf, sizeof(buf), "wm: %x - %x",
248 d.low_watermark_level, d.lowest_watermark_level);
249 lcd_puts(0, 7, buf);
251 lcd_update();
253 return false;
255 #endif /* !SIMULATOR */
256 #else /* CONFIG_CODEC == SWCODEC */
257 extern size_t filebuflen;
258 /* This is a size_t, but call it a long so it puts a - when it's bad. */
260 static unsigned int ticks, boost_ticks;
262 static void dbg_audio_task(void)
264 #ifndef SIMULATOR
265 if(FREQ > CPUFREQ_NORMAL)
266 boost_ticks++;
267 #endif
269 ticks++;
272 static bool dbg_buffering_thread(void)
274 char buf[32];
275 int button;
276 int line;
277 bool done = false;
278 size_t bufused;
279 size_t bufsize = pcmbuf_get_bufsize();
280 int pcmbufdescs = pcmbuf_descs();
281 struct buffering_debug d;
283 ticks = boost_ticks = 0;
285 tick_add_task(dbg_audio_task);
287 lcd_setmargins(0, 0);
288 lcd_setfont(FONT_SYSFIXED);
289 while(!done)
291 button = get_action(CONTEXT_STD,HZ/5);
292 switch(button)
294 case ACTION_STD_NEXT:
295 audio_next();
296 break;
297 case ACTION_STD_PREV:
298 audio_prev();
299 break;
300 case ACTION_STD_CANCEL:
301 done = true;
302 break;
305 buffering_get_debugdata(&d);
307 line = 0;
308 lcd_clear_display();
310 bufused = bufsize - pcmbuf_free();
312 snprintf(buf, sizeof(buf), "pcm: %7ld/%7ld", (long) bufused, (long) bufsize);
313 lcd_puts(0, line++, buf);
315 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6,
316 bufsize, 0, bufused, HORIZONTAL);
317 line++;
319 snprintf(buf, sizeof(buf), "alloc: %8ld/%8ld", audio_filebufused(),
320 (long) filebuflen);
321 lcd_puts(0, line++, buf);
323 #if LCD_HEIGHT > 80
324 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6,
325 filebuflen, 0, audio_filebufused(), HORIZONTAL);
326 line++;
328 snprintf(buf, sizeof(buf), "real: %8ld/%8ld", (long)d.buffered_data,
329 (long)filebuflen);
330 lcd_puts(0, line++, buf);
332 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6,
333 filebuflen, 0, (long)d.buffered_data, HORIZONTAL);
334 line++;
335 #endif
337 snprintf(buf, sizeof(buf), "usefl: %8ld/%8ld", (long)(d.useful_data),
338 (long)filebuflen);
339 lcd_puts(0, line++, buf);
341 #if LCD_HEIGHT > 80
342 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6,
343 filebuflen, 0, d.useful_data, HORIZONTAL);
344 line++;
345 #endif
347 snprintf(buf, sizeof(buf), "data_rem: %ld", (long)d.data_rem);
348 lcd_puts(0, line++, buf);
350 snprintf(buf, sizeof(buf), "track count: %2d", audio_track_count());
351 lcd_puts(0, line++, buf);
353 snprintf(buf, sizeof(buf), "handle count: %d", (int)d.num_handles);
354 lcd_puts(0, line++, buf);
356 #ifndef SIMULATOR
357 snprintf(buf, sizeof(buf), "cpu freq: %3dMHz",
358 (int)((FREQ + 500000) / 1000000));
359 lcd_puts(0, line++, buf);
360 #endif
362 if (ticks > 0)
364 snprintf(buf, sizeof(buf), "boost ratio: %3d%%",
365 boost_ticks * 100 / ticks);
366 lcd_puts(0, line++, buf);
369 snprintf(buf, sizeof(buf), "pcmbufdesc: %2d/%2d",
370 pcmbuf_used_descs(), pcmbufdescs);
371 lcd_puts(0, line++, buf);
373 lcd_update();
376 tick_remove_task(dbg_audio_task);
378 return false;
380 #endif /* CONFIG_CODEC */
381 #endif /* HAVE_LCD_BITMAP */
384 #if (CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE))
385 /* Tool function to read the flash manufacturer and type, if available.
386 Only chips which could be reprogrammed in system will return values.
387 (The mode switch addresses vary between flash manufacturers, hence addr1/2) */
388 /* In IRAM to avoid problems when running directly from Flash */
389 static bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
390 unsigned addr1, unsigned addr2)
391 ICODE_ATTR __attribute__((noinline));
392 static bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
393 unsigned addr1, unsigned addr2)
396 unsigned not_manu, not_id; /* read values before switching to ID mode */
397 unsigned manu, id; /* read values when in ID mode */
399 #if CONFIG_CPU == SH7034
400 volatile unsigned char* flash = (unsigned char*)0x2000000; /* flash mapping */
401 #elif defined(CPU_COLDFIRE)
402 volatile unsigned short* flash = (unsigned short*)0; /* flash mapping */
403 #endif
404 int old_level; /* saved interrupt level */
406 not_manu = flash[0]; /* read the normal content */
407 not_id = flash[1]; /* should be 'A' (0x41) and 'R' (0x52) from the "ARCH" marker */
409 /* disable interrupts, prevent any stray flash access */
410 old_level = set_irq_level(HIGHEST_IRQ_LEVEL);
412 flash[addr1] = 0xAA; /* enter command mode */
413 flash[addr2] = 0x55;
414 flash[addr1] = 0x90; /* ID command */
415 /* Atmel wants 20ms pause here */
416 /* sleep(HZ/50); no sleeping possible while interrupts are disabled */
418 manu = flash[0]; /* read the IDs */
419 id = flash[1];
421 flash[0] = 0xF0; /* reset flash (back to normal read mode) */
422 /* Atmel wants 20ms pause here */
423 /* sleep(HZ/50); no sleeping possible while interrupts are disabled */
425 set_irq_level(old_level); /* enable interrupts again */
427 /* I assume success if the obtained values are different from
428 the normal flash content. This is not perfectly bulletproof, they
429 could theoretically be the same by chance, causing us to fail. */
430 if (not_manu != manu || not_id != id) /* a value has changed */
432 *p_manufacturer = manu; /* return the results */
433 *p_device = id;
434 return true; /* success */
436 return false; /* fail */
438 #endif /* (CONFIG_CPU == SH7034 || CPU_COLDFIRE) */
440 #ifndef SIMULATOR
441 #ifdef CPU_PP
442 static int perfcheck(void)
444 int result;
446 asm (
447 "mrs r2, CPSR \n"
448 "orr r0, r2, #0xc0 \n" /* disable IRQ and FIQ */
449 "msr CPSR_c, r0 \n"
450 "mov %[res], #0 \n"
451 "ldr r0, [%[timr]] \n"
452 "add r0, r0, %[tmo] \n"
453 "1: \n"
454 "add %[res], %[res], #1 \n"
455 "ldr r1, [%[timr]] \n"
456 "cmp r1, r0 \n"
457 "bmi 1b \n"
458 "msr CPSR_c, r2 \n" /* reset IRQ and FIQ state */
460 [res]"=&r"(result)
462 [timr]"r"(&USEC_TIMER),
463 [tmo]"r"(
464 #if CONFIG_CPU == PP5002
465 16000
466 #else /* PP5020/5022/5024 */
467 10226
468 #endif
471 "r0", "r1", "r2"
473 return result;
475 #endif
477 #ifdef HAVE_LCD_BITMAP
478 static bool dbg_hw_info(void)
480 #if CONFIG_CPU == SH7034
481 char buf[32];
482 int bitmask = HW_MASK;
483 int rom_version = ROM_VERSION;
484 unsigned manu, id; /* flash IDs */
485 bool got_id; /* flag if we managed to get the flash IDs */
486 unsigned rom_crc = 0xffffffff; /* CRC32 of the boot ROM */
487 bool has_bootrom; /* flag for boot ROM present */
488 int oldmode; /* saved memory guard mode */
490 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
492 /* get flash ROM type */
493 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
494 if (!got_id)
495 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
497 /* check if the boot ROM area is a flash mirror */
498 has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0);
499 if (has_bootrom) /* if ROM and Flash different */
501 /* calculate CRC16 checksum of boot ROM */
502 rom_crc = crc_32((unsigned char*)0x0000, 64*1024, 0xffffffff);
505 system_memory_guard(oldmode); /* re-enable memory guard */
507 lcd_setmargins(0, 0);
508 lcd_setfont(FONT_SYSFIXED);
509 lcd_clear_display();
511 lcd_puts(0, 0, "[Hardware info]");
513 snprintf(buf, 32, "ROM: %d.%02d", rom_version/100, rom_version%100);
514 lcd_puts(0, 1, buf);
516 snprintf(buf, 32, "Mask: 0x%04x", bitmask);
517 lcd_puts(0, 2, buf);
519 if (got_id)
520 snprintf(buf, 32, "Flash: M=%02x D=%02x", manu, id);
521 else
522 snprintf(buf, 32, "Flash: M=?? D=??"); /* unknown, sorry */
523 lcd_puts(0, 3, buf);
525 if (has_bootrom)
527 if (rom_crc == 0x56DBA4EE) /* known Version 1 */
528 snprintf(buf, 32, "Boot ROM: V1");
529 else
530 snprintf(buf, 32, "ROMcrc: 0x%08x", rom_crc);
532 else
534 snprintf(buf, 32, "Boot ROM: none");
536 lcd_puts(0, 4, buf);
538 lcd_update();
540 while (!(action_userabort(TIMEOUT_BLOCK)));
542 #elif CONFIG_CPU == MCF5249 || CONFIG_CPU == MCF5250
543 char buf[32];
544 unsigned manu, id; /* flash IDs */
545 int got_id; /* flag if we managed to get the flash IDs */
546 int oldmode; /* saved memory guard mode */
547 int line = 0;
549 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
551 /* get flash ROM type */
552 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
553 if (!got_id)
554 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
556 system_memory_guard(oldmode); /* re-enable memory guard */
558 lcd_setmargins(0, 0);
559 lcd_setfont(FONT_SYSFIXED);
560 lcd_clear_display();
562 lcd_puts(0, line++, "[Hardware info]");
564 if (got_id)
565 snprintf(buf, 32, "Flash: M=%04x D=%04x", manu, id);
566 else
567 snprintf(buf, 32, "Flash: M=???? D=????"); /* unknown, sorry */
568 lcd_puts(0, line++, buf);
570 #ifdef IAUDIO_X5
572 struct ds2411_id id;
574 lcd_puts(0, ++line, "Serial Number:");
576 got_id = ds2411_read_id(&id);
578 if (got_id == DS2411_OK)
580 snprintf(buf, 32, " FC=%02x", (unsigned)id.family_code);
581 lcd_puts(0, ++line, buf);
582 snprintf(buf, 32, " ID=%02X %02X %02X %02X %02X %02X",
583 (unsigned)id.uid[0], (unsigned)id.uid[1], (unsigned)id.uid[2],
584 (unsigned)id.uid[3], (unsigned)id.uid[4], (unsigned)id.uid[5]);
585 lcd_puts(0, ++line, buf);
586 snprintf(buf, 32, " CRC=%02X", (unsigned)id.crc);
588 else
590 snprintf(buf, 32, "READ ERR=%d", got_id);
593 lcd_puts(0, ++line, buf);
595 #endif
597 lcd_update();
599 while (!(action_userabort(TIMEOUT_BLOCK)));
601 #elif defined(CPU_PP502x)
602 int line = 0;
603 char buf[32];
604 char pp_version[] = { (PP_VER2 >> 24) & 0xff, (PP_VER2 >> 16) & 0xff,
605 (PP_VER2 >> 8) & 0xff, (PP_VER2) & 0xff,
606 (PP_VER1 >> 24) & 0xff, (PP_VER1 >> 16) & 0xff,
607 (PP_VER1 >> 8) & 0xff, (PP_VER1) & 0xff, '\0' };
609 lcd_setmargins(0, 0);
610 lcd_setfont(FONT_SYSFIXED);
611 lcd_clear_display();
613 lcd_puts(0, line++, "[Hardware info]");
615 #ifdef IPOD_ARCH
616 snprintf(buf, sizeof(buf), "HW rev: 0x%08lx", IPOD_HW_REVISION);
617 lcd_puts(0, line++, buf);
618 #endif
620 #ifdef IPOD_COLOR
621 extern int lcd_type; /* Defined in lcd-colornano.c */
623 snprintf(buf, sizeof(buf), "LCD type: %d", lcd_type);
624 lcd_puts(0, line++, buf);
625 #endif
627 snprintf(buf, sizeof(buf), "PP version: %s", pp_version);
628 lcd_puts(0, line++, buf);
630 snprintf(buf, sizeof(buf), "Est. clock (kHz): %d", perfcheck());
631 lcd_puts(0, line++, buf);
633 lcd_update();
635 while (!(action_userabort(TIMEOUT_BLOCK)));
637 #elif CONFIG_CPU == PP5002
638 int line = 0;
639 char buf[32];
640 char pp_version[] = { (PP_VER4 >> 8) & 0xff, PP_VER4 & 0xff,
641 (PP_VER3 >> 8) & 0xff, PP_VER3 & 0xff,
642 (PP_VER2 >> 8) & 0xff, PP_VER2 & 0xff,
643 (PP_VER1 >> 8) & 0xff, PP_VER1 & 0xff, '\0' };
646 lcd_setmargins(0, 0);
647 lcd_setfont(FONT_SYSFIXED);
648 lcd_clear_display();
650 lcd_puts(0, line++, "[Hardware info]");
652 #ifdef IPOD_ARCH
653 snprintf(buf, sizeof(buf), "HW rev: 0x%08lx", IPOD_HW_REVISION);
654 lcd_puts(0, line++, buf);
655 #endif
657 snprintf(buf, sizeof(buf), "PP version: %s", pp_version);
658 lcd_puts(0, line++, buf);
660 snprintf(buf, sizeof(buf), "Est. clock (kHz): %d", perfcheck());
661 lcd_puts(0, line++, buf);
663 lcd_update();
665 while (!(action_userabort(TIMEOUT_BLOCK)));
666 #else
667 /* Define this function in your target tree */
668 return __dbg_hw_info();
669 #endif /* CONFIG_CPU */
670 return false;
672 #else /* !HAVE_LCD_BITMAP */
673 static bool dbg_hw_info(void)
675 char buf[32];
676 int button;
677 int currval = 0;
678 int rom_version = ROM_VERSION;
679 unsigned manu, id; /* flash IDs */
680 bool got_id; /* flag if we managed to get the flash IDs */
681 unsigned rom_crc = 0xffffffff; /* CRC32 of the boot ROM */
682 bool has_bootrom; /* flag for boot ROM present */
683 int oldmode; /* saved memory guard mode */
685 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
687 /* get flash ROM type */
688 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
689 if (!got_id)
690 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
692 /* check if the boot ROM area is a flash mirror */
693 has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0);
694 if (has_bootrom) /* if ROM and Flash different */
696 /* calculate CRC16 checksum of boot ROM */
697 rom_crc = crc_32((unsigned char*)0x0000, 64*1024, 0xffffffff);
700 system_memory_guard(oldmode); /* re-enable memory guard */
702 lcd_clear_display();
704 lcd_puts(0, 0, "[HW Info]");
705 while(1)
707 switch(currval)
709 case 0:
710 snprintf(buf, 32, "ROM: %d.%02d",
711 rom_version/100, rom_version%100);
712 break;
713 case 1:
714 if (got_id)
715 snprintf(buf, 32, "Flash:%02x,%02x", manu, id);
716 else
717 snprintf(buf, 32, "Flash:??,??"); /* unknown, sorry */
718 break;
719 case 2:
720 if (has_bootrom)
722 if (rom_crc == 0x56DBA4EE) /* known Version 1 */
723 snprintf(buf, 32, "BootROM: V1");
724 else if (rom_crc == 0x358099E8)
725 snprintf(buf, 32, "BootROM: V2");
726 /* alternative boot ROM found in one single player so far */
727 else
728 snprintf(buf, 32, "R: %08x", rom_crc);
730 else
731 snprintf(buf, 32, "BootROM: no");
734 lcd_puts(0, 1, buf);
735 lcd_update();
737 button = get_action(CONTEXT_SETTINGS,TIMEOUT_BLOCK);
739 switch(button)
741 case ACTION_STD_CANCEL:
742 return false;
744 case ACTION_SETTINGS_DEC:
745 currval--;
746 if(currval < 0)
747 currval = 2;
748 break;
750 case ACTION_SETTINGS_INC:
751 currval++;
752 if(currval > 2)
753 currval = 0;
754 break;
757 return false;
759 #endif /* !HAVE_LCD_BITMAP */
760 #endif /* !SIMULATOR */
762 #ifndef SIMULATOR
763 static char* dbg_partitions_getname(int selected_item, void * data, char *buffer)
765 (void)data;
766 int partition = selected_item/2;
767 struct partinfo* p = disk_partinfo(partition);
768 if (selected_item%2)
770 snprintf(buffer, MAX_PATH, " T:%x %ld MB", p->type, p->size / 2048);
772 else
774 snprintf(buffer, MAX_PATH, "P%d: S:%lx", partition, p->start);
776 return buffer;
779 bool dbg_partitions(void)
781 struct simplelist_info info;
782 simplelist_info_init(&info, "Partition Info", 4, NULL);
783 info.selection_size = 2;
784 info.hide_selection = true;
785 info.get_name = dbg_partitions_getname;
786 return simplelist_show_list(&info);
788 #endif
790 #if defined(CPU_COLDFIRE) && defined(HAVE_SPDIF_OUT)
791 static bool dbg_spdif(void)
793 char buf[128];
794 int line;
795 unsigned int control;
796 int x;
797 char *s;
798 int category;
799 int generation;
800 unsigned int interruptstat;
801 bool valnogood, symbolerr, parityerr;
802 bool done = false;
803 bool spdif_src_on;
804 int spdif_source = spdif_get_output_source(&spdif_src_on);
805 spdif_set_output_source(AUDIO_SRC_SPDIF IF_SPDIF_POWER_(, true));
807 lcd_setmargins(0, 0);
808 lcd_clear_display();
809 lcd_setfont(FONT_SYSFIXED);
811 #ifdef HAVE_SPDIF_POWER
812 spdif_power_enable(true); /* We need SPDIF power for both sending & receiving */
813 #endif
815 while (!done)
817 line = 0;
819 control = EBU1RCVCCHANNEL1;
820 interruptstat = INTERRUPTSTAT;
821 INTERRUPTCLEAR = 0x03c00000;
823 valnogood = (interruptstat & 0x01000000)?true:false;
824 symbolerr = (interruptstat & 0x00800000)?true:false;
825 parityerr = (interruptstat & 0x00400000)?true:false;
827 snprintf(buf, sizeof(buf), "Val: %s Sym: %s Par: %s",
828 valnogood?"--":"OK",
829 symbolerr?"--":"OK",
830 parityerr?"--":"OK");
831 lcd_puts(0, line++, buf);
833 snprintf(buf, sizeof(buf), "Status word: %08x", (int)control);
834 lcd_puts(0, line++, buf);
836 line++;
838 x = control >> 31;
839 snprintf(buf, sizeof(buf), "PRO: %d (%s)",
840 x, x?"Professional":"Consumer");
841 lcd_puts(0, line++, buf);
843 x = (control >> 30) & 1;
844 snprintf(buf, sizeof(buf), "Audio: %d (%s)",
845 x, x?"Non-PCM":"PCM");
846 lcd_puts(0, line++, buf);
848 x = (control >> 29) & 1;
849 snprintf(buf, sizeof(buf), "Copy: %d (%s)",
850 x, x?"Permitted":"Inhibited");
851 lcd_puts(0, line++, buf);
853 x = (control >> 27) & 7;
854 switch(x)
856 case 0:
857 s = "None";
858 break;
859 case 1:
860 s = "50/15us";
861 break;
862 default:
863 s = "Reserved";
864 break;
866 snprintf(buf, sizeof(buf), "Preemphasis: %d (%s)", x, s);
867 lcd_puts(0, line++, buf);
869 x = (control >> 24) & 3;
870 snprintf(buf, sizeof(buf), "Mode: %d", x);
871 lcd_puts(0, line++, buf);
873 category = (control >> 17) & 127;
874 switch(category)
876 case 0x00:
877 s = "General";
878 break;
879 case 0x40:
880 s = "Audio CD";
881 break;
882 default:
883 s = "Unknown";
885 snprintf(buf, sizeof(buf), "Category: 0x%02x (%s)", category, s);
886 lcd_puts(0, line++, buf);
888 x = (control >> 16) & 1;
889 generation = x;
890 if(((category & 0x70) == 0x10) ||
891 ((category & 0x70) == 0x40) ||
892 ((category & 0x78) == 0x38))
894 generation = !generation;
896 snprintf(buf, sizeof(buf), "Generation: %d (%s)",
897 x, generation?"Original":"No ind.");
898 lcd_puts(0, line++, buf);
900 x = (control >> 12) & 15;
901 snprintf(buf, sizeof(buf), "Source: %d", x);
902 lcd_puts(0, line++, buf);
904 x = (control >> 8) & 15;
905 switch(x)
907 case 0:
908 s = "Unspecified";
909 break;
910 case 8:
911 s = "A (Left)";
912 break;
913 case 4:
914 s = "B (Right)";
915 break;
916 default:
917 s = "";
918 break;
920 snprintf(buf, sizeof(buf), "Channel: %d (%s)", x, s);
921 lcd_puts(0, line++, buf);
923 x = (control >> 4) & 15;
924 switch(x)
926 case 0:
927 s = "44.1kHz";
928 break;
929 case 0x4:
930 s = "48kHz";
931 break;
932 case 0xc:
933 s = "32kHz";
934 break;
936 snprintf(buf, sizeof(buf), "Frequency: %d (%s)", x, s);
937 lcd_puts(0, line++, buf);
939 x = (control >> 2) & 3;
940 snprintf(buf, sizeof(buf), "Clock accuracy: %d", x);
941 lcd_puts(0, line++, buf);
942 line++;
944 #ifndef SIMULATOR
945 snprintf(buf, sizeof(buf), "Measured freq: %ldHz",
946 spdif_measure_frequency());
947 lcd_puts(0, line++, buf);
948 #endif
950 lcd_update();
952 if (action_userabort(HZ/10))
953 break;
956 spdif_set_output_source(spdif_source IF_SPDIF_POWER_(, spdif_src_on));
958 #ifdef HAVE_SPDIF_POWER
959 spdif_power_enable(global_settings.spdif_enable);
960 #endif
962 return false;
964 #endif /* CPU_COLDFIRE */
966 #ifndef SIMULATOR
967 #ifdef HAVE_LCD_BITMAP
968 /* button definitions */
969 #if (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
970 (CONFIG_KEYPAD == IRIVER_H300_PAD)
971 # define DEBUG_CANCEL BUTTON_OFF
973 #elif CONFIG_KEYPAD == RECORDER_PAD
974 # define DEBUG_CANCEL BUTTON_OFF
976 #elif CONFIG_KEYPAD == ONDIO_PAD
977 # define DEBUG_CANCEL BUTTON_MENU
979 #elif (CONFIG_KEYPAD == IPOD_1G2G_PAD) || \
980 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
981 (CONFIG_KEYPAD == IPOD_4G_PAD)
982 # define DEBUG_CANCEL BUTTON_MENU
984 #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
985 # define DEBUG_CANCEL BUTTON_PLAY
987 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
988 # define DEBUG_CANCEL BUTTON_REC
990 #elif (CONFIG_KEYPAD == IRIVER_H10_PAD) || \
991 (CONFIG_KEYPAD == MROBE100_PAD)
992 # define DEBUG_CANCEL BUTTON_REW
994 #elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \
995 (CONFIG_KEYPAD == SANSA_C200_PAD)
996 # define DEBUG_CANCEL BUTTON_LEFT
997 #endif /* key definitions */
999 /* Test code!!! */
1000 bool dbg_ports(void)
1002 #if CONFIG_CPU == SH7034
1003 char buf[32];
1004 int adc_battery_voltage, adc_battery_level;
1006 lcd_setfont(FONT_SYSFIXED);
1007 lcd_setmargins(0, 0);
1008 lcd_clear_display();
1010 while(1)
1012 snprintf(buf, 32, "PADR: %04x", (unsigned short)PADR);
1013 lcd_puts(0, 0, buf);
1014 snprintf(buf, 32, "PBDR: %04x", (unsigned short)PBDR);
1015 lcd_puts(0, 1, buf);
1017 snprintf(buf, 32, "AN0: %03x AN4: %03x", adc_read(0), adc_read(4));
1018 lcd_puts(0, 2, buf);
1019 snprintf(buf, 32, "AN1: %03x AN5: %03x", adc_read(1), adc_read(5));
1020 lcd_puts(0, 3, buf);
1021 snprintf(buf, 32, "AN2: %03x AN6: %03x", adc_read(2), adc_read(6));
1022 lcd_puts(0, 4, buf);
1023 snprintf(buf, 32, "AN3: %03x AN7: %03x", adc_read(3), adc_read(7));
1024 lcd_puts(0, 5, buf);
1026 battery_read_info(&adc_battery_voltage, &adc_battery_level);
1027 snprintf(buf, 32, "Batt: %d.%03dV %d%% ", adc_battery_voltage / 1000,
1028 adc_battery_voltage % 1000, adc_battery_level);
1029 lcd_puts(0, 6, buf);
1031 lcd_update();
1032 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1033 return false;
1035 #elif defined(CPU_COLDFIRE)
1036 unsigned int gpio_out;
1037 unsigned int gpio1_out;
1038 unsigned int gpio_read;
1039 unsigned int gpio1_read;
1040 unsigned int gpio_function;
1041 unsigned int gpio1_function;
1042 unsigned int gpio_enable;
1043 unsigned int gpio1_enable;
1044 int adc_buttons, adc_remote;
1045 int adc_battery_voltage, adc_battery_level;
1046 char buf[128];
1047 int line;
1049 lcd_setmargins(0, 0);
1050 lcd_clear_display();
1051 lcd_setfont(FONT_SYSFIXED);
1053 while(1)
1055 line = 0;
1056 gpio_read = GPIO_READ;
1057 gpio1_read = GPIO1_READ;
1058 gpio_out = GPIO_OUT;
1059 gpio1_out = GPIO1_OUT;
1060 gpio_function = GPIO_FUNCTION;
1061 gpio1_function = GPIO1_FUNCTION;
1062 gpio_enable = GPIO_ENABLE;
1063 gpio1_enable = GPIO1_ENABLE;
1065 snprintf(buf, sizeof(buf), "GPIO_READ: %08x", gpio_read);
1066 lcd_puts(0, line++, buf);
1067 snprintf(buf, sizeof(buf), "GPIO_OUT: %08x", gpio_out);
1068 lcd_puts(0, line++, buf);
1069 snprintf(buf, sizeof(buf), "GPIO_FUNCTION: %08x", gpio_function);
1070 lcd_puts(0, line++, buf);
1071 snprintf(buf, sizeof(buf), "GPIO_ENABLE: %08x", gpio_enable);
1072 lcd_puts(0, line++, buf);
1074 snprintf(buf, sizeof(buf), "GPIO1_READ: %08x", gpio1_read);
1075 lcd_puts(0, line++, buf);
1076 snprintf(buf, sizeof(buf), "GPIO1_OUT: %08x", gpio1_out);
1077 lcd_puts(0, line++, buf);
1078 snprintf(buf, sizeof(buf), "GPIO1_FUNCTION: %08x", gpio1_function);
1079 lcd_puts(0, line++, buf);
1080 snprintf(buf, sizeof(buf), "GPIO1_ENABLE: %08x", gpio1_enable);
1081 lcd_puts(0, line++, buf);
1083 adc_buttons = adc_read(ADC_BUTTONS);
1084 adc_remote = adc_read(ADC_REMOTE);
1085 battery_read_info(&adc_battery_voltage, &adc_battery_level);
1086 #if defined(IAUDIO_X5) || defined(IAUDIO_M5) || defined(IRIVER_H300_SERIES)
1087 snprintf(buf, sizeof(buf), "ADC_BUTTONS (%c): %02x",
1088 button_scan_enabled() ? '+' : '-', adc_buttons);
1089 #else
1090 snprintf(buf, sizeof(buf), "ADC_BUTTONS: %02x", adc_buttons);
1091 #endif
1092 lcd_puts(0, line++, buf);
1093 #if defined(IAUDIO_X5) || defined(IAUDIO_M5)
1094 snprintf(buf, sizeof(buf), "ADC_REMOTE (%c): %02x",
1095 remote_detect() ? '+' : '-', adc_remote);
1096 #else
1097 snprintf(buf, sizeof(buf), "ADC_REMOTE: %02x", adc_remote);
1098 #endif
1099 lcd_puts(0, line++, buf);
1100 #if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES)
1101 snprintf(buf, sizeof(buf), "ADC_REMOTEDETECT: %02x",
1102 adc_read(ADC_REMOTEDETECT));
1103 lcd_puts(0, line++, buf);
1104 #endif
1106 snprintf(buf, 32, "Batt: %d.%03dV %d%% ", adc_battery_voltage / 1000,
1107 adc_battery_voltage % 1000, adc_battery_level);
1108 lcd_puts(0, line++, buf);
1110 #if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES)
1111 snprintf(buf, sizeof(buf), "remotetype: %d", remote_type());
1112 lcd_puts(0, line++, buf);
1113 #endif
1115 lcd_update();
1116 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1117 return false;
1120 #elif defined(CPU_PP502x)
1122 char buf[128];
1123 int line;
1125 lcd_setmargins(0, 0);
1126 lcd_clear_display();
1127 lcd_setfont(FONT_SYSFIXED);
1129 while(1)
1131 line = 0;
1132 lcd_puts(0, line++, "GPIO STATES:");
1133 snprintf(buf, sizeof(buf), "A: %02x E: %02x I: %02x",
1134 (unsigned int)GPIOA_INPUT_VAL,
1135 (unsigned int)GPIOE_INPUT_VAL,
1136 (unsigned int)GPIOI_INPUT_VAL);
1137 lcd_puts(0, line++, buf);
1138 snprintf(buf, sizeof(buf), "B: %02x F: %02x J: %02x",
1139 (unsigned int)GPIOB_INPUT_VAL,
1140 (unsigned int)GPIOF_INPUT_VAL,
1141 (unsigned int)GPIOJ_INPUT_VAL);
1142 lcd_puts(0, line++, buf);
1143 snprintf(buf, sizeof(buf), "C: %02x G: %02x K: %02x",
1144 (unsigned int)GPIOC_INPUT_VAL,
1145 (unsigned int)GPIOG_INPUT_VAL,
1146 (unsigned int)GPIOK_INPUT_VAL);
1147 lcd_puts(0, line++, buf);
1148 snprintf(buf, sizeof(buf), "D: %02x H: %02x L: %02x",
1149 (unsigned int)GPIOD_INPUT_VAL,
1150 (unsigned int)GPIOH_INPUT_VAL,
1151 (unsigned int)GPIOL_INPUT_VAL);
1152 lcd_puts(0, line++, buf);
1153 line++;
1154 snprintf(buf, sizeof(buf), "GPO32_VAL: %08lx", GPO32_VAL);
1155 lcd_puts(0, line++, buf);
1156 snprintf(buf, sizeof(buf), "GPO32_EN: %08lx", GPO32_ENABLE);
1157 lcd_puts(0, line++, buf);
1158 snprintf(buf, sizeof(buf), "DEV_EN: %08lx", DEV_EN);
1159 lcd_puts(0, line++, buf);
1160 snprintf(buf, sizeof(buf), "DEV_EN2: %08lx", DEV_EN2);
1161 lcd_puts(0, line++, buf);
1162 snprintf(buf, sizeof(buf), "DEV_EN3: %08lx", inl(0x60006044));
1163 lcd_puts(0, line++, buf); /* to be verified */
1164 snprintf(buf, sizeof(buf), "DEV_INIT1: %08lx", DEV_INIT1);
1165 lcd_puts(0, line++, buf);
1166 snprintf(buf, sizeof(buf), "DEV_INIT2: %08lx", DEV_INIT2);
1167 lcd_puts(0, line++, buf);
1169 #if defined(IRIVER_H10) || defined(IRIVER_H10_5GB)
1170 line++;
1171 snprintf(buf, sizeof(buf), "BATT: %03x UNK1: %03x",
1172 adc_read(ADC_BATTERY), adc_read(ADC_UNKNOWN_1));
1173 lcd_puts(0, line++, buf);
1174 snprintf(buf, sizeof(buf), "REM: %03x PAD: %03x",
1175 adc_read(ADC_REMOTE), adc_read(ADC_SCROLLPAD));
1176 lcd_puts(0, line++, buf);
1177 #elif defined(SANSA_E200)
1178 line++;
1179 snprintf(buf, sizeof(buf), "ADC_BVDD: %4d", adc_read(ADC_BVDD));
1180 lcd_puts(0, line++, buf);
1181 snprintf(buf, sizeof(buf), "ADC_RTCSUP: %4d", adc_read(ADC_RTCSUP));
1182 lcd_puts(0, line++, buf);
1183 snprintf(buf, sizeof(buf), "ADC_UVDD: %4d", adc_read(ADC_UVDD));
1184 lcd_puts(0, line++, buf);
1185 snprintf(buf, sizeof(buf), "ADC_CHG_IN: %4d", adc_read(ADC_CHG_IN));
1186 lcd_puts(0, line++, buf);
1187 snprintf(buf, sizeof(buf), "ADC_CVDD: %4d", adc_read(ADC_CVDD));
1188 lcd_puts(0, line++, buf);
1189 snprintf(buf, sizeof(buf), "ADC_BATTEMP: %4d", adc_read(ADC_BATTEMP));
1190 lcd_puts(0, line++, buf);
1191 snprintf(buf, sizeof(buf), "ADC_MICSUP1: %4d", adc_read(ADC_MICSUP1));
1192 lcd_puts(0, line++, buf);
1193 snprintf(buf, sizeof(buf), "ADC_MICSUP2: %4d", adc_read(ADC_MICSUP2));
1194 lcd_puts(0, line++, buf);
1195 snprintf(buf, sizeof(buf), "ADC_VBE1: %4d", adc_read(ADC_VBE1));
1196 lcd_puts(0, line++, buf);
1197 snprintf(buf, sizeof(buf), "ADC_VBE2: %4d", adc_read(ADC_VBE2));
1198 lcd_puts(0, line++, buf);
1199 snprintf(buf, sizeof(buf), "ADC_I_MICSUP1:%4d", adc_read(ADC_I_MICSUP1));
1200 lcd_puts(0, line++, buf);
1201 snprintf(buf, sizeof(buf), "ADC_I_MICSUP2:%4d", adc_read(ADC_I_MICSUP2));
1202 lcd_puts(0, line++, buf);
1203 snprintf(buf, sizeof(buf), "ADC_VBAT: %4d", adc_read(ADC_VBAT));
1204 lcd_puts(0, line++, buf);
1205 #endif
1206 lcd_update();
1207 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1208 return false;
1211 #elif CONFIG_CPU == PP5002
1212 char buf[128];
1213 int line;
1215 lcd_setmargins(0, 0);
1216 lcd_clear_display();
1217 lcd_setfont(FONT_SYSFIXED);
1219 while(1)
1221 line = 0;
1222 snprintf(buf, sizeof(buf), "GPIO_A: %02x GPIO_B: %02x",
1223 (unsigned int)GPIOA_INPUT_VAL, (unsigned int)GPIOB_INPUT_VAL);
1224 lcd_puts(0, line++, buf);
1225 snprintf(buf, sizeof(buf), "GPIO_C: %02x GPIO_D: %02x",
1226 (unsigned int)GPIOC_INPUT_VAL, (unsigned int)GPIOD_INPUT_VAL);
1227 lcd_puts(0, line++, buf);
1229 snprintf(buf, sizeof(buf), "DEV_EN: %08lx", DEV_EN);
1230 lcd_puts(0, line++, buf);
1231 snprintf(buf, sizeof(buf), "CLOCK_ENABLE: %08lx", CLOCK_ENABLE);
1232 lcd_puts(0, line++, buf);
1233 snprintf(buf, sizeof(buf), "CLOCK_SOURCE: %08lx", CLOCK_SOURCE);
1234 lcd_puts(0, line++, buf);
1235 snprintf(buf, sizeof(buf), "PLL_CONTROL: %08lx", PLL_CONTROL);
1236 lcd_puts(0, line++, buf);
1237 snprintf(buf, sizeof(buf), "PLL_DIV: %08lx", PLL_DIV);
1238 lcd_puts(0, line++, buf);
1239 snprintf(buf, sizeof(buf), "PLL_MULT: %08lx", PLL_MULT);
1240 lcd_puts(0, line++, buf);
1241 snprintf(buf, sizeof(buf), "TIMING1_CTL: %08lx", TIMING1_CTL);
1242 lcd_puts(0, line++, buf);
1243 snprintf(buf, sizeof(buf), "TIMING2_CTL: %08lx", TIMING2_CTL);
1244 lcd_puts(0, line++, buf);
1246 lcd_update();
1247 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1248 return false;
1250 #else
1251 return __dbg_ports();
1252 #endif /* CPU */
1253 return false;
1255 #else /* !HAVE_LCD_BITMAP */
1256 bool dbg_ports(void)
1258 char buf[32];
1259 int button;
1260 int adc_battery_voltage;
1261 int currval = 0;
1263 lcd_clear_display();
1265 while(1)
1267 switch(currval)
1269 case 0:
1270 snprintf(buf, 32, "PADR: %04x", (unsigned short)PADR);
1271 break;
1272 case 1:
1273 snprintf(buf, 32, "PBDR: %04x", (unsigned short)PBDR);
1274 break;
1275 case 2:
1276 snprintf(buf, 32, "AN0: %03x", adc_read(0));
1277 break;
1278 case 3:
1279 snprintf(buf, 32, "AN1: %03x", adc_read(1));
1280 break;
1281 case 4:
1282 snprintf(buf, 32, "AN2: %03x", adc_read(2));
1283 break;
1284 case 5:
1285 snprintf(buf, 32, "AN3: %03x", adc_read(3));
1286 break;
1287 case 6:
1288 snprintf(buf, 32, "AN4: %03x", adc_read(4));
1289 break;
1290 case 7:
1291 snprintf(buf, 32, "AN5: %03x", adc_read(5));
1292 break;
1293 case 8:
1294 snprintf(buf, 32, "AN6: %03x", adc_read(6));
1295 break;
1296 case 9:
1297 snprintf(buf, 32, "AN7: %03x", adc_read(7));
1298 break;
1299 break;
1301 lcd_puts(0, 0, buf);
1303 battery_read_info(&adc_battery_voltage, NULL);
1304 snprintf(buf, 32, "Batt: %d.%03dV", adc_battery_voltage / 1000,
1305 adc_battery_voltage % 1000);
1306 lcd_puts(0, 1, buf);
1307 lcd_update();
1309 button = get_action(CONTEXT_SETTINGS,HZ/5);
1311 switch(button)
1313 case ACTION_STD_CANCEL:
1314 return false;
1316 case ACTION_SETTINGS_DEC:
1317 currval--;
1318 if(currval < 0)
1319 currval = 9;
1320 break;
1322 case ACTION_SETTINGS_INC:
1323 currval++;
1324 if(currval > 9)
1325 currval = 0;
1326 break;
1329 return false;
1331 #endif /* !HAVE_LCD_BITMAP */
1332 #endif /* !SIMULATOR */
1334 #if (CONFIG_RTC == RTC_PCF50605) && !defined(SIMULATOR)
1335 static bool dbg_pcf(void)
1337 char buf[128];
1338 int line;
1340 #ifdef HAVE_LCD_BITMAP
1341 lcd_setmargins(0, 0);
1342 lcd_setfont(FONT_SYSFIXED);
1343 #endif
1344 lcd_clear_display();
1346 while(1)
1348 line = 0;
1350 snprintf(buf, sizeof(buf), "DCDC1: %02x", pcf50605_read(0x1b));
1351 lcd_puts(0, line++, buf);
1352 snprintf(buf, sizeof(buf), "DCDC2: %02x", pcf50605_read(0x1c));
1353 lcd_puts(0, line++, buf);
1354 snprintf(buf, sizeof(buf), "DCDC3: %02x", pcf50605_read(0x1d));
1355 lcd_puts(0, line++, buf);
1356 snprintf(buf, sizeof(buf), "DCDC4: %02x", pcf50605_read(0x1e));
1357 lcd_puts(0, line++, buf);
1358 snprintf(buf, sizeof(buf), "DCDEC1: %02x", pcf50605_read(0x1f));
1359 lcd_puts(0, line++, buf);
1360 snprintf(buf, sizeof(buf), "DCDEC2: %02x", pcf50605_read(0x20));
1361 lcd_puts(0, line++, buf);
1362 snprintf(buf, sizeof(buf), "DCUDC1: %02x", pcf50605_read(0x21));
1363 lcd_puts(0, line++, buf);
1364 snprintf(buf, sizeof(buf), "DCUDC2: %02x", pcf50605_read(0x22));
1365 lcd_puts(0, line++, buf);
1366 snprintf(buf, sizeof(buf), "IOREGC: %02x", pcf50605_read(0x23));
1367 lcd_puts(0, line++, buf);
1368 snprintf(buf, sizeof(buf), "D1REGC: %02x", pcf50605_read(0x24));
1369 lcd_puts(0, line++, buf);
1370 snprintf(buf, sizeof(buf), "D2REGC: %02x", pcf50605_read(0x25));
1371 lcd_puts(0, line++, buf);
1372 snprintf(buf, sizeof(buf), "D3REGC: %02x", pcf50605_read(0x26));
1373 lcd_puts(0, line++, buf);
1374 snprintf(buf, sizeof(buf), "LPREG1: %02x", pcf50605_read(0x27));
1375 lcd_puts(0, line++, buf);
1377 lcd_update();
1378 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1380 return false;
1384 return false;
1386 #endif
1388 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
1389 static bool dbg_cpufreq(void)
1391 char buf[128];
1392 int line;
1393 int button;
1395 #ifdef HAVE_LCD_BITMAP
1396 lcd_setmargins(0, 0);
1397 lcd_setfont(FONT_SYSFIXED);
1398 #endif
1399 lcd_clear_display();
1401 while(1)
1403 line = 0;
1405 snprintf(buf, sizeof(buf), "Frequency: %ld", FREQ);
1406 lcd_puts(0, line++, buf);
1408 snprintf(buf, sizeof(buf), "boost_counter: %d", get_cpu_boost_counter());
1409 lcd_puts(0, line++, buf);
1411 lcd_update();
1412 button = get_action(CONTEXT_STD,HZ/10);
1414 switch(button)
1416 case ACTION_STD_PREV:
1417 cpu_boost(true);
1418 break;
1420 case ACTION_STD_NEXT:
1421 cpu_boost(false);
1422 break;
1424 case ACTION_STD_OK:
1425 while (get_cpu_boost_counter() > 0)
1426 cpu_boost(false);
1427 set_cpu_frequency(CPUFREQ_DEFAULT);
1428 break;
1430 case ACTION_STD_CANCEL:
1431 return false;
1435 return false;
1437 #endif /* HAVE_ADJUSTABLE_CPU_FREQ */
1439 #if defined(HAVE_TSC2100) && !defined(SIMULATOR)
1440 #include "tsc2100.h"
1441 char *itob(int n, int len)
1443 static char binary[64];
1444 int i,j;
1445 for (i=1, j=0;i<=len;i++)
1447 binary[j++] = n&(1<<(len-i))?'1':'0';
1448 if (i%4 == 0)
1449 binary[j++] = ' ';
1451 binary[j] = '\0';
1452 return binary;
1454 static char* tsc2100_debug_getname(int selected_item, void * data, char *buffer)
1456 int *page = (int*)data;
1457 bool reserved = false;
1458 switch (*page)
1460 case 0:
1461 if ((selected_item > 0x0a) ||
1462 (selected_item == 0x04) ||
1463 (selected_item == 0x08))
1464 reserved = true;
1465 break;
1466 case 1:
1467 if ((selected_item > 0x05) ||
1468 (selected_item == 0x02))
1469 reserved = true;
1470 break;
1471 case 2:
1472 if (selected_item > 0x1e)
1473 reserved = true;
1474 break;
1476 if (reserved)
1477 snprintf(buffer, MAX_PATH, "%02x: RESERVED", selected_item);
1478 else
1479 snprintf(buffer, MAX_PATH, "%02x: %s", selected_item,
1480 itob(tsc2100_readreg(*page, selected_item)&0xffff,16));
1481 return buffer;
1483 static int tsc2100debug_action_callback(int action, struct gui_synclist *lists)
1485 int *page = (int*)lists->data;
1486 if (action == ACTION_STD_OK)
1488 *page = (*page+1)%3;
1489 snprintf(lists->title, 32,
1490 "tsc2100 registers - Page %d", *page);
1491 return ACTION_REDRAW;
1493 return action;
1495 bool tsc2100_debug(void)
1497 int page = 0;
1498 char title[32] = "tsc2100 registers - Page 0";
1499 struct simplelist_info info;
1500 simplelist_info_init(&info, title, 32, &page);
1501 info.timeout = HZ/100;
1502 info.get_name = tsc2100_debug_getname;
1503 info.action_callback= tsc2100debug_action_callback;
1504 return simplelist_show_list(&info);
1506 #endif
1507 #ifndef SIMULATOR
1508 #ifdef HAVE_LCD_BITMAP
1510 * view_battery() shows a automatically scaled graph of the battery voltage
1511 * over time. Usable for estimating battery life / charging rate.
1512 * The power_history array is updated in power_thread of powermgmt.c.
1515 #define BAT_LAST_VAL MIN(LCD_WIDTH, POWER_HISTORY_LEN)
1516 #define BAT_YSPACE (LCD_HEIGHT - 20)
1518 static bool view_battery(void)
1520 int view = 0;
1521 int i, x, y;
1522 unsigned short maxv, minv;
1523 char buf[32];
1525 lcd_setmargins(0, 0);
1526 lcd_setfont(FONT_SYSFIXED);
1528 while(1)
1530 lcd_clear_display();
1531 switch (view) {
1532 case 0: /* voltage history graph */
1533 /* Find maximum and minimum voltage for scaling */
1534 minv = power_history[0];
1535 maxv = minv + 1;
1536 for (i = 1; i < BAT_LAST_VAL && power_history[i]; i++) {
1537 if (power_history[i] > maxv)
1538 maxv = power_history[i];
1539 if (power_history[i] < minv)
1540 minv = power_history[i];
1543 snprintf(buf, 30, "Battery %d.%03d", power_history[0] / 1000,
1544 power_history[0] % 1000);
1545 lcd_puts(0, 0, buf);
1546 snprintf(buf, 30, "scale %d.%03d-%d.%03dV",
1547 minv / 1000, minv % 1000, maxv / 1000, maxv % 1000);
1548 lcd_puts(0, 1, buf);
1550 x = 0;
1551 for (i = BAT_LAST_VAL - 1; i >= 0; i--) {
1552 y = (power_history[i] - minv) * BAT_YSPACE / (maxv - minv);
1553 lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
1554 lcd_vline(x, LCD_HEIGHT-1, 20);
1555 lcd_set_drawmode(DRMODE_SOLID);
1556 lcd_vline(x, LCD_HEIGHT-1,
1557 MIN(MAX(LCD_HEIGHT-1 - y, 20), LCD_HEIGHT-1));
1558 x++;
1561 break;
1563 case 1: /* status: */
1564 lcd_puts(0, 0, "Power status:");
1566 battery_read_info(&y, NULL);
1567 snprintf(buf, 30, "Battery: %d.%03d V", y / 1000, y % 1000);
1568 lcd_puts(0, 1, buf);
1569 #ifdef ADC_EXT_POWER
1570 y = (adc_read(ADC_EXT_POWER) * EXT_SCALE_FACTOR) / 1000;
1571 snprintf(buf, 30, "External: %d.%03d V", y / 1000, y % 1000);
1572 lcd_puts(0, 2, buf);
1573 #endif
1574 #if CONFIG_CHARGING
1575 #if CONFIG_CHARGING == CHARGING_CONTROL
1576 snprintf(buf, 30, "Chgr: %s %s",
1577 charger_inserted() ? "present" : "absent",
1578 charger_enabled ? "on" : "off");
1579 lcd_puts(0, 3, buf);
1580 snprintf(buf, 30, "short delta: %d", short_delta);
1581 lcd_puts(0, 5, buf);
1582 snprintf(buf, 30, "long delta: %d", long_delta);
1583 lcd_puts(0, 6, buf);
1584 lcd_puts(0, 7, power_message);
1585 snprintf(buf, 30, "USB Inserted: %s",
1586 usb_inserted() ? "yes" : "no");
1587 lcd_puts(0, 8, buf);
1588 #if defined IRIVER_H300_SERIES
1589 snprintf(buf, 30, "USB Charging Enabled: %s",
1590 usb_charging_enabled() ? "yes" : "no");
1591 lcd_puts(0, 9, buf);
1592 #endif
1593 #else /* CONFIG_CHARGING != CHARGING_CONTROL */
1594 #if defined IPOD_NANO || defined IPOD_VIDEO
1595 int usb_pwr = (GPIOL_INPUT_VAL & 0x10)?true:false;
1596 int ext_pwr = (GPIOL_INPUT_VAL & 0x08)?false:true;
1597 int dock = (GPIOA_INPUT_VAL & 0x10)?true:false;
1598 int charging = (GPIOB_INPUT_VAL & 0x01)?false:true;
1599 int headphone= (GPIOA_INPUT_VAL & 0x80)?true:false;
1601 snprintf(buf, 30, "USB pwr: %s",
1602 usb_pwr ? "present" : "absent");
1603 lcd_puts(0, 3, buf);
1604 snprintf(buf, 30, "EXT pwr: %s",
1605 ext_pwr ? "present" : "absent");
1606 lcd_puts(0, 4, buf);
1607 snprintf(buf, 30, "Battery: %s",
1608 charging ? "charging" : (usb_pwr||ext_pwr) ? "charged" : "discharging");
1609 lcd_puts(0, 5, buf);
1610 snprintf(buf, 30, "Dock mode: %s",
1611 dock ? "enabled" : "disabled");
1612 lcd_puts(0, 6, buf);
1613 snprintf(buf, 30, "Headphone: %s",
1614 headphone ? "connected" : "disconnected");
1615 lcd_puts(0, 7, buf);
1616 #else
1617 snprintf(buf, 30, "Charger: %s",
1618 charger_inserted() ? "present" : "absent");
1619 lcd_puts(0, 3, buf);
1620 #endif
1621 #endif /* CONFIG_CHARGING != CHARGING_CONTROL */
1622 #endif /* CONFIG_CHARGING */
1623 break;
1625 case 2: /* voltage deltas: */
1626 lcd_puts(0, 0, "Voltage deltas:");
1628 for (i = 0; i <= 6; i++) {
1629 y = power_history[i] - power_history[i+1];
1630 snprintf(buf, 30, "-%d min: %s%d.%03d V", i,
1631 (y < 0) ? "-" : "", ((y < 0) ? y * -1 : y) / 1000,
1632 ((y < 0) ? y * -1 : y ) % 1000);
1633 lcd_puts(0, i+1, buf);
1635 break;
1637 case 3: /* remaining time estimation: */
1639 #if CONFIG_CHARGING == CHARGING_CONTROL
1640 snprintf(buf, 30, "charge_state: %d", charge_state);
1641 lcd_puts(0, 0, buf);
1643 snprintf(buf, 30, "Cycle time: %d m", powermgmt_last_cycle_startstop_min);
1644 lcd_puts(0, 1, buf);
1646 snprintf(buf, 30, "Lvl@cyc st: %d%%", powermgmt_last_cycle_level);
1647 lcd_puts(0, 2, buf);
1649 snprintf(buf, 30, "P=%2d I=%2d", pid_p, pid_i);
1650 lcd_puts(0, 3, buf);
1652 snprintf(buf, 30, "Trickle sec: %d/60", trickle_sec);
1653 lcd_puts(0, 4, buf);
1654 #endif /* CONFIG_CHARGING == CHARGING_CONTROL */
1656 snprintf(buf, 30, "Last PwrHist: %d.%03dV",
1657 power_history[0] / 1000,
1658 power_history[0] % 1000);
1659 lcd_puts(0, 5, buf);
1661 snprintf(buf, 30, "battery level: %d%%", battery_level());
1662 lcd_puts(0, 6, buf);
1664 snprintf(buf, 30, "Est. remain: %d m", battery_time());
1665 lcd_puts(0, 7, buf);
1666 break;
1669 lcd_update();
1671 switch(get_action(CONTEXT_SETTINGS,HZ/2))
1673 case ACTION_SETTINGS_DEC:
1674 if (view)
1675 view--;
1676 break;
1678 case ACTION_SETTINGS_INC:
1679 if (view < 3)
1680 view++;
1681 break;
1683 case ACTION_STD_CANCEL:
1684 return false;
1687 return false;
1690 #endif /* HAVE_LCD_BITMAP */
1691 #endif
1693 #ifndef SIMULATOR
1694 #if defined(HAVE_MMC) || defined(HAVE_HOTSWAP)
1695 #if defined(HAVE_MMC)
1696 #define CARDTYPE "MMC"
1697 #else
1698 #define CARDTYPE "microSD"
1699 #endif
1700 static int disk_callback(int btn, struct gui_synclist *lists)
1702 tCardInfo *card;
1703 int *cardnum = (int*)lists->data;
1704 unsigned char card_name[7];
1705 unsigned char pbuf[32];
1706 char *title = lists->title;
1707 static const unsigned char i_vmin[] = { 0, 1, 5, 10, 25, 35, 60, 100 };
1708 static const unsigned char i_vmax[] = { 1, 5, 10, 25, 35, 45, 80, 200 };
1709 static const unsigned char *kbit_units[] = { "kBit/s", "MBit/s", "GBit/s" };
1710 static const unsigned char *nsec_units[] = { "ns", "�s", "ms" };
1711 static const char *spec_vers[] = { "1.0-1.2", "1.4", "2.0-2.2",
1712 "3.1-3.31", "4.0" };
1713 if ((btn == ACTION_STD_OK) || (btn == SYS_FS_CHANGED) || (btn == ACTION_REDRAW))
1715 if (btn == ACTION_STD_OK)
1717 *cardnum ^= 0x1; /* change cards */
1720 simplelist_set_line_count(0);
1722 card = card_get_info(*cardnum);
1724 if (card->initialized > 0)
1726 card_name[6] = '\0';
1727 strncpy(card_name, ((unsigned char*)card->cid) + 3, 6);
1728 simplelist_addline(SIMPLELIST_ADD_LINE,
1729 "%s Rev %d.%d", card_name,
1730 (int) card_extract_bits(card->cid, 72, 4),
1731 (int) card_extract_bits(card->cid, 76, 4));
1732 simplelist_addline(SIMPLELIST_ADD_LINE,
1733 "Prod: %d/%d",
1734 (int) card_extract_bits(card->cid, 112, 4),
1735 (int) card_extract_bits(card->cid, 116, 4) + 1997);
1736 simplelist_addline(SIMPLELIST_ADD_LINE,
1737 "Ser#: 0x%08lx",
1738 card_extract_bits(card->cid, 80, 32));
1739 simplelist_addline(SIMPLELIST_ADD_LINE,
1740 "M=%02x, O=%04x",
1741 (int) card_extract_bits(card->cid, 0, 8),
1742 (int) card_extract_bits(card->cid, 8, 16));
1743 int temp = card_extract_bits(card->csd, 2, 4);
1744 simplelist_addline(SIMPLELIST_ADD_LINE,
1745 CARDTYPE " v%s", temp < 5 ?
1746 spec_vers[temp] : "?.?");
1747 simplelist_addline(SIMPLELIST_ADD_LINE,
1748 "Blocks: 0x%06lx", card->numblocks);
1749 simplelist_addline(SIMPLELIST_ADD_LINE,
1750 "Blksz.: %d P:%c%c", card->blocksize,
1751 card_extract_bits(card->csd, 48, 1) ? 'R' : '-',
1752 card_extract_bits(card->csd, 106, 1) ? 'W' : '-');
1753 output_dyn_value(pbuf, sizeof pbuf, card->speed / 1000,
1754 kbit_units, false);
1755 simplelist_addline(SIMPLELIST_ADD_LINE,
1756 "Speed: %s", pbuf);
1757 output_dyn_value(pbuf, sizeof pbuf, card->tsac,
1758 nsec_units, false);
1759 simplelist_addline(SIMPLELIST_ADD_LINE,
1760 "Tsac: %s", pbuf);
1761 simplelist_addline(SIMPLELIST_ADD_LINE,
1762 "Nsac: %d clk", card->nsac);
1763 simplelist_addline(SIMPLELIST_ADD_LINE,
1764 "R2W: *%d", card->r2w_factor);
1765 simplelist_addline(SIMPLELIST_ADD_LINE,
1766 "IRmax: %d..%d mA",
1767 i_vmin[card_extract_bits(card->csd, 66, 3)],
1768 i_vmax[card_extract_bits(card->csd, 69, 3)]);
1769 simplelist_addline(SIMPLELIST_ADD_LINE,
1770 "IWmax: %d..%d mA",
1771 i_vmin[card_extract_bits(card->csd, 72, 3)],
1772 i_vmax[card_extract_bits(card->csd, 75, 3)]);
1774 else if (card->initialized == 0)
1776 simplelist_addline(SIMPLELIST_ADD_LINE, "Not Found!");
1778 #ifndef HAVE_MMC
1779 else /* card->initialized < 0 */
1781 simplelist_addline(SIMPLELIST_ADD_LINE, "Init Error! (%d)", card->initialized);
1783 #endif
1784 snprintf(title, 16, "[" CARDTYPE " %d]", *cardnum);
1785 gui_synclist_set_title(lists, title, Icon_NOICON);
1786 gui_synclist_set_nb_items(lists, simplelist_get_line_count());
1787 gui_synclist_select_item(lists, 0);
1788 btn = ACTION_REDRAW;
1790 return btn;
1792 #else /* !defined(HAVE_MMC) && !defined(HAVE_HOTSWAP) */
1793 static int disk_callback(int btn, struct gui_synclist *lists)
1795 (void)lists;
1796 int i;
1797 char buf[128];
1798 unsigned short* identify_info = ata_get_identify();
1799 bool timing_info_present = false;
1800 (void)btn;
1802 simplelist_set_line_count(0);
1804 for (i=0; i < 20; i++)
1805 ((unsigned short*)buf)[i]=htobe16(identify_info[i+27]);
1806 buf[40]=0;
1807 /* kill trailing space */
1808 for (i=39; i && buf[i]==' '; i--)
1809 buf[i] = 0;
1810 simplelist_addline(SIMPLELIST_ADD_LINE, "Model: %s", buf);
1811 for (i=0; i < 4; i++)
1812 ((unsigned short*)buf)[i]=htobe16(identify_info[i+23]);
1813 buf[8]=0;
1814 simplelist_addline(SIMPLELIST_ADD_LINE,
1815 "Firmware: %s", buf);
1816 snprintf(buf, sizeof buf, "%ld MB",
1817 ((unsigned long)identify_info[61] << 16 |
1818 (unsigned long)identify_info[60]) / 2048 );
1819 simplelist_addline(SIMPLELIST_ADD_LINE,
1820 "Size: %s", buf);
1821 unsigned long free;
1822 fat_size( IF_MV2(0,) NULL, &free );
1823 simplelist_addline(SIMPLELIST_ADD_LINE,
1824 "Free: %ld MB", free / 1024);
1825 simplelist_addline(SIMPLELIST_ADD_LINE,
1826 "Spinup time: %d ms", ata_spinup_time * (1000/HZ));
1827 i = identify_info[83] & (1<<3);
1828 simplelist_addline(SIMPLELIST_ADD_LINE,
1829 "Power mgmt: %s", i ? "enabled" : "unsupported");
1830 i = identify_info[83] & (1<<9);
1831 simplelist_addline(SIMPLELIST_ADD_LINE,
1832 "Noise mgmt: %s", i ? "enabled" : "unsupported");
1833 i = identify_info[82] & (1<<6);
1834 simplelist_addline(SIMPLELIST_ADD_LINE,
1835 "Read-ahead: %s", i ? "enabled" : "unsupported");
1836 timing_info_present = identify_info[53] & (1<<1);
1837 if(timing_info_present) {
1838 char pio3[2], pio4[2];pio3[1] = 0;
1839 pio4[1] = 0;
1840 pio3[0] = (identify_info[64] & (1<<0)) ? '3' : 0;
1841 pio4[0] = (identify_info[64] & (1<<1)) ? '4' : 0;
1842 simplelist_addline(SIMPLELIST_ADD_LINE,
1843 "PIO modes: 0 1 2 %s %s", pio3, pio4);
1845 else {
1846 simplelist_addline(SIMPLELIST_ADD_LINE,
1847 "No PIO mode info");
1849 timing_info_present = identify_info[53] & (1<<1);
1850 if(timing_info_present) {
1851 simplelist_addline(SIMPLELIST_ADD_LINE,
1852 "Cycle times %dns/%dns",
1853 identify_info[67],
1854 identify_info[68] );
1855 } else {
1856 simplelist_addline(SIMPLELIST_ADD_LINE,
1857 "No timing info");
1859 timing_info_present = identify_info[53] & (1<<1);
1860 if(timing_info_present) {
1861 i = identify_info[49] & (1<<11);
1862 simplelist_addline(SIMPLELIST_ADD_LINE,
1863 "IORDY support: %s", i ? "yes" : "no");
1864 i = identify_info[49] & (1<<10);
1865 simplelist_addline(SIMPLELIST_ADD_LINE,
1866 "IORDY disable: %s", i ? "yes" : "no");
1867 } else {
1868 simplelist_addline(SIMPLELIST_ADD_LINE,
1869 "No timing info");
1871 simplelist_addline(SIMPLELIST_ADD_LINE,
1872 "Cluster size: %d bytes", fat_get_cluster_size(IF_MV(0)));
1873 return btn;
1875 #endif /* !defined(HAVE_MMC) && !defined(HAVE_HOTSWAP) */
1876 static bool dbg_disk_info(void)
1878 struct simplelist_info info;
1879 simplelist_info_init(&info, "Disk Info", 1, NULL);
1880 #if defined(HAVE_MMC) || defined(HAVE_HOTSWAP)
1881 char title[16];
1882 int card = 0;
1883 info.callback_data = (void*)&card;
1884 info.title = title;
1885 #endif
1886 info.action_callback = disk_callback;
1887 info.hide_selection = true;
1888 return simplelist_show_list(&info);
1890 #endif /* !SIMULATOR */
1892 #ifdef HAVE_DIRCACHE
1893 static int dircache_callback(int btn, struct gui_synclist *lists)
1895 (void)btn; (void)lists;
1896 simplelist_set_line_count(0);
1897 simplelist_addline(SIMPLELIST_ADD_LINE, "Cache initialized: %s",
1898 dircache_is_enabled() ? "Yes" : "No");
1899 simplelist_addline(SIMPLELIST_ADD_LINE, "Cache size: %d B",
1900 dircache_get_cache_size());
1901 simplelist_addline(SIMPLELIST_ADD_LINE, "Last size: %d B",
1902 global_status.dircache_size);
1903 simplelist_addline(SIMPLELIST_ADD_LINE, "Limit: %d B",
1904 DIRCACHE_LIMIT);
1905 simplelist_addline(SIMPLELIST_ADD_LINE, "Reserve: %d/%d B",
1906 dircache_get_reserve_used(), DIRCACHE_RESERVE);
1907 simplelist_addline(SIMPLELIST_ADD_LINE, "Scanning took: %d s",
1908 dircache_get_build_ticks() / HZ);
1909 simplelist_addline(SIMPLELIST_ADD_LINE, "Entry count: %d",
1910 dircache_get_entry_count());
1911 return btn;
1914 static bool dbg_dircache_info(void)
1916 struct simplelist_info info;
1917 simplelist_info_init(&info, "Dircache Info", 7, NULL);
1918 info.action_callback = dircache_callback;
1919 info.hide_selection = true;
1920 return simplelist_show_list(&info);
1923 #endif /* HAVE_DIRCACHE */
1925 #ifdef HAVE_TAGCACHE
1926 static int database_callback(int btn, struct gui_synclist *lists)
1928 (void)lists;
1929 struct tagcache_stat *stat = tagcache_get_stat();
1930 static bool synced = false;
1932 simplelist_set_line_count(0);
1934 simplelist_addline(SIMPLELIST_ADD_LINE, "Initialized: %s",
1935 stat->initialized ? "Yes" : "No");
1936 simplelist_addline(SIMPLELIST_ADD_LINE, "DB Ready: %s",
1937 stat->ready ? "Yes" : "No");
1938 simplelist_addline(SIMPLELIST_ADD_LINE, "RAM Cache: %s",
1939 stat->ramcache ? "Yes" : "No");
1940 simplelist_addline(SIMPLELIST_ADD_LINE, "RAM: %d/%d B",
1941 stat->ramcache_used, stat->ramcache_allocated);
1942 simplelist_addline(SIMPLELIST_ADD_LINE, "Progress: %d%% (%d entries)",
1943 stat->progress, stat->processed_entries);
1944 simplelist_addline(SIMPLELIST_ADD_LINE, "Curfile: %s",
1945 stat->curentry ? stat->curentry : "---");
1946 simplelist_addline(SIMPLELIST_ADD_LINE, "Commit step: %d",
1947 stat->commit_step);
1948 simplelist_addline(SIMPLELIST_ADD_LINE, "Commit delayed: %s",
1949 stat->commit_delayed ? "Yes" : "No");
1951 simplelist_addline(SIMPLELIST_ADD_LINE, "Queue length: %d",
1952 stat->queue_length);
1954 if (synced)
1956 synced = false;
1957 tagcache_screensync_event();
1960 if (!btn && stat->curentry)
1962 synced = true;
1963 return ACTION_REDRAW;
1966 if (btn == ACTION_STD_CANCEL)
1967 tagcache_screensync_enable(false);
1969 return btn;
1971 static bool dbg_tagcache_info(void)
1973 struct simplelist_info info;
1974 simplelist_info_init(&info, "Database Info", 8, NULL);
1975 info.action_callback = database_callback;
1976 info.hide_selection = true;
1978 /* Don't do nonblock here, must give enough processing time
1979 for tagcache thread. */
1980 /* info.timeout = TIMEOUT_NOBLOCK; */
1981 info.timeout = 1;
1982 tagcache_screensync_enable(true);
1983 return simplelist_show_list(&info);
1985 #endif
1987 #if CONFIG_CPU == SH7034
1988 static bool dbg_save_roms(void)
1990 int fd;
1991 int oldmode = system_memory_guard(MEMGUARD_NONE);
1993 fd = creat("/internal_rom_0000-FFFF.bin");
1994 if(fd >= 0)
1996 write(fd, (void *)0, 0x10000);
1997 close(fd);
2000 fd = creat("/internal_rom_2000000-203FFFF.bin");
2001 if(fd >= 0)
2003 write(fd, (void *)0x2000000, 0x40000);
2004 close(fd);
2007 system_memory_guard(oldmode);
2008 return false;
2010 #elif defined CPU_COLDFIRE
2011 static bool dbg_save_roms(void)
2013 int fd;
2014 int oldmode = system_memory_guard(MEMGUARD_NONE);
2016 #if defined(IRIVER_H100_SERIES)
2017 fd = creat("/internal_rom_000000-1FFFFF.bin");
2018 #elif defined(IRIVER_H300_SERIES)
2019 fd = creat("/internal_rom_000000-3FFFFF.bin");
2020 #elif defined(IAUDIO_X5) || defined(IAUDIO_M5)
2021 fd = creat("/internal_rom_000000-3FFFFF.bin");
2022 #endif
2023 if(fd >= 0)
2025 write(fd, (void *)0, FLASH_SIZE);
2026 close(fd);
2028 system_memory_guard(oldmode);
2030 #ifdef HAVE_EEPROM
2031 fd = creat("/internal_eeprom.bin");
2032 if (fd >= 0)
2034 int old_irq_level;
2035 char buf[EEPROM_SIZE];
2036 int err;
2038 old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL);
2040 err = eeprom_24cxx_read(0, buf, sizeof buf);
2041 if (err)
2042 gui_syncsplash(HZ*3, "Eeprom read failure (%d)",err);
2043 else
2045 write(fd, buf, sizeof buf);
2048 set_irq_level(old_irq_level);
2050 close(fd);
2052 #endif
2054 return false;
2056 #elif defined(CPU_PP) && !(defined(SANSA_E200) || defined(SANSA_C200))
2057 static bool dbg_save_roms(void)
2059 int fd;
2061 fd = creat("/internal_rom_000000-0FFFFF.bin");
2062 if(fd >= 0)
2064 write(fd, (void *)0x20000000, FLASH_SIZE);
2065 close(fd);
2068 return false;
2070 #endif /* CPU */
2072 #ifndef SIMULATOR
2073 #if CONFIG_TUNER
2074 static int radio_callback(int btn, struct gui_synclist *lists)
2076 (void)lists;
2077 if (btn == ACTION_STD_CANCEL)
2078 return btn;
2079 simplelist_set_line_count(1);
2081 #if (CONFIG_TUNER & LV24020LP)
2082 simplelist_addline(SIMPLELIST_ADD_LINE,
2083 "CTRL_STAT: %02X", lv24020lp_get(LV24020LP_CTRL_STAT) );
2084 simplelist_addline(SIMPLELIST_ADD_LINE,
2085 "RADIO_STAT: %02X", lv24020lp_get(LV24020LP_REG_STAT) );
2086 simplelist_addline(SIMPLELIST_ADD_LINE,
2087 "MSS_FM: %d kHz", lv24020lp_get(LV24020LP_MSS_FM) );
2088 simplelist_addline(SIMPLELIST_ADD_LINE,
2089 "MSS_IF: %d Hz", lv24020lp_get(LV24020LP_MSS_IF) );
2090 simplelist_addline(SIMPLELIST_ADD_LINE,
2091 "MSS_SD: %d Hz", lv24020lp_get(LV24020LP_MSS_SD) );
2092 simplelist_addline(SIMPLELIST_ADD_LINE,
2093 "if_set: %d Hz", lv24020lp_get(LV24020LP_IF_SET) );
2094 simplelist_addline(SIMPLELIST_ADD_LINE,
2095 "sd_set: %d Hz", lv24020lp_get(LV24020LP_SD_SET) );
2096 #endif
2097 #if (CONFIG_TUNER & S1A0903X01)
2098 simplelist_addline(SIMPLELIST_ADD_LINE,
2099 "Samsung regs: %08X", s1a0903x01_get(RADIO_ALL));
2100 /* This one doesn't return dynamic data atm */
2101 #endif
2102 #if (CONFIG_TUNER & TEA5767)
2103 struct tea5767_dbg_info nfo;
2104 tea5767_dbg_info(&nfo);
2105 simplelist_addline(SIMPLELIST_ADD_LINE, "Philips regs:");
2106 simplelist_addline(SIMPLELIST_ADD_LINE,
2107 " Read: %02X %02X %02X %02X %02X",
2108 (unsigned)nfo.read_regs[0], (unsigned)nfo.read_regs[1],
2109 (unsigned)nfo.read_regs[2], (unsigned)nfo.read_regs[3],
2110 (unsigned)nfo.read_regs[4]);
2111 simplelist_addline(SIMPLELIST_ADD_LINE,
2112 " Write: %02X %02X %02X %02X %02X",
2113 (unsigned)nfo.write_regs[0], (unsigned)nfo.write_regs[1],
2114 (unsigned)nfo.write_regs[2], (unsigned)nfo.write_regs[3],
2115 (unsigned)nfo.write_regs[4]);
2116 #endif
2117 return ACTION_REDRAW;
2119 static bool dbg_fm_radio(void)
2121 struct simplelist_info info;
2122 simplelist_info_init(&info, "FM Radio", 1, NULL);
2123 simplelist_set_line_count(0);
2124 simplelist_addline(SIMPLELIST_ADD_LINE, "HW detected: %s",
2125 radio_hardware_present() ? "yes" : "no");
2127 info.action_callback = radio_hardware_present()?radio_callback : NULL;
2128 info.hide_selection = true;
2129 return simplelist_show_list(&info);
2131 #endif /* CONFIG_TUNER */
2132 #endif /* !SIMULATOR */
2134 #ifdef HAVE_LCD_BITMAP
2135 extern bool do_screendump_instead_of_usb;
2137 static bool dbg_screendump(void)
2139 do_screendump_instead_of_usb = !do_screendump_instead_of_usb;
2140 gui_syncsplash(HZ, "Screendump %s",
2141 do_screendump_instead_of_usb?"enabled":"disabled");
2142 return false;
2144 #endif /* HAVE_LCD_BITMAP */
2146 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
2147 static bool dbg_set_memory_guard(void)
2149 static const struct opt_items names[MAXMEMGUARD] = {
2150 { "None", -1 },
2151 { "Flash ROM writes", -1 },
2152 { "Zero area (all)", -1 }
2154 int mode = system_memory_guard(MEMGUARD_KEEP);
2156 set_option( "Catch mem accesses", &mode, INT, names, MAXMEMGUARD, NULL);
2157 system_memory_guard(mode);
2159 return false;
2161 #endif /* CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) */
2163 #if defined(TOSHIBA_GIGABEAT_F) && !defined(SIMULATOR)
2165 extern volatile bool lcd_poweroff;
2167 static bool dbg_lcd_power_off(void)
2169 lcd_setmargins(0, 0);
2171 while(1)
2173 int button;
2175 lcd_clear_display();
2176 lcd_puts(0, 0, "LCD Power Off");
2177 if(lcd_poweroff)
2178 lcd_puts(1, 1, "Yes");
2179 else
2180 lcd_puts(1, 1, "No");
2182 lcd_update();
2184 button = get_action(CONTEXT_STD,HZ/5);
2185 switch(button)
2187 case ACTION_STD_PREV:
2188 case ACTION_STD_NEXT:
2189 lcd_poweroff = !lcd_poweroff;
2190 break;
2191 case ACTION_STD_OK:
2192 case ACTION_STD_CANCEL:
2193 return false;
2194 default:
2195 sleep(HZ/10);
2196 break;
2199 return false;
2201 #endif
2203 #if defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS)
2204 static bool dbg_write_eeprom(void)
2206 int fd;
2207 int rc;
2208 int old_irq_level;
2209 char buf[EEPROM_SIZE];
2210 int err;
2212 fd = open("/internal_eeprom.bin", O_RDONLY);
2214 if (fd >= 0)
2216 rc = read(fd, buf, EEPROM_SIZE);
2218 if(rc == EEPROM_SIZE)
2220 old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL);
2222 err = eeprom_24cxx_write(0, buf, sizeof buf);
2223 if (err)
2224 gui_syncsplash(HZ*3, "Eeprom write failure (%d)",err);
2225 else
2226 gui_syncsplash(HZ*3, "Eeprom written successfully");
2228 set_irq_level(old_irq_level);
2230 else
2232 gui_syncsplash(HZ*3, "File read error (%d)",rc);
2234 close(fd);
2236 else
2238 gui_syncsplash(HZ*3, "Failed to open 'internal_eeprom.bin'");
2241 return false;
2243 #endif /* defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS) */
2244 #ifdef CPU_BOOST_LOGGING
2245 static bool cpu_boost_log(void)
2247 int i = 0,j=0;
2248 int count = cpu_boost_log_getcount();
2249 int lines = LCD_HEIGHT/SYSFONT_HEIGHT;
2250 char *str;
2251 bool done;
2252 lcd_setmargins(0, 0);
2253 lcd_setfont(FONT_SYSFIXED);
2254 str = cpu_boost_log_getlog_first();
2255 while (i < count)
2257 lcd_clear_display();
2258 for(j=0; j<lines; j++,i++)
2260 if (!str)
2261 str = cpu_boost_log_getlog_next();
2262 if (str)
2264 lcd_puts(0, j,str);
2266 str = NULL;
2268 lcd_update();
2269 done = false;
2270 while (!done)
2272 switch(get_action(CONTEXT_STD,TIMEOUT_BLOCK))
2274 case ACTION_STD_OK:
2275 case ACTION_STD_PREV:
2276 case ACTION_STD_NEXT:
2277 done = true;
2278 break;
2279 case ACTION_STD_CANCEL:
2280 i = count;
2281 done = true;
2282 break;
2286 get_action(CONTEXT_STD,TIMEOUT_BLOCK);
2287 lcd_setfont(FONT_UI);
2288 return false;
2290 #endif
2292 #if (defined(HAVE_SCROLLWHEEL) && (CONFIG_KEYPAD==IPOD_4G_PAD) && !defined(SIMULATOR))
2293 extern bool wheel_is_touched;
2294 extern int old_wheel_value;
2295 extern int new_wheel_value;
2296 extern int wheel_delta;
2297 extern unsigned int accumulated_wheel_delta;
2298 extern unsigned int wheel_velocity;
2300 static bool dbg_scrollwheel(void)
2302 char buf[64];
2303 unsigned int speed;
2305 lcd_setmargins(0, 0);
2306 lcd_setfont(FONT_SYSFIXED);
2308 while (1)
2310 if (action_userabort(HZ/10))
2311 return false;
2313 lcd_clear_display();
2315 /* show internal variables of scrollwheel driver */
2316 snprintf(buf, sizeof(buf), "wheel touched: %s", (wheel_is_touched) ? "true" : "false");
2317 lcd_puts(0, 0, buf);
2318 snprintf(buf, sizeof(buf), "new position: %2d", new_wheel_value);
2319 lcd_puts(0, 1, buf);
2320 snprintf(buf, sizeof(buf), "old position: %2d", old_wheel_value);
2321 lcd_puts(0, 2, buf);
2322 snprintf(buf, sizeof(buf), "wheel delta: %2d", wheel_delta);
2323 lcd_puts(0, 3, buf);
2324 snprintf(buf, sizeof(buf), "accumulated delta: %2d", accumulated_wheel_delta);
2325 lcd_puts(0, 4, buf);
2326 snprintf(buf, sizeof(buf), "velo [deg/s]: %4d", (int)wheel_velocity);
2327 lcd_puts(0, 5, buf);
2329 /* show effective accelerated scrollspeed */
2330 speed = button_apply_acceleration( (1<<31)|(1<<24)|wheel_velocity);
2331 snprintf(buf, sizeof(buf), "accel. speed: %4d", speed);
2332 lcd_puts(0, 6, buf);
2334 lcd_update();
2336 return false;
2338 #endif
2341 /****** The menu *********/
2342 struct the_menu_item {
2343 unsigned char *desc; /* string or ID */
2344 bool (*function) (void); /* return true if USB was connected */
2346 static const struct the_menu_item menuitems[] = {
2347 #if defined(TOSHIBA_GIGABEAT_F) && !defined(SIMULATOR)
2348 { "LCD Power Off", dbg_lcd_power_off },
2349 #endif
2350 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || \
2351 (defined(CPU_PP) && !(defined(SANSA_E200) || defined(SANSA_C200)))
2352 { "Dump ROM contents", dbg_save_roms },
2353 #endif
2354 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || defined(CPU_PP) || CONFIG_CPU == S3C2440
2355 { "View I/O ports", dbg_ports },
2356 #endif
2357 #if (CONFIG_RTC == RTC_PCF50605) && !defined(SIMULATOR)
2358 { "View PCF registers", dbg_pcf },
2359 #endif
2360 #if defined(HAVE_TSC2100) && !defined(SIMULATOR)
2361 { "TSC2100 debug", tsc2100_debug },
2362 #endif
2363 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
2364 { "CPU frequency", dbg_cpufreq },
2365 #endif
2366 #if defined(IRIVER_H100_SERIES) && !defined(SIMULATOR)
2367 { "S/PDIF analyzer", dbg_spdif },
2368 #endif
2369 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
2370 { "Catch mem accesses", dbg_set_memory_guard },
2371 #endif
2372 { "View OS stacks", dbg_os },
2373 #ifdef HAVE_LCD_BITMAP
2374 #ifndef SIMULATOR
2375 { "View battery", view_battery },
2376 #endif
2377 { "Screendump", dbg_screendump },
2378 #endif
2379 #ifndef SIMULATOR
2380 { "View HW info", dbg_hw_info },
2381 #endif
2382 #ifndef SIMULATOR
2383 { "View partitions", dbg_partitions },
2384 #endif
2385 #ifndef SIMULATOR
2386 { "View disk info", dbg_disk_info },
2387 #endif
2388 #ifdef HAVE_DIRCACHE
2389 { "View dircache info", dbg_dircache_info },
2390 #endif
2391 #ifdef HAVE_TAGCACHE
2392 { "View database info", dbg_tagcache_info },
2393 #endif
2394 #ifdef HAVE_LCD_BITMAP
2395 #if CONFIG_CODEC == SWCODEC
2396 { "View buffering thread", dbg_buffering_thread },
2397 #elif !defined(SIMULATOR)
2398 { "View audio thread", dbg_audio_thread },
2399 #endif
2400 #ifdef PM_DEBUG
2401 { "pm histogram", peak_meter_histogram},
2402 #endif /* PM_DEBUG */
2403 #endif /* HAVE_LCD_BITMAP */
2404 #ifndef SIMULATOR
2405 #if CONFIG_TUNER
2406 { "FM Radio", dbg_fm_radio },
2407 #endif
2408 #endif
2409 #if defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS)
2410 { "Write back EEPROM", dbg_write_eeprom },
2411 #endif
2412 #ifdef ROCKBOX_HAS_LOGF
2413 {"logf", logfdisplay },
2414 {"logfdump", logfdump },
2415 #endif
2416 #ifdef CPU_BOOST_LOGGING
2417 {"cpu_boost log",cpu_boost_log},
2418 #endif
2419 #if (defined(HAVE_SCROLLWHEEL) && (CONFIG_KEYPAD==IPOD_4G_PAD) && !defined(SIMULATOR))
2420 {"Debug scrollwheel", dbg_scrollwheel},
2421 #endif
2423 static int menu_action_callback(int btn, struct gui_synclist *lists)
2425 if (btn == ACTION_STD_OK)
2427 menuitems[gui_synclist_get_sel_pos(lists)].function();
2428 btn = ACTION_REDRAW;
2430 return btn;
2432 static char* dbg_menu_getname(int item, void * data, char *buffer)
2434 (void)data; (void)buffer;
2435 return menuitems[item].desc;
2437 bool debug_menu(void)
2439 struct simplelist_info info;
2441 simplelist_info_init(&info, "Debug Menu", ARRAYLEN(menuitems), NULL);
2442 info.action_callback = menu_action_callback;
2443 info.get_name = dbg_menu_getname;
2445 return simplelist_show_list(&info);