more green seen as everyone has a green fetish atm
[Rockbox.git] / apps / debug_menu.c
blobf5dbbf17a53bbe8f0980359433e23dc64461016e
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 #if CONFIG_CPU == DM320 || CONFIG_CPU == S3C2440
92 #include "debug-target.h"
93 #endif
95 /*---------------------------------------------------*/
96 /* SPECIAL DEBUG STUFF */
97 /*---------------------------------------------------*/
98 extern struct thread_entry threads[MAXTHREADS];
100 static char thread_status_char(unsigned status)
102 static const char thread_status_chars[THREAD_NUM_STATES+1] =
104 [0 ... THREAD_NUM_STATES] = '?',
105 [STATE_RUNNING] = 'R',
106 [STATE_BLOCKED] = 'B',
107 [STATE_SLEEPING] = 'S',
108 [STATE_BLOCKED_W_TMO] = 'T',
109 [STATE_FROZEN] = 'F',
110 [STATE_KILLED] = 'K',
113 #if NUM_CORES > 1
114 if (status == STATE_BUSY) /* Not a state index */
115 return '.';
116 #endif
118 if (status > THREAD_NUM_STATES)
119 status = THREAD_NUM_STATES;
121 return thread_status_chars[status];
124 static char* threads_getname(int selected_item, void * data, char *buffer)
126 (void)data;
127 struct thread_entry *thread;
128 char name[32];
130 #if NUM_CORES > 1
131 if (selected_item < (int)NUM_CORES)
133 snprintf(buffer, MAX_PATH, "Idle (%d): %2d%%", selected_item,
134 idle_stack_usage(selected_item));
135 return buffer;
138 selected_item -= NUM_CORES;
139 #endif
141 thread = &threads[selected_item];
143 if (thread->state == STATE_KILLED)
145 snprintf(buffer, MAX_PATH, "%2d: ---", selected_item);
146 return buffer;
149 thread_get_name(name, 32, 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 #ifdef HAVE_SCHEDULER_BOOSTCTRL
156 (thread->boosted) ? '+' :
157 #endif
158 ((thread->state == STATE_RUNNING) ? '*' : ' '),
159 thread_status_char(thread->state),
160 IF_PRIO(thread->priority,)
161 thread_stack_usage(thread), name);
163 return buffer;
165 static int dbg_threads_action_callback(int action, struct gui_synclist *lists)
167 (void)lists;
168 #ifdef ROCKBOX_HAS_LOGF
169 if (action == ACTION_STD_OK)
171 int selpos = gui_synclist_get_sel_pos(lists);
172 #if NUM_CORES > 1
173 if (selpos >= NUM_CORES)
174 remove_thread(&threads[selpos - NUM_CORES]);
175 #else
176 remove_thread(&threads[selpos]);
177 #endif
178 return ACTION_REDRAW;
180 #endif /* ROCKBOX_HAS_LOGF */
181 return action;
183 /* Test code!!! */
184 static bool dbg_os(void)
186 struct simplelist_info info;
187 simplelist_info_init(&info, IF_COP("Core and ") "Stack usage:",
188 #if NUM_CORES == 1
189 MAXTHREADS,
190 #else
191 MAXTHREADS+NUM_CORES,
192 #endif
193 NULL);
194 #ifndef ROCKBOX_HAS_LOGF
195 info.hide_selection = true;
196 #endif
197 info.action_callback = dbg_threads_action_callback;
198 info.get_name = threads_getname;
199 return simplelist_show_list(&info);
202 #ifdef HAVE_LCD_BITMAP
203 #if CONFIG_CODEC != SWCODEC
204 #ifndef SIMULATOR
205 static bool dbg_audio_thread(void)
207 char buf[32];
208 struct audio_debug d;
210 lcd_setmargins(0, 0);
211 lcd_setfont(FONT_SYSFIXED);
213 while(1)
215 if (action_userabort(HZ/5))
216 return false;
218 audio_get_debugdata(&d);
220 lcd_clear_display();
222 snprintf(buf, sizeof(buf), "read: %x", d.audiobuf_read);
223 lcd_puts(0, 0, buf);
224 snprintf(buf, sizeof(buf), "write: %x", d.audiobuf_write);
225 lcd_puts(0, 1, buf);
226 snprintf(buf, sizeof(buf), "swap: %x", d.audiobuf_swapwrite);
227 lcd_puts(0, 2, buf);
228 snprintf(buf, sizeof(buf), "playing: %d", d.playing);
229 lcd_puts(0, 3, buf);
230 snprintf(buf, sizeof(buf), "playable: %x", d.playable_space);
231 lcd_puts(0, 4, buf);
232 snprintf(buf, sizeof(buf), "unswapped: %x", d.unswapped_space);
233 lcd_puts(0, 5, buf);
235 /* Playable space left */
236 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, 6*8, 112, 4, d.audiobuflen, 0,
237 d.playable_space, HORIZONTAL);
239 /* Show the watermark limit */
240 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, 6*8+4, 112, 4, d.audiobuflen, 0,
241 d.low_watermark_level, HORIZONTAL);
243 snprintf(buf, sizeof(buf), "wm: %x - %x",
244 d.low_watermark_level, d.lowest_watermark_level);
245 lcd_puts(0, 7, buf);
247 lcd_update();
249 return false;
251 #endif /* !SIMULATOR */
252 #else /* CONFIG_CODEC == SWCODEC */
253 extern size_t filebuflen;
254 /* This is a size_t, but call it a long so it puts a - when it's bad. */
256 static unsigned int ticks, boost_ticks;
258 static void dbg_audio_task(void)
260 #ifndef SIMULATOR
261 if(FREQ > CPUFREQ_NORMAL)
262 boost_ticks++;
263 #endif
265 ticks++;
268 static bool dbg_buffering_thread(void)
270 char buf[32];
271 int button;
272 int line;
273 bool done = false;
274 size_t bufused;
275 size_t bufsize = pcmbuf_get_bufsize();
276 int pcmbufdescs = pcmbuf_descs();
277 struct buffering_debug d;
279 ticks = boost_ticks = 0;
281 tick_add_task(dbg_audio_task);
283 lcd_setmargins(0, 0);
284 lcd_setfont(FONT_SYSFIXED);
285 while(!done)
287 button = get_action(CONTEXT_STD,HZ/5);
288 switch(button)
290 case ACTION_STD_NEXT:
291 audio_next();
292 break;
293 case ACTION_STD_PREV:
294 audio_prev();
295 break;
296 case ACTION_STD_CANCEL:
297 done = true;
298 break;
301 buffering_get_debugdata(&d);
303 line = 0;
304 lcd_clear_display();
306 bufused = bufsize - pcmbuf_free();
308 snprintf(buf, sizeof(buf), "pcm: %7ld/%7ld", (long) bufused, (long) bufsize);
309 lcd_puts(0, line++, buf);
311 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6,
312 bufsize, 0, bufused, HORIZONTAL);
313 line++;
315 snprintf(buf, sizeof(buf), "alloc: %8ld/%8ld", audio_filebufused(),
316 (long) filebuflen);
317 lcd_puts(0, line++, buf);
319 #if LCD_HEIGHT > 80
320 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6,
321 filebuflen, 0, audio_filebufused(), HORIZONTAL);
322 line++;
324 snprintf(buf, sizeof(buf), "real: %8ld/%8ld", (long)d.buffered_data,
325 (long)filebuflen);
326 lcd_puts(0, line++, buf);
328 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6,
329 filebuflen, 0, (long)d.buffered_data, HORIZONTAL);
330 line++;
331 #endif
333 snprintf(buf, sizeof(buf), "usefl: %8ld/%8ld", (long)(d.useful_data),
334 (long)filebuflen);
335 lcd_puts(0, line++, buf);
337 #if LCD_HEIGHT > 80
338 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6,
339 filebuflen, 0, d.useful_data, HORIZONTAL);
340 line++;
341 #endif
343 snprintf(buf, sizeof(buf), "data_rem: %ld", (long)d.data_rem);
344 lcd_puts(0, line++, buf);
346 snprintf(buf, sizeof(buf), "track count: %2d", audio_track_count());
347 lcd_puts(0, line++, buf);
349 snprintf(buf, sizeof(buf), "handle count: %d", (int)d.num_handles);
350 lcd_puts(0, line++, buf);
352 #ifndef SIMULATOR
353 snprintf(buf, sizeof(buf), "cpu freq: %3dMHz",
354 (int)((FREQ + 500000) / 1000000));
355 lcd_puts(0, line++, buf);
356 #endif
358 if (ticks > 0)
360 snprintf(buf, sizeof(buf), "boost ratio: %3d%%",
361 boost_ticks * 100 / ticks);
362 lcd_puts(0, line++, buf);
365 snprintf(buf, sizeof(buf), "pcmbufdesc: %2d/%2d",
366 pcmbuf_used_descs(), pcmbufdescs);
367 lcd_puts(0, line++, buf);
369 lcd_update();
372 tick_remove_task(dbg_audio_task);
374 return false;
376 #endif /* CONFIG_CODEC */
377 #endif /* HAVE_LCD_BITMAP */
380 #if (CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE))
381 /* Tool function to read the flash manufacturer and type, if available.
382 Only chips which could be reprogrammed in system will return values.
383 (The mode switch addresses vary between flash manufacturers, hence addr1/2) */
384 /* In IRAM to avoid problems when running directly from Flash */
385 static bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
386 unsigned addr1, unsigned addr2)
387 ICODE_ATTR __attribute__((noinline));
388 static bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
389 unsigned addr1, unsigned addr2)
392 unsigned not_manu, not_id; /* read values before switching to ID mode */
393 unsigned manu, id; /* read values when in ID mode */
395 #if CONFIG_CPU == SH7034
396 volatile unsigned char* flash = (unsigned char*)0x2000000; /* flash mapping */
397 #elif defined(CPU_COLDFIRE)
398 volatile unsigned short* flash = (unsigned short*)0; /* flash mapping */
399 #endif
400 int old_level; /* saved interrupt level */
402 not_manu = flash[0]; /* read the normal content */
403 not_id = flash[1]; /* should be 'A' (0x41) and 'R' (0x52) from the "ARCH" marker */
405 /* disable interrupts, prevent any stray flash access */
406 old_level = set_irq_level(HIGHEST_IRQ_LEVEL);
408 flash[addr1] = 0xAA; /* enter command mode */
409 flash[addr2] = 0x55;
410 flash[addr1] = 0x90; /* ID command */
411 /* Atmel wants 20ms pause here */
412 /* sleep(HZ/50); no sleeping possible while interrupts are disabled */
414 manu = flash[0]; /* read the IDs */
415 id = flash[1];
417 flash[0] = 0xF0; /* reset flash (back to normal read mode) */
418 /* Atmel wants 20ms pause here */
419 /* sleep(HZ/50); no sleeping possible while interrupts are disabled */
421 set_irq_level(old_level); /* enable interrupts again */
423 /* I assume success if the obtained values are different from
424 the normal flash content. This is not perfectly bulletproof, they
425 could theoretically be the same by chance, causing us to fail. */
426 if (not_manu != manu || not_id != id) /* a value has changed */
428 *p_manufacturer = manu; /* return the results */
429 *p_device = id;
430 return true; /* success */
432 return false; /* fail */
434 #endif /* (CONFIG_CPU == SH7034 || CPU_COLDFIRE) */
436 #ifndef SIMULATOR
437 #ifdef CPU_PP
438 static int perfcheck(void)
440 int result;
442 asm (
443 "mrs r2, CPSR \n"
444 "orr r0, r2, #0xc0 \n" /* disable IRQ and FIQ */
445 "msr CPSR_c, r0 \n"
446 "mov %[res], #0 \n"
447 "ldr r0, [%[timr]] \n"
448 "add r0, r0, %[tmo] \n"
449 "1: \n"
450 "add %[res], %[res], #1 \n"
451 "ldr r1, [%[timr]] \n"
452 "cmp r1, r0 \n"
453 "bmi 1b \n"
454 "msr CPSR_c, r2 \n" /* reset IRQ and FIQ state */
456 [res]"=&r"(result)
458 [timr]"r"(&USEC_TIMER),
459 [tmo]"r"(
460 #if CONFIG_CPU == PP5002
461 16000
462 #else /* PP5020/5022/5024 */
463 10226
464 #endif
467 "r0", "r1", "r2"
469 return result;
471 #endif
473 #ifdef HAVE_LCD_BITMAP
474 static bool dbg_hw_info(void)
476 #if CONFIG_CPU == SH7034
477 char buf[32];
478 int bitmask = HW_MASK;
479 int rom_version = ROM_VERSION;
480 unsigned manu, id; /* flash IDs */
481 bool got_id; /* flag if we managed to get the flash IDs */
482 unsigned rom_crc = 0xffffffff; /* CRC32 of the boot ROM */
483 bool has_bootrom; /* flag for boot ROM present */
484 int oldmode; /* saved memory guard mode */
486 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
488 /* get flash ROM type */
489 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
490 if (!got_id)
491 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
493 /* check if the boot ROM area is a flash mirror */
494 has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0);
495 if (has_bootrom) /* if ROM and Flash different */
497 /* calculate CRC16 checksum of boot ROM */
498 rom_crc = crc_32((unsigned char*)0x0000, 64*1024, 0xffffffff);
501 system_memory_guard(oldmode); /* re-enable memory guard */
503 lcd_setmargins(0, 0);
504 lcd_setfont(FONT_SYSFIXED);
505 lcd_clear_display();
507 lcd_puts(0, 0, "[Hardware info]");
509 snprintf(buf, 32, "ROM: %d.%02d", rom_version/100, rom_version%100);
510 lcd_puts(0, 1, buf);
512 snprintf(buf, 32, "Mask: 0x%04x", bitmask);
513 lcd_puts(0, 2, buf);
515 if (got_id)
516 snprintf(buf, 32, "Flash: M=%02x D=%02x", manu, id);
517 else
518 snprintf(buf, 32, "Flash: M=?? D=??"); /* unknown, sorry */
519 lcd_puts(0, 3, buf);
521 if (has_bootrom)
523 if (rom_crc == 0x56DBA4EE) /* known Version 1 */
524 snprintf(buf, 32, "Boot ROM: V1");
525 else
526 snprintf(buf, 32, "ROMcrc: 0x%08x", rom_crc);
528 else
530 snprintf(buf, 32, "Boot ROM: none");
532 lcd_puts(0, 4, buf);
534 lcd_update();
536 while (!(action_userabort(TIMEOUT_BLOCK)));
538 #elif CONFIG_CPU == MCF5249 || CONFIG_CPU == MCF5250
539 char buf[32];
540 unsigned manu, id; /* flash IDs */
541 int got_id; /* flag if we managed to get the flash IDs */
542 int oldmode; /* saved memory guard mode */
543 int line = 0;
545 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
547 /* get flash ROM type */
548 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
549 if (!got_id)
550 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
552 system_memory_guard(oldmode); /* re-enable memory guard */
554 lcd_setmargins(0, 0);
555 lcd_setfont(FONT_SYSFIXED);
556 lcd_clear_display();
558 lcd_puts(0, line++, "[Hardware info]");
560 if (got_id)
561 snprintf(buf, 32, "Flash: M=%04x D=%04x", manu, id);
562 else
563 snprintf(buf, 32, "Flash: M=???? D=????"); /* unknown, sorry */
564 lcd_puts(0, line++, buf);
566 #ifdef IAUDIO_X5
568 struct ds2411_id id;
570 lcd_puts(0, ++line, "Serial Number:");
572 got_id = ds2411_read_id(&id);
574 if (got_id == DS2411_OK)
576 snprintf(buf, 32, " FC=%02x", (unsigned)id.family_code);
577 lcd_puts(0, ++line, buf);
578 snprintf(buf, 32, " ID=%02X %02X %02X %02X %02X %02X",
579 (unsigned)id.uid[0], (unsigned)id.uid[1], (unsigned)id.uid[2],
580 (unsigned)id.uid[3], (unsigned)id.uid[4], (unsigned)id.uid[5]);
581 lcd_puts(0, ++line, buf);
582 snprintf(buf, 32, " CRC=%02X", (unsigned)id.crc);
584 else
586 snprintf(buf, 32, "READ ERR=%d", got_id);
589 lcd_puts(0, ++line, buf);
591 #endif
593 lcd_update();
595 while (!(action_userabort(TIMEOUT_BLOCK)));
597 #elif defined(CPU_PP502x)
598 int line = 0;
599 char buf[32];
600 char pp_version[] = { (PP_VER2 >> 24) & 0xff, (PP_VER2 >> 16) & 0xff,
601 (PP_VER2 >> 8) & 0xff, (PP_VER2) & 0xff,
602 (PP_VER1 >> 24) & 0xff, (PP_VER1 >> 16) & 0xff,
603 (PP_VER1 >> 8) & 0xff, (PP_VER1) & 0xff, '\0' };
605 lcd_setmargins(0, 0);
606 lcd_setfont(FONT_SYSFIXED);
607 lcd_clear_display();
609 lcd_puts(0, line++, "[Hardware info]");
611 #ifdef IPOD_ARCH
612 snprintf(buf, sizeof(buf), "HW rev: 0x%08lx", IPOD_HW_REVISION);
613 lcd_puts(0, line++, buf);
614 #endif
616 #ifdef IPOD_COLOR
617 extern int lcd_type; /* Defined in lcd-colornano.c */
619 snprintf(buf, sizeof(buf), "LCD type: %d", lcd_type);
620 lcd_puts(0, line++, buf);
621 #endif
623 snprintf(buf, sizeof(buf), "PP version: %s", pp_version);
624 lcd_puts(0, line++, buf);
626 snprintf(buf, sizeof(buf), "Est. clock (kHz): %d", perfcheck());
627 lcd_puts(0, line++, buf);
629 lcd_update();
631 while (!(action_userabort(TIMEOUT_BLOCK)));
633 #elif CONFIG_CPU == PP5002
634 int line = 0;
635 char buf[32];
636 char pp_version[] = { (PP_VER4 >> 8) & 0xff, PP_VER4 & 0xff,
637 (PP_VER3 >> 8) & 0xff, PP_VER3 & 0xff,
638 (PP_VER2 >> 8) & 0xff, PP_VER2 & 0xff,
639 (PP_VER1 >> 8) & 0xff, PP_VER1 & 0xff, '\0' };
642 lcd_setmargins(0, 0);
643 lcd_setfont(FONT_SYSFIXED);
644 lcd_clear_display();
646 lcd_puts(0, line++, "[Hardware info]");
648 #ifdef IPOD_ARCH
649 snprintf(buf, sizeof(buf), "HW rev: 0x%08lx", IPOD_HW_REVISION);
650 lcd_puts(0, line++, buf);
651 #endif
653 snprintf(buf, sizeof(buf), "PP version: %s", pp_version);
654 lcd_puts(0, line++, buf);
656 snprintf(buf, sizeof(buf), "Est. clock (kHz): %d", perfcheck());
657 lcd_puts(0, line++, buf);
659 lcd_update();
661 while (!(action_userabort(TIMEOUT_BLOCK)));
662 #else
663 /* Define this function in your target tree */
664 return __dbg_hw_info();
665 #endif /* CONFIG_CPU */
666 return false;
668 #else /* !HAVE_LCD_BITMAP */
669 static bool dbg_hw_info(void)
671 char buf[32];
672 int button;
673 int currval = 0;
674 int rom_version = ROM_VERSION;
675 unsigned manu, id; /* flash IDs */
676 bool got_id; /* flag if we managed to get the flash IDs */
677 unsigned rom_crc = 0xffffffff; /* CRC32 of the boot ROM */
678 bool has_bootrom; /* flag for boot ROM present */
679 int oldmode; /* saved memory guard mode */
681 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
683 /* get flash ROM type */
684 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
685 if (!got_id)
686 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
688 /* check if the boot ROM area is a flash mirror */
689 has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0);
690 if (has_bootrom) /* if ROM and Flash different */
692 /* calculate CRC16 checksum of boot ROM */
693 rom_crc = crc_32((unsigned char*)0x0000, 64*1024, 0xffffffff);
696 system_memory_guard(oldmode); /* re-enable memory guard */
698 lcd_clear_display();
700 lcd_puts(0, 0, "[HW Info]");
701 while(1)
703 switch(currval)
705 case 0:
706 snprintf(buf, 32, "ROM: %d.%02d",
707 rom_version/100, rom_version%100);
708 break;
709 case 1:
710 if (got_id)
711 snprintf(buf, 32, "Flash:%02x,%02x", manu, id);
712 else
713 snprintf(buf, 32, "Flash:??,??"); /* unknown, sorry */
714 break;
715 case 2:
716 if (has_bootrom)
718 if (rom_crc == 0x56DBA4EE) /* known Version 1 */
719 snprintf(buf, 32, "BootROM: V1");
720 else if (rom_crc == 0x358099E8)
721 snprintf(buf, 32, "BootROM: V2");
722 /* alternative boot ROM found in one single player so far */
723 else
724 snprintf(buf, 32, "R: %08x", rom_crc);
726 else
727 snprintf(buf, 32, "BootROM: no");
730 lcd_puts(0, 1, buf);
731 lcd_update();
733 button = get_action(CONTEXT_SETTINGS,TIMEOUT_BLOCK);
735 switch(button)
737 case ACTION_STD_CANCEL:
738 return false;
740 case ACTION_SETTINGS_DEC:
741 currval--;
742 if(currval < 0)
743 currval = 2;
744 break;
746 case ACTION_SETTINGS_INC:
747 currval++;
748 if(currval > 2)
749 currval = 0;
750 break;
753 return false;
755 #endif /* !HAVE_LCD_BITMAP */
756 #endif /* !SIMULATOR */
758 #ifndef SIMULATOR
759 static char* dbg_partitions_getname(int selected_item, void * data, char *buffer)
761 (void)data;
762 int partition = selected_item/2;
763 struct partinfo* p = disk_partinfo(partition);
764 if (selected_item%2)
766 snprintf(buffer, MAX_PATH, " T:%x %ld MB", p->type, p->size / 2048);
768 else
770 snprintf(buffer, MAX_PATH, "P%d: S:%lx", partition, p->start);
772 return buffer;
775 bool dbg_partitions(void)
777 struct simplelist_info info;
778 simplelist_info_init(&info, "Partition Info", 4, NULL);
779 info.selection_size = 2;
780 info.hide_selection = true;
781 info.get_name = dbg_partitions_getname;
782 return simplelist_show_list(&info);
784 #endif
786 #if defined(CPU_COLDFIRE) && defined(HAVE_SPDIF_OUT)
787 static bool dbg_spdif(void)
789 char buf[128];
790 int line;
791 unsigned int control;
792 int x;
793 char *s;
794 int category;
795 int generation;
796 unsigned int interruptstat;
797 bool valnogood, symbolerr, parityerr;
798 bool done = false;
799 bool spdif_src_on;
800 int spdif_source = spdif_get_output_source(&spdif_src_on);
801 spdif_set_output_source(AUDIO_SRC_SPDIF IF_SPDIF_POWER_(, true));
803 lcd_setmargins(0, 0);
804 lcd_clear_display();
805 lcd_setfont(FONT_SYSFIXED);
807 #ifdef HAVE_SPDIF_POWER
808 spdif_power_enable(true); /* We need SPDIF power for both sending & receiving */
809 #endif
811 while (!done)
813 line = 0;
815 control = EBU1RCVCCHANNEL1;
816 interruptstat = INTERRUPTSTAT;
817 INTERRUPTCLEAR = 0x03c00000;
819 valnogood = (interruptstat & 0x01000000)?true:false;
820 symbolerr = (interruptstat & 0x00800000)?true:false;
821 parityerr = (interruptstat & 0x00400000)?true:false;
823 snprintf(buf, sizeof(buf), "Val: %s Sym: %s Par: %s",
824 valnogood?"--":"OK",
825 symbolerr?"--":"OK",
826 parityerr?"--":"OK");
827 lcd_puts(0, line++, buf);
829 snprintf(buf, sizeof(buf), "Status word: %08x", (int)control);
830 lcd_puts(0, line++, buf);
832 line++;
834 x = control >> 31;
835 snprintf(buf, sizeof(buf), "PRO: %d (%s)",
836 x, x?"Professional":"Consumer");
837 lcd_puts(0, line++, buf);
839 x = (control >> 30) & 1;
840 snprintf(buf, sizeof(buf), "Audio: %d (%s)",
841 x, x?"Non-PCM":"PCM");
842 lcd_puts(0, line++, buf);
844 x = (control >> 29) & 1;
845 snprintf(buf, sizeof(buf), "Copy: %d (%s)",
846 x, x?"Permitted":"Inhibited");
847 lcd_puts(0, line++, buf);
849 x = (control >> 27) & 7;
850 switch(x)
852 case 0:
853 s = "None";
854 break;
855 case 1:
856 s = "50/15us";
857 break;
858 default:
859 s = "Reserved";
860 break;
862 snprintf(buf, sizeof(buf), "Preemphasis: %d (%s)", x, s);
863 lcd_puts(0, line++, buf);
865 x = (control >> 24) & 3;
866 snprintf(buf, sizeof(buf), "Mode: %d", x);
867 lcd_puts(0, line++, buf);
869 category = (control >> 17) & 127;
870 switch(category)
872 case 0x00:
873 s = "General";
874 break;
875 case 0x40:
876 s = "Audio CD";
877 break;
878 default:
879 s = "Unknown";
881 snprintf(buf, sizeof(buf), "Category: 0x%02x (%s)", category, s);
882 lcd_puts(0, line++, buf);
884 x = (control >> 16) & 1;
885 generation = x;
886 if(((category & 0x70) == 0x10) ||
887 ((category & 0x70) == 0x40) ||
888 ((category & 0x78) == 0x38))
890 generation = !generation;
892 snprintf(buf, sizeof(buf), "Generation: %d (%s)",
893 x, generation?"Original":"No ind.");
894 lcd_puts(0, line++, buf);
896 x = (control >> 12) & 15;
897 snprintf(buf, sizeof(buf), "Source: %d", x);
898 lcd_puts(0, line++, buf);
900 x = (control >> 8) & 15;
901 switch(x)
903 case 0:
904 s = "Unspecified";
905 break;
906 case 8:
907 s = "A (Left)";
908 break;
909 case 4:
910 s = "B (Right)";
911 break;
912 default:
913 s = "";
914 break;
916 snprintf(buf, sizeof(buf), "Channel: %d (%s)", x, s);
917 lcd_puts(0, line++, buf);
919 x = (control >> 4) & 15;
920 switch(x)
922 case 0:
923 s = "44.1kHz";
924 break;
925 case 0x4:
926 s = "48kHz";
927 break;
928 case 0xc:
929 s = "32kHz";
930 break;
932 snprintf(buf, sizeof(buf), "Frequency: %d (%s)", x, s);
933 lcd_puts(0, line++, buf);
935 x = (control >> 2) & 3;
936 snprintf(buf, sizeof(buf), "Clock accuracy: %d", x);
937 lcd_puts(0, line++, buf);
938 line++;
940 #ifndef SIMULATOR
941 snprintf(buf, sizeof(buf), "Measured freq: %ldHz",
942 spdif_measure_frequency());
943 lcd_puts(0, line++, buf);
944 #endif
946 lcd_update();
948 if (action_userabort(HZ/10))
949 break;
952 spdif_set_output_source(spdif_source IF_SPDIF_POWER_(, spdif_src_on));
954 #ifdef HAVE_SPDIF_POWER
955 spdif_power_enable(global_settings.spdif_enable);
956 #endif
958 return false;
960 #endif /* CPU_COLDFIRE */
962 #ifndef SIMULATOR
963 #ifdef HAVE_LCD_BITMAP
964 /* button definitions */
965 #if (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
966 (CONFIG_KEYPAD == IRIVER_H300_PAD)
967 # define DEBUG_CANCEL BUTTON_OFF
969 #elif CONFIG_KEYPAD == RECORDER_PAD
970 # define DEBUG_CANCEL BUTTON_OFF
972 #elif CONFIG_KEYPAD == ONDIO_PAD
973 # define DEBUG_CANCEL BUTTON_MENU
975 #elif (CONFIG_KEYPAD == IPOD_1G2G_PAD) || \
976 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
977 (CONFIG_KEYPAD == IPOD_4G_PAD)
978 # define DEBUG_CANCEL BUTTON_MENU
980 #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
981 # define DEBUG_CANCEL BUTTON_PLAY
983 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
984 # define DEBUG_CANCEL BUTTON_REC
986 #elif (CONFIG_KEYPAD == IRIVER_H10_PAD) || \
987 (CONFIG_KEYPAD == MROBE100_PAD)
988 # define DEBUG_CANCEL BUTTON_REW
990 #elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \
991 (CONFIG_KEYPAD == SANSA_C200_PAD)
992 # define DEBUG_CANCEL BUTTON_LEFT
993 #endif /* key definitions */
995 /* Test code!!! */
996 bool dbg_ports(void)
998 #if CONFIG_CPU == SH7034
999 unsigned short porta;
1000 unsigned short portb;
1001 unsigned char portc;
1002 char buf[32];
1003 int adc_battery_voltage, adc_battery_level;
1005 lcd_setfont(FONT_SYSFIXED);
1006 lcd_setmargins(0, 0);
1007 lcd_clear_display();
1009 while(1)
1011 porta = PADR;
1012 portb = PBDR;
1013 portc = PCDR;
1015 snprintf(buf, 32, "PADR: %04x", porta);
1016 lcd_puts(0, 0, buf);
1017 snprintf(buf, 32, "PBDR: %04x", portb);
1018 lcd_puts(0, 1, buf);
1020 snprintf(buf, 32, "AN0: %03x AN4: %03x", adc_read(0), adc_read(4));
1021 lcd_puts(0, 2, buf);
1022 snprintf(buf, 32, "AN1: %03x AN5: %03x", adc_read(1), adc_read(5));
1023 lcd_puts(0, 3, buf);
1024 snprintf(buf, 32, "AN2: %03x AN6: %03x", adc_read(2), adc_read(6));
1025 lcd_puts(0, 4, buf);
1026 snprintf(buf, 32, "AN3: %03x AN7: %03x", adc_read(3), adc_read(7));
1027 lcd_puts(0, 5, buf);
1029 battery_read_info(&adc_battery_voltage, &adc_battery_level);
1030 snprintf(buf, 32, "Batt: %d.%03dV %d%% ", adc_battery_voltage / 1000,
1031 adc_battery_voltage % 1000, adc_battery_level);
1032 lcd_puts(0, 6, buf);
1034 lcd_update();
1035 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1036 return false;
1038 #elif defined(CPU_COLDFIRE)
1039 unsigned int gpio_out;
1040 unsigned int gpio1_out;
1041 unsigned int gpio_read;
1042 unsigned int gpio1_read;
1043 unsigned int gpio_function;
1044 unsigned int gpio1_function;
1045 unsigned int gpio_enable;
1046 unsigned int gpio1_enable;
1047 int adc_buttons, adc_remote;
1048 int adc_battery_voltage, adc_battery_level;
1049 char buf[128];
1050 int line;
1052 lcd_setmargins(0, 0);
1053 lcd_clear_display();
1054 lcd_setfont(FONT_SYSFIXED);
1056 while(1)
1058 line = 0;
1059 gpio_read = GPIO_READ;
1060 gpio1_read = GPIO1_READ;
1061 gpio_out = GPIO_OUT;
1062 gpio1_out = GPIO1_OUT;
1063 gpio_function = GPIO_FUNCTION;
1064 gpio1_function = GPIO1_FUNCTION;
1065 gpio_enable = GPIO_ENABLE;
1066 gpio1_enable = GPIO1_ENABLE;
1068 snprintf(buf, sizeof(buf), "GPIO_READ: %08x", gpio_read);
1069 lcd_puts(0, line++, buf);
1070 snprintf(buf, sizeof(buf), "GPIO_OUT: %08x", gpio_out);
1071 lcd_puts(0, line++, buf);
1072 snprintf(buf, sizeof(buf), "GPIO_FUNCTION: %08x", gpio_function);
1073 lcd_puts(0, line++, buf);
1074 snprintf(buf, sizeof(buf), "GPIO_ENABLE: %08x", gpio_enable);
1075 lcd_puts(0, line++, buf);
1077 snprintf(buf, sizeof(buf), "GPIO1_READ: %08x", gpio1_read);
1078 lcd_puts(0, line++, buf);
1079 snprintf(buf, sizeof(buf), "GPIO1_OUT: %08x", gpio1_out);
1080 lcd_puts(0, line++, buf);
1081 snprintf(buf, sizeof(buf), "GPIO1_FUNCTION: %08x", gpio1_function);
1082 lcd_puts(0, line++, buf);
1083 snprintf(buf, sizeof(buf), "GPIO1_ENABLE: %08x", gpio1_enable);
1084 lcd_puts(0, line++, buf);
1086 adc_buttons = adc_read(ADC_BUTTONS);
1087 adc_remote = adc_read(ADC_REMOTE);
1088 battery_read_info(&adc_battery_voltage, &adc_battery_level);
1089 #if defined(IAUDIO_X5) || defined(IAUDIO_M5) || defined(IRIVER_H300_SERIES)
1090 snprintf(buf, sizeof(buf), "ADC_BUTTONS (%c): %02x",
1091 button_scan_enabled() ? '+' : '-', adc_buttons);
1092 #else
1093 snprintf(buf, sizeof(buf), "ADC_BUTTONS: %02x", adc_buttons);
1094 #endif
1095 lcd_puts(0, line++, buf);
1096 #if defined(IAUDIO_X5) || defined(IAUDIO_M5)
1097 snprintf(buf, sizeof(buf), "ADC_REMOTE (%c): %02x",
1098 remote_detect() ? '+' : '-', adc_remote);
1099 #else
1100 snprintf(buf, sizeof(buf), "ADC_REMOTE: %02x", adc_remote);
1101 #endif
1102 lcd_puts(0, line++, buf);
1103 #if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES)
1104 snprintf(buf, sizeof(buf), "ADC_REMOTEDETECT: %02x",
1105 adc_read(ADC_REMOTEDETECT));
1106 lcd_puts(0, line++, buf);
1107 #endif
1109 snprintf(buf, 32, "Batt: %d.%03dV %d%% ", adc_battery_voltage / 1000,
1110 adc_battery_voltage % 1000, adc_battery_level);
1111 lcd_puts(0, line++, buf);
1113 #if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES)
1114 snprintf(buf, sizeof(buf), "remotetype: %d", remote_type());
1115 lcd_puts(0, line++, buf);
1116 #endif
1118 lcd_update();
1119 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1120 return false;
1123 #elif defined(CPU_PP502x)
1125 unsigned int gpio_a, gpio_b, gpio_c, gpio_d;
1126 unsigned int gpio_e, gpio_f, gpio_g, gpio_h;
1127 unsigned int gpio_i, gpio_j, gpio_k, gpio_l;
1129 char buf[128];
1130 int line;
1132 lcd_setmargins(0, 0);
1133 lcd_clear_display();
1134 lcd_setfont(FONT_SYSFIXED);
1136 while(1)
1138 gpio_a = GPIOA_INPUT_VAL;
1139 gpio_b = GPIOB_INPUT_VAL;
1140 gpio_c = GPIOC_INPUT_VAL;
1142 gpio_g = GPIOG_INPUT_VAL;
1143 gpio_h = GPIOH_INPUT_VAL;
1144 gpio_i = GPIOI_INPUT_VAL;
1146 line = 0;
1147 snprintf(buf, sizeof(buf), "GPIO_A: %02x GPIO_G: %02x", gpio_a, gpio_g);
1148 lcd_puts(0, line++, buf);
1149 snprintf(buf, sizeof(buf), "GPIO_B: %02x GPIO_H: %02x", gpio_b, gpio_h);
1150 lcd_puts(0, line++, buf);
1151 snprintf(buf, sizeof(buf), "GPIO_C: %02x GPIO_I: %02x", gpio_c, gpio_i);
1152 lcd_puts(0, line++, buf);
1154 gpio_d = GPIOD_INPUT_VAL;
1155 gpio_e = GPIOE_INPUT_VAL;
1156 gpio_f = GPIOF_INPUT_VAL;
1158 gpio_j = GPIOJ_INPUT_VAL;
1159 gpio_k = GPIOK_INPUT_VAL;
1160 gpio_l = GPIOL_INPUT_VAL;
1162 snprintf(buf, sizeof(buf), "GPIO_D: %02x GPIO_J: %02x", gpio_d, gpio_j);
1163 lcd_puts(0, line++, buf);
1164 snprintf(buf, sizeof(buf), "GPIO_E: %02x GPIO_K: %02x", gpio_e, gpio_k);
1165 lcd_puts(0, line++, buf);
1166 snprintf(buf, sizeof(buf), "GPIO_F: %02x GPIO_L: %02x", gpio_f, gpio_l);
1167 lcd_puts(0, line++, buf);
1168 line++;
1170 snprintf(buf, sizeof(buf), "GPO32: %08lx", GPO32_VAL);
1171 lcd_puts(0, line++, buf);
1172 snprintf(buf, sizeof(buf), "DEV_EN: %08lx", DEV_EN);
1173 lcd_puts(0, line++, buf);
1174 snprintf(buf, sizeof(buf), "DEV_EN2: %08lx", DEV_EN2);
1175 lcd_puts(0, line++, buf);
1176 snprintf(buf, sizeof(buf), "DEV_EN3: %08lx", inl(0x60006044));
1177 lcd_puts(0, line++, buf); /* to be verified */
1179 #if defined(IRIVER_H10) || defined(IRIVER_H10_5GB)
1180 line++;
1181 snprintf(buf, sizeof(buf), "BATT: %03x UNK1: %03x", adc_read(ADC_BATTERY),
1182 adc_read(ADC_UNKNOWN_1));
1183 lcd_puts(0, line++, buf);
1184 snprintf(buf, sizeof(buf), "REM: %03x PAD: %03x", adc_read(ADC_REMOTE),
1185 adc_read(ADC_SCROLLPAD));
1186 lcd_puts(0, line++, buf);
1187 #elif defined(SANSA_E200)
1188 line++;
1189 snprintf(buf, sizeof(buf), "ADC_BVDD: %4d", adc_read(ADC_BVDD));
1190 lcd_puts(0, line++, buf);
1191 snprintf(buf, sizeof(buf), "ADC_RTCSUP: %4d", adc_read(ADC_RTCSUP));
1192 lcd_puts(0, line++, buf);
1193 snprintf(buf, sizeof(buf), "ADC_UVDD: %4d", adc_read(ADC_UVDD));
1194 lcd_puts(0, line++, buf);
1195 snprintf(buf, sizeof(buf), "ADC_CHG_IN: %4d", adc_read(ADC_CHG_IN));
1196 lcd_puts(0, line++, buf);
1197 snprintf(buf, sizeof(buf), "ADC_CVDD: %4d", adc_read(ADC_CVDD));
1198 lcd_puts(0, line++, buf);
1199 snprintf(buf, sizeof(buf), "ADC_BATTEMP: %4d", adc_read(ADC_BATTEMP));
1200 lcd_puts(0, line++, buf);
1201 snprintf(buf, sizeof(buf), "ADC_MICSUP1: %4d", adc_read(ADC_MICSUP1));
1202 lcd_puts(0, line++, buf);
1203 snprintf(buf, sizeof(buf), "ADC_MICSUP2: %4d", adc_read(ADC_MICSUP2));
1204 lcd_puts(0, line++, buf);
1205 snprintf(buf, sizeof(buf), "ADC_VBE1: %4d", adc_read(ADC_VBE1));
1206 lcd_puts(0, line++, buf);
1207 snprintf(buf, sizeof(buf), "ADC_VBE2: %4d", adc_read(ADC_VBE2));
1208 lcd_puts(0, line++, buf);
1209 snprintf(buf, sizeof(buf), "ADC_I_MICSUP1:%4d", adc_read(ADC_I_MICSUP1));
1210 lcd_puts(0, line++, buf);
1211 snprintf(buf, sizeof(buf), "ADC_I_MICSUP2:%4d", adc_read(ADC_I_MICSUP2));
1212 lcd_puts(0, line++, buf);
1213 snprintf(buf, sizeof(buf), "ADC_VBAT: %4d", adc_read(ADC_VBAT));
1214 lcd_puts(0, line++, buf);
1215 #endif
1216 lcd_update();
1217 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1218 return false;
1221 #elif CONFIG_CPU == PP5002
1222 unsigned int gpio_a, gpio_b, gpio_c, gpio_d;
1224 char buf[128];
1225 int line;
1227 lcd_setmargins(0, 0);
1228 lcd_clear_display();
1229 lcd_setfont(FONT_SYSFIXED);
1231 while(1)
1233 gpio_a = GPIOA_INPUT_VAL;
1234 gpio_b = GPIOB_INPUT_VAL;
1235 gpio_c = GPIOC_INPUT_VAL;
1236 gpio_d = GPIOD_INPUT_VAL;
1238 line = 0;
1239 snprintf(buf, sizeof(buf), "GPIO_A: %02x GPIO_B: %02x", gpio_a, gpio_b);
1240 lcd_puts(0, line++, buf);
1241 snprintf(buf, sizeof(buf), "GPIO_C: %02x GPIO_D: %02x", gpio_c, gpio_d);
1242 lcd_puts(0, line++, buf);
1244 snprintf(buf, sizeof(buf), "DEV_EN: %08lx", DEV_EN);
1245 lcd_puts(0, line++, buf);
1246 snprintf(buf, sizeof(buf), "CLOCK_ENABLE: %08lx", CLOCK_ENABLE);
1247 lcd_puts(0, line++, buf);
1248 snprintf(buf, sizeof(buf), "CLOCK_SOURCE: %08lx", CLOCK_SOURCE);
1249 lcd_puts(0, line++, buf);
1250 snprintf(buf, sizeof(buf), "PLL_CONTROL: %08lx", PLL_CONTROL);
1251 lcd_puts(0, line++, buf);
1252 snprintf(buf, sizeof(buf), "PLL_DIV: %08lx", PLL_DIV);
1253 lcd_puts(0, line++, buf);
1254 snprintf(buf, sizeof(buf), "PLL_MULT: %08lx", PLL_MULT);
1255 lcd_puts(0, line++, buf);
1256 snprintf(buf, sizeof(buf), "TIMING1_CTL: %08lx", TIMING1_CTL);
1257 lcd_puts(0, line++, buf);
1258 snprintf(buf, sizeof(buf), "TIMING2_CTL: %08lx", TIMING2_CTL);
1259 lcd_puts(0, line++, buf);
1261 lcd_update();
1262 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1263 return false;
1265 #else
1266 return __dbg_ports();
1267 #endif /* CPU */
1268 return false;
1270 #else /* !HAVE_LCD_BITMAP */
1271 bool dbg_ports(void)
1273 unsigned short porta;
1274 unsigned short portb;
1275 unsigned char portc;
1276 char buf[32];
1277 int button;
1278 int adc_battery_voltage;
1279 int currval = 0;
1281 lcd_clear_display();
1283 while(1)
1285 porta = PADR;
1286 portb = PBDR;
1287 portc = PCDR;
1289 switch(currval)
1291 case 0:
1292 snprintf(buf, 32, "PADR: %04x", porta);
1293 break;
1294 case 1:
1295 snprintf(buf, 32, "PBDR: %04x", portb);
1296 break;
1297 case 2:
1298 snprintf(buf, 32, "AN0: %03x", adc_read(0));
1299 break;
1300 case 3:
1301 snprintf(buf, 32, "AN1: %03x", adc_read(1));
1302 break;
1303 case 4:
1304 snprintf(buf, 32, "AN2: %03x", adc_read(2));
1305 break;
1306 case 5:
1307 snprintf(buf, 32, "AN3: %03x", adc_read(3));
1308 break;
1309 case 6:
1310 snprintf(buf, 32, "AN4: %03x", adc_read(4));
1311 break;
1312 case 7:
1313 snprintf(buf, 32, "AN5: %03x", adc_read(5));
1314 break;
1315 case 8:
1316 snprintf(buf, 32, "AN6: %03x", adc_read(6));
1317 break;
1318 case 9:
1319 snprintf(buf, 32, "AN7: %03x", adc_read(7));
1320 break;
1321 break;
1323 lcd_puts(0, 0, buf);
1325 battery_read_info(&adc_battery_voltage, NULL);
1326 snprintf(buf, 32, "Batt: %d.%03dV", adc_battery_voltage / 1000,
1327 adc_battery_voltage % 1000);
1328 lcd_puts(0, 1, buf);
1329 lcd_update();
1331 button = get_action(CONTEXT_SETTINGS,HZ/5);
1333 switch(button)
1335 case ACTION_STD_CANCEL:
1336 return false;
1338 case ACTION_SETTINGS_DEC:
1339 currval--;
1340 if(currval < 0)
1341 currval = 9;
1342 break;
1344 case ACTION_SETTINGS_INC:
1345 currval++;
1346 if(currval > 9)
1347 currval = 0;
1348 break;
1351 return false;
1353 #endif /* !HAVE_LCD_BITMAP */
1354 #endif /* !SIMULATOR */
1356 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
1357 static bool dbg_cpufreq(void)
1359 char buf[128];
1360 int line;
1361 int button;
1363 #ifdef HAVE_LCD_BITMAP
1364 lcd_setmargins(0, 0);
1365 lcd_setfont(FONT_SYSFIXED);
1366 #endif
1367 lcd_clear_display();
1369 while(1)
1371 line = 0;
1373 snprintf(buf, sizeof(buf), "Frequency: %ld", FREQ);
1374 lcd_puts(0, line++, buf);
1376 snprintf(buf, sizeof(buf), "boost_counter: %d", get_cpu_boost_counter());
1377 lcd_puts(0, line++, buf);
1379 lcd_update();
1380 button = get_action(CONTEXT_STD,HZ/10);
1382 switch(button)
1384 case ACTION_STD_PREV:
1385 cpu_boost(true);
1386 break;
1388 case ACTION_STD_NEXT:
1389 cpu_boost(false);
1390 break;
1392 case ACTION_STD_OK:
1393 while (get_cpu_boost_counter() > 0)
1394 cpu_boost(false);
1395 set_cpu_frequency(CPUFREQ_DEFAULT);
1396 break;
1398 case ACTION_STD_CANCEL:
1399 return false;
1403 return false;
1405 #endif /* HAVE_ADJUSTABLE_CPU_FREQ */
1407 #if defined(HAVE_TSC2100) && !defined(SIMULATOR)
1408 #include "tsc2100.h"
1409 char *itob(int n, int len)
1411 static char binary[64];
1412 int i,j;
1413 for (i=1, j=0;i<=len;i++)
1415 binary[j++] = n&(1<<(len-i))?'1':'0';
1416 if (i%4 == 0)
1417 binary[j++] = ' ';
1419 binary[j] = '\0';
1420 return binary;
1422 static char* tsc2100_debug_getname(int selected_item, void * data, char *buffer)
1424 int *page = (int*)data;
1425 bool reserved = false;
1426 switch (*page)
1428 case 0:
1429 if ((selected_item > 0x0a) ||
1430 (selected_item == 0x04) ||
1431 (selected_item == 0x08))
1432 reserved = true;
1433 break;
1434 case 1:
1435 if ((selected_item > 0x05) ||
1436 (selected_item == 0x02))
1437 reserved = true;
1438 break;
1439 case 2:
1440 if (selected_item > 0x1e)
1441 reserved = true;
1442 break;
1444 if (reserved)
1445 snprintf(buffer, MAX_PATH, "%02x: RESERVED", selected_item);
1446 else
1447 snprintf(buffer, MAX_PATH, "%02x: %s", selected_item,
1448 itob(tsc2100_readreg(*page, selected_item)&0xffff,16));
1449 return buffer;
1451 static int tsc2100debug_action_callback(int action, struct gui_synclist *lists)
1453 int *page = (int*)lists->data;
1454 if (action == ACTION_STD_OK)
1456 *page = (*page+1)%3;
1457 snprintf(lists->title, 32,
1458 "tsc2100 registers - Page %d", *page);
1459 return ACTION_REDRAW;
1461 return action;
1463 bool tsc2100_debug(void)
1465 int page = 0;
1466 char title[32] = "tsc2100 registers - Page 0";
1467 struct simplelist_info info;
1468 simplelist_info_init(&info, title, 32, &page);
1469 info.timeout = HZ/100;
1470 info.get_name = tsc2100_debug_getname;
1471 info.action_callback= tsc2100debug_action_callback;
1472 return simplelist_show_list(&info);
1474 #endif
1475 #ifndef SIMULATOR
1476 #ifdef HAVE_LCD_BITMAP
1478 * view_battery() shows a automatically scaled graph of the battery voltage
1479 * over time. Usable for estimating battery life / charging rate.
1480 * The power_history array is updated in power_thread of powermgmt.c.
1483 #define BAT_LAST_VAL MIN(LCD_WIDTH, POWER_HISTORY_LEN)
1484 #define BAT_YSPACE (LCD_HEIGHT - 20)
1486 static bool view_battery(void)
1488 int view = 0;
1489 int i, x, y;
1490 unsigned short maxv, minv;
1491 char buf[32];
1493 lcd_setmargins(0, 0);
1494 lcd_setfont(FONT_SYSFIXED);
1496 while(1)
1498 lcd_clear_display();
1499 switch (view) {
1500 case 0: /* voltage history graph */
1501 /* Find maximum and minimum voltage for scaling */
1502 minv = power_history[0];
1503 maxv = minv + 1;
1504 for (i = 1; i < BAT_LAST_VAL && power_history[i]; i++) {
1505 if (power_history[i] > maxv)
1506 maxv = power_history[i];
1507 if (power_history[i] < minv)
1508 minv = power_history[i];
1511 snprintf(buf, 30, "Battery %d.%03d", power_history[0] / 1000,
1512 power_history[0] % 1000);
1513 lcd_puts(0, 0, buf);
1514 snprintf(buf, 30, "scale %d.%03d-%d.%03dV",
1515 minv / 1000, minv % 1000, maxv / 1000, maxv % 1000);
1516 lcd_puts(0, 1, buf);
1518 x = 0;
1519 for (i = BAT_LAST_VAL - 1; i >= 0; i--) {
1520 y = (power_history[i] - minv) * BAT_YSPACE / (maxv - minv);
1521 lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
1522 lcd_vline(x, LCD_HEIGHT-1, 20);
1523 lcd_set_drawmode(DRMODE_SOLID);
1524 lcd_vline(x, LCD_HEIGHT-1,
1525 MIN(MAX(LCD_HEIGHT-1 - y, 20), LCD_HEIGHT-1));
1526 x++;
1529 break;
1531 case 1: /* status: */
1532 lcd_puts(0, 0, "Power status:");
1534 battery_read_info(&y, NULL);
1535 snprintf(buf, 30, "Battery: %d.%03d V", y / 1000, y % 1000);
1536 lcd_puts(0, 1, buf);
1537 #ifdef ADC_EXT_POWER
1538 y = (adc_read(ADC_EXT_POWER) * EXT_SCALE_FACTOR) / 1000;
1539 snprintf(buf, 30, "External: %d.%03d V", y / 1000, y % 1000);
1540 lcd_puts(0, 2, buf);
1541 #endif
1542 #if CONFIG_CHARGING
1543 #if CONFIG_CHARGING == CHARGING_CONTROL
1544 snprintf(buf, 30, "Chgr: %s %s",
1545 charger_inserted() ? "present" : "absent",
1546 charger_enabled ? "on" : "off");
1547 lcd_puts(0, 3, buf);
1548 snprintf(buf, 30, "short delta: %d", short_delta);
1549 lcd_puts(0, 5, buf);
1550 snprintf(buf, 30, "long delta: %d", long_delta);
1551 lcd_puts(0, 6, buf);
1552 lcd_puts(0, 7, power_message);
1553 snprintf(buf, 30, "USB Inserted: %s",
1554 usb_inserted() ? "yes" : "no");
1555 lcd_puts(0, 8, buf);
1556 #if defined IRIVER_H300_SERIES
1557 snprintf(buf, 30, "USB Charging Enabled: %s",
1558 usb_charging_enabled() ? "yes" : "no");
1559 lcd_puts(0, 9, buf);
1560 #endif
1561 #else /* CONFIG_CHARGING != CHARGING_CONTROL */
1562 #if defined IPOD_NANO || defined IPOD_VIDEO
1563 int usb_pwr = (GPIOL_INPUT_VAL & 0x10)?true:false;
1564 int ext_pwr = (GPIOL_INPUT_VAL & 0x08)?false:true;
1565 int dock = (GPIOA_INPUT_VAL & 0x10)?true:false;
1566 int charging = (GPIOB_INPUT_VAL & 0x01)?false:true;
1567 int headphone= (GPIOA_INPUT_VAL & 0x80)?true:false;
1569 snprintf(buf, 30, "USB pwr: %s",
1570 usb_pwr ? "present" : "absent");
1571 lcd_puts(0, 3, buf);
1572 snprintf(buf, 30, "EXT pwr: %s",
1573 ext_pwr ? "present" : "absent");
1574 lcd_puts(0, 4, buf);
1575 snprintf(buf, 30, "Battery: %s",
1576 charging ? "charging" : (usb_pwr||ext_pwr) ? "charged" : "discharging");
1577 lcd_puts(0, 5, buf);
1578 snprintf(buf, 30, "Dock mode: %s",
1579 dock ? "enabled" : "disabled");
1580 lcd_puts(0, 6, buf);
1581 snprintf(buf, 30, "Headphone: %s",
1582 headphone ? "connected" : "disconnected");
1583 lcd_puts(0, 7, buf);
1584 #else
1585 snprintf(buf, 30, "Charger: %s",
1586 charger_inserted() ? "present" : "absent");
1587 lcd_puts(0, 3, buf);
1588 #endif
1589 #endif /* CONFIG_CHARGING != CHARGING_CONTROL */
1590 #endif /* CONFIG_CHARGING */
1591 break;
1593 case 2: /* voltage deltas: */
1594 lcd_puts(0, 0, "Voltage deltas:");
1596 for (i = 0; i <= 6; i++) {
1597 y = power_history[i] - power_history[i+1];
1598 snprintf(buf, 30, "-%d min: %s%d.%03d V", i,
1599 (y < 0) ? "-" : "", ((y < 0) ? y * -1 : y) / 1000,
1600 ((y < 0) ? y * -1 : y ) % 1000);
1601 lcd_puts(0, i+1, buf);
1603 break;
1605 case 3: /* remaining time estimation: */
1607 #if CONFIG_CHARGING == CHARGING_CONTROL
1608 snprintf(buf, 30, "charge_state: %d", charge_state);
1609 lcd_puts(0, 0, buf);
1611 snprintf(buf, 30, "Cycle time: %d m", powermgmt_last_cycle_startstop_min);
1612 lcd_puts(0, 1, buf);
1614 snprintf(buf, 30, "Lvl@cyc st: %d%%", powermgmt_last_cycle_level);
1615 lcd_puts(0, 2, buf);
1617 snprintf(buf, 30, "P=%2d I=%2d", pid_p, pid_i);
1618 lcd_puts(0, 3, buf);
1620 snprintf(buf, 30, "Trickle sec: %d/60", trickle_sec);
1621 lcd_puts(0, 4, buf);
1622 #endif /* CONFIG_CHARGING == CHARGING_CONTROL */
1624 snprintf(buf, 30, "Last PwrHist: %d.%03dV",
1625 power_history[0] / 1000,
1626 power_history[0] % 1000);
1627 lcd_puts(0, 5, buf);
1629 snprintf(buf, 30, "battery level: %d%%", battery_level());
1630 lcd_puts(0, 6, buf);
1632 snprintf(buf, 30, "Est. remain: %d m", battery_time());
1633 lcd_puts(0, 7, buf);
1634 break;
1637 lcd_update();
1639 switch(get_action(CONTEXT_SETTINGS,HZ/2))
1641 case ACTION_SETTINGS_DEC:
1642 if (view)
1643 view--;
1644 break;
1646 case ACTION_SETTINGS_INC:
1647 if (view < 3)
1648 view++;
1649 break;
1651 case ACTION_STD_CANCEL:
1652 return false;
1655 return false;
1658 #endif /* HAVE_LCD_BITMAP */
1659 #endif
1661 #ifndef SIMULATOR
1662 #if defined(HAVE_MMC) || defined(HAVE_HOTSWAP)
1663 #if defined(HAVE_MMC)
1664 #define CARDTYPE "MMC"
1665 #else
1666 #define CARDTYPE "microSD"
1667 #endif
1668 static int disk_callback(int btn, struct gui_synclist *lists)
1670 tCardInfo *card;
1671 int *cardnum = (int*)lists->data;
1672 unsigned char card_name[7];
1673 unsigned char pbuf[32];
1674 char *title = lists->title;
1675 static const unsigned char i_vmin[] = { 0, 1, 5, 10, 25, 35, 60, 100 };
1676 static const unsigned char i_vmax[] = { 1, 5, 10, 25, 35, 45, 80, 200 };
1677 static const unsigned char *kbit_units[] = { "kBit/s", "MBit/s", "GBit/s" };
1678 static const unsigned char *nsec_units[] = { "ns", "�s", "ms" };
1679 static const char *spec_vers[] = { "1.0-1.2", "1.4", "2.0-2.2",
1680 "3.1-3.31", "4.0" };
1681 if ((btn == ACTION_STD_OK) || (btn == SYS_FS_CHANGED) || (btn == ACTION_REDRAW))
1683 if (btn == ACTION_STD_OK)
1685 *cardnum ^= 0x1; /* change cards */
1688 simplelist_set_line_count(0);
1690 card = card_get_info(*cardnum);
1692 if (card->initialized > 0)
1694 card_name[6] = '\0';
1695 strncpy(card_name, ((unsigned char*)card->cid) + 3, 6);
1696 simplelist_addline(SIMPLELIST_ADD_LINE,
1697 "%s Rev %d.%d", card_name,
1698 (int) card_extract_bits(card->cid, 72, 4),
1699 (int) card_extract_bits(card->cid, 76, 4));
1700 simplelist_addline(SIMPLELIST_ADD_LINE,
1701 "Prod: %d/%d",
1702 (int) card_extract_bits(card->cid, 112, 4),
1703 (int) card_extract_bits(card->cid, 116, 4) + 1997);
1704 simplelist_addline(SIMPLELIST_ADD_LINE,
1705 "Ser#: 0x%08lx",
1706 card_extract_bits(card->cid, 80, 32));
1707 simplelist_addline(SIMPLELIST_ADD_LINE,
1708 "M=%02x, O=%04x",
1709 (int) card_extract_bits(card->cid, 0, 8),
1710 (int) card_extract_bits(card->cid, 8, 16));
1711 int temp = card_extract_bits(card->csd, 2, 4);
1712 simplelist_addline(SIMPLELIST_ADD_LINE,
1713 CARDTYPE " v%s", temp < 5 ?
1714 spec_vers[temp] : "?.?");
1715 simplelist_addline(SIMPLELIST_ADD_LINE,
1716 "Blocks: 0x%06lx", card->numblocks);
1717 simplelist_addline(SIMPLELIST_ADD_LINE,
1718 "Blksz.: %d P:%c%c", card->blocksize,
1719 card_extract_bits(card->csd, 48, 1) ? 'R' : '-',
1720 card_extract_bits(card->csd, 106, 1) ? 'W' : '-');
1721 output_dyn_value(pbuf, sizeof pbuf, card->speed / 1000,
1722 kbit_units, false);
1723 simplelist_addline(SIMPLELIST_ADD_LINE,
1724 "Speed: %s", pbuf);
1725 output_dyn_value(pbuf, sizeof pbuf, card->tsac,
1726 nsec_units, false);
1727 simplelist_addline(SIMPLELIST_ADD_LINE,
1728 "Tsac: %s", pbuf);
1729 simplelist_addline(SIMPLELIST_ADD_LINE,
1730 "Nsac: %d clk", card->nsac);
1731 simplelist_addline(SIMPLELIST_ADD_LINE,
1732 "R2W: *%d", card->r2w_factor);
1733 simplelist_addline(SIMPLELIST_ADD_LINE,
1734 "IRmax: %d..%d mA",
1735 i_vmin[card_extract_bits(card->csd, 66, 3)],
1736 i_vmax[card_extract_bits(card->csd, 69, 3)]);
1737 simplelist_addline(SIMPLELIST_ADD_LINE,
1738 "IWmax: %d..%d mA",
1739 i_vmin[card_extract_bits(card->csd, 72, 3)],
1740 i_vmax[card_extract_bits(card->csd, 75, 3)]);
1742 else if (card->initialized == 0)
1744 simplelist_addline(SIMPLELIST_ADD_LINE, "Not Found!");
1746 #ifndef HAVE_MMC
1747 else /* card->initialized < 0 */
1749 simplelist_addline(SIMPLELIST_ADD_LINE, "Init Error! (%d)", card->initialized);
1751 #endif
1752 snprintf(title, 16, "[" CARDTYPE " %d]", *cardnum);
1753 gui_synclist_set_title(lists, title, Icon_NOICON);
1754 gui_synclist_set_nb_items(lists, simplelist_get_line_count());
1755 gui_synclist_select_item(lists, 0);
1756 btn = ACTION_REDRAW;
1758 return btn;
1760 #else /* !defined(HAVE_MMC) && !defined(HAVE_HOTSWAP) */
1761 static int disk_callback(int btn, struct gui_synclist *lists)
1763 (void)lists;
1764 int i;
1765 char buf[128];
1766 unsigned short* identify_info = ata_get_identify();
1767 bool timing_info_present = false;
1768 (void)btn;
1770 simplelist_set_line_count(0);
1772 for (i=0; i < 20; i++)
1773 ((unsigned short*)buf)[i]=htobe16(identify_info[i+27]);
1774 buf[40]=0;
1775 /* kill trailing space */
1776 for (i=39; i && buf[i]==' '; i--)
1777 buf[i] = 0;
1778 simplelist_addline(SIMPLELIST_ADD_LINE, "Model: %s", buf);
1779 for (i=0; i < 4; i++)
1780 ((unsigned short*)buf)[i]=htobe16(identify_info[i+23]);
1781 buf[8]=0;
1782 simplelist_addline(SIMPLELIST_ADD_LINE,
1783 "Firmware: %s", buf);
1784 snprintf(buf, sizeof buf, "%ld MB",
1785 ((unsigned long)identify_info[61] << 16 |
1786 (unsigned long)identify_info[60]) / 2048 );
1787 simplelist_addline(SIMPLELIST_ADD_LINE,
1788 "Size: %s", buf);
1789 unsigned long free;
1790 fat_size( IF_MV2(0,) NULL, &free );
1791 simplelist_addline(SIMPLELIST_ADD_LINE,
1792 "Free: %ld MB", free / 1024);
1793 simplelist_addline(SIMPLELIST_ADD_LINE,
1794 "Spinup time: %d ms", ata_spinup_time * (1000/HZ));
1795 i = identify_info[83] & (1<<3);
1796 simplelist_addline(SIMPLELIST_ADD_LINE,
1797 "Power mgmt: %s", i ? "enabled" : "unsupported");
1798 i = identify_info[83] & (1<<9);
1799 simplelist_addline(SIMPLELIST_ADD_LINE,
1800 "Noise mgmt: %s", i ? "enabled" : "unsupported");
1801 i = identify_info[82] & (1<<6);
1802 simplelist_addline(SIMPLELIST_ADD_LINE,
1803 "Read-ahead: %s", i ? "enabled" : "unsupported");
1804 timing_info_present = identify_info[53] & (1<<1);
1805 if(timing_info_present) {
1806 char pio3[2], pio4[2];pio3[1] = 0;
1807 pio4[1] = 0;
1808 pio3[0] = (identify_info[64] & (1<<0)) ? '3' : 0;
1809 pio4[0] = (identify_info[64] & (1<<1)) ? '4' : 0;
1810 simplelist_addline(SIMPLELIST_ADD_LINE,
1811 "PIO modes: 0 1 2 %s %s", pio3, pio4);
1813 else {
1814 simplelist_addline(SIMPLELIST_ADD_LINE,
1815 "No PIO mode info");
1817 timing_info_present = identify_info[53] & (1<<1);
1818 if(timing_info_present) {
1819 simplelist_addline(SIMPLELIST_ADD_LINE,
1820 "Cycle times %dns/%dns",
1821 identify_info[67],
1822 identify_info[68] );
1823 } else {
1824 simplelist_addline(SIMPLELIST_ADD_LINE,
1825 "No timing info");
1827 timing_info_present = identify_info[53] & (1<<1);
1828 if(timing_info_present) {
1829 i = identify_info[49] & (1<<11);
1830 simplelist_addline(SIMPLELIST_ADD_LINE,
1831 "IORDY support: %s", i ? "yes" : "no");
1832 i = identify_info[49] & (1<<10);
1833 simplelist_addline(SIMPLELIST_ADD_LINE,
1834 "IORDY disable: %s", i ? "yes" : "no");
1835 } else {
1836 simplelist_addline(SIMPLELIST_ADD_LINE,
1837 "No timing info");
1839 simplelist_addline(SIMPLELIST_ADD_LINE,
1840 "Cluster size: %d bytes", fat_get_cluster_size(IF_MV(0)));
1841 return btn;
1843 #endif /* !defined(HAVE_MMC) && !defined(HAVE_HOTSWAP) */
1844 static bool dbg_disk_info(void)
1846 struct simplelist_info info;
1847 simplelist_info_init(&info, "Disk Info", 1, NULL);
1848 #if defined(HAVE_MMC) || defined(HAVE_HOTSWAP)
1849 char title[16];
1850 int card = 0;
1851 info.callback_data = (void*)&card;
1852 info.title = title;
1853 #endif
1854 info.action_callback = disk_callback;
1855 info.hide_selection = true;
1856 return simplelist_show_list(&info);
1858 #endif /* !SIMULATOR */
1860 #ifdef HAVE_DIRCACHE
1861 static int dircache_callback(int btn, struct gui_synclist *lists)
1863 (void)btn; (void)lists;
1864 simplelist_set_line_count(0);
1865 simplelist_addline(SIMPLELIST_ADD_LINE, "Cache initialized: %s",
1866 dircache_is_enabled() ? "Yes" : "No");
1867 simplelist_addline(SIMPLELIST_ADD_LINE, "Cache size: %d B",
1868 dircache_get_cache_size());
1869 simplelist_addline(SIMPLELIST_ADD_LINE, "Last size: %d B",
1870 global_status.dircache_size);
1871 simplelist_addline(SIMPLELIST_ADD_LINE, "Limit: %d B",
1872 DIRCACHE_LIMIT);
1873 simplelist_addline(SIMPLELIST_ADD_LINE, "Reserve: %d/%d B",
1874 dircache_get_reserve_used(), DIRCACHE_RESERVE);
1875 simplelist_addline(SIMPLELIST_ADD_LINE, "Scanning took: %d s",
1876 dircache_get_build_ticks() / HZ);
1877 simplelist_addline(SIMPLELIST_ADD_LINE, "Entry count: %d",
1878 dircache_get_entry_count());
1879 return btn;
1882 static bool dbg_dircache_info(void)
1884 struct simplelist_info info;
1885 simplelist_info_init(&info, "Dircache Info", 7, NULL);
1886 info.action_callback = dircache_callback;
1887 info.hide_selection = true;
1888 return simplelist_show_list(&info);
1891 #endif /* HAVE_DIRCACHE */
1893 #ifdef HAVE_TAGCACHE
1894 static int database_callback(int btn, struct gui_synclist *lists)
1896 (void)lists;
1897 struct tagcache_stat *stat = tagcache_get_stat();
1898 static bool synced = false;
1900 simplelist_set_line_count(0);
1902 simplelist_addline(SIMPLELIST_ADD_LINE, "Initialized: %s",
1903 stat->initialized ? "Yes" : "No");
1904 simplelist_addline(SIMPLELIST_ADD_LINE, "DB Ready: %s",
1905 stat->ready ? "Yes" : "No");
1906 simplelist_addline(SIMPLELIST_ADD_LINE, "RAM Cache: %s",
1907 stat->ramcache ? "Yes" : "No");
1908 simplelist_addline(SIMPLELIST_ADD_LINE, "RAM: %d/%d B",
1909 stat->ramcache_used, stat->ramcache_allocated);
1910 simplelist_addline(SIMPLELIST_ADD_LINE, "Progress: %d%% (%d entries)",
1911 stat->progress, stat->processed_entries);
1912 simplelist_addline(SIMPLELIST_ADD_LINE, "Curfile: %s",
1913 stat->curentry ? stat->curentry : "---");
1914 simplelist_addline(SIMPLELIST_ADD_LINE, "Commit step: %d",
1915 stat->commit_step);
1916 simplelist_addline(SIMPLELIST_ADD_LINE, "Commit delayed: %s",
1917 stat->commit_delayed ? "Yes" : "No");
1920 if (synced)
1922 synced = false;
1923 tagcache_screensync_event();
1926 if (!btn && stat->curentry)
1928 synced = true;
1929 return ACTION_REDRAW;
1932 if (btn == ACTION_STD_CANCEL)
1933 tagcache_screensync_enable(false);
1935 return btn;
1937 static bool dbg_tagcache_info(void)
1939 struct simplelist_info info;
1940 simplelist_info_init(&info, "Database Info", 8, NULL);
1941 info.action_callback = database_callback;
1942 info.hide_selection = true;
1943 info.timeout = TIMEOUT_NOBLOCK;
1944 tagcache_screensync_enable(true);
1945 return simplelist_show_list(&info);
1947 #endif
1949 #if CONFIG_CPU == SH7034
1950 static bool dbg_save_roms(void)
1952 int fd;
1953 int oldmode = system_memory_guard(MEMGUARD_NONE);
1955 fd = creat("/internal_rom_0000-FFFF.bin");
1956 if(fd >= 0)
1958 write(fd, (void *)0, 0x10000);
1959 close(fd);
1962 fd = creat("/internal_rom_2000000-203FFFF.bin");
1963 if(fd >= 0)
1965 write(fd, (void *)0x2000000, 0x40000);
1966 close(fd);
1969 system_memory_guard(oldmode);
1970 return false;
1972 #elif defined CPU_COLDFIRE
1973 static bool dbg_save_roms(void)
1975 int fd;
1976 int oldmode = system_memory_guard(MEMGUARD_NONE);
1978 #if defined(IRIVER_H100_SERIES)
1979 fd = creat("/internal_rom_000000-1FFFFF.bin");
1980 #elif defined(IRIVER_H300_SERIES)
1981 fd = creat("/internal_rom_000000-3FFFFF.bin");
1982 #elif defined(IAUDIO_X5) || defined(IAUDIO_M5)
1983 fd = creat("/internal_rom_000000-3FFFFF.bin");
1984 #endif
1985 if(fd >= 0)
1987 write(fd, (void *)0, FLASH_SIZE);
1988 close(fd);
1990 system_memory_guard(oldmode);
1992 #ifdef HAVE_EEPROM
1993 fd = creat("/internal_eeprom.bin");
1994 if (fd >= 0)
1996 int old_irq_level;
1997 char buf[EEPROM_SIZE];
1998 int err;
2000 old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL);
2002 err = eeprom_24cxx_read(0, buf, sizeof buf);
2003 if (err)
2004 gui_syncsplash(HZ*3, "Eeprom read failure (%d)",err);
2005 else
2007 write(fd, buf, sizeof buf);
2010 set_irq_level(old_irq_level);
2012 close(fd);
2014 #endif
2016 return false;
2018 #elif defined(CPU_PP) && !(defined(SANSA_E200) || defined(SANSA_C200))
2019 static bool dbg_save_roms(void)
2021 int fd;
2023 fd = creat("/internal_rom_000000-0FFFFF.bin");
2024 if(fd >= 0)
2026 write(fd, (void *)0x20000000, FLASH_SIZE);
2027 close(fd);
2030 return false;
2032 #endif /* CPU */
2034 #ifndef SIMULATOR
2035 #if CONFIG_TUNER
2036 static int radio_callback(int btn, struct gui_synclist *lists)
2038 (void)lists;
2039 if (btn == ACTION_STD_CANCEL)
2040 return btn;
2041 simplelist_set_line_count(1);
2043 #if (CONFIG_TUNER & LV24020LP)
2044 simplelist_addline(SIMPLELIST_ADD_LINE,
2045 "CTRL_STAT: %02X", lv24020lp_get(LV24020LP_CTRL_STAT) );
2046 simplelist_addline(SIMPLELIST_ADD_LINE,
2047 "RADIO_STAT: %02X", lv24020lp_get(LV24020LP_REG_STAT) );
2048 simplelist_addline(SIMPLELIST_ADD_LINE,
2049 "MSS_FM: %d kHz", lv24020lp_get(LV24020LP_MSS_FM) );
2050 simplelist_addline(SIMPLELIST_ADD_LINE,
2051 "MSS_IF: %d Hz", lv24020lp_get(LV24020LP_MSS_IF) );
2052 simplelist_addline(SIMPLELIST_ADD_LINE,
2053 "MSS_SD: %d Hz", lv24020lp_get(LV24020LP_MSS_SD) );
2054 simplelist_addline(SIMPLELIST_ADD_LINE,
2055 "if_set: %d Hz", lv24020lp_get(LV24020LP_IF_SET) );
2056 simplelist_addline(SIMPLELIST_ADD_LINE,
2057 "sd_set: %d Hz", lv24020lp_get(LV24020LP_SD_SET) );
2058 #endif
2059 #if (CONFIG_TUNER & S1A0903X01)
2060 simplelist_addline(SIMPLELIST_ADD_LINE,
2061 "Samsung regs: %08X", s1a0903x01_get(RADIO_ALL));
2062 /* This one doesn't return dynamic data atm */
2063 #endif
2064 #if (CONFIG_TUNER & TEA5767)
2065 struct tea5767_dbg_info nfo;
2066 tea5767_dbg_info(&nfo);
2067 simplelist_addline(SIMPLELIST_ADD_LINE, "Philips regs:");
2068 simplelist_addline(SIMPLELIST_ADD_LINE,
2069 " Read: %02X %02X %02X %02X %02X",
2070 (unsigned)nfo.read_regs[0], (unsigned)nfo.read_regs[1],
2071 (unsigned)nfo.read_regs[2], (unsigned)nfo.read_regs[3],
2072 (unsigned)nfo.read_regs[4]);
2073 simplelist_addline(SIMPLELIST_ADD_LINE,
2074 " Write: %02X %02X %02X %02X %02X",
2075 (unsigned)nfo.write_regs[0], (unsigned)nfo.write_regs[1],
2076 (unsigned)nfo.write_regs[2], (unsigned)nfo.write_regs[3],
2077 (unsigned)nfo.write_regs[4]);
2078 #endif
2079 return ACTION_REDRAW;
2081 static bool dbg_fm_radio(void)
2083 struct simplelist_info info;
2084 simplelist_info_init(&info, "FM Radio", 1, NULL);
2085 simplelist_set_line_count(0);
2086 simplelist_addline(SIMPLELIST_ADD_LINE, "HW detected: %s",
2087 radio_hardware_present() ? "yes" : "no");
2089 info.action_callback = radio_hardware_present()?radio_callback : NULL;
2090 info.hide_selection = true;
2091 return simplelist_show_list(&info);
2093 #endif /* CONFIG_TUNER */
2094 #endif /* !SIMULATOR */
2096 #ifdef HAVE_LCD_BITMAP
2097 extern bool do_screendump_instead_of_usb;
2099 static bool dbg_screendump(void)
2101 do_screendump_instead_of_usb = !do_screendump_instead_of_usb;
2102 gui_syncsplash(HZ, "Screendump %s",
2103 do_screendump_instead_of_usb?"enabled":"disabled");
2104 return false;
2106 #endif /* HAVE_LCD_BITMAP */
2108 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
2109 static bool dbg_set_memory_guard(void)
2111 static const struct opt_items names[MAXMEMGUARD] = {
2112 { "None", -1 },
2113 { "Flash ROM writes", -1 },
2114 { "Zero area (all)", -1 }
2116 int mode = system_memory_guard(MEMGUARD_KEEP);
2118 set_option( "Catch mem accesses", &mode, INT, names, MAXMEMGUARD, NULL);
2119 system_memory_guard(mode);
2121 return false;
2123 #endif /* CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) */
2125 #if defined(TOSHIBA_GIGABEAT_F) && !defined(SIMULATOR)
2127 extern volatile bool lcd_poweroff;
2129 static bool dbg_lcd_power_off(void)
2131 lcd_setmargins(0, 0);
2133 while(1)
2135 int button;
2137 lcd_clear_display();
2138 lcd_puts(0, 0, "LCD Power Off");
2139 if(lcd_poweroff)
2140 lcd_puts(1, 1, "Yes");
2141 else
2142 lcd_puts(1, 1, "No");
2144 lcd_update();
2146 button = get_action(CONTEXT_STD,HZ/5);
2147 switch(button)
2149 case ACTION_STD_PREV:
2150 case ACTION_STD_NEXT:
2151 lcd_poweroff = !lcd_poweroff;
2152 break;
2153 case ACTION_STD_OK:
2154 case ACTION_STD_CANCEL:
2155 return false;
2156 default:
2157 sleep(HZ/10);
2158 break;
2161 return false;
2163 #endif
2165 #if defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS)
2166 static bool dbg_write_eeprom(void)
2168 int fd;
2169 int rc;
2170 int old_irq_level;
2171 char buf[EEPROM_SIZE];
2172 int err;
2174 fd = open("/internal_eeprom.bin", O_RDONLY);
2176 if (fd >= 0)
2178 rc = read(fd, buf, EEPROM_SIZE);
2180 if(rc == EEPROM_SIZE)
2182 old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL);
2184 err = eeprom_24cxx_write(0, buf, sizeof buf);
2185 if (err)
2186 gui_syncsplash(HZ*3, "Eeprom write failure (%d)",err);
2187 else
2188 gui_syncsplash(HZ*3, "Eeprom written successfully");
2190 set_irq_level(old_irq_level);
2192 else
2194 gui_syncsplash(HZ*3, "File read error (%d)",rc);
2196 close(fd);
2198 else
2200 gui_syncsplash(HZ*3, "Failed to open 'internal_eeprom.bin'");
2203 return false;
2205 #endif /* defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS) */
2206 #ifdef CPU_BOOST_LOGGING
2207 static bool cpu_boost_log(void)
2209 int i = 0,j=0;
2210 int count = cpu_boost_log_getcount();
2211 int lines = LCD_HEIGHT/SYSFONT_HEIGHT;
2212 char *str;
2213 bool done;
2214 lcd_setmargins(0, 0);
2215 lcd_setfont(FONT_SYSFIXED);
2216 str = cpu_boost_log_getlog_first();
2217 while (i < count)
2219 lcd_clear_display();
2220 for(j=0; j<lines; j++,i++)
2222 if (!str)
2223 str = cpu_boost_log_getlog_next();
2224 if (str)
2226 lcd_puts(0, j,str);
2228 str = NULL;
2230 lcd_update();
2231 done = false;
2232 while (!done)
2234 switch(get_action(CONTEXT_STD,TIMEOUT_BLOCK))
2236 case ACTION_STD_OK:
2237 case ACTION_STD_PREV:
2238 case ACTION_STD_NEXT:
2239 done = true;
2240 break;
2241 case ACTION_STD_CANCEL:
2242 i = count;
2243 done = true;
2244 break;
2248 get_action(CONTEXT_STD,TIMEOUT_BLOCK);
2249 lcd_setfont(FONT_UI);
2250 return false;
2252 #endif
2256 /****** The menu *********/
2257 struct the_menu_item {
2258 unsigned char *desc; /* string or ID */
2259 bool (*function) (void); /* return true if USB was connected */
2261 static const struct the_menu_item menuitems[] = {
2262 #if defined(TOSHIBA_GIGABEAT_F) && !defined(SIMULATOR)
2263 { "LCD Power Off", dbg_lcd_power_off },
2264 #endif
2265 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || \
2266 (defined(CPU_PP) && !(defined(SANSA_E200) || defined(SANSA_C200)))
2267 { "Dump ROM contents", dbg_save_roms },
2268 #endif
2269 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || defined(CPU_PP) || CONFIG_CPU == S3C2440
2270 { "View I/O ports", dbg_ports },
2271 #endif
2272 #if defined(HAVE_TSC2100) && !defined(SIMULATOR)
2273 { "TSC2100 debug", tsc2100_debug },
2274 #endif
2275 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
2276 { "CPU frequency", dbg_cpufreq },
2277 #endif
2278 #if defined(IRIVER_H100_SERIES) && !defined(SIMULATOR)
2279 { "S/PDIF analyzer", dbg_spdif },
2280 #endif
2281 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
2282 { "Catch mem accesses", dbg_set_memory_guard },
2283 #endif
2284 { "View OS stacks", dbg_os },
2285 #ifdef HAVE_LCD_BITMAP
2286 #ifndef SIMULATOR
2287 { "View battery", view_battery },
2288 #endif
2289 { "Screendump", dbg_screendump },
2290 #endif
2291 #ifndef SIMULATOR
2292 { "View HW info", dbg_hw_info },
2293 #endif
2294 #ifndef SIMULATOR
2295 { "View partitions", dbg_partitions },
2296 #endif
2297 #ifndef SIMULATOR
2298 { "View disk info", dbg_disk_info },
2299 #endif
2300 #ifdef HAVE_DIRCACHE
2301 { "View dircache info", dbg_dircache_info },
2302 #endif
2303 #ifdef HAVE_TAGCACHE
2304 { "View database info", dbg_tagcache_info },
2305 #endif
2306 #ifdef HAVE_LCD_BITMAP
2307 #if CONFIG_CODEC == SWCODEC
2308 { "View buffering thread", dbg_buffering_thread },
2309 #elif !defined(SIMULATOR)
2310 { "View audio thread", dbg_audio_thread },
2311 #endif
2312 #ifdef PM_DEBUG
2313 { "pm histogram", peak_meter_histogram},
2314 #endif /* PM_DEBUG */
2315 #endif /* HAVE_LCD_BITMAP */
2316 #ifndef SIMULATOR
2317 #if CONFIG_TUNER
2318 { "FM Radio", dbg_fm_radio },
2319 #endif
2320 #endif
2321 #if defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS)
2322 { "Write back EEPROM", dbg_write_eeprom },
2323 #endif
2324 #ifdef ROCKBOX_HAS_LOGF
2325 {"logf", logfdisplay },
2326 {"logfdump", logfdump },
2327 #endif
2328 #ifdef CPU_BOOST_LOGGING
2329 {"cpu_boost log",cpu_boost_log},
2330 #endif
2332 static int menu_action_callback(int btn, struct gui_synclist *lists)
2334 if (btn == ACTION_STD_OK)
2336 menuitems[gui_synclist_get_sel_pos(lists)].function();
2337 btn = ACTION_REDRAW;
2339 return btn;
2341 static char* dbg_menu_getname(int item, void * data, char *buffer)
2343 (void)data; (void)buffer;
2344 return menuitems[item].desc;
2346 bool debug_menu(void)
2348 struct simplelist_info info;
2350 simplelist_info_init(&info, "Debug Menu", ARRAYLEN(menuitems), NULL);
2351 info.action_callback = menu_action_callback;
2352 info.get_name = dbg_menu_getname;
2354 return simplelist_show_list(&info);