Hopefully the last word on getting rid of yield_codecs loops (cut read chunk to 16kB...
[Rockbox.git] / apps / debug_menu.c
bloba8eb786f838de1957d3122597fb7bce774562af2
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 # define DEBUG_CANCEL BUTTON_REW
989 #elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \
990 (CONFIG_KEYPAD == SANSA_C200_PAD)
991 # define DEBUG_CANCEL BUTTON_LEFT
992 #endif /* key definitions */
994 /* Test code!!! */
995 bool dbg_ports(void)
997 #if CONFIG_CPU == SH7034
998 unsigned short porta;
999 unsigned short portb;
1000 unsigned char portc;
1001 char buf[32];
1002 int adc_battery_voltage, adc_battery_level;
1004 lcd_setfont(FONT_SYSFIXED);
1005 lcd_setmargins(0, 0);
1006 lcd_clear_display();
1008 while(1)
1010 porta = PADR;
1011 portb = PBDR;
1012 portc = PCDR;
1014 snprintf(buf, 32, "PADR: %04x", porta);
1015 lcd_puts(0, 0, buf);
1016 snprintf(buf, 32, "PBDR: %04x", portb);
1017 lcd_puts(0, 1, buf);
1019 snprintf(buf, 32, "AN0: %03x AN4: %03x", adc_read(0), adc_read(4));
1020 lcd_puts(0, 2, buf);
1021 snprintf(buf, 32, "AN1: %03x AN5: %03x", adc_read(1), adc_read(5));
1022 lcd_puts(0, 3, buf);
1023 snprintf(buf, 32, "AN2: %03x AN6: %03x", adc_read(2), adc_read(6));
1024 lcd_puts(0, 4, buf);
1025 snprintf(buf, 32, "AN3: %03x AN7: %03x", adc_read(3), adc_read(7));
1026 lcd_puts(0, 5, buf);
1028 battery_read_info(&adc_battery_voltage, &adc_battery_level);
1029 snprintf(buf, 32, "Batt: %d.%03dV %d%% ", adc_battery_voltage / 1000,
1030 adc_battery_voltage % 1000, adc_battery_level);
1031 lcd_puts(0, 6, buf);
1033 lcd_update();
1034 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1035 return false;
1037 #elif defined(CPU_COLDFIRE)
1038 unsigned int gpio_out;
1039 unsigned int gpio1_out;
1040 unsigned int gpio_read;
1041 unsigned int gpio1_read;
1042 unsigned int gpio_function;
1043 unsigned int gpio1_function;
1044 unsigned int gpio_enable;
1045 unsigned int gpio1_enable;
1046 int adc_buttons, adc_remote;
1047 int adc_battery_voltage, adc_battery_level;
1048 char buf[128];
1049 int line;
1051 lcd_setmargins(0, 0);
1052 lcd_clear_display();
1053 lcd_setfont(FONT_SYSFIXED);
1055 while(1)
1057 line = 0;
1058 gpio_read = GPIO_READ;
1059 gpio1_read = GPIO1_READ;
1060 gpio_out = GPIO_OUT;
1061 gpio1_out = GPIO1_OUT;
1062 gpio_function = GPIO_FUNCTION;
1063 gpio1_function = GPIO1_FUNCTION;
1064 gpio_enable = GPIO_ENABLE;
1065 gpio1_enable = GPIO1_ENABLE;
1067 snprintf(buf, sizeof(buf), "GPIO_READ: %08x", gpio_read);
1068 lcd_puts(0, line++, buf);
1069 snprintf(buf, sizeof(buf), "GPIO_OUT: %08x", gpio_out);
1070 lcd_puts(0, line++, buf);
1071 snprintf(buf, sizeof(buf), "GPIO_FUNCTION: %08x", gpio_function);
1072 lcd_puts(0, line++, buf);
1073 snprintf(buf, sizeof(buf), "GPIO_ENABLE: %08x", gpio_enable);
1074 lcd_puts(0, line++, buf);
1076 snprintf(buf, sizeof(buf), "GPIO1_READ: %08x", gpio1_read);
1077 lcd_puts(0, line++, buf);
1078 snprintf(buf, sizeof(buf), "GPIO1_OUT: %08x", gpio1_out);
1079 lcd_puts(0, line++, buf);
1080 snprintf(buf, sizeof(buf), "GPIO1_FUNCTION: %08x", gpio1_function);
1081 lcd_puts(0, line++, buf);
1082 snprintf(buf, sizeof(buf), "GPIO1_ENABLE: %08x", gpio1_enable);
1083 lcd_puts(0, line++, buf);
1085 adc_buttons = adc_read(ADC_BUTTONS);
1086 adc_remote = adc_read(ADC_REMOTE);
1087 battery_read_info(&adc_battery_voltage, &adc_battery_level);
1088 #if defined(IAUDIO_X5) || defined(IAUDIO_M5) || defined(IRIVER_H300_SERIES)
1089 snprintf(buf, sizeof(buf), "ADC_BUTTONS (%c): %02x",
1090 button_scan_enabled() ? '+' : '-', adc_buttons);
1091 #else
1092 snprintf(buf, sizeof(buf), "ADC_BUTTONS: %02x", adc_buttons);
1093 #endif
1094 lcd_puts(0, line++, buf);
1095 #if defined(IAUDIO_X5) || defined(IAUDIO_M5)
1096 snprintf(buf, sizeof(buf), "ADC_REMOTE (%c): %02x",
1097 remote_detect() ? '+' : '-', adc_remote);
1098 #else
1099 snprintf(buf, sizeof(buf), "ADC_REMOTE: %02x", adc_remote);
1100 #endif
1101 lcd_puts(0, line++, buf);
1102 #if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES)
1103 snprintf(buf, sizeof(buf), "ADC_REMOTEDETECT: %02x",
1104 adc_read(ADC_REMOTEDETECT));
1105 lcd_puts(0, line++, buf);
1106 #endif
1108 snprintf(buf, 32, "Batt: %d.%03dV %d%% ", adc_battery_voltage / 1000,
1109 adc_battery_voltage % 1000, adc_battery_level);
1110 lcd_puts(0, line++, buf);
1112 #if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES)
1113 snprintf(buf, sizeof(buf), "remotetype: %d", remote_type());
1114 lcd_puts(0, line++, buf);
1115 #endif
1117 lcd_update();
1118 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1119 return false;
1122 #elif defined(CPU_PP502x)
1124 unsigned int gpio_a, gpio_b, gpio_c, gpio_d;
1125 unsigned int gpio_e, gpio_f, gpio_g, gpio_h;
1126 unsigned int gpio_i, gpio_j, gpio_k, gpio_l;
1128 char buf[128];
1129 int line;
1131 lcd_setmargins(0, 0);
1132 lcd_clear_display();
1133 lcd_setfont(FONT_SYSFIXED);
1135 while(1)
1137 gpio_a = GPIOA_INPUT_VAL;
1138 gpio_b = GPIOB_INPUT_VAL;
1139 gpio_c = GPIOC_INPUT_VAL;
1141 gpio_g = GPIOG_INPUT_VAL;
1142 gpio_h = GPIOH_INPUT_VAL;
1143 gpio_i = GPIOI_INPUT_VAL;
1145 line = 0;
1146 snprintf(buf, sizeof(buf), "GPIO_A: %02x GPIO_G: %02x", gpio_a, gpio_g);
1147 lcd_puts(0, line++, buf);
1148 snprintf(buf, sizeof(buf), "GPIO_B: %02x GPIO_H: %02x", gpio_b, gpio_h);
1149 lcd_puts(0, line++, buf);
1150 snprintf(buf, sizeof(buf), "GPIO_C: %02x GPIO_I: %02x", gpio_c, gpio_i);
1151 lcd_puts(0, line++, buf);
1153 gpio_d = GPIOD_INPUT_VAL;
1154 gpio_e = GPIOE_INPUT_VAL;
1155 gpio_f = GPIOF_INPUT_VAL;
1157 gpio_j = GPIOJ_INPUT_VAL;
1158 gpio_k = GPIOK_INPUT_VAL;
1159 gpio_l = GPIOL_INPUT_VAL;
1161 snprintf(buf, sizeof(buf), "GPIO_D: %02x GPIO_J: %02x", gpio_d, gpio_j);
1162 lcd_puts(0, line++, buf);
1163 snprintf(buf, sizeof(buf), "GPIO_E: %02x GPIO_K: %02x", gpio_e, gpio_k);
1164 lcd_puts(0, line++, buf);
1165 snprintf(buf, sizeof(buf), "GPIO_F: %02x GPIO_L: %02x", gpio_f, gpio_l);
1166 lcd_puts(0, line++, buf);
1167 line++;
1169 snprintf(buf, sizeof(buf), "GPO32: %08lx", GPO32_VAL);
1170 lcd_puts(0, line++, buf);
1171 snprintf(buf, sizeof(buf), "DEV_EN: %08lx", DEV_EN);
1172 lcd_puts(0, line++, buf);
1173 snprintf(buf, sizeof(buf), "DEV_EN2: %08lx", DEV_EN2);
1174 lcd_puts(0, line++, buf);
1175 snprintf(buf, sizeof(buf), "DEV_EN3: %08lx", inl(0x60006044));
1176 lcd_puts(0, line++, buf); /* to be verified */
1178 #if defined(IRIVER_H10) || defined(IRIVER_H10_5GB)
1179 line++;
1180 snprintf(buf, sizeof(buf), "BATT: %03x UNK1: %03x", adc_read(ADC_BATTERY),
1181 adc_read(ADC_UNKNOWN_1));
1182 lcd_puts(0, line++, buf);
1183 snprintf(buf, sizeof(buf), "REM: %03x PAD: %03x", adc_read(ADC_REMOTE),
1184 adc_read(ADC_SCROLLPAD));
1185 lcd_puts(0, line++, buf);
1186 #elif defined(SANSA_E200)
1187 line++;
1188 snprintf(buf, sizeof(buf), "ADC_BVDD: %4d", adc_read(ADC_BVDD));
1189 lcd_puts(0, line++, buf);
1190 snprintf(buf, sizeof(buf), "ADC_RTCSUP: %4d", adc_read(ADC_RTCSUP));
1191 lcd_puts(0, line++, buf);
1192 snprintf(buf, sizeof(buf), "ADC_UVDD: %4d", adc_read(ADC_UVDD));
1193 lcd_puts(0, line++, buf);
1194 snprintf(buf, sizeof(buf), "ADC_CHG_IN: %4d", adc_read(ADC_CHG_IN));
1195 lcd_puts(0, line++, buf);
1196 snprintf(buf, sizeof(buf), "ADC_CVDD: %4d", adc_read(ADC_CVDD));
1197 lcd_puts(0, line++, buf);
1198 snprintf(buf, sizeof(buf), "ADC_BATTEMP: %4d", adc_read(ADC_BATTEMP));
1199 lcd_puts(0, line++, buf);
1200 snprintf(buf, sizeof(buf), "ADC_MICSUP1: %4d", adc_read(ADC_MICSUP1));
1201 lcd_puts(0, line++, buf);
1202 snprintf(buf, sizeof(buf), "ADC_MICSUP2: %4d", adc_read(ADC_MICSUP2));
1203 lcd_puts(0, line++, buf);
1204 snprintf(buf, sizeof(buf), "ADC_VBE1: %4d", adc_read(ADC_VBE1));
1205 lcd_puts(0, line++, buf);
1206 snprintf(buf, sizeof(buf), "ADC_VBE2: %4d", adc_read(ADC_VBE2));
1207 lcd_puts(0, line++, buf);
1208 snprintf(buf, sizeof(buf), "ADC_I_MICSUP1:%4d", adc_read(ADC_I_MICSUP1));
1209 lcd_puts(0, line++, buf);
1210 snprintf(buf, sizeof(buf), "ADC_I_MICSUP2:%4d", adc_read(ADC_I_MICSUP2));
1211 lcd_puts(0, line++, buf);
1212 snprintf(buf, sizeof(buf), "ADC_VBAT: %4d", adc_read(ADC_VBAT));
1213 lcd_puts(0, line++, buf);
1214 #endif
1215 lcd_update();
1216 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1217 return false;
1220 #elif CONFIG_CPU == PP5002
1221 unsigned int gpio_a, gpio_b, gpio_c, gpio_d;
1223 char buf[128];
1224 int line;
1226 lcd_setmargins(0, 0);
1227 lcd_clear_display();
1228 lcd_setfont(FONT_SYSFIXED);
1230 while(1)
1232 gpio_a = GPIOA_INPUT_VAL;
1233 gpio_b = GPIOB_INPUT_VAL;
1234 gpio_c = GPIOC_INPUT_VAL;
1235 gpio_d = GPIOD_INPUT_VAL;
1237 line = 0;
1238 snprintf(buf, sizeof(buf), "GPIO_A: %02x GPIO_B: %02x", gpio_a, gpio_b);
1239 lcd_puts(0, line++, buf);
1240 snprintf(buf, sizeof(buf), "GPIO_C: %02x GPIO_D: %02x", gpio_c, gpio_d);
1241 lcd_puts(0, line++, buf);
1243 snprintf(buf, sizeof(buf), "DEV_EN: %08lx", DEV_EN);
1244 lcd_puts(0, line++, buf);
1245 snprintf(buf, sizeof(buf), "CLOCK_ENABLE: %08lx", CLOCK_ENABLE);
1246 lcd_puts(0, line++, buf);
1247 snprintf(buf, sizeof(buf), "CLOCK_SOURCE: %08lx", CLOCK_SOURCE);
1248 lcd_puts(0, line++, buf);
1249 snprintf(buf, sizeof(buf), "PLL_CONTROL: %08lx", PLL_CONTROL);
1250 lcd_puts(0, line++, buf);
1251 snprintf(buf, sizeof(buf), "PLL_DIV: %08lx", PLL_DIV);
1252 lcd_puts(0, line++, buf);
1253 snprintf(buf, sizeof(buf), "PLL_MULT: %08lx", PLL_MULT);
1254 lcd_puts(0, line++, buf);
1255 snprintf(buf, sizeof(buf), "TIMING1_CTL: %08lx", TIMING1_CTL);
1256 lcd_puts(0, line++, buf);
1257 snprintf(buf, sizeof(buf), "TIMING2_CTL: %08lx", TIMING2_CTL);
1258 lcd_puts(0, line++, buf);
1260 lcd_update();
1261 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1262 return false;
1264 #else
1265 return __dbg_ports();
1266 #endif /* CPU */
1267 return false;
1269 #else /* !HAVE_LCD_BITMAP */
1270 bool dbg_ports(void)
1272 unsigned short porta;
1273 unsigned short portb;
1274 unsigned char portc;
1275 char buf[32];
1276 int button;
1277 int adc_battery_voltage;
1278 int currval = 0;
1280 lcd_clear_display();
1282 while(1)
1284 porta = PADR;
1285 portb = PBDR;
1286 portc = PCDR;
1288 switch(currval)
1290 case 0:
1291 snprintf(buf, 32, "PADR: %04x", porta);
1292 break;
1293 case 1:
1294 snprintf(buf, 32, "PBDR: %04x", portb);
1295 break;
1296 case 2:
1297 snprintf(buf, 32, "AN0: %03x", adc_read(0));
1298 break;
1299 case 3:
1300 snprintf(buf, 32, "AN1: %03x", adc_read(1));
1301 break;
1302 case 4:
1303 snprintf(buf, 32, "AN2: %03x", adc_read(2));
1304 break;
1305 case 5:
1306 snprintf(buf, 32, "AN3: %03x", adc_read(3));
1307 break;
1308 case 6:
1309 snprintf(buf, 32, "AN4: %03x", adc_read(4));
1310 break;
1311 case 7:
1312 snprintf(buf, 32, "AN5: %03x", adc_read(5));
1313 break;
1314 case 8:
1315 snprintf(buf, 32, "AN6: %03x", adc_read(6));
1316 break;
1317 case 9:
1318 snprintf(buf, 32, "AN7: %03x", adc_read(7));
1319 break;
1320 break;
1322 lcd_puts(0, 0, buf);
1324 battery_read_info(&adc_battery_voltage, NULL);
1325 snprintf(buf, 32, "Batt: %d.%03dV", adc_battery_voltage / 1000,
1326 adc_battery_voltage % 1000);
1327 lcd_puts(0, 1, buf);
1328 lcd_update();
1330 button = get_action(CONTEXT_SETTINGS,HZ/5);
1332 switch(button)
1334 case ACTION_STD_CANCEL:
1335 return false;
1337 case ACTION_SETTINGS_DEC:
1338 currval--;
1339 if(currval < 0)
1340 currval = 9;
1341 break;
1343 case ACTION_SETTINGS_INC:
1344 currval++;
1345 if(currval > 9)
1346 currval = 0;
1347 break;
1350 return false;
1352 #endif /* !HAVE_LCD_BITMAP */
1353 #endif /* !SIMULATOR */
1355 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
1356 static bool dbg_cpufreq(void)
1358 char buf[128];
1359 int line;
1360 int button;
1362 #ifdef HAVE_LCD_BITMAP
1363 lcd_setmargins(0, 0);
1364 lcd_setfont(FONT_SYSFIXED);
1365 #endif
1366 lcd_clear_display();
1368 while(1)
1370 line = 0;
1372 snprintf(buf, sizeof(buf), "Frequency: %ld", FREQ);
1373 lcd_puts(0, line++, buf);
1375 snprintf(buf, sizeof(buf), "boost_counter: %d", get_cpu_boost_counter());
1376 lcd_puts(0, line++, buf);
1378 lcd_update();
1379 button = get_action(CONTEXT_STD,HZ/10);
1381 switch(button)
1383 case ACTION_STD_PREV:
1384 cpu_boost(true);
1385 break;
1387 case ACTION_STD_NEXT:
1388 cpu_boost(false);
1389 break;
1391 case ACTION_STD_OK:
1392 while (get_cpu_boost_counter() > 0)
1393 cpu_boost(false);
1394 set_cpu_frequency(CPUFREQ_DEFAULT);
1395 break;
1397 case ACTION_STD_CANCEL:
1398 return false;
1402 return false;
1404 #endif /* HAVE_ADJUSTABLE_CPU_FREQ */
1406 #if defined(HAVE_TSC2100) && !defined(SIMULATOR)
1407 #include "tsc2100.h"
1408 char *itob(int n, int len)
1410 static char binary[64];
1411 int i,j;
1412 for (i=1, j=0;i<=len;i++)
1414 binary[j++] = n&(1<<(len-i))?'1':'0';
1415 if (i%4 == 0)
1416 binary[j++] = ' ';
1418 binary[j] = '\0';
1419 return binary;
1421 static char* tsc2100_debug_getname(int selected_item, void * data, char *buffer)
1423 int *page = (int*)data;
1424 bool reserved = false;
1425 switch (*page)
1427 case 0:
1428 if ((selected_item > 0x0a) ||
1429 (selected_item == 0x04) ||
1430 (selected_item == 0x08))
1431 reserved = true;
1432 break;
1433 case 1:
1434 if ((selected_item > 0x05) ||
1435 (selected_item == 0x02))
1436 reserved = true;
1437 break;
1438 case 2:
1439 if (selected_item > 0x1e)
1440 reserved = true;
1441 break;
1443 if (reserved)
1444 snprintf(buffer, MAX_PATH, "%02x: RESERVED", selected_item);
1445 else
1446 snprintf(buffer, MAX_PATH, "%02x: %s", selected_item,
1447 itob(tsc2100_readreg(*page, selected_item)&0xffff,16));
1448 return buffer;
1450 static int tsc2100debug_action_callback(int action, struct gui_synclist *lists)
1452 int *page = (int*)lists->gui_list[SCREEN_MAIN].data;
1453 if (action == ACTION_STD_OK)
1455 *page = (*page+1)%3;
1456 snprintf(lists->gui_list[SCREEN_MAIN].title, 32,
1457 "tsc2100 registers - Page %d", *page);
1458 return ACTION_REDRAW;
1460 return action;
1462 bool tsc2100_debug(void)
1464 int page = 0;
1465 char title[32] = "tsc2100 registers - Page 0";
1466 struct simplelist_info info;
1467 simplelist_info_init(&info, title, 32, &page);
1468 info.timeout = HZ/100;
1469 info.get_name = tsc2100_debug_getname;
1470 info.action_callback= tsc2100debug_action_callback;
1471 return simplelist_show_list(&info);
1473 #endif
1474 #ifndef SIMULATOR
1475 #ifdef HAVE_LCD_BITMAP
1477 * view_battery() shows a automatically scaled graph of the battery voltage
1478 * over time. Usable for estimating battery life / charging rate.
1479 * The power_history array is updated in power_thread of powermgmt.c.
1482 #define BAT_LAST_VAL MIN(LCD_WIDTH, POWER_HISTORY_LEN)
1483 #define BAT_YSPACE (LCD_HEIGHT - 20)
1485 static bool view_battery(void)
1487 int view = 0;
1488 int i, x, y;
1489 unsigned short maxv, minv;
1490 char buf[32];
1492 lcd_setmargins(0, 0);
1493 lcd_setfont(FONT_SYSFIXED);
1495 while(1)
1497 lcd_clear_display();
1498 switch (view) {
1499 case 0: /* voltage history graph */
1500 /* Find maximum and minimum voltage for scaling */
1501 minv = power_history[0];
1502 maxv = minv + 1;
1503 for (i = 1; i < BAT_LAST_VAL && power_history[i]; i++) {
1504 if (power_history[i] > maxv)
1505 maxv = power_history[i];
1506 if (power_history[i] < minv)
1507 minv = power_history[i];
1510 snprintf(buf, 30, "Battery %d.%03d", power_history[0] / 1000,
1511 power_history[0] % 1000);
1512 lcd_puts(0, 0, buf);
1513 snprintf(buf, 30, "scale %d.%03d-%d.%03dV",
1514 minv / 1000, minv % 1000, maxv / 1000, maxv % 1000);
1515 lcd_puts(0, 1, buf);
1517 x = 0;
1518 for (i = BAT_LAST_VAL - 1; i >= 0; i--) {
1519 y = (power_history[i] - minv) * BAT_YSPACE / (maxv - minv);
1520 lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
1521 lcd_vline(x, LCD_HEIGHT-1, 20);
1522 lcd_set_drawmode(DRMODE_SOLID);
1523 lcd_vline(x, LCD_HEIGHT-1,
1524 MIN(MAX(LCD_HEIGHT-1 - y, 20), LCD_HEIGHT-1));
1525 x++;
1528 break;
1530 case 1: /* status: */
1531 lcd_puts(0, 0, "Power status:");
1533 battery_read_info(&y, NULL);
1534 snprintf(buf, 30, "Battery: %d.%03d V", y / 1000, y % 1000);
1535 lcd_puts(0, 1, buf);
1536 #ifdef ADC_EXT_POWER
1537 y = (adc_read(ADC_EXT_POWER) * EXT_SCALE_FACTOR) / 1000;
1538 snprintf(buf, 30, "External: %d.%03d V", y / 1000, y % 1000);
1539 lcd_puts(0, 2, buf);
1540 #endif
1541 #if CONFIG_CHARGING
1542 #if CONFIG_CHARGING == CHARGING_CONTROL
1543 snprintf(buf, 30, "Chgr: %s %s",
1544 charger_inserted() ? "present" : "absent",
1545 charger_enabled ? "on" : "off");
1546 lcd_puts(0, 3, buf);
1547 snprintf(buf, 30, "short delta: %d", short_delta);
1548 lcd_puts(0, 5, buf);
1549 snprintf(buf, 30, "long delta: %d", long_delta);
1550 lcd_puts(0, 6, buf);
1551 lcd_puts(0, 7, power_message);
1552 snprintf(buf, 30, "USB Inserted: %s",
1553 usb_inserted() ? "yes" : "no");
1554 lcd_puts(0, 8, buf);
1555 #if defined IRIVER_H300_SERIES
1556 snprintf(buf, 30, "USB Charging Enabled: %s",
1557 usb_charging_enabled() ? "yes" : "no");
1558 lcd_puts(0, 9, buf);
1559 #endif
1560 #else /* CONFIG_CHARGING != CHARGING_CONTROL */
1561 #if defined IPOD_NANO || defined IPOD_VIDEO
1562 int usb_pwr = (GPIOL_INPUT_VAL & 0x10)?true:false;
1563 int ext_pwr = (GPIOL_INPUT_VAL & 0x08)?false:true;
1564 int dock = (GPIOA_INPUT_VAL & 0x10)?true:false;
1565 int charging = (GPIOB_INPUT_VAL & 0x01)?false:true;
1566 int headphone= (GPIOA_INPUT_VAL & 0x80)?true:false;
1568 snprintf(buf, 30, "USB pwr: %s",
1569 usb_pwr ? "present" : "absent");
1570 lcd_puts(0, 3, buf);
1571 snprintf(buf, 30, "EXT pwr: %s",
1572 ext_pwr ? "present" : "absent");
1573 lcd_puts(0, 4, buf);
1574 snprintf(buf, 30, "Battery: %s",
1575 charging ? "charging" : (usb_pwr||ext_pwr) ? "charged" : "discharging");
1576 lcd_puts(0, 5, buf);
1577 snprintf(buf, 30, "Dock mode: %s",
1578 dock ? "enabled" : "disabled");
1579 lcd_puts(0, 6, buf);
1580 snprintf(buf, 30, "Headphone: %s",
1581 headphone ? "connected" : "disconnected");
1582 lcd_puts(0, 7, buf);
1583 #else
1584 snprintf(buf, 30, "Charger: %s",
1585 charger_inserted() ? "present" : "absent");
1586 lcd_puts(0, 3, buf);
1587 #endif
1588 #endif /* CONFIG_CHARGING != CHARGING_CONTROL */
1589 #endif /* CONFIG_CHARGING */
1590 break;
1592 case 2: /* voltage deltas: */
1593 lcd_puts(0, 0, "Voltage deltas:");
1595 for (i = 0; i <= 6; i++) {
1596 y = power_history[i] - power_history[i+1];
1597 snprintf(buf, 30, "-%d min: %s%d.%03d V", i,
1598 (y < 0) ? "-" : "", ((y < 0) ? y * -1 : y) / 1000,
1599 ((y < 0) ? y * -1 : y ) % 1000);
1600 lcd_puts(0, i+1, buf);
1602 break;
1604 case 3: /* remaining time estimation: */
1606 #if CONFIG_CHARGING == CHARGING_CONTROL
1607 snprintf(buf, 30, "charge_state: %d", charge_state);
1608 lcd_puts(0, 0, buf);
1610 snprintf(buf, 30, "Cycle time: %d m", powermgmt_last_cycle_startstop_min);
1611 lcd_puts(0, 1, buf);
1613 snprintf(buf, 30, "Lvl@cyc st: %d%%", powermgmt_last_cycle_level);
1614 lcd_puts(0, 2, buf);
1616 snprintf(buf, 30, "P=%2d I=%2d", pid_p, pid_i);
1617 lcd_puts(0, 3, buf);
1619 snprintf(buf, 30, "Trickle sec: %d/60", trickle_sec);
1620 lcd_puts(0, 4, buf);
1621 #endif /* CONFIG_CHARGING == CHARGING_CONTROL */
1623 snprintf(buf, 30, "Last PwrHist: %d.%03dV",
1624 power_history[0] / 1000,
1625 power_history[0] % 1000);
1626 lcd_puts(0, 5, buf);
1628 snprintf(buf, 30, "battery level: %d%%", battery_level());
1629 lcd_puts(0, 6, buf);
1631 snprintf(buf, 30, "Est. remain: %d m", battery_time());
1632 lcd_puts(0, 7, buf);
1633 break;
1636 lcd_update();
1638 switch(get_action(CONTEXT_SETTINGS,HZ/2))
1640 case ACTION_SETTINGS_DEC:
1641 if (view)
1642 view--;
1643 break;
1645 case ACTION_SETTINGS_INC:
1646 if (view < 3)
1647 view++;
1648 break;
1650 case ACTION_STD_CANCEL:
1651 return false;
1654 return false;
1657 #endif /* HAVE_LCD_BITMAP */
1658 #endif
1660 #ifndef SIMULATOR
1661 #if defined(HAVE_MMC) || defined(HAVE_HOTSWAP)
1662 #if defined(HAVE_MMC)
1663 #define CARDTYPE "MMC"
1664 #else
1665 #define CARDTYPE "microSD"
1666 #endif
1667 static int disk_callback(int btn, struct gui_synclist *lists)
1669 tCardInfo *card;
1670 int *cardnum = (int*)lists->gui_list[SCREEN_MAIN].data;
1671 unsigned char card_name[7];
1672 unsigned char pbuf[32];
1673 char *title = lists->gui_list[SCREEN_MAIN].title;
1674 static const unsigned char i_vmin[] = { 0, 1, 5, 10, 25, 35, 60, 100 };
1675 static const unsigned char i_vmax[] = { 1, 5, 10, 25, 35, 45, 80, 200 };
1676 static const unsigned char *kbit_units[] = { "kBit/s", "MBit/s", "GBit/s" };
1677 static const unsigned char *nsec_units[] = { "ns", "�s", "ms" };
1678 static const char *spec_vers[] = { "1.0-1.2", "1.4", "2.0-2.2",
1679 "3.1-3.31", "4.0" };
1680 if ((btn == ACTION_STD_OK) || (btn == SYS_FS_CHANGED) || (btn == ACTION_REDRAW))
1682 if (btn == ACTION_STD_OK)
1684 *cardnum ^= 0x1; /* change cards */
1687 simplelist_set_line_count(0);
1689 card = card_get_info(*cardnum);
1691 if (card->initialized > 0)
1693 card_name[6] = '\0';
1694 strncpy(card_name, ((unsigned char*)card->cid) + 3, 6);
1695 simplelist_addline(SIMPLELIST_ADD_LINE,
1696 "%s Rev %d.%d", card_name,
1697 (int) card_extract_bits(card->cid, 72, 4),
1698 (int) card_extract_bits(card->cid, 76, 4));
1699 simplelist_addline(SIMPLELIST_ADD_LINE,
1700 "Prod: %d/%d",
1701 (int) card_extract_bits(card->cid, 112, 4),
1702 (int) card_extract_bits(card->cid, 116, 4) + 1997);
1703 simplelist_addline(SIMPLELIST_ADD_LINE,
1704 "Ser#: 0x%08lx",
1705 card_extract_bits(card->cid, 80, 32));
1706 simplelist_addline(SIMPLELIST_ADD_LINE,
1707 "M=%02x, O=%04x",
1708 (int) card_extract_bits(card->cid, 0, 8),
1709 (int) card_extract_bits(card->cid, 8, 16));
1710 int temp = card_extract_bits(card->csd, 2, 4);
1711 simplelist_addline(SIMPLELIST_ADD_LINE,
1712 CARDTYPE " v%s", temp < 5 ?
1713 spec_vers[temp] : "?.?");
1714 simplelist_addline(SIMPLELIST_ADD_LINE,
1715 "Blocks: 0x%06lx", card->numblocks);
1716 simplelist_addline(SIMPLELIST_ADD_LINE,
1717 "Blksz.: %d P:%c%c", card->blocksize,
1718 card_extract_bits(card->csd, 48, 1) ? 'R' : '-',
1719 card_extract_bits(card->csd, 106, 1) ? 'W' : '-');
1720 output_dyn_value(pbuf, sizeof pbuf, card->speed / 1000,
1721 kbit_units, false);
1722 simplelist_addline(SIMPLELIST_ADD_LINE,
1723 "Speed: %s", pbuf);
1724 output_dyn_value(pbuf, sizeof pbuf, card->tsac,
1725 nsec_units, false);
1726 simplelist_addline(SIMPLELIST_ADD_LINE,
1727 "Tsac: %s", pbuf);
1728 simplelist_addline(SIMPLELIST_ADD_LINE,
1729 "Nsac: %d clk", card->nsac);
1730 simplelist_addline(SIMPLELIST_ADD_LINE,
1731 "R2W: *%d", card->r2w_factor);
1732 simplelist_addline(SIMPLELIST_ADD_LINE,
1733 "IRmax: %d..%d mA",
1734 i_vmin[card_extract_bits(card->csd, 66, 3)],
1735 i_vmax[card_extract_bits(card->csd, 69, 3)]);
1736 simplelist_addline(SIMPLELIST_ADD_LINE,
1737 "IWmax: %d..%d mA",
1738 i_vmin[card_extract_bits(card->csd, 72, 3)],
1739 i_vmax[card_extract_bits(card->csd, 75, 3)]);
1741 else if (card->initialized == 0)
1743 simplelist_addline(SIMPLELIST_ADD_LINE, "Not Found!");
1745 #ifndef HAVE_MMC
1746 else /* card->initialized < 0 */
1748 simplelist_addline(SIMPLELIST_ADD_LINE, "Init Error! (%d)", card->initialized);
1750 #endif
1751 snprintf(title, 16, "[" CARDTYPE " %d]", *cardnum);
1752 gui_synclist_set_title(lists, title, Icon_NOICON);
1753 gui_synclist_set_nb_items(lists, simplelist_get_line_count());
1754 gui_synclist_select_item(lists, 0);
1755 btn = ACTION_REDRAW;
1757 return btn;
1759 #else /* !defined(HAVE_MMC) && !defined(HAVE_HOTSWAP) */
1760 static int disk_callback(int btn, struct gui_synclist *lists)
1762 (void)lists;
1763 int i;
1764 char buf[128];
1765 unsigned short* identify_info = ata_get_identify();
1766 bool timing_info_present = false;
1767 (void)btn;
1769 simplelist_set_line_count(0);
1771 for (i=0; i < 20; i++)
1772 ((unsigned short*)buf)[i]=htobe16(identify_info[i+27]);
1773 buf[40]=0;
1774 /* kill trailing space */
1775 for (i=39; i && buf[i]==' '; i--)
1776 buf[i] = 0;
1777 simplelist_addline(SIMPLELIST_ADD_LINE, "Model: %s", buf);
1778 for (i=0; i < 4; i++)
1779 ((unsigned short*)buf)[i]=htobe16(identify_info[i+23]);
1780 buf[8]=0;
1781 simplelist_addline(SIMPLELIST_ADD_LINE,
1782 "Firmware: %s", buf);
1783 snprintf(buf, sizeof buf, "%ld MB",
1784 ((unsigned long)identify_info[61] << 16 |
1785 (unsigned long)identify_info[60]) / 2048 );
1786 simplelist_addline(SIMPLELIST_ADD_LINE,
1787 "Size: %s", buf);
1788 unsigned long free;
1789 fat_size( IF_MV2(0,) NULL, &free );
1790 simplelist_addline(SIMPLELIST_ADD_LINE,
1791 "Free: %ld MB", free / 1024);
1792 simplelist_addline(SIMPLELIST_ADD_LINE,
1793 "Spinup time: %d ms", ata_spinup_time * (1000/HZ));
1794 i = identify_info[83] & (1<<3);
1795 simplelist_addline(SIMPLELIST_ADD_LINE,
1796 "Power mgmt: %s", i ? "enabled" : "unsupported");
1797 i = identify_info[83] & (1<<9);
1798 simplelist_addline(SIMPLELIST_ADD_LINE,
1799 "Noise mgmt: %s", i ? "enabled" : "unsupported");
1800 i = identify_info[82] & (1<<6);
1801 simplelist_addline(SIMPLELIST_ADD_LINE,
1802 "Read-ahead: %s", i ? "enabled" : "unsupported");
1803 timing_info_present = identify_info[53] & (1<<1);
1804 if(timing_info_present) {
1805 char pio3[2], pio4[2];pio3[1] = 0;
1806 pio4[1] = 0;
1807 pio3[0] = (identify_info[64] & (1<<0)) ? '3' : 0;
1808 pio4[0] = (identify_info[64] & (1<<1)) ? '4' : 0;
1809 simplelist_addline(SIMPLELIST_ADD_LINE,
1810 "PIO modes: 0 1 2 %s %s", pio3, pio4);
1812 else {
1813 simplelist_addline(SIMPLELIST_ADD_LINE,
1814 "No PIO mode info");
1816 timing_info_present = identify_info[53] & (1<<1);
1817 if(timing_info_present) {
1818 simplelist_addline(SIMPLELIST_ADD_LINE,
1819 "Cycle times %dns/%dns",
1820 identify_info[67],
1821 identify_info[68] );
1822 } else {
1823 simplelist_addline(SIMPLELIST_ADD_LINE,
1824 "No timing info");
1826 timing_info_present = identify_info[53] & (1<<1);
1827 if(timing_info_present) {
1828 i = identify_info[49] & (1<<11);
1829 simplelist_addline(SIMPLELIST_ADD_LINE,
1830 "IORDY support: %s", i ? "yes" : "no");
1831 i = identify_info[49] & (1<<10);
1832 simplelist_addline(SIMPLELIST_ADD_LINE,
1833 "IORDY disable: %s", i ? "yes" : "no");
1834 } else {
1835 simplelist_addline(SIMPLELIST_ADD_LINE,
1836 "No timing info");
1838 simplelist_addline(SIMPLELIST_ADD_LINE,
1839 "Cluster size: %d bytes", fat_get_cluster_size(IF_MV(0)));
1840 return btn;
1842 #endif /* !defined(HAVE_MMC) && !defined(HAVE_HOTSWAP) */
1843 static bool dbg_disk_info(void)
1845 struct simplelist_info info;
1846 simplelist_info_init(&info, "Disk Info", 1, NULL);
1847 #if defined(HAVE_MMC) || defined(HAVE_HOTSWAP)
1848 char title[16];
1849 int card = 0;
1850 info.callback_data = (void*)&card;
1851 info.title = title;
1852 #endif
1853 info.action_callback = disk_callback;
1854 info.hide_selection = true;
1855 return simplelist_show_list(&info);
1857 #endif /* !SIMULATOR */
1859 #ifdef HAVE_DIRCACHE
1860 static int dircache_callback(int btn, struct gui_synclist *lists)
1862 (void)btn; (void)lists;
1863 simplelist_set_line_count(0);
1864 simplelist_addline(SIMPLELIST_ADD_LINE, "Cache initialized: %s",
1865 dircache_is_enabled() ? "Yes" : "No");
1866 simplelist_addline(SIMPLELIST_ADD_LINE, "Cache size: %d B",
1867 dircache_get_cache_size());
1868 simplelist_addline(SIMPLELIST_ADD_LINE, "Last size: %d B",
1869 global_status.dircache_size);
1870 simplelist_addline(SIMPLELIST_ADD_LINE, "Limit: %d B",
1871 DIRCACHE_LIMIT);
1872 simplelist_addline(SIMPLELIST_ADD_LINE, "Reserve: %d/%d B",
1873 dircache_get_reserve_used(), DIRCACHE_RESERVE);
1874 simplelist_addline(SIMPLELIST_ADD_LINE, "Scanning took: %d s",
1875 dircache_get_build_ticks() / HZ);
1876 simplelist_addline(SIMPLELIST_ADD_LINE, "Entry count: %d",
1877 dircache_get_entry_count());
1878 return btn;
1881 static bool dbg_dircache_info(void)
1883 struct simplelist_info info;
1884 simplelist_info_init(&info, "Dircache Info", 7, NULL);
1885 info.action_callback = dircache_callback;
1886 info.hide_selection = true;
1887 return simplelist_show_list(&info);
1890 #endif /* HAVE_DIRCACHE */
1892 #ifdef HAVE_TAGCACHE
1893 static int database_callback(int btn, struct gui_synclist *lists)
1895 (void)lists;
1896 struct tagcache_stat *stat = tagcache_get_stat();
1897 static bool synced = false;
1899 simplelist_set_line_count(0);
1901 simplelist_addline(SIMPLELIST_ADD_LINE, "Initialized: %s",
1902 stat->initialized ? "Yes" : "No");
1903 simplelist_addline(SIMPLELIST_ADD_LINE, "DB Ready: %s",
1904 stat->ready ? "Yes" : "No");
1905 simplelist_addline(SIMPLELIST_ADD_LINE, "RAM Cache: %s",
1906 stat->ramcache ? "Yes" : "No");
1907 simplelist_addline(SIMPLELIST_ADD_LINE, "RAM: %d/%d B",
1908 stat->ramcache_used, stat->ramcache_allocated);
1909 simplelist_addline(SIMPLELIST_ADD_LINE, "Progress: %d%% (%d entries)",
1910 stat->progress, stat->processed_entries);
1911 simplelist_addline(SIMPLELIST_ADD_LINE, "Curfile: %s",
1912 stat->curentry ? stat->curentry : "---");
1913 simplelist_addline(SIMPLELIST_ADD_LINE, "Commit step: %d",
1914 stat->commit_step);
1915 simplelist_addline(SIMPLELIST_ADD_LINE, "Commit delayed: %s",
1916 stat->commit_delayed ? "Yes" : "No");
1919 if (synced)
1921 synced = false;
1922 tagcache_screensync_event();
1925 if (!btn && stat->curentry)
1927 synced = true;
1928 return ACTION_REDRAW;
1931 if (btn == ACTION_STD_CANCEL)
1932 tagcache_screensync_enable(false);
1934 return btn;
1936 static bool dbg_tagcache_info(void)
1938 struct simplelist_info info;
1939 simplelist_info_init(&info, "Database Info", 8, NULL);
1940 info.action_callback = database_callback;
1941 info.hide_selection = true;
1942 info.timeout = TIMEOUT_NOBLOCK;
1943 tagcache_screensync_enable(true);
1944 return simplelist_show_list(&info);
1946 #endif
1948 #if CONFIG_CPU == SH7034
1949 static bool dbg_save_roms(void)
1951 int fd;
1952 int oldmode = system_memory_guard(MEMGUARD_NONE);
1954 fd = creat("/internal_rom_0000-FFFF.bin");
1955 if(fd >= 0)
1957 write(fd, (void *)0, 0x10000);
1958 close(fd);
1961 fd = creat("/internal_rom_2000000-203FFFF.bin");
1962 if(fd >= 0)
1964 write(fd, (void *)0x2000000, 0x40000);
1965 close(fd);
1968 system_memory_guard(oldmode);
1969 return false;
1971 #elif defined CPU_COLDFIRE
1972 static bool dbg_save_roms(void)
1974 int fd;
1975 int oldmode = system_memory_guard(MEMGUARD_NONE);
1977 #if defined(IRIVER_H100_SERIES)
1978 fd = creat("/internal_rom_000000-1FFFFF.bin");
1979 #elif defined(IRIVER_H300_SERIES)
1980 fd = creat("/internal_rom_000000-3FFFFF.bin");
1981 #elif defined(IAUDIO_X5) || defined(IAUDIO_M5)
1982 fd = creat("/internal_rom_000000-3FFFFF.bin");
1983 #endif
1984 if(fd >= 0)
1986 write(fd, (void *)0, FLASH_SIZE);
1987 close(fd);
1989 system_memory_guard(oldmode);
1991 #ifdef HAVE_EEPROM
1992 fd = creat("/internal_eeprom.bin");
1993 if (fd >= 0)
1995 int old_irq_level;
1996 char buf[EEPROM_SIZE];
1997 int err;
1999 old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL);
2001 err = eeprom_24cxx_read(0, buf, sizeof buf);
2002 if (err)
2003 gui_syncsplash(HZ*3, "Eeprom read failure (%d)",err);
2004 else
2006 write(fd, buf, sizeof buf);
2009 set_irq_level(old_irq_level);
2011 close(fd);
2013 #endif
2015 return false;
2017 #elif defined(CPU_PP) && !(defined(SANSA_E200) || defined(SANSA_C200))
2018 static bool dbg_save_roms(void)
2020 int fd;
2022 fd = creat("/internal_rom_000000-0FFFFF.bin");
2023 if(fd >= 0)
2025 write(fd, (void *)0x20000000, FLASH_SIZE);
2026 close(fd);
2029 return false;
2031 #endif /* CPU */
2033 #ifndef SIMULATOR
2034 #if CONFIG_TUNER
2035 static int radio_callback(int btn, struct gui_synclist *lists)
2037 (void)lists;
2038 if (btn == ACTION_STD_CANCEL)
2039 return btn;
2040 simplelist_set_line_count(1);
2042 #if (CONFIG_TUNER & LV24020LP)
2043 simplelist_addline(SIMPLELIST_ADD_LINE,
2044 "CTRL_STAT: %02X", lv24020lp_get(LV24020LP_CTRL_STAT) );
2045 simplelist_addline(SIMPLELIST_ADD_LINE,
2046 "RADIO_STAT: %02X", lv24020lp_get(LV24020LP_REG_STAT) );
2047 simplelist_addline(SIMPLELIST_ADD_LINE,
2048 "MSS_FM: %d kHz", lv24020lp_get(LV24020LP_MSS_FM) );
2049 simplelist_addline(SIMPLELIST_ADD_LINE,
2050 "MSS_IF: %d Hz", lv24020lp_get(LV24020LP_MSS_IF) );
2051 simplelist_addline(SIMPLELIST_ADD_LINE,
2052 "MSS_SD: %d Hz", lv24020lp_get(LV24020LP_MSS_SD) );
2053 simplelist_addline(SIMPLELIST_ADD_LINE,
2054 "if_set: %d Hz", lv24020lp_get(LV24020LP_IF_SET) );
2055 simplelist_addline(SIMPLELIST_ADD_LINE,
2056 "sd_set: %d Hz", lv24020lp_get(LV24020LP_SD_SET) );
2057 #endif
2058 #if (CONFIG_TUNER & S1A0903X01)
2059 simplelist_addline(SIMPLELIST_ADD_LINE,
2060 "Samsung regs: %08X", s1a0903x01_get(RADIO_ALL));
2061 /* This one doesn't return dynamic data atm */
2062 #endif
2063 #if (CONFIG_TUNER & TEA5767)
2064 struct tea5767_dbg_info nfo;
2065 tea5767_dbg_info(&nfo);
2066 simplelist_addline(SIMPLELIST_ADD_LINE, "Philips regs:");
2067 simplelist_addline(SIMPLELIST_ADD_LINE,
2068 " Read: %02X %02X %02X %02X %02X",
2069 (unsigned)nfo.read_regs[0], (unsigned)nfo.read_regs[1],
2070 (unsigned)nfo.read_regs[2], (unsigned)nfo.read_regs[3],
2071 (unsigned)nfo.read_regs[4]);
2072 simplelist_addline(SIMPLELIST_ADD_LINE,
2073 " Write: %02X %02X %02X %02X %02X",
2074 (unsigned)nfo.write_regs[0], (unsigned)nfo.write_regs[1],
2075 (unsigned)nfo.write_regs[2], (unsigned)nfo.write_regs[3],
2076 (unsigned)nfo.write_regs[4]);
2077 #endif
2078 return ACTION_REDRAW;
2080 static bool dbg_fm_radio(void)
2082 struct simplelist_info info;
2083 simplelist_info_init(&info, "FM Radio", 1, NULL);
2084 simplelist_set_line_count(0);
2085 simplelist_addline(SIMPLELIST_ADD_LINE, "HW detected: %s",
2086 radio_hardware_present() ? "yes" : "no");
2088 info.action_callback = radio_hardware_present()?radio_callback : NULL;
2089 info.hide_selection = true;
2090 return simplelist_show_list(&info);
2092 #endif /* CONFIG_TUNER */
2093 #endif /* !SIMULATOR */
2095 #ifdef HAVE_LCD_BITMAP
2096 extern bool do_screendump_instead_of_usb;
2098 static bool dbg_screendump(void)
2100 do_screendump_instead_of_usb = !do_screendump_instead_of_usb;
2101 gui_syncsplash(HZ, "Screendump %s",
2102 do_screendump_instead_of_usb?"enabled":"disabled");
2103 return false;
2105 #endif /* HAVE_LCD_BITMAP */
2107 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
2108 static bool dbg_set_memory_guard(void)
2110 static const struct opt_items names[MAXMEMGUARD] = {
2111 { "None", -1 },
2112 { "Flash ROM writes", -1 },
2113 { "Zero area (all)", -1 }
2115 int mode = system_memory_guard(MEMGUARD_KEEP);
2117 set_option( "Catch mem accesses", &mode, INT, names, MAXMEMGUARD, NULL);
2118 system_memory_guard(mode);
2120 return false;
2122 #endif /* CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) */
2124 #if defined(TOSHIBA_GIGABEAT_F) && !defined(SIMULATOR)
2126 extern volatile bool lcd_poweroff;
2128 static bool dbg_lcd_power_off(void)
2130 lcd_setmargins(0, 0);
2132 while(1)
2134 int button;
2136 lcd_clear_display();
2137 lcd_puts(0, 0, "LCD Power Off");
2138 if(lcd_poweroff)
2139 lcd_puts(1, 1, "Yes");
2140 else
2141 lcd_puts(1, 1, "No");
2143 lcd_update();
2145 button = get_action(CONTEXT_STD,HZ/5);
2146 switch(button)
2148 case ACTION_STD_PREV:
2149 case ACTION_STD_NEXT:
2150 lcd_poweroff = !lcd_poweroff;
2151 break;
2152 case ACTION_STD_OK:
2153 case ACTION_STD_CANCEL:
2154 return false;
2155 default:
2156 sleep(HZ/10);
2157 break;
2160 return false;
2162 #endif
2164 #if defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS)
2165 static bool dbg_write_eeprom(void)
2167 int fd;
2168 int rc;
2169 int old_irq_level;
2170 char buf[EEPROM_SIZE];
2171 int err;
2173 fd = open("/internal_eeprom.bin", O_RDONLY);
2175 if (fd >= 0)
2177 rc = read(fd, buf, EEPROM_SIZE);
2179 if(rc == EEPROM_SIZE)
2181 old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL);
2183 err = eeprom_24cxx_write(0, buf, sizeof buf);
2184 if (err)
2185 gui_syncsplash(HZ*3, "Eeprom write failure (%d)",err);
2186 else
2187 gui_syncsplash(HZ*3, "Eeprom written successfully");
2189 set_irq_level(old_irq_level);
2191 else
2193 gui_syncsplash(HZ*3, "File read error (%d)",rc);
2195 close(fd);
2197 else
2199 gui_syncsplash(HZ*3, "Failed to open 'internal_eeprom.bin'");
2202 return false;
2204 #endif /* defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS) */
2205 #ifdef CPU_BOOST_LOGGING
2206 static bool cpu_boost_log(void)
2208 int i = 0,j=0;
2209 int count = cpu_boost_log_getcount();
2210 int lines = LCD_HEIGHT/SYSFONT_HEIGHT;
2211 char *str;
2212 bool done;
2213 lcd_setmargins(0, 0);
2214 lcd_setfont(FONT_SYSFIXED);
2215 str = cpu_boost_log_getlog_first();
2216 while (i < count)
2218 lcd_clear_display();
2219 for(j=0; j<lines; j++,i++)
2221 if (!str)
2222 str = cpu_boost_log_getlog_next();
2223 if (str)
2225 lcd_puts(0, j,str);
2227 str = NULL;
2229 lcd_update();
2230 done = false;
2231 while (!done)
2233 switch(get_action(CONTEXT_STD,TIMEOUT_BLOCK))
2235 case ACTION_STD_OK:
2236 case ACTION_STD_PREV:
2237 case ACTION_STD_NEXT:
2238 done = true;
2239 break;
2240 case ACTION_STD_CANCEL:
2241 i = count;
2242 done = true;
2243 break;
2247 get_action(CONTEXT_STD,TIMEOUT_BLOCK);
2248 lcd_setfont(FONT_UI);
2249 return false;
2251 #endif
2255 /****** The menu *********/
2256 struct the_menu_item {
2257 unsigned char *desc; /* string or ID */
2258 bool (*function) (void); /* return true if USB was connected */
2260 static const struct the_menu_item menuitems[] = {
2261 #if defined(TOSHIBA_GIGABEAT_F) && !defined(SIMULATOR)
2262 { "LCD Power Off", dbg_lcd_power_off },
2263 #endif
2264 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || \
2265 (defined(CPU_PP) && !(defined(SANSA_E200) || defined(SANSA_C200)))
2266 { "Dump ROM contents", dbg_save_roms },
2267 #endif
2268 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || defined(CPU_PP) || CONFIG_CPU == S3C2440
2269 { "View I/O ports", dbg_ports },
2270 #endif
2271 #if defined(HAVE_TSC2100) && !defined(SIMULATOR)
2272 { "TSC2100 debug", tsc2100_debug },
2273 #endif
2274 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
2275 { "CPU frequency", dbg_cpufreq },
2276 #endif
2277 #if defined(IRIVER_H100_SERIES) && !defined(SIMULATOR)
2278 { "S/PDIF analyzer", dbg_spdif },
2279 #endif
2280 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
2281 { "Catch mem accesses", dbg_set_memory_guard },
2282 #endif
2283 { "View OS stacks", dbg_os },
2284 #ifdef HAVE_LCD_BITMAP
2285 #ifndef SIMULATOR
2286 { "View battery", view_battery },
2287 #endif
2288 { "Screendump", dbg_screendump },
2289 #endif
2290 #ifndef SIMULATOR
2291 { "View HW info", dbg_hw_info },
2292 #endif
2293 #ifndef SIMULATOR
2294 { "View partitions", dbg_partitions },
2295 #endif
2296 #ifndef SIMULATOR
2297 { "View disk info", dbg_disk_info },
2298 #endif
2299 #ifdef HAVE_DIRCACHE
2300 { "View dircache info", dbg_dircache_info },
2301 #endif
2302 #ifdef HAVE_TAGCACHE
2303 { "View database info", dbg_tagcache_info },
2304 #endif
2305 #ifdef HAVE_LCD_BITMAP
2306 #if CONFIG_CODEC == SWCODEC
2307 { "View buffering thread", dbg_buffering_thread },
2308 #elif !defined(SIMULATOR)
2309 { "View audio thread", dbg_audio_thread },
2310 #endif
2311 #ifdef PM_DEBUG
2312 { "pm histogram", peak_meter_histogram},
2313 #endif /* PM_DEBUG */
2314 #endif /* HAVE_LCD_BITMAP */
2315 #ifndef SIMULATOR
2316 #if CONFIG_TUNER
2317 { "FM Radio", dbg_fm_radio },
2318 #endif
2319 #endif
2320 #if defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS)
2321 { "Write back EEPROM", dbg_write_eeprom },
2322 #endif
2323 #ifdef ROCKBOX_HAS_LOGF
2324 {"logf", logfdisplay },
2325 {"logfdump", logfdump },
2326 #endif
2327 #ifdef CPU_BOOST_LOGGING
2328 {"cpu_boost log",cpu_boost_log},
2329 #endif
2331 static int menu_action_callback(int btn, struct gui_synclist *lists)
2333 if (btn == ACTION_STD_OK)
2335 menuitems[gui_synclist_get_sel_pos(lists)].function();
2336 btn = ACTION_REDRAW;
2338 return btn;
2340 static char* dbg_menu_getname(int item, void * data, char *buffer)
2342 (void)data; (void)buffer;
2343 return menuitems[item].desc;
2345 bool debug_menu(void)
2347 struct simplelist_info info;
2349 simplelist_info_init(&info, "Debug Menu", ARRAYLEN(menuitems), NULL);
2350 info.action_callback = menu_action_callback;
2351 info.get_name = dbg_menu_getname;
2353 return simplelist_show_list(&info);