Add a bit more debug info
[Rockbox.git] / apps / debug_menu.c
blobe95bccd838f7f19cccb7156d1c0078f25388b741
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"
91 /*---------------------------------------------------*/
92 /* SPECIAL DEBUG STUFF */
93 /*---------------------------------------------------*/
94 extern struct thread_entry threads[MAXTHREADS];
96 static char thread_status_char(unsigned status)
98 static const char thread_status_chars[THREAD_NUM_STATES+1] =
100 [0 ... THREAD_NUM_STATES] = '?',
101 [STATE_RUNNING] = 'R',
102 [STATE_BLOCKED] = 'B',
103 [STATE_SLEEPING] = 'S',
104 [STATE_BLOCKED_W_TMO] = 'T',
105 [STATE_FROZEN] = 'F',
106 [STATE_KILLED] = 'K',
109 #if NUM_CORES > 1
110 if (status == STATE_BUSY) /* Not a state index */
111 return '.';
112 #endif
114 if (status > THREAD_NUM_STATES)
115 status = THREAD_NUM_STATES;
117 return thread_status_chars[status];
120 static char* threads_getname(int selected_item, void * data, char *buffer)
122 (void)data;
123 char name[32];
124 struct thread_entry *thread = NULL;
125 unsigned status;
126 int usage;
128 #if NUM_CORES > 1
129 if (selected_item < (int)NUM_CORES)
131 usage = idle_stack_usage(selected_item);
132 snprintf(buffer, MAX_PATH, "Idle (%d): %2d%%", selected_item, usage);
133 return buffer;
136 selected_item -= NUM_CORES;
137 #endif
139 thread = &threads[selected_item];
140 status = thread_get_status(thread);
142 if (status == STATE_KILLED)
144 snprintf(buffer, MAX_PATH, "%2d: ---", selected_item);
145 return buffer;
148 thread_get_name(name, 32, thread);
149 usage = thread_stack_usage(thread);
151 snprintf(buffer, MAX_PATH,
152 "%2d: " IF_COP("(%d) ") "%c%c " IF_PRIO("%d ") "%2d%% %s",
153 selected_item,
154 IF_COP(thread->core,)
155 (status == STATE_RUNNING) ? '*' : ' ',
156 thread_status_char(status),
157 IF_PRIO(thread->priority,)
158 usage, name);
160 return buffer;
162 static int dbg_threads_action_callback(int action, struct gui_synclist *lists)
164 (void)lists;
165 #ifdef ROCKBOX_HAS_LOGF
166 if (action == ACTION_STD_OK)
168 int selpos = gui_synclist_get_sel_pos(lists);
169 #if NUM_CORES > 1
170 if (selpos >= NUM_CORES)
171 remove_thread(&threads[selpos - NUM_CORES]);
172 #else
173 remove_thread(&threads[selpos]);
174 #endif
175 return ACTION_REDRAW;
177 #endif /* ROCKBOX_HAS_LOGF */
178 return action;
180 /* Test code!!! */
181 static bool dbg_os(void)
183 struct simplelist_info info;
184 simplelist_info_init(&info, IF_COP("Core and ") "Stack usage:",
185 #if NUM_CORES == 1
186 MAXTHREADS,
187 #else
188 MAXTHREADS+NUM_CORES,
189 #endif
190 NULL);
191 #ifndef ROCKBOX_HAS_LOGF
192 info.hide_selection = true;
193 #endif
194 info.action_callback = dbg_threads_action_callback;
195 info.get_name = threads_getname;
196 return simplelist_show_list(&info);
199 #ifdef HAVE_LCD_BITMAP
200 #if CONFIG_CODEC != SWCODEC
201 #ifndef SIMULATOR
202 static bool dbg_audio_thread(void)
204 char buf[32];
205 struct audio_debug d;
207 lcd_setmargins(0, 0);
208 lcd_setfont(FONT_SYSFIXED);
210 while(1)
212 if (action_userabort(HZ/5))
213 return false;
215 audio_get_debugdata(&d);
217 lcd_clear_display();
219 snprintf(buf, sizeof(buf), "read: %x", d.audiobuf_read);
220 lcd_puts(0, 0, buf);
221 snprintf(buf, sizeof(buf), "write: %x", d.audiobuf_write);
222 lcd_puts(0, 1, buf);
223 snprintf(buf, sizeof(buf), "swap: %x", d.audiobuf_swapwrite);
224 lcd_puts(0, 2, buf);
225 snprintf(buf, sizeof(buf), "playing: %d", d.playing);
226 lcd_puts(0, 3, buf);
227 snprintf(buf, sizeof(buf), "playable: %x", d.playable_space);
228 lcd_puts(0, 4, buf);
229 snprintf(buf, sizeof(buf), "unswapped: %x", d.unswapped_space);
230 lcd_puts(0, 5, buf);
232 /* Playable space left */
233 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, 6*8, 112, 4, d.audiobuflen, 0,
234 d.playable_space, HORIZONTAL);
236 /* Show the watermark limit */
237 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, 6*8+4, 112, 4, d.audiobuflen, 0,
238 d.low_watermark_level, HORIZONTAL);
240 snprintf(buf, sizeof(buf), "wm: %x - %x",
241 d.low_watermark_level, d.lowest_watermark_level);
242 lcd_puts(0, 7, buf);
244 lcd_update();
246 return false;
248 #endif /* !SIMULATOR */
249 #else /* CONFIG_CODEC == SWCODEC */
250 extern size_t filebuflen;
251 /* This is a size_t, but call it a long so it puts a - when it's bad. */
253 static unsigned int ticks, boost_ticks;
255 static void dbg_audio_task(void)
257 #ifndef SIMULATOR
258 if(FREQ > CPUFREQ_NORMAL)
259 boost_ticks++;
260 #endif
262 ticks++;
265 static bool dbg_audio_thread(void)
267 char buf[32];
268 int button;
269 int line;
270 bool done = false;
271 size_t bufused;
272 size_t bufsize = pcmbuf_get_bufsize();
273 int pcmbufdescs = pcmbuf_descs();
275 ticks = boost_ticks = 0;
277 tick_add_task(dbg_audio_task);
279 lcd_setmargins(0, 0);
280 lcd_setfont(FONT_SYSFIXED);
281 while(!done)
283 button = get_action(CONTEXT_STD,HZ/5);
284 switch(button)
286 case ACTION_STD_NEXT:
287 audio_next();
288 break;
289 case ACTION_STD_PREV:
290 audio_prev();
291 break;
292 case ACTION_STD_CANCEL:
293 done = true;
294 break;
296 line = 0;
297 lcd_clear_display();
299 bufused = bufsize - pcmbuf_free();
301 snprintf(buf, sizeof(buf), "pcm: %7ld/%7ld", (long) bufused, (long) bufsize);
302 lcd_puts(0, line++, buf);
304 /* Playable space left */
305 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6, bufsize, 0, bufused, HORIZONTAL);
306 line++;
308 snprintf(buf, sizeof(buf), "codec: %8ld/%8ld", audio_filebufused(), (long) filebuflen);
309 lcd_puts(0, line++, buf);
311 /* Playable space left */
312 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6, filebuflen, 0,
313 audio_filebufused(), HORIZONTAL);
314 line++;
316 snprintf(buf, sizeof(buf), "track count: %2d", audio_track_count());
317 lcd_puts(0, line++, buf);
319 #ifndef SIMULATOR
320 snprintf(buf, sizeof(buf), "cpu freq: %3dMHz",
321 (int)((FREQ + 500000) / 1000000));
322 lcd_puts(0, line++, buf);
323 #endif
325 if (ticks > 0)
327 snprintf(buf, sizeof(buf), "boost ratio: %3d%%",
328 boost_ticks * 100 / ticks);
329 lcd_puts(0, line++, buf);
332 snprintf(buf, sizeof(buf), "pcmbufdesc: %2d/%2d",
333 pcmbuf_used_descs(), pcmbufdescs);
334 lcd_puts(0, line++, buf);
336 lcd_update();
339 tick_remove_task(dbg_audio_task);
341 return false;
344 static bool dbg_buffering_thread(void)
346 char buf[32];
347 int button;
348 int line;
349 bool done = false;
350 size_t bufused;
351 size_t bufsize = pcmbuf_get_bufsize();
352 struct buffering_debug d;
354 lcd_setmargins(0, 0);
355 lcd_setfont(FONT_SYSFIXED);
356 while(!done)
358 button = get_action(CONTEXT_STD,HZ/5);
359 switch(button)
361 case ACTION_STD_NEXT:
362 audio_next();
363 break;
364 case ACTION_STD_PREV:
365 audio_prev();
366 break;
367 case ACTION_STD_CANCEL:
368 done = true;
369 break;
372 buffering_get_debugdata(&d);
374 line = 0;
375 lcd_clear_display();
377 bufused = bufsize - pcmbuf_free();
379 snprintf(buf, sizeof(buf), "pcm: %7ld/%7ld", (long) bufused, (long) bufsize);
380 lcd_puts(0, line++, buf);
382 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6,
383 bufsize, 0, bufused, HORIZONTAL);
384 line++;
386 snprintf(buf, sizeof(buf), "handle count: %d", (int)d.num_handles);
387 lcd_puts(0, line++, buf);
389 snprintf(buf, sizeof(buf), "track count: %2d", audio_track_count()-1);
390 lcd_puts(0, line++, buf);
392 snprintf(buf, sizeof(buf), "data_rem: %8ld", (long)d.data_rem);
393 lcd_puts(0, line++, buf);
395 snprintf(buf, sizeof(buf), "alloc: %8ld/%8ld", audio_filebufused(),
396 (long) filebuflen);
397 lcd_puts(0, line++, buf);
399 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6,
400 filebuflen, 0, audio_filebufused(), HORIZONTAL);
401 line++;
403 snprintf(buf, sizeof(buf), "real: %8ld/%8ld", (long)d.buffered_data,
404 (long)filebuflen);
405 lcd_puts(0, line++, buf);
407 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6,
408 filebuflen, 0, d.buffered_data, HORIZONTAL);
409 line++;
411 snprintf(buf, sizeof(buf), "usefl: %8ld/%8ld",
412 (long)(d.buffered_data - d.wasted_space), (long)filebuflen);
413 lcd_puts(0, line++, buf);
415 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6,
416 filebuflen, 0, d.buffered_data - d.wasted_space,
417 HORIZONTAL);
418 line++;
420 #ifndef SIMULATOR
421 snprintf(buf, sizeof(buf), "cpu freq: %3dMHz",
422 (int)((FREQ + 500000) / 1000000));
423 lcd_puts(0, line++, buf);
424 #endif
426 lcd_update();
429 return false;
431 #endif /* CONFIG_CODEC */
432 #endif /* HAVE_LCD_BITMAP */
435 #if (CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE))
436 /* Tool function to read the flash manufacturer and type, if available.
437 Only chips which could be reprogrammed in system will return values.
438 (The mode switch addresses vary between flash manufacturers, hence addr1/2) */
439 /* In IRAM to avoid problems when running directly from Flash */
440 static bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
441 unsigned addr1, unsigned addr2)
442 ICODE_ATTR __attribute__((noinline));
443 static bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
444 unsigned addr1, unsigned addr2)
447 unsigned not_manu, not_id; /* read values before switching to ID mode */
448 unsigned manu, id; /* read values when in ID mode */
450 #if CONFIG_CPU == SH7034
451 volatile unsigned char* flash = (unsigned char*)0x2000000; /* flash mapping */
452 #elif defined(CPU_COLDFIRE)
453 volatile unsigned short* flash = (unsigned short*)0; /* flash mapping */
454 #endif
455 int old_level; /* saved interrupt level */
457 not_manu = flash[0]; /* read the normal content */
458 not_id = flash[1]; /* should be 'A' (0x41) and 'R' (0x52) from the "ARCH" marker */
460 /* disable interrupts, prevent any stray flash access */
461 old_level = set_irq_level(HIGHEST_IRQ_LEVEL);
463 flash[addr1] = 0xAA; /* enter command mode */
464 flash[addr2] = 0x55;
465 flash[addr1] = 0x90; /* ID command */
466 /* Atmel wants 20ms pause here */
467 /* sleep(HZ/50); no sleeping possible while interrupts are disabled */
469 manu = flash[0]; /* read the IDs */
470 id = flash[1];
472 flash[0] = 0xF0; /* reset flash (back to normal read mode) */
473 /* Atmel wants 20ms pause here */
474 /* sleep(HZ/50); no sleeping possible while interrupts are disabled */
476 set_irq_level(old_level); /* enable interrupts again */
478 /* I assume success if the obtained values are different from
479 the normal flash content. This is not perfectly bulletproof, they
480 could theoretically be the same by chance, causing us to fail. */
481 if (not_manu != manu || not_id != id) /* a value has changed */
483 *p_manufacturer = manu; /* return the results */
484 *p_device = id;
485 return true; /* success */
487 return false; /* fail */
489 #endif /* (CONFIG_CPU == SH7034 || CPU_COLDFIRE) */
491 #ifndef SIMULATOR
492 #ifdef CPU_PP
493 static int perfcheck(void)
495 int result;
497 asm (
498 "mrs r2, CPSR \n"
499 "orr r0, r2, #0xc0 \n" /* disable IRQ and FIQ */
500 "msr CPSR_c, r0 \n"
501 "mov %[res], #0 \n"
502 "ldr r0, [%[timr]] \n"
503 "add r0, r0, %[tmo] \n"
504 "1: \n"
505 "add %[res], %[res], #1 \n"
506 "ldr r1, [%[timr]] \n"
507 "cmp r1, r0 \n"
508 "bmi 1b \n"
509 "msr CPSR_c, r2 \n" /* reset IRQ and FIQ state */
511 [res]"=&r"(result)
513 [timr]"r"(&USEC_TIMER),
514 [tmo]"r"(
515 #if CONFIG_CPU == PP5002
516 16000
517 #else /* PP5020/5022/5024 */
518 10226
519 #endif
522 "r0", "r1", "r2"
524 return result;
526 #endif
528 #ifdef HAVE_LCD_BITMAP
529 static bool dbg_hw_info(void)
531 #if CONFIG_CPU == SH7034
532 char buf[32];
533 int bitmask = HW_MASK;
534 int rom_version = ROM_VERSION;
535 unsigned manu, id; /* flash IDs */
536 bool got_id; /* flag if we managed to get the flash IDs */
537 unsigned rom_crc = 0xffffffff; /* CRC32 of the boot ROM */
538 bool has_bootrom; /* flag for boot ROM present */
539 int oldmode; /* saved memory guard mode */
541 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
543 /* get flash ROM type */
544 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
545 if (!got_id)
546 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
548 /* check if the boot ROM area is a flash mirror */
549 has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0);
550 if (has_bootrom) /* if ROM and Flash different */
552 /* calculate CRC16 checksum of boot ROM */
553 rom_crc = crc_32((unsigned char*)0x0000, 64*1024, 0xffffffff);
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, 0, "[Hardware info]");
564 snprintf(buf, 32, "ROM: %d.%02d", rom_version/100, rom_version%100);
565 lcd_puts(0, 1, buf);
567 snprintf(buf, 32, "Mask: 0x%04x", bitmask);
568 lcd_puts(0, 2, buf);
570 if (got_id)
571 snprintf(buf, 32, "Flash: M=%02x D=%02x", manu, id);
572 else
573 snprintf(buf, 32, "Flash: M=?? D=??"); /* unknown, sorry */
574 lcd_puts(0, 3, buf);
576 if (has_bootrom)
578 if (rom_crc == 0x56DBA4EE) /* known Version 1 */
579 snprintf(buf, 32, "Boot ROM: V1");
580 else
581 snprintf(buf, 32, "ROMcrc: 0x%08x", rom_crc);
583 else
585 snprintf(buf, 32, "Boot ROM: none");
587 lcd_puts(0, 4, buf);
589 lcd_update();
591 while (!(action_userabort(TIMEOUT_BLOCK)));
593 #elif CONFIG_CPU == MCF5249 || CONFIG_CPU == MCF5250
594 char buf[32];
595 unsigned manu, id; /* flash IDs */
596 int got_id; /* flag if we managed to get the flash IDs */
597 int oldmode; /* saved memory guard mode */
598 int line = 0;
600 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
602 /* get flash ROM type */
603 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
604 if (!got_id)
605 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
607 system_memory_guard(oldmode); /* re-enable memory guard */
609 lcd_setmargins(0, 0);
610 lcd_setfont(FONT_SYSFIXED);
611 lcd_clear_display();
613 lcd_puts(0, line++, "[Hardware info]");
615 if (got_id)
616 snprintf(buf, 32, "Flash: M=%04x D=%04x", manu, id);
617 else
618 snprintf(buf, 32, "Flash: M=???? D=????"); /* unknown, sorry */
619 lcd_puts(0, line++, buf);
621 #ifdef IAUDIO_X5
623 struct ds2411_id id;
625 lcd_puts(0, ++line, "Serial Number:");
627 got_id = ds2411_read_id(&id);
629 if (got_id == DS2411_OK)
631 snprintf(buf, 32, " FC=%02x", (unsigned)id.family_code);
632 lcd_puts(0, ++line, buf);
633 snprintf(buf, 32, " ID=%02X %02X %02X %02X %02X %02X",
634 (unsigned)id.uid[0], (unsigned)id.uid[1], (unsigned)id.uid[2],
635 (unsigned)id.uid[3], (unsigned)id.uid[4], (unsigned)id.uid[5]);
636 lcd_puts(0, ++line, buf);
637 snprintf(buf, 32, " CRC=%02X", (unsigned)id.crc);
639 else
641 snprintf(buf, 32, "READ ERR=%d", got_id);
644 lcd_puts(0, ++line, buf);
646 #endif
648 lcd_update();
650 while (!(action_userabort(TIMEOUT_BLOCK)));
652 #elif defined(CPU_PP502x)
653 int line = 0;
654 char buf[32];
655 char pp_version[] = { (PP_VER2 >> 24) & 0xff, (PP_VER2 >> 16) & 0xff,
656 (PP_VER2 >> 8) & 0xff, (PP_VER2) & 0xff,
657 (PP_VER1 >> 24) & 0xff, (PP_VER1 >> 16) & 0xff,
658 (PP_VER1 >> 8) & 0xff, (PP_VER1) & 0xff, '\0' };
660 lcd_setmargins(0, 0);
661 lcd_setfont(FONT_SYSFIXED);
662 lcd_clear_display();
664 lcd_puts(0, line++, "[Hardware info]");
666 #ifdef IPOD_ARCH
667 snprintf(buf, sizeof(buf), "HW rev: 0x%08lx", IPOD_HW_REVISION);
668 lcd_puts(0, line++, buf);
669 #endif
671 #ifdef IPOD_COLOR
672 extern int lcd_type; /* Defined in lcd-colornano.c */
674 snprintf(buf, sizeof(buf), "LCD type: %d", lcd_type);
675 lcd_puts(0, line++, buf);
676 #endif
678 snprintf(buf, sizeof(buf), "PP version: %s", pp_version);
679 lcd_puts(0, line++, buf);
681 snprintf(buf, sizeof(buf), "Est. clock (kHz): %d", perfcheck());
682 lcd_puts(0, line++, buf);
684 lcd_update();
686 while (!(action_userabort(TIMEOUT_BLOCK)));
688 #elif CONFIG_CPU == PP5002
689 int line = 0;
690 char buf[32];
692 lcd_setmargins(0, 0);
693 lcd_setfont(FONT_SYSFIXED);
694 lcd_clear_display();
696 lcd_puts(0, line++, "[Hardware info]");
698 #ifdef IPOD_ARCH
699 snprintf(buf, sizeof(buf), "HW rev: 0x%08lx", IPOD_HW_REVISION);
700 lcd_puts(0, line++, buf);
701 #endif
703 snprintf(buf, sizeof(buf), "Est. clock (kHz): %d", perfcheck());
704 lcd_puts(0, line++, buf);
706 lcd_update();
708 while (!(action_userabort(TIMEOUT_BLOCK)));
710 #endif /* CONFIG_CPU */
711 return false;
713 #else /* !HAVE_LCD_BITMAP */
714 static bool dbg_hw_info(void)
716 char buf[32];
717 int button;
718 int currval = 0;
719 int rom_version = ROM_VERSION;
720 unsigned manu, id; /* flash IDs */
721 bool got_id; /* flag if we managed to get the flash IDs */
722 unsigned rom_crc = 0xffffffff; /* CRC32 of the boot ROM */
723 bool has_bootrom; /* flag for boot ROM present */
724 int oldmode; /* saved memory guard mode */
726 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
728 /* get flash ROM type */
729 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
730 if (!got_id)
731 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
733 /* check if the boot ROM area is a flash mirror */
734 has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0);
735 if (has_bootrom) /* if ROM and Flash different */
737 /* calculate CRC16 checksum of boot ROM */
738 rom_crc = crc_32((unsigned char*)0x0000, 64*1024, 0xffffffff);
741 system_memory_guard(oldmode); /* re-enable memory guard */
743 lcd_clear_display();
745 lcd_puts(0, 0, "[HW Info]");
746 while(1)
748 switch(currval)
750 case 0:
751 snprintf(buf, 32, "ROM: %d.%02d",
752 rom_version/100, rom_version%100);
753 break;
754 case 1:
755 if (got_id)
756 snprintf(buf, 32, "Flash:%02x,%02x", manu, id);
757 else
758 snprintf(buf, 32, "Flash:??,??"); /* unknown, sorry */
759 break;
760 case 2:
761 if (has_bootrom)
763 if (rom_crc == 0x56DBA4EE) /* known Version 1 */
764 snprintf(buf, 32, "BootROM: V1");
765 else if (rom_crc == 0x358099E8)
766 snprintf(buf, 32, "BootROM: V2");
767 /* alternative boot ROM found in one single player so far */
768 else
769 snprintf(buf, 32, "R: %08x", rom_crc);
771 else
772 snprintf(buf, 32, "BootROM: no");
775 lcd_puts(0, 1, buf);
776 lcd_update();
778 button = get_action(CONTEXT_SETTINGS,TIMEOUT_BLOCK);
780 switch(button)
782 case ACTION_STD_CANCEL:
783 return false;
785 case ACTION_SETTINGS_DEC:
786 currval--;
787 if(currval < 0)
788 currval = 2;
789 break;
791 case ACTION_SETTINGS_INC:
792 currval++;
793 if(currval > 2)
794 currval = 0;
795 break;
798 return false;
800 #endif /* !HAVE_LCD_BITMAP */
801 #endif /* !SIMULATOR */
803 #ifndef SIMULATOR
804 static char* dbg_partitions_getname(int selected_item, void * data, char *buffer)
806 (void)data;
807 int partition = selected_item/2;
808 struct partinfo* p = disk_partinfo(partition);
809 if (selected_item%2)
811 snprintf(buffer, MAX_PATH, " T:%x %ld MB", p->type, p->size / 2048);
813 else
815 snprintf(buffer, MAX_PATH, "P%d: S:%lx", partition, p->start);
817 return buffer;
820 bool dbg_partitions(void)
822 struct simplelist_info info;
823 simplelist_info_init(&info, "Partition Info", 4, NULL);
824 info.selection_size = 2;
825 info.hide_selection = true;
826 info.get_name = dbg_partitions_getname;
827 return simplelist_show_list(&info);
829 #endif
831 #if defined(CPU_COLDFIRE) && defined(HAVE_SPDIF_OUT)
832 static bool dbg_spdif(void)
834 char buf[128];
835 int line;
836 unsigned int control;
837 int x;
838 char *s;
839 int category;
840 int generation;
841 unsigned int interruptstat;
842 bool valnogood, symbolerr, parityerr;
843 bool done = false;
844 bool spdif_src_on;
845 int spdif_source = spdif_get_output_source(&spdif_src_on);
846 spdif_set_output_source(AUDIO_SRC_SPDIF IF_SPDIF_POWER_(, true));
848 lcd_setmargins(0, 0);
849 lcd_clear_display();
850 lcd_setfont(FONT_SYSFIXED);
852 #ifdef HAVE_SPDIF_POWER
853 spdif_power_enable(true); /* We need SPDIF power for both sending & receiving */
854 #endif
856 while (!done)
858 line = 0;
860 control = EBU1RCVCCHANNEL1;
861 interruptstat = INTERRUPTSTAT;
862 INTERRUPTCLEAR = 0x03c00000;
864 valnogood = (interruptstat & 0x01000000)?true:false;
865 symbolerr = (interruptstat & 0x00800000)?true:false;
866 parityerr = (interruptstat & 0x00400000)?true:false;
868 snprintf(buf, sizeof(buf), "Val: %s Sym: %s Par: %s",
869 valnogood?"--":"OK",
870 symbolerr?"--":"OK",
871 parityerr?"--":"OK");
872 lcd_puts(0, line++, buf);
874 snprintf(buf, sizeof(buf), "Status word: %08x", (int)control);
875 lcd_puts(0, line++, buf);
877 line++;
879 x = control >> 31;
880 snprintf(buf, sizeof(buf), "PRO: %d (%s)",
881 x, x?"Professional":"Consumer");
882 lcd_puts(0, line++, buf);
884 x = (control >> 30) & 1;
885 snprintf(buf, sizeof(buf), "Audio: %d (%s)",
886 x, x?"Non-PCM":"PCM");
887 lcd_puts(0, line++, buf);
889 x = (control >> 29) & 1;
890 snprintf(buf, sizeof(buf), "Copy: %d (%s)",
891 x, x?"Permitted":"Inhibited");
892 lcd_puts(0, line++, buf);
894 x = (control >> 27) & 7;
895 switch(x)
897 case 0:
898 s = "None";
899 break;
900 case 1:
901 s = "50/15us";
902 break;
903 default:
904 s = "Reserved";
905 break;
907 snprintf(buf, sizeof(buf), "Preemphasis: %d (%s)", x, s);
908 lcd_puts(0, line++, buf);
910 x = (control >> 24) & 3;
911 snprintf(buf, sizeof(buf), "Mode: %d", x);
912 lcd_puts(0, line++, buf);
914 category = (control >> 17) & 127;
915 switch(category)
917 case 0x00:
918 s = "General";
919 break;
920 case 0x40:
921 s = "Audio CD";
922 break;
923 default:
924 s = "Unknown";
926 snprintf(buf, sizeof(buf), "Category: 0x%02x (%s)", category, s);
927 lcd_puts(0, line++, buf);
929 x = (control >> 16) & 1;
930 generation = x;
931 if(((category & 0x70) == 0x10) ||
932 ((category & 0x70) == 0x40) ||
933 ((category & 0x78) == 0x38))
935 generation = !generation;
937 snprintf(buf, sizeof(buf), "Generation: %d (%s)",
938 x, generation?"Original":"No ind.");
939 lcd_puts(0, line++, buf);
941 x = (control >> 12) & 15;
942 snprintf(buf, sizeof(buf), "Source: %d", x);
943 lcd_puts(0, line++, buf);
945 x = (control >> 8) & 15;
946 switch(x)
948 case 0:
949 s = "Unspecified";
950 break;
951 case 8:
952 s = "A (Left)";
953 break;
954 case 4:
955 s = "B (Right)";
956 break;
957 default:
958 s = "";
959 break;
961 snprintf(buf, sizeof(buf), "Channel: %d (%s)", x, s);
962 lcd_puts(0, line++, buf);
964 x = (control >> 4) & 15;
965 switch(x)
967 case 0:
968 s = "44.1kHz";
969 break;
970 case 0x4:
971 s = "48kHz";
972 break;
973 case 0xc:
974 s = "32kHz";
975 break;
977 snprintf(buf, sizeof(buf), "Frequency: %d (%s)", x, s);
978 lcd_puts(0, line++, buf);
980 x = (control >> 2) & 3;
981 snprintf(buf, sizeof(buf), "Clock accuracy: %d", x);
982 lcd_puts(0, line++, buf);
983 line++;
985 #ifndef SIMULATOR
986 snprintf(buf, sizeof(buf), "Measured freq: %ldHz",
987 spdif_measure_frequency());
988 lcd_puts(0, line++, buf);
989 #endif
991 lcd_update();
993 if (action_userabort(HZ/10))
994 break;
997 spdif_set_output_source(spdif_source IF_SPDIF_POWER_(, spdif_src_on));
999 #ifdef HAVE_SPDIF_POWER
1000 spdif_power_enable(global_settings.spdif_enable);
1001 #endif
1003 return false;
1005 #endif /* CPU_COLDFIRE */
1007 #ifndef SIMULATOR
1008 #ifdef HAVE_LCD_BITMAP
1009 /* button definitions */
1010 #if (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
1011 (CONFIG_KEYPAD == IRIVER_H300_PAD)
1012 # define DEBUG_CANCEL BUTTON_OFF
1014 #elif CONFIG_KEYPAD == RECORDER_PAD
1015 # define DEBUG_CANCEL BUTTON_OFF
1017 #elif CONFIG_KEYPAD == ONDIO_PAD
1018 # define DEBUG_CANCEL BUTTON_MENU
1020 #elif (CONFIG_KEYPAD == IPOD_1G2G_PAD) || \
1021 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
1022 (CONFIG_KEYPAD == IPOD_4G_PAD)
1023 # define DEBUG_CANCEL BUTTON_MENU
1025 #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
1026 # define DEBUG_CANCEL BUTTON_PLAY
1028 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
1029 # define DEBUG_CANCEL BUTTON_REC
1031 #elif CONFIG_KEYPAD == GIGABEAT_PAD
1032 # define DEBUG_CANCEL BUTTON_A
1034 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
1035 # define DEBUG_CANCEL BUTTON_REW
1037 #elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \
1038 (CONFIG_KEYPAD == SANSA_C200_PAD)
1039 # define DEBUG_CANCEL BUTTON_LEFT
1040 #endif /* key definitios */
1042 /* Test code!!! */
1043 bool dbg_ports(void)
1045 #if CONFIG_CPU == SH7034
1046 unsigned short porta;
1047 unsigned short portb;
1048 unsigned char portc;
1049 char buf[32];
1050 int adc_battery_voltage, adc_battery_level;
1052 lcd_setfont(FONT_SYSFIXED);
1053 lcd_setmargins(0, 0);
1054 lcd_clear_display();
1056 while(1)
1058 porta = PADR;
1059 portb = PBDR;
1060 portc = PCDR;
1062 snprintf(buf, 32, "PADR: %04x", porta);
1063 lcd_puts(0, 0, buf);
1064 snprintf(buf, 32, "PBDR: %04x", portb);
1065 lcd_puts(0, 1, buf);
1067 snprintf(buf, 32, "AN0: %03x AN4: %03x", adc_read(0), adc_read(4));
1068 lcd_puts(0, 2, buf);
1069 snprintf(buf, 32, "AN1: %03x AN5: %03x", adc_read(1), adc_read(5));
1070 lcd_puts(0, 3, buf);
1071 snprintf(buf, 32, "AN2: %03x AN6: %03x", adc_read(2), adc_read(6));
1072 lcd_puts(0, 4, buf);
1073 snprintf(buf, 32, "AN3: %03x AN7: %03x", adc_read(3), adc_read(7));
1074 lcd_puts(0, 5, buf);
1076 battery_read_info(&adc_battery_voltage, &adc_battery_level);
1077 snprintf(buf, 32, "Batt: %d.%03dV %d%% ", adc_battery_voltage / 1000,
1078 adc_battery_voltage % 1000, adc_battery_level);
1079 lcd_puts(0, 6, buf);
1081 lcd_update();
1082 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1083 return false;
1085 #elif defined(CPU_COLDFIRE)
1086 unsigned int gpio_out;
1087 unsigned int gpio1_out;
1088 unsigned int gpio_read;
1089 unsigned int gpio1_read;
1090 unsigned int gpio_function;
1091 unsigned int gpio1_function;
1092 unsigned int gpio_enable;
1093 unsigned int gpio1_enable;
1094 int adc_buttons, adc_remote;
1095 int adc_battery_voltage, adc_battery_level;
1096 char buf[128];
1097 int line;
1099 lcd_setmargins(0, 0);
1100 lcd_clear_display();
1101 lcd_setfont(FONT_SYSFIXED);
1103 while(1)
1105 line = 0;
1106 gpio_read = GPIO_READ;
1107 gpio1_read = GPIO1_READ;
1108 gpio_out = GPIO_OUT;
1109 gpio1_out = GPIO1_OUT;
1110 gpio_function = GPIO_FUNCTION;
1111 gpio1_function = GPIO1_FUNCTION;
1112 gpio_enable = GPIO_ENABLE;
1113 gpio1_enable = GPIO1_ENABLE;
1115 snprintf(buf, sizeof(buf), "GPIO_READ: %08x", gpio_read);
1116 lcd_puts(0, line++, buf);
1117 snprintf(buf, sizeof(buf), "GPIO_OUT: %08x", gpio_out);
1118 lcd_puts(0, line++, buf);
1119 snprintf(buf, sizeof(buf), "GPIO_FUNCTION: %08x", gpio_function);
1120 lcd_puts(0, line++, buf);
1121 snprintf(buf, sizeof(buf), "GPIO_ENABLE: %08x", gpio_enable);
1122 lcd_puts(0, line++, buf);
1124 snprintf(buf, sizeof(buf), "GPIO1_READ: %08x", gpio1_read);
1125 lcd_puts(0, line++, buf);
1126 snprintf(buf, sizeof(buf), "GPIO1_OUT: %08x", gpio1_out);
1127 lcd_puts(0, line++, buf);
1128 snprintf(buf, sizeof(buf), "GPIO1_FUNCTION: %08x", gpio1_function);
1129 lcd_puts(0, line++, buf);
1130 snprintf(buf, sizeof(buf), "GPIO1_ENABLE: %08x", gpio1_enable);
1131 lcd_puts(0, line++, buf);
1133 adc_buttons = adc_read(ADC_BUTTONS);
1134 adc_remote = adc_read(ADC_REMOTE);
1135 battery_read_info(&adc_battery_voltage, &adc_battery_level);
1136 #if defined(IAUDIO_X5) || defined(IAUDIO_M5) || defined(IRIVER_H300_SERIES)
1137 snprintf(buf, sizeof(buf), "ADC_BUTTONS (%c): %02x",
1138 button_scan_enabled() ? '+' : '-', adc_buttons);
1139 #else
1140 snprintf(buf, sizeof(buf), "ADC_BUTTONS: %02x", adc_buttons);
1141 #endif
1142 lcd_puts(0, line++, buf);
1143 #if defined(IAUDIO_X5) || defined(IAUDIO_M5)
1144 snprintf(buf, sizeof(buf), "ADC_REMOTE (%c): %02x",
1145 remote_detect() ? '+' : '-', adc_remote);
1146 #else
1147 snprintf(buf, sizeof(buf), "ADC_REMOTE: %02x", adc_remote);
1148 #endif
1149 lcd_puts(0, line++, buf);
1150 #if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES)
1151 snprintf(buf, sizeof(buf), "ADC_REMOTEDETECT: %02x",
1152 adc_read(ADC_REMOTEDETECT));
1153 lcd_puts(0, line++, buf);
1154 #endif
1156 snprintf(buf, 32, "Batt: %d.%03dV %d%% ", adc_battery_voltage / 1000,
1157 adc_battery_voltage % 1000, adc_battery_level);
1158 lcd_puts(0, line++, buf);
1160 #if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES)
1161 snprintf(buf, sizeof(buf), "remotetype: %d", remote_type());
1162 lcd_puts(0, line++, buf);
1163 #endif
1165 lcd_update();
1166 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1167 return false;
1170 #elif defined(CPU_PP502x)
1172 unsigned int gpio_a, gpio_b, gpio_c, gpio_d;
1173 unsigned int gpio_e, gpio_f, gpio_g, gpio_h;
1174 unsigned int gpio_i, gpio_j, gpio_k, gpio_l;
1176 char buf[128];
1177 int line;
1179 lcd_setmargins(0, 0);
1180 lcd_clear_display();
1181 lcd_setfont(FONT_SYSFIXED);
1183 while(1)
1185 gpio_a = GPIOA_INPUT_VAL;
1186 gpio_b = GPIOB_INPUT_VAL;
1187 gpio_c = GPIOC_INPUT_VAL;
1189 gpio_g = GPIOG_INPUT_VAL;
1190 gpio_h = GPIOH_INPUT_VAL;
1191 gpio_i = GPIOI_INPUT_VAL;
1193 line = 0;
1194 snprintf(buf, sizeof(buf), "GPIO_A: %02x GPIO_G: %02x", gpio_a, gpio_g);
1195 lcd_puts(0, line++, buf);
1196 snprintf(buf, sizeof(buf), "GPIO_B: %02x GPIO_H: %02x", gpio_b, gpio_h);
1197 lcd_puts(0, line++, buf);
1198 snprintf(buf, sizeof(buf), "GPIO_C: %02x GPIO_I: %02x", gpio_c, gpio_i);
1199 lcd_puts(0, line++, buf);
1201 gpio_d = GPIOD_INPUT_VAL;
1202 gpio_e = GPIOE_INPUT_VAL;
1203 gpio_f = GPIOF_INPUT_VAL;
1205 gpio_j = GPIOJ_INPUT_VAL;
1206 gpio_k = GPIOK_INPUT_VAL;
1207 gpio_l = GPIOL_INPUT_VAL;
1209 snprintf(buf, sizeof(buf), "GPIO_D: %02x GPIO_J: %02x", gpio_d, gpio_j);
1210 lcd_puts(0, line++, buf);
1211 snprintf(buf, sizeof(buf), "GPIO_E: %02x GPIO_K: %02x", gpio_e, gpio_k);
1212 lcd_puts(0, line++, buf);
1213 snprintf(buf, sizeof(buf), "GPIO_F: %02x GPIO_L: %02x", gpio_f, gpio_l);
1214 lcd_puts(0, line++, buf);
1215 line++;
1217 snprintf(buf, sizeof(buf), "DEV_EN: %08lx", DEV_EN);
1218 lcd_puts(0, line++, buf);
1219 snprintf(buf, sizeof(buf), "CLOCK_SRC: %08lx", CLOCK_SOURCE);
1220 lcd_puts(0, line++, buf);
1221 snprintf(buf, sizeof(buf), "CLCD_CLK_SRC: %08lx", CLCD_CLOCK_SRC);
1222 lcd_puts(0, line++, buf);
1223 snprintf(buf, sizeof(buf), "PLL_CONTROL: %08lx", PLL_CONTROL);
1224 lcd_puts(0, line++, buf);
1225 snprintf(buf, sizeof(buf), "PLL_STATUS: %08lx", PLL_STATUS);
1226 lcd_puts(0, line++, buf);
1227 snprintf(buf, sizeof(buf), "DEV_TIMING1: %08lx", DEV_TIMING1);
1228 lcd_puts(0, line++, buf);
1230 #if defined(IRIVER_H10) || defined(IRIVER_H10_5GB)
1231 line++;
1232 snprintf(buf, sizeof(buf), "BATT: %03x UNK1: %03x", adc_read(ADC_BATTERY),
1233 adc_read(ADC_UNKNOWN_1));
1234 lcd_puts(0, line++, buf);
1235 snprintf(buf, sizeof(buf), "REM: %03x PAD: %03x", adc_read(ADC_REMOTE),
1236 adc_read(ADC_SCROLLPAD));
1237 lcd_puts(0, line++, buf);
1238 #elif defined(SANSA_E200)
1239 line++;
1240 snprintf(buf, sizeof(buf), "ADC_BVDD: %4d", adc_read(ADC_BVDD));
1241 lcd_puts(0, line++, buf);
1242 snprintf(buf, sizeof(buf), "ADC_RTCSUP: %4d", adc_read(ADC_RTCSUP));
1243 lcd_puts(0, line++, buf);
1244 snprintf(buf, sizeof(buf), "ADC_UVDD: %4d", adc_read(ADC_UVDD));
1245 lcd_puts(0, line++, buf);
1246 snprintf(buf, sizeof(buf), "ADC_CHG_IN: %4d", adc_read(ADC_CHG_IN));
1247 lcd_puts(0, line++, buf);
1248 snprintf(buf, sizeof(buf), "ADC_CVDD: %4d", adc_read(ADC_CVDD));
1249 lcd_puts(0, line++, buf);
1250 snprintf(buf, sizeof(buf), "ADC_BATTEMP: %4d", adc_read(ADC_BATTEMP));
1251 lcd_puts(0, line++, buf);
1252 snprintf(buf, sizeof(buf), "ADC_MICSUP1: %4d", adc_read(ADC_MICSUP1));
1253 lcd_puts(0, line++, buf);
1254 snprintf(buf, sizeof(buf), "ADC_MICSUP2: %4d", adc_read(ADC_MICSUP2));
1255 lcd_puts(0, line++, buf);
1256 snprintf(buf, sizeof(buf), "ADC_VBE1: %4d", adc_read(ADC_VBE1));
1257 lcd_puts(0, line++, buf);
1258 snprintf(buf, sizeof(buf), "ADC_VBE2: %4d", adc_read(ADC_VBE2));
1259 lcd_puts(0, line++, buf);
1260 snprintf(buf, sizeof(buf), "ADC_I_MICSUP1:%4d", adc_read(ADC_I_MICSUP1));
1261 lcd_puts(0, line++, buf);
1262 snprintf(buf, sizeof(buf), "ADC_I_MICSUP2:%4d", adc_read(ADC_I_MICSUP2));
1263 lcd_puts(0, line++, buf);
1264 snprintf(buf, sizeof(buf), "ADC_VBAT: %4d", adc_read(ADC_VBAT));
1265 lcd_puts(0, line++, buf);
1266 #endif
1267 lcd_update();
1268 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1269 return false;
1272 #elif CONFIG_CPU == PP5002
1273 unsigned int gpio_a, gpio_b, gpio_c, gpio_d;
1275 char buf[128];
1276 int line;
1278 lcd_setmargins(0, 0);
1279 lcd_clear_display();
1280 lcd_setfont(FONT_SYSFIXED);
1282 while(1)
1284 gpio_a = GPIOA_INPUT_VAL;
1285 gpio_b = GPIOB_INPUT_VAL;
1286 gpio_c = GPIOC_INPUT_VAL;
1287 gpio_d = GPIOD_INPUT_VAL;
1289 line = 0;
1290 snprintf(buf, sizeof(buf), "GPIO_A: %02x GPIO_B: %02x", gpio_a, gpio_b);
1291 lcd_puts(0, line++, buf);
1292 snprintf(buf, sizeof(buf), "GPIO_C: %02x GPIO_D: %02x", gpio_c, gpio_d);
1293 lcd_puts(0, line++, buf);
1295 snprintf(buf, sizeof(buf), "DEV_EN: %08lx", DEV_EN);
1296 lcd_puts(0, line++, buf);
1297 snprintf(buf, sizeof(buf), "CLOCK_ENABLE: %08lx", CLOCK_ENABLE);
1298 lcd_puts(0, line++, buf);
1299 snprintf(buf, sizeof(buf), "CLOCK_SOURCE: %08lx", CLOCK_SOURCE);
1300 lcd_puts(0, line++, buf);
1301 snprintf(buf, sizeof(buf), "PLL_CONTROL: %08lx", PLL_CONTROL);
1302 lcd_puts(0, line++, buf);
1303 snprintf(buf, sizeof(buf), "PLL_DIV: %08lx", PLL_DIV);
1304 lcd_puts(0, line++, buf);
1305 snprintf(buf, sizeof(buf), "PLL_MULT: %08lx", PLL_MULT);
1306 lcd_puts(0, line++, buf);
1307 snprintf(buf, sizeof(buf), "TIMING1_CTL: %08lx", TIMING1_CTL);
1308 lcd_puts(0, line++, buf);
1309 snprintf(buf, sizeof(buf), "TIMING2_CTL: %08lx", TIMING2_CTL);
1310 lcd_puts(0, line++, buf);
1312 lcd_update();
1313 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1314 return false;
1316 #elif CONFIG_CPU == S3C2440
1317 char buf[50];
1318 int line;
1320 lcd_setmargins(0, 0);
1321 lcd_clear_display();
1322 lcd_setfont(FONT_SYSFIXED);
1324 while(1)
1326 line = 0;
1327 snprintf(buf, sizeof(buf), "[Ports and Registers]"); lcd_puts(0, line++, buf);
1329 snprintf(buf, sizeof(buf), "GPACON: %08x GPBCON: %08x", GPACON, GPBCON); lcd_puts(0, line++, buf);
1330 snprintf(buf, sizeof(buf), "GPADAT: %08x GPBDAT: %08x", GPADAT, GPBDAT); lcd_puts(0, line++, buf);
1331 snprintf(buf, sizeof(buf), "GPAUP: %08x GPBUP: %08x", 0, GPBUP); lcd_puts(0, line++, buf);
1332 snprintf(buf, sizeof(buf), "GPCCON: %08x GPDCON: %08x", GPCCON, GPDCON); lcd_puts(0, line++, buf);
1333 snprintf(buf, sizeof(buf), "GPCDAT: %08x GPDDAT: %08x", GPCDAT, GPDDAT); lcd_puts(0, line++, buf);
1334 snprintf(buf, sizeof(buf), "GPCUP: %08x GPDUP: %08x", GPCUP, GPDUP); lcd_puts(0, line++, buf);
1336 snprintf(buf, sizeof(buf), "GPCCON: %08x GPDCON: %08x", GPCCON, GPDCON); lcd_puts(0, line++, buf);
1337 snprintf(buf, sizeof(buf), "GPCDAT: %08x GPDDAT: %08x", GPCDAT, GPDDAT); lcd_puts(0, line++, buf);
1338 snprintf(buf, sizeof(buf), "GPCUP: %08x GPDUP: %08x", GPCUP, GPDUP); lcd_puts(0, line++, buf);
1340 snprintf(buf, sizeof(buf), "GPECON: %08x GPFCON: %08x", GPECON, GPFCON); lcd_puts(0, line++, buf);
1341 snprintf(buf, sizeof(buf), "GPEDAT: %08x GPFDAT: %08x", GPEDAT, GPFDAT); lcd_puts(0, line++, buf);
1342 snprintf(buf, sizeof(buf), "GPEUP: %08x GPFUP: %08x", GPEUP, GPFUP); lcd_puts(0, line++, buf);
1344 snprintf(buf, sizeof(buf), "GPGCON: %08x GPHCON: %08x", GPGCON, GPHCON); lcd_puts(0, line++, buf);
1345 snprintf(buf, sizeof(buf), "GPGDAT: %08x GPHDAT: %08x", GPGDAT, GPHDAT); lcd_puts(0, line++, buf);
1346 snprintf(buf, sizeof(buf), "GPGUP: %08x GPHUP: %08x", GPGUP, GPHUP); lcd_puts(0, line++, buf);
1348 snprintf(buf, sizeof(buf), "GPJCON: %08x", GPJCON); lcd_puts(0, line++, buf);
1349 snprintf(buf, sizeof(buf), "GPJDAT: %08x", GPJDAT); lcd_puts(0, line++, buf);
1350 snprintf(buf, sizeof(buf), "GPJUP: %08x", GPJUP); lcd_puts(0, line++, buf);
1352 line++;
1354 snprintf(buf, sizeof(buf), "SRCPND: %08x INTMOD: %08x", SRCPND, INTMOD); lcd_puts(0, line++, buf);
1355 snprintf(buf, sizeof(buf), "INTMSK: %08x INTPND: %08x", INTMSK, INTPND); lcd_puts(0, line++, buf);
1356 snprintf(buf, sizeof(buf), "CLKCON: %08x CLKSLOW: %08x", CLKCON, CLKSLOW); lcd_puts(0, line++, buf);
1357 snprintf(buf, sizeof(buf), "MPLLCON: %08x UPLLCON: %08x", MPLLCON, UPLLCON); lcd_puts(0, line++, buf);
1358 snprintf(buf, sizeof(buf), "CLKDIVN: %08x", CLKDIVN); lcd_puts(0, line++, buf);
1360 lcd_update();
1361 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1362 return false;
1364 #endif /* CPU */
1365 return false;
1367 #else /* !HAVE_LCD_BITMAP */
1368 bool dbg_ports(void)
1370 unsigned short porta;
1371 unsigned short portb;
1372 unsigned char portc;
1373 char buf[32];
1374 int button;
1375 int adc_battery_voltage;
1376 int currval = 0;
1378 lcd_clear_display();
1380 while(1)
1382 porta = PADR;
1383 portb = PBDR;
1384 portc = PCDR;
1386 switch(currval)
1388 case 0:
1389 snprintf(buf, 32, "PADR: %04x", porta);
1390 break;
1391 case 1:
1392 snprintf(buf, 32, "PBDR: %04x", portb);
1393 break;
1394 case 2:
1395 snprintf(buf, 32, "AN0: %03x", adc_read(0));
1396 break;
1397 case 3:
1398 snprintf(buf, 32, "AN1: %03x", adc_read(1));
1399 break;
1400 case 4:
1401 snprintf(buf, 32, "AN2: %03x", adc_read(2));
1402 break;
1403 case 5:
1404 snprintf(buf, 32, "AN3: %03x", adc_read(3));
1405 break;
1406 case 6:
1407 snprintf(buf, 32, "AN4: %03x", adc_read(4));
1408 break;
1409 case 7:
1410 snprintf(buf, 32, "AN5: %03x", adc_read(5));
1411 break;
1412 case 8:
1413 snprintf(buf, 32, "AN6: %03x", adc_read(6));
1414 break;
1415 case 9:
1416 snprintf(buf, 32, "AN7: %03x", adc_read(7));
1417 break;
1418 break;
1420 lcd_puts(0, 0, buf);
1422 battery_read_info(&adc_battery_voltage, NULL);
1423 snprintf(buf, 32, "Batt: %d.%03dV", adc_battery_voltage / 1000,
1424 adc_battery_voltage % 1000);
1425 lcd_puts(0, 1, buf);
1426 lcd_update();
1428 button = get_action(CONTEXT_SETTINGS,HZ/5);
1430 switch(button)
1432 case ACTION_STD_CANCEL:
1433 return false;
1435 case ACTION_SETTINGS_DEC:
1436 currval--;
1437 if(currval < 0)
1438 currval = 9;
1439 break;
1441 case ACTION_SETTINGS_INC:
1442 currval++;
1443 if(currval > 9)
1444 currval = 0;
1445 break;
1448 return false;
1450 #endif /* !HAVE_LCD_BITMAP */
1451 #endif /* !SIMULATOR */
1453 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
1454 static bool dbg_cpufreq(void)
1456 char buf[128];
1457 int line;
1458 int button;
1460 #ifdef HAVE_LCD_BITMAP
1461 lcd_setmargins(0, 0);
1462 lcd_setfont(FONT_SYSFIXED);
1463 #endif
1464 lcd_clear_display();
1466 while(1)
1468 line = 0;
1470 snprintf(buf, sizeof(buf), "Frequency: %ld", FREQ);
1471 lcd_puts(0, line++, buf);
1473 snprintf(buf, sizeof(buf), "boost_counter: %d", get_cpu_boost_counter());
1474 lcd_puts(0, line++, buf);
1476 lcd_update();
1477 button = get_action(CONTEXT_STD,HZ/10);
1479 switch(button)
1481 case ACTION_STD_PREV:
1482 cpu_boost(true);
1483 break;
1485 case ACTION_STD_NEXT:
1486 cpu_boost(false);
1487 break;
1489 case ACTION_STD_OK:
1490 while (get_cpu_boost_counter() > 0)
1491 cpu_boost(false);
1492 set_cpu_frequency(CPUFREQ_DEFAULT);
1493 break;
1495 case ACTION_STD_CANCEL:
1496 return false;
1500 return false;
1502 #endif /* HAVE_ADJUSTABLE_CPU_FREQ */
1504 #ifndef SIMULATOR
1505 #ifdef HAVE_LCD_BITMAP
1507 * view_battery() shows a automatically scaled graph of the battery voltage
1508 * over time. Usable for estimating battery life / charging rate.
1509 * The power_history array is updated in power_thread of powermgmt.c.
1512 #define BAT_LAST_VAL MIN(LCD_WIDTH, POWER_HISTORY_LEN)
1513 #define BAT_YSPACE (LCD_HEIGHT - 20)
1515 static bool view_battery(void)
1517 int view = 0;
1518 int i, x, y;
1519 unsigned short maxv, minv;
1520 char buf[32];
1522 lcd_setmargins(0, 0);
1523 lcd_setfont(FONT_SYSFIXED);
1525 while(1)
1527 lcd_clear_display();
1528 switch (view) {
1529 case 0: /* voltage history graph */
1530 /* Find maximum and minimum voltage for scaling */
1531 minv = power_history[0];
1532 maxv = minv + 1;
1533 for (i = 1; i < BAT_LAST_VAL && power_history[i]; i++) {
1534 if (power_history[i] > maxv)
1535 maxv = power_history[i];
1536 if (power_history[i] < minv)
1537 minv = power_history[i];
1540 snprintf(buf, 30, "Battery %d.%03d", power_history[0] / 1000,
1541 power_history[0] % 1000);
1542 lcd_puts(0, 0, buf);
1543 snprintf(buf, 30, "scale %d.%03d-%d.%03dV",
1544 minv / 1000, minv % 1000, maxv / 1000, maxv % 1000);
1545 lcd_puts(0, 1, buf);
1547 x = 0;
1548 for (i = BAT_LAST_VAL - 1; i >= 0; i--) {
1549 y = (power_history[i] - minv) * BAT_YSPACE / (maxv - minv);
1550 lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
1551 lcd_vline(x, LCD_HEIGHT-1, 20);
1552 lcd_set_drawmode(DRMODE_SOLID);
1553 lcd_vline(x, LCD_HEIGHT-1,
1554 MIN(MAX(LCD_HEIGHT-1 - y, 20), LCD_HEIGHT-1));
1555 x++;
1558 break;
1560 case 1: /* status: */
1561 lcd_puts(0, 0, "Power status:");
1563 battery_read_info(&y, NULL);
1564 snprintf(buf, 30, "Battery: %d.%03d V", y / 1000, y % 1000);
1565 lcd_puts(0, 1, buf);
1566 #ifdef ADC_EXT_POWER
1567 y = (adc_read(ADC_EXT_POWER) * EXT_SCALE_FACTOR) / 1000;
1568 snprintf(buf, 30, "External: %d.%03d V", y / 1000, y % 1000);
1569 lcd_puts(0, 2, buf);
1570 #endif
1571 #if CONFIG_CHARGING
1572 #if CONFIG_CHARGING == CHARGING_CONTROL
1573 snprintf(buf, 30, "Chgr: %s %s",
1574 charger_inserted() ? "present" : "absent",
1575 charger_enabled ? "on" : "off");
1576 lcd_puts(0, 3, buf);
1577 snprintf(buf, 30, "short delta: %d", short_delta);
1578 lcd_puts(0, 5, buf);
1579 snprintf(buf, 30, "long delta: %d", long_delta);
1580 lcd_puts(0, 6, buf);
1581 lcd_puts(0, 7, power_message);
1582 snprintf(buf, 30, "USB Inserted: %s",
1583 usb_inserted() ? "yes" : "no");
1584 lcd_puts(0, 8, buf);
1585 #if defined IRIVER_H300_SERIES
1586 snprintf(buf, 30, "USB Charging Enabled: %s",
1587 usb_charging_enabled() ? "yes" : "no");
1588 lcd_puts(0, 9, buf);
1589 #endif
1590 #else /* CONFIG_CHARGING != CHARGING_CONTROL */
1591 #if defined IPOD_NANO || defined IPOD_VIDEO
1592 int usb_pwr = (GPIOL_INPUT_VAL & 0x10)?true:false;
1593 int ext_pwr = (GPIOL_INPUT_VAL & 0x08)?false:true;
1594 int dock = (GPIOA_INPUT_VAL & 0x10)?true:false;
1595 int charging = (GPIOB_INPUT_VAL & 0x01)?false:true;
1596 int headphone= (GPIOA_INPUT_VAL & 0x80)?true:false;
1598 snprintf(buf, 30, "USB pwr: %s",
1599 usb_pwr ? "present" : "absent");
1600 lcd_puts(0, 3, buf);
1601 snprintf(buf, 30, "EXT pwr: %s",
1602 ext_pwr ? "present" : "absent");
1603 lcd_puts(0, 4, buf);
1604 snprintf(buf, 30, "Battery: %s",
1605 charging ? "charging" : (usb_pwr||ext_pwr) ? "charged" : "discharging");
1606 lcd_puts(0, 5, buf);
1607 snprintf(buf, 30, "Dock mode: %s",
1608 dock ? "enabled" : "disabled");
1609 lcd_puts(0, 6, buf);
1610 snprintf(buf, 30, "Headphone: %s",
1611 headphone ? "connected" : "disconnected");
1612 lcd_puts(0, 7, buf);
1613 #else
1614 snprintf(buf, 30, "Charger: %s",
1615 charger_inserted() ? "present" : "absent");
1616 lcd_puts(0, 3, buf);
1617 #endif
1618 #endif /* CONFIG_CHARGING != CHARGING_CONTROL */
1619 #endif /* CONFIG_CHARGING */
1620 break;
1622 case 2: /* voltage deltas: */
1623 lcd_puts(0, 0, "Voltage deltas:");
1625 for (i = 0; i <= 6; i++) {
1626 y = power_history[i] - power_history[i+1];
1627 snprintf(buf, 30, "-%d min: %s%d.%03d V", i,
1628 (y < 0) ? "-" : "", ((y < 0) ? y * -1 : y) / 1000,
1629 ((y < 0) ? y * -1 : y ) % 1000);
1630 lcd_puts(0, i+1, buf);
1632 break;
1634 case 3: /* remaining time estimation: */
1636 #if CONFIG_CHARGING == CHARGING_CONTROL
1637 snprintf(buf, 30, "charge_state: %d", charge_state);
1638 lcd_puts(0, 0, buf);
1640 snprintf(buf, 30, "Cycle time: %d m", powermgmt_last_cycle_startstop_min);
1641 lcd_puts(0, 1, buf);
1643 snprintf(buf, 30, "Lvl@cyc st: %d%%", powermgmt_last_cycle_level);
1644 lcd_puts(0, 2, buf);
1646 snprintf(buf, 30, "P=%2d I=%2d", pid_p, pid_i);
1647 lcd_puts(0, 3, buf);
1649 snprintf(buf, 30, "Trickle sec: %d/60", trickle_sec);
1650 lcd_puts(0, 4, buf);
1651 #endif /* CONFIG_CHARGING == CHARGING_CONTROL */
1653 snprintf(buf, 30, "Last PwrHist: %d.%03dV",
1654 power_history[0] / 1000,
1655 power_history[0] % 1000);
1656 lcd_puts(0, 5, buf);
1658 snprintf(buf, 30, "battery level: %d%%", battery_level());
1659 lcd_puts(0, 6, buf);
1661 snprintf(buf, 30, "Est. remain: %d m", battery_time());
1662 lcd_puts(0, 7, buf);
1663 break;
1666 lcd_update();
1668 switch(get_action(CONTEXT_SETTINGS,HZ/2))
1670 case ACTION_SETTINGS_DEC:
1671 if (view)
1672 view--;
1673 break;
1675 case ACTION_SETTINGS_INC:
1676 if (view < 3)
1677 view++;
1678 break;
1680 case ACTION_STD_CANCEL:
1681 return false;
1684 return false;
1687 #endif /* HAVE_LCD_BITMAP */
1688 #endif
1690 #ifndef SIMULATOR
1691 #if defined(HAVE_MMC) || defined(HAVE_HOTSWAP)
1692 #if defined(HAVE_MMC)
1693 #define CARDTYPE "MMC"
1694 #else
1695 #define CARDTYPE "microSD"
1696 #endif
1697 static int disk_callback(int btn, struct gui_synclist *lists)
1699 tCardInfo *card;
1700 int *cardnum = (int*)lists->gui_list[SCREEN_MAIN].data;
1701 unsigned char card_name[7];
1702 unsigned char pbuf[32];
1703 char *title = lists->gui_list[SCREEN_MAIN].title;
1704 static const unsigned char i_vmin[] = { 0, 1, 5, 10, 25, 35, 60, 100 };
1705 static const unsigned char i_vmax[] = { 1, 5, 10, 25, 35, 45, 80, 200 };
1706 static const unsigned char *kbit_units[] = { "kBit/s", "MBit/s", "GBit/s" };
1707 static const unsigned char *nsec_units[] = { "ns", "�s", "ms" };
1708 static const char *spec_vers[] = { "1.0-1.2", "1.4", "2.0-2.2",
1709 "3.1-3.31", "4.0" };
1710 if ((btn == ACTION_STD_OK) || (btn == SYS_FS_CHANGED) || (btn == ACTION_REDRAW))
1712 if (btn == ACTION_STD_OK)
1714 *cardnum ^= 0x1; /* change cards */
1717 simplelist_set_line_count(0);
1719 card = card_get_info(*cardnum);
1721 if (card->initialized > 0)
1723 card_name[6] = '\0';
1724 strncpy(card_name, ((unsigned char*)card->cid) + 3, 6);
1725 simplelist_addline(SIMPLELIST_ADD_LINE,
1726 "%s Rev %d.%d", card_name,
1727 (int) card_extract_bits(card->cid, 72, 4),
1728 (int) card_extract_bits(card->cid, 76, 4));
1729 simplelist_addline(SIMPLELIST_ADD_LINE,
1730 "Prod: %d/%d",
1731 (int) card_extract_bits(card->cid, 112, 4),
1732 (int) card_extract_bits(card->cid, 116, 4) + 1997);
1733 simplelist_addline(SIMPLELIST_ADD_LINE,
1734 "Ser#: 0x%08lx",
1735 card_extract_bits(card->cid, 80, 32));
1736 simplelist_addline(SIMPLELIST_ADD_LINE,
1737 "M=%02x, O=%04x",
1738 (int) card_extract_bits(card->cid, 0, 8),
1739 (int) card_extract_bits(card->cid, 8, 16));
1740 int temp = card_extract_bits(card->csd, 2, 4);
1741 simplelist_addline(SIMPLELIST_ADD_LINE,
1742 CARDTYPE " v%s", temp < 5 ?
1743 spec_vers[temp] : "?.?");
1744 simplelist_addline(SIMPLELIST_ADD_LINE,
1745 "Blocks: 0x%06lx", card->numblocks);
1746 simplelist_addline(SIMPLELIST_ADD_LINE,
1747 "Blksz.: %d P:%c%c", card->blocksize,
1748 card_extract_bits(card->csd, 48, 1) ? 'R' : '-',
1749 card_extract_bits(card->csd, 106, 1) ? 'W' : '-');
1750 output_dyn_value(pbuf, sizeof pbuf, card->speed / 1000,
1751 kbit_units, false);
1752 simplelist_addline(SIMPLELIST_ADD_LINE,
1753 "Speed: %s", pbuf);
1754 output_dyn_value(pbuf, sizeof pbuf, card->tsac,
1755 nsec_units, false);
1756 simplelist_addline(SIMPLELIST_ADD_LINE,
1757 "Tsac: %s", pbuf);
1758 simplelist_addline(SIMPLELIST_ADD_LINE,
1759 "Nsac: %d clk", card->nsac);
1760 simplelist_addline(SIMPLELIST_ADD_LINE,
1761 "R2W: *%d", card->r2w_factor);
1762 simplelist_addline(SIMPLELIST_ADD_LINE,
1763 "IRmax: %d..%d mA",
1764 i_vmin[card_extract_bits(card->csd, 66, 3)],
1765 i_vmax[card_extract_bits(card->csd, 69, 3)]);
1766 simplelist_addline(SIMPLELIST_ADD_LINE,
1767 "IWmax: %d..%d mA",
1768 i_vmin[card_extract_bits(card->csd, 72, 3)],
1769 i_vmax[card_extract_bits(card->csd, 75, 3)]);
1771 else if (card->initialized == 0)
1773 simplelist_addline(SIMPLELIST_ADD_LINE, "Not Found!");
1775 #ifndef HAVE_MMC
1776 else /* card->initialized < 0 */
1778 simplelist_addline(SIMPLELIST_ADD_LINE, "Init Error! (%d)", card->initialized);
1780 #endif
1781 snprintf(title, 16, "[" CARDTYPE " %d]", *cardnum);
1782 gui_synclist_set_title(lists, title, Icon_NOICON);
1783 gui_synclist_set_nb_items(lists, simplelist_get_line_count());
1784 gui_synclist_select_item(lists, 0);
1785 btn = ACTION_REDRAW;
1787 return btn;
1789 #else /* !defined(HAVE_MMC) && !defined(HAVE_HOTSWAP) */
1790 static int disk_callback(int btn, struct gui_synclist *lists)
1792 (void)lists;
1793 int i;
1794 char buf[128];
1795 unsigned short* identify_info = ata_get_identify();
1796 bool timing_info_present = false;
1797 (void)btn;
1799 simplelist_set_line_count(0);
1801 for (i=0; i < 20; i++)
1802 ((unsigned short*)buf)[i]=htobe16(identify_info[i+27]);
1803 buf[40]=0;
1804 /* kill trailing space */
1805 for (i=39; i && buf[i]==' '; i--)
1806 buf[i] = 0;
1807 simplelist_addline(SIMPLELIST_ADD_LINE, "Model: %s", buf);
1808 for (i=0; i < 4; i++)
1809 ((unsigned short*)buf)[i]=htobe16(identify_info[i+23]);
1810 buf[8]=0;
1811 simplelist_addline(SIMPLELIST_ADD_LINE,
1812 "Firmware: %s", buf);
1813 snprintf(buf, sizeof buf, "%ld MB",
1814 ((unsigned long)identify_info[61] << 16 |
1815 (unsigned long)identify_info[60]) / 2048 );
1816 simplelist_addline(SIMPLELIST_ADD_LINE,
1817 "Size: %s", buf);
1818 unsigned long free;
1819 fat_size( IF_MV2(0,) NULL, &free );
1820 simplelist_addline(SIMPLELIST_ADD_LINE,
1821 "Free: %ld MB", free / 1024);
1822 simplelist_addline(SIMPLELIST_ADD_LINE,
1823 "Spinup time: %d ms", ata_spinup_time * (1000/HZ));
1824 i = identify_info[83] & (1<<3);
1825 simplelist_addline(SIMPLELIST_ADD_LINE,
1826 "Power mgmt: %s", i ? "enabled" : "unsupported");
1827 i = identify_info[83] & (1<<9);
1828 simplelist_addline(SIMPLELIST_ADD_LINE,
1829 "Noise mgmt: %s", i ? "enabled" : "unsupported");
1830 i = identify_info[82] & (1<<6);
1831 simplelist_addline(SIMPLELIST_ADD_LINE,
1832 "Read-ahead: %s", i ? "enabled" : "unsupported");
1833 timing_info_present = identify_info[53] & (1<<1);
1834 if(timing_info_present) {
1835 char pio3[2], pio4[2];pio3[1] = 0;
1836 pio4[1] = 0;
1837 pio3[0] = (identify_info[64] & (1<<0)) ? '3' : 0;
1838 pio4[0] = (identify_info[64] & (1<<1)) ? '4' : 0;
1839 simplelist_addline(SIMPLELIST_ADD_LINE,
1840 "PIO modes: 0 1 2 %s %s", pio3, pio4);
1842 else {
1843 simplelist_addline(SIMPLELIST_ADD_LINE,
1844 "No PIO mode info");
1846 timing_info_present = identify_info[53] & (1<<1);
1847 if(timing_info_present) {
1848 simplelist_addline(SIMPLELIST_ADD_LINE,
1849 "Cycle times %dns/%dns",
1850 identify_info[67],
1851 identify_info[68] );
1852 } else {
1853 simplelist_addline(SIMPLELIST_ADD_LINE,
1854 "No timing info");
1856 timing_info_present = identify_info[53] & (1<<1);
1857 if(timing_info_present) {
1858 i = identify_info[49] & (1<<11);
1859 simplelist_addline(SIMPLELIST_ADD_LINE,
1860 "IORDY support: %s", i ? "yes" : "no");
1861 i = identify_info[49] & (1<<10);
1862 simplelist_addline(SIMPLELIST_ADD_LINE,
1863 "IORDY disable: %s", i ? "yes" : "no");
1864 } else {
1865 simplelist_addline(SIMPLELIST_ADD_LINE,
1866 "No timing info");
1868 simplelist_addline(SIMPLELIST_ADD_LINE,
1869 "Cluster size: %d bytes", fat_get_cluster_size(IF_MV(0)));
1870 return btn;
1872 #endif /* !defined(HAVE_MMC) && !defined(HAVE_HOTSWAP) */
1873 static bool dbg_disk_info(void)
1875 struct simplelist_info info;
1876 simplelist_info_init(&info, "Disk Info", 1, NULL);
1877 #if defined(HAVE_MMC) || defined(HAVE_HOTSWAP)
1878 char title[16];
1879 int card = 0;
1880 info.callback_data = (void*)&card;
1881 info.title = title;
1882 #endif
1883 info.action_callback = disk_callback;
1884 info.hide_selection = true;
1885 return simplelist_show_list(&info);
1887 #endif /* !SIMULATOR */
1889 #ifdef HAVE_DIRCACHE
1890 static int dircache_callback(int btn, struct gui_synclist *lists)
1892 (void)btn; (void)lists;
1893 simplelist_set_line_count(0);
1894 simplelist_addline(SIMPLELIST_ADD_LINE, "Cache initialized: %s",
1895 dircache_is_enabled() ? "Yes" : "No");
1896 simplelist_addline(SIMPLELIST_ADD_LINE, "Cache size: %d B",
1897 dircache_get_cache_size());
1898 simplelist_addline(SIMPLELIST_ADD_LINE, "Last size: %d B",
1899 global_status.dircache_size);
1900 simplelist_addline(SIMPLELIST_ADD_LINE, "Limit: %d B",
1901 DIRCACHE_LIMIT);
1902 simplelist_addline(SIMPLELIST_ADD_LINE, "Reserve: %d/%d B",
1903 dircache_get_reserve_used(), DIRCACHE_RESERVE);
1904 simplelist_addline(SIMPLELIST_ADD_LINE, "Scanning took: %d s",
1905 dircache_get_build_ticks() / HZ);
1906 simplelist_addline(SIMPLELIST_ADD_LINE, "Entry count: %d",
1907 dircache_get_entry_count());
1908 return btn;
1911 static bool dbg_dircache_info(void)
1913 struct simplelist_info info;
1914 simplelist_info_init(&info, "Dircache Info", 7, NULL);
1915 info.action_callback = dircache_callback;
1916 info.hide_selection = true;
1917 return simplelist_show_list(&info);
1920 #endif /* HAVE_DIRCACHE */
1922 #ifdef HAVE_TAGCACHE
1923 static int database_callback(int btn, struct gui_synclist *lists)
1925 (void)lists;
1926 struct tagcache_stat *stat = tagcache_get_stat();
1927 static bool synced = false;
1929 simplelist_set_line_count(0);
1931 simplelist_addline(SIMPLELIST_ADD_LINE, "Initialized: %s",
1932 stat->initialized ? "Yes" : "No");
1933 simplelist_addline(SIMPLELIST_ADD_LINE, "DB Ready: %s",
1934 stat->ready ? "Yes" : "No");
1935 simplelist_addline(SIMPLELIST_ADD_LINE, "RAM Cache: %s",
1936 stat->ramcache ? "Yes" : "No");
1937 simplelist_addline(SIMPLELIST_ADD_LINE, "RAM: %d/%d B",
1938 stat->ramcache_used, stat->ramcache_allocated);
1939 simplelist_addline(SIMPLELIST_ADD_LINE, "Progress: %d%% (%d entries)",
1940 stat->progress, stat->processed_entries);
1941 simplelist_addline(SIMPLELIST_ADD_LINE, "Curfile: %s",
1942 stat->curentry ? stat->curentry : "---");
1943 simplelist_addline(SIMPLELIST_ADD_LINE, "Commit step: %d",
1944 stat->commit_step);
1945 simplelist_addline(SIMPLELIST_ADD_LINE, "Commit delayed: %s",
1946 stat->commit_delayed ? "Yes" : "No");
1949 if (synced)
1951 synced = false;
1952 tagcache_screensync_event();
1955 if (!btn && stat->curentry)
1957 synced = true;
1958 return ACTION_REDRAW;
1961 if (btn == ACTION_STD_CANCEL)
1962 tagcache_screensync_enable(false);
1964 return btn;
1966 static bool dbg_tagcache_info(void)
1968 struct simplelist_info info;
1969 simplelist_info_init(&info, "Database Info", 8, NULL);
1970 info.action_callback = database_callback;
1971 info.hide_selection = true;
1972 info.timeout = TIMEOUT_NOBLOCK;
1973 tagcache_screensync_enable(true);
1974 return simplelist_show_list(&info);
1976 #endif
1978 #if CONFIG_CPU == SH7034
1979 static bool dbg_save_roms(void)
1981 int fd;
1982 int oldmode = system_memory_guard(MEMGUARD_NONE);
1984 fd = creat("/internal_rom_0000-FFFF.bin");
1985 if(fd >= 0)
1987 write(fd, (void *)0, 0x10000);
1988 close(fd);
1991 fd = creat("/internal_rom_2000000-203FFFF.bin");
1992 if(fd >= 0)
1994 write(fd, (void *)0x2000000, 0x40000);
1995 close(fd);
1998 system_memory_guard(oldmode);
1999 return false;
2001 #elif defined CPU_COLDFIRE
2002 static bool dbg_save_roms(void)
2004 int fd;
2005 int oldmode = system_memory_guard(MEMGUARD_NONE);
2007 #if defined(IRIVER_H100_SERIES)
2008 fd = creat("/internal_rom_000000-1FFFFF.bin");
2009 #elif defined(IRIVER_H300_SERIES)
2010 fd = creat("/internal_rom_000000-3FFFFF.bin");
2011 #elif defined(IAUDIO_X5) || defined(IAUDIO_M5)
2012 fd = creat("/internal_rom_000000-3FFFFF.bin");
2013 #endif
2014 if(fd >= 0)
2016 write(fd, (void *)0, FLASH_SIZE);
2017 close(fd);
2019 system_memory_guard(oldmode);
2021 #ifdef HAVE_EEPROM
2022 fd = creat("/internal_eeprom.bin");
2023 if (fd >= 0)
2025 int old_irq_level;
2026 char buf[EEPROM_SIZE];
2027 int err;
2029 old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL);
2031 err = eeprom_24cxx_read(0, buf, sizeof buf);
2032 if (err)
2033 gui_syncsplash(HZ*3, "Eeprom read failure (%d)",err);
2034 else
2036 write(fd, buf, sizeof buf);
2039 set_irq_level(old_irq_level);
2041 close(fd);
2043 #endif
2045 return false;
2047 #elif defined(CPU_PP) && !(defined(SANSA_E200) || defined(SANSA_C200))
2048 static bool dbg_save_roms(void)
2050 int fd;
2052 fd = creat("/internal_rom_000000-0FFFFF.bin");
2053 if(fd >= 0)
2055 write(fd, (void *)0x20000000, FLASH_SIZE);
2056 close(fd);
2059 return false;
2061 #endif /* CPU */
2063 #ifndef SIMULATOR
2064 #if CONFIG_TUNER
2065 static int radio_callback(int btn, struct gui_synclist *lists)
2067 (void)lists;
2068 if (btn == ACTION_STD_CANCEL)
2069 return btn;
2070 simplelist_set_line_count(1);
2072 #if (CONFIG_TUNER & LV24020LP)
2073 simplelist_addline(SIMPLELIST_ADD_LINE,
2074 "CTRL_STAT: %02X", lv24020lp_get(LV24020LP_CTRL_STAT) );
2075 simplelist_addline(SIMPLELIST_ADD_LINE,
2076 "RADIO_STAT: %02X", lv24020lp_get(LV24020LP_REG_STAT) );
2077 simplelist_addline(SIMPLELIST_ADD_LINE,
2078 "MSS_FM: %d kHz", lv24020lp_get(LV24020LP_MSS_FM) );
2079 simplelist_addline(SIMPLELIST_ADD_LINE,
2080 "MSS_IF: %d Hz", lv24020lp_get(LV24020LP_MSS_IF) );
2081 simplelist_addline(SIMPLELIST_ADD_LINE,
2082 "MSS_SD: %d Hz", lv24020lp_get(LV24020LP_MSS_SD) );
2083 simplelist_addline(SIMPLELIST_ADD_LINE,
2084 "if_set: %d Hz", lv24020lp_get(LV24020LP_IF_SET) );
2085 simplelist_addline(SIMPLELIST_ADD_LINE,
2086 "sd_set: %d Hz", lv24020lp_get(LV24020LP_SD_SET) );
2087 #endif
2088 #if (CONFIG_TUNER & S1A0903X01)
2089 simplelist_addline(SIMPLELIST_ADD_LINE,
2090 "Samsung regs: %08X", s1a0903x01_get(RADIO_ALL));
2091 /* This one doesn't return dynamic data atm */
2092 #endif
2093 #if (CONFIG_TUNER & TEA5767)
2094 struct tea5767_dbg_info nfo;
2095 tea5767_dbg_info(&nfo);
2096 simplelist_addline(SIMPLELIST_ADD_LINE, "Philips regs:");
2097 simplelist_addline(SIMPLELIST_ADD_LINE,
2098 " Read: %02X %02X %02X %02X %02X",
2099 (unsigned)nfo.read_regs[0], (unsigned)nfo.read_regs[1],
2100 (unsigned)nfo.read_regs[2], (unsigned)nfo.read_regs[3],
2101 (unsigned)nfo.read_regs[4]);
2102 simplelist_addline(SIMPLELIST_ADD_LINE,
2103 " Write: %02X %02X %02X %02X %02X",
2104 (unsigned)nfo.write_regs[0], (unsigned)nfo.write_regs[1],
2105 (unsigned)nfo.write_regs[2], (unsigned)nfo.write_regs[3],
2106 (unsigned)nfo.write_regs[4]);
2107 #endif
2108 return ACTION_REDRAW;
2110 static bool dbg_fm_radio(void)
2112 struct simplelist_info info;
2113 simplelist_info_init(&info, "FM Radio", 1, NULL);
2114 simplelist_set_line_count(0);
2115 simplelist_addline(SIMPLELIST_ADD_LINE, "HW detected: %s",
2116 radio_hardware_present() ? "yes" : "no");
2118 info.action_callback = radio_hardware_present()?radio_callback : NULL;
2119 info.hide_selection = true;
2120 return simplelist_show_list(&info);
2122 #endif /* CONFIG_TUNER */
2123 #endif /* !SIMULATOR */
2125 #ifdef HAVE_LCD_BITMAP
2126 extern bool do_screendump_instead_of_usb;
2128 static bool dbg_screendump(void)
2130 do_screendump_instead_of_usb = !do_screendump_instead_of_usb;
2131 gui_syncsplash(HZ, "Screendump %s",
2132 do_screendump_instead_of_usb?"enabled":"disabled");
2133 return false;
2135 #endif /* HAVE_LCD_BITMAP */
2137 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
2138 static bool dbg_set_memory_guard(void)
2140 static const struct opt_items names[MAXMEMGUARD] = {
2141 { "None", -1 },
2142 { "Flash ROM writes", -1 },
2143 { "Zero area (all)", -1 }
2145 int mode = system_memory_guard(MEMGUARD_KEEP);
2147 set_option( "Catch mem accesses", &mode, INT, names, MAXMEMGUARD, NULL);
2148 system_memory_guard(mode);
2150 return false;
2152 #endif /* CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) */
2154 #if defined(TOSHIBA_GIGABEAT_F) && !defined(SIMULATOR)
2156 extern volatile bool lcd_poweroff;
2158 static bool dbg_lcd_power_off(void)
2160 lcd_setmargins(0, 0);
2162 while(1)
2164 int button;
2166 lcd_clear_display();
2167 lcd_puts(0, 0, "LCD Power Off");
2168 if(lcd_poweroff)
2169 lcd_puts(1, 1, "Yes");
2170 else
2171 lcd_puts(1, 1, "No");
2173 lcd_update();
2175 button = get_action(CONTEXT_STD,HZ/5);
2176 switch(button)
2178 case ACTION_STD_PREV:
2179 case ACTION_STD_NEXT:
2180 lcd_poweroff = !lcd_poweroff;
2181 break;
2182 case ACTION_STD_OK:
2183 case ACTION_STD_CANCEL:
2184 return false;
2185 default:
2186 sleep(HZ/10);
2187 break;
2190 return false;
2192 #endif
2194 #if defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS)
2195 static bool dbg_write_eeprom(void)
2197 int fd;
2198 int rc;
2199 int old_irq_level;
2200 char buf[EEPROM_SIZE];
2201 int err;
2203 fd = open("/internal_eeprom.bin", O_RDONLY);
2205 if (fd >= 0)
2207 rc = read(fd, buf, EEPROM_SIZE);
2209 if(rc == EEPROM_SIZE)
2211 old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL);
2213 err = eeprom_24cxx_write(0, buf, sizeof buf);
2214 if (err)
2215 gui_syncsplash(HZ*3, "Eeprom write failure (%d)",err);
2216 else
2217 gui_syncsplash(HZ*3, "Eeprom written successfully");
2219 set_irq_level(old_irq_level);
2221 else
2223 gui_syncsplash(HZ*3, "File read error (%d)",rc);
2225 close(fd);
2227 else
2229 gui_syncsplash(HZ*3, "Failed to open 'internal_eeprom.bin'");
2232 return false;
2234 #endif /* defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS) */
2235 #ifdef CPU_BOOST_LOGGING
2236 static bool cpu_boost_log(void)
2238 int i = 0,j=0;
2239 int count = cpu_boost_log_getcount();
2240 int lines = LCD_HEIGHT/SYSFONT_HEIGHT;
2241 char *str;
2242 bool done;
2243 lcd_setmargins(0, 0);
2244 lcd_setfont(FONT_SYSFIXED);
2245 str = cpu_boost_log_getlog_first();
2246 while (i < count)
2248 lcd_clear_display();
2249 for(j=0; j<lines; j++,i++)
2251 if (!str)
2252 str = cpu_boost_log_getlog_next();
2253 if (str)
2255 lcd_puts(0, j,str);
2257 str = NULL;
2259 lcd_update();
2260 done = false;
2261 while (!done)
2263 switch(get_action(CONTEXT_STD,TIMEOUT_BLOCK))
2265 case ACTION_STD_OK:
2266 case ACTION_STD_PREV:
2267 case ACTION_STD_NEXT:
2268 done = true;
2269 break;
2270 case ACTION_STD_CANCEL:
2271 i = count;
2272 done = true;
2273 break;
2277 get_action(CONTEXT_STD,TIMEOUT_BLOCK);
2278 lcd_setfont(FONT_UI);
2279 return false;
2281 #endif
2285 /****** The menu *********/
2286 struct the_menu_item {
2287 unsigned char *desc; /* string or ID */
2288 bool (*function) (void); /* return true if USB was connected */
2290 static const struct the_menu_item menuitems[] = {
2291 #if defined(TOSHIBA_GIGABEAT_F) && !defined(SIMULATOR)
2292 { "LCD Power Off", dbg_lcd_power_off },
2293 #endif
2294 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || \
2295 (defined(CPU_PP) && !(defined(SANSA_E200) || defined(SANSA_C200)))
2296 { "Dump ROM contents", dbg_save_roms },
2297 #endif
2298 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || defined(CPU_PP) || CONFIG_CPU == S3C2440
2299 { "View I/O ports", dbg_ports },
2300 #endif
2301 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
2302 { "CPU frequency", dbg_cpufreq },
2303 #endif
2304 #if defined(IRIVER_H100_SERIES) && !defined(SIMULATOR)
2305 { "S/PDIF analyzer", dbg_spdif },
2306 #endif
2307 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
2308 { "Catch mem accesses", dbg_set_memory_guard },
2309 #endif
2310 { "View OS stacks", dbg_os },
2311 #ifdef HAVE_LCD_BITMAP
2312 #ifndef SIMULATOR
2313 { "View battery", view_battery },
2314 #endif
2315 { "Screendump", dbg_screendump },
2316 #endif
2317 #ifndef SIMULATOR
2318 { "View HW info", dbg_hw_info },
2319 #endif
2320 #ifndef SIMULATOR
2321 { "View partitions", dbg_partitions },
2322 #endif
2323 #ifndef SIMULATOR
2324 { "View disk info", dbg_disk_info },
2325 #endif
2326 #ifdef HAVE_DIRCACHE
2327 { "View dircache info", dbg_dircache_info },
2328 #endif
2329 #ifdef HAVE_TAGCACHE
2330 { "View database info", dbg_tagcache_info },
2331 #endif
2332 #ifdef HAVE_LCD_BITMAP
2333 #if CONFIG_CODEC == SWCODEC || !defined(SIMULATOR)
2334 { "View audio thread", dbg_audio_thread },
2335 { "View buffering thread", dbg_buffering_thread },
2336 #endif
2337 #ifdef PM_DEBUG
2338 { "pm histogram", peak_meter_histogram},
2339 #endif /* PM_DEBUG */
2340 #endif /* HAVE_LCD_BITMAP */
2341 #ifndef SIMULATOR
2342 #if CONFIG_TUNER
2343 { "FM Radio", dbg_fm_radio },
2344 #endif
2345 #endif
2346 #if defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS)
2347 { "Write back EEPROM", dbg_write_eeprom },
2348 #endif
2349 #ifdef ROCKBOX_HAS_LOGF
2350 {"logf", logfdisplay },
2351 {"logfdump", logfdump },
2352 #endif
2353 #ifdef CPU_BOOST_LOGGING
2354 {"cpu_boost log",cpu_boost_log},
2355 #endif
2357 static int menu_action_callback(int btn, struct gui_synclist *lists)
2359 if (btn == ACTION_STD_OK)
2361 menuitems[gui_synclist_get_sel_pos(lists)].function();
2362 btn = ACTION_REDRAW;
2364 return btn;
2366 static char* dbg_menu_getname(int item, void * data, char *buffer)
2368 (void)data; (void)buffer;
2369 return menuitems[item].desc;
2371 bool debug_menu(void)
2373 struct simplelist_info info;
2375 simplelist_info_init(&info, "Debug Menu", ARRAYLEN(menuitems), NULL);
2376 info.action_callback = menu_action_callback;
2377 info.get_name = dbg_menu_getname;
2379 return simplelist_show_list(&info);