change the SCREEN_ROTATE define to be more meaningful, and set the mr500 orientation...
[Rockbox.git] / apps / debug_menu.c
blobf343ce6c7878d0224ea1139fa5182d9e0d9042c8
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 char name[32];
128 struct thread_entry *thread = NULL;
129 unsigned status;
130 int usage;
132 #if NUM_CORES > 1
133 if (selected_item < (int)NUM_CORES)
135 usage = idle_stack_usage(selected_item);
136 snprintf(buffer, MAX_PATH, "Idle (%d): %2d%%", selected_item, usage);
137 return buffer;
140 selected_item -= NUM_CORES;
141 #endif
143 thread = &threads[selected_item];
144 status = thread_get_status(thread);
146 if (status == STATE_KILLED)
148 snprintf(buffer, MAX_PATH, "%2d: ---", selected_item);
149 return buffer;
152 thread_get_name(name, 32, thread);
153 usage = thread_stack_usage(thread);
155 snprintf(buffer, MAX_PATH,
156 "%2d: " IF_COP("(%d) ") "%c%c " IF_PRIO("%d ") "%2d%% %s",
157 selected_item,
158 IF_COP(thread->core,)
159 (status == STATE_RUNNING) ? '*' : ' ',
160 thread_status_char(status),
161 IF_PRIO(thread->priority,)
162 usage, name);
164 return buffer;
166 static int dbg_threads_action_callback(int action, struct gui_synclist *lists)
168 (void)lists;
169 #ifdef ROCKBOX_HAS_LOGF
170 if (action == ACTION_STD_OK)
172 int selpos = gui_synclist_get_sel_pos(lists);
173 #if NUM_CORES > 1
174 if (selpos >= NUM_CORES)
175 remove_thread(&threads[selpos - NUM_CORES]);
176 #else
177 remove_thread(&threads[selpos]);
178 #endif
179 return ACTION_REDRAW;
181 #endif /* ROCKBOX_HAS_LOGF */
182 return action;
184 /* Test code!!! */
185 static bool dbg_os(void)
187 struct simplelist_info info;
188 simplelist_info_init(&info, IF_COP("Core and ") "Stack usage:",
189 #if NUM_CORES == 1
190 MAXTHREADS,
191 #else
192 MAXTHREADS+NUM_CORES,
193 #endif
194 NULL);
195 #ifndef ROCKBOX_HAS_LOGF
196 info.hide_selection = true;
197 #endif
198 info.action_callback = dbg_threads_action_callback;
199 info.get_name = threads_getname;
200 return simplelist_show_list(&info);
203 #ifdef HAVE_LCD_BITMAP
204 #if CONFIG_CODEC != SWCODEC
205 #ifndef SIMULATOR
206 static bool dbg_audio_thread(void)
208 char buf[32];
209 struct audio_debug d;
211 lcd_setmargins(0, 0);
212 lcd_setfont(FONT_SYSFIXED);
214 while(1)
216 if (action_userabort(HZ/5))
217 return false;
219 audio_get_debugdata(&d);
221 lcd_clear_display();
223 snprintf(buf, sizeof(buf), "read: %x", d.audiobuf_read);
224 lcd_puts(0, 0, buf);
225 snprintf(buf, sizeof(buf), "write: %x", d.audiobuf_write);
226 lcd_puts(0, 1, buf);
227 snprintf(buf, sizeof(buf), "swap: %x", d.audiobuf_swapwrite);
228 lcd_puts(0, 2, buf);
229 snprintf(buf, sizeof(buf), "playing: %d", d.playing);
230 lcd_puts(0, 3, buf);
231 snprintf(buf, sizeof(buf), "playable: %x", d.playable_space);
232 lcd_puts(0, 4, buf);
233 snprintf(buf, sizeof(buf), "unswapped: %x", d.unswapped_space);
234 lcd_puts(0, 5, buf);
236 /* Playable space left */
237 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, 6*8, 112, 4, d.audiobuflen, 0,
238 d.playable_space, HORIZONTAL);
240 /* Show the watermark limit */
241 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, 6*8+4, 112, 4, d.audiobuflen, 0,
242 d.low_watermark_level, HORIZONTAL);
244 snprintf(buf, sizeof(buf), "wm: %x - %x",
245 d.low_watermark_level, d.lowest_watermark_level);
246 lcd_puts(0, 7, buf);
248 lcd_update();
250 return false;
252 #endif /* !SIMULATOR */
253 #else /* CONFIG_CODEC == SWCODEC */
254 extern size_t filebuflen;
255 /* This is a size_t, but call it a long so it puts a - when it's bad. */
257 static unsigned int ticks, boost_ticks;
259 static void dbg_audio_task(void)
261 #ifndef SIMULATOR
262 if(FREQ > CPUFREQ_NORMAL)
263 boost_ticks++;
264 #endif
266 ticks++;
269 static bool dbg_buffering_thread(void)
271 char buf[32];
272 int button;
273 int line;
274 bool done = false;
275 size_t bufused;
276 size_t bufsize = pcmbuf_get_bufsize();
277 int pcmbufdescs = pcmbuf_descs();
278 struct buffering_debug d;
280 ticks = boost_ticks = 0;
282 tick_add_task(dbg_audio_task);
284 lcd_setmargins(0, 0);
285 lcd_setfont(FONT_SYSFIXED);
286 while(!done)
288 button = get_action(CONTEXT_STD,HZ/5);
289 switch(button)
291 case ACTION_STD_NEXT:
292 audio_next();
293 break;
294 case ACTION_STD_PREV:
295 audio_prev();
296 break;
297 case ACTION_STD_CANCEL:
298 done = true;
299 break;
302 buffering_get_debugdata(&d);
304 line = 0;
305 lcd_clear_display();
307 bufused = bufsize - pcmbuf_free();
309 snprintf(buf, sizeof(buf), "pcm: %7ld/%7ld", (long) bufused, (long) bufsize);
310 lcd_puts(0, line++, buf);
312 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6,
313 bufsize, 0, bufused, HORIZONTAL);
314 line++;
316 snprintf(buf, sizeof(buf), "alloc: %8ld/%8ld", audio_filebufused(),
317 (long) filebuflen);
318 lcd_puts(0, line++, buf);
320 #if LCD_HEIGHT > 80
321 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6,
322 filebuflen, 0, audio_filebufused(), HORIZONTAL);
323 line++;
325 snprintf(buf, sizeof(buf), "real: %8ld/%8ld", (long)d.buffered_data,
326 (long)filebuflen);
327 lcd_puts(0, line++, buf);
329 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6,
330 filebuflen, 0, (long)d.buffered_data, HORIZONTAL);
331 line++;
332 #endif
334 snprintf(buf, sizeof(buf), "usefl: %8ld/%8ld", (long)(d.useful_data),
335 (long)filebuflen);
336 lcd_puts(0, line++, buf);
338 #if LCD_HEIGHT > 80
339 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6,
340 filebuflen, 0, d.useful_data, HORIZONTAL);
341 line++;
342 #endif
344 snprintf(buf, sizeof(buf), "data_rem: %ld", (long)d.data_rem);
345 lcd_puts(0, line++, buf);
347 snprintf(buf, sizeof(buf), "track count: %2d", audio_track_count()-1);
348 lcd_puts(0, line++, buf);
350 snprintf(buf, sizeof(buf), "handle count: %d", (int)d.num_handles);
351 lcd_puts(0, line++, buf);
353 #ifndef SIMULATOR
354 snprintf(buf, sizeof(buf), "cpu freq: %3dMHz",
355 (int)((FREQ + 500000) / 1000000));
356 lcd_puts(0, line++, buf);
357 #endif
359 if (ticks > 0)
361 snprintf(buf, sizeof(buf), "boost ratio: %3d%%",
362 boost_ticks * 100 / ticks);
363 lcd_puts(0, line++, buf);
366 snprintf(buf, sizeof(buf), "pcmbufdesc: %2d/%2d",
367 pcmbuf_used_descs(), pcmbufdescs);
368 lcd_puts(0, line++, buf);
370 lcd_update();
373 tick_remove_task(dbg_audio_task);
375 return false;
377 #endif /* CONFIG_CODEC */
378 #endif /* HAVE_LCD_BITMAP */
381 #if (CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE))
382 /* Tool function to read the flash manufacturer and type, if available.
383 Only chips which could be reprogrammed in system will return values.
384 (The mode switch addresses vary between flash manufacturers, hence addr1/2) */
385 /* In IRAM to avoid problems when running directly from Flash */
386 static bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
387 unsigned addr1, unsigned addr2)
388 ICODE_ATTR __attribute__((noinline));
389 static bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
390 unsigned addr1, unsigned addr2)
393 unsigned not_manu, not_id; /* read values before switching to ID mode */
394 unsigned manu, id; /* read values when in ID mode */
396 #if CONFIG_CPU == SH7034
397 volatile unsigned char* flash = (unsigned char*)0x2000000; /* flash mapping */
398 #elif defined(CPU_COLDFIRE)
399 volatile unsigned short* flash = (unsigned short*)0; /* flash mapping */
400 #endif
401 int old_level; /* saved interrupt level */
403 not_manu = flash[0]; /* read the normal content */
404 not_id = flash[1]; /* should be 'A' (0x41) and 'R' (0x52) from the "ARCH" marker */
406 /* disable interrupts, prevent any stray flash access */
407 old_level = set_irq_level(HIGHEST_IRQ_LEVEL);
409 flash[addr1] = 0xAA; /* enter command mode */
410 flash[addr2] = 0x55;
411 flash[addr1] = 0x90; /* ID command */
412 /* Atmel wants 20ms pause here */
413 /* sleep(HZ/50); no sleeping possible while interrupts are disabled */
415 manu = flash[0]; /* read the IDs */
416 id = flash[1];
418 flash[0] = 0xF0; /* reset flash (back to normal read mode) */
419 /* Atmel wants 20ms pause here */
420 /* sleep(HZ/50); no sleeping possible while interrupts are disabled */
422 set_irq_level(old_level); /* enable interrupts again */
424 /* I assume success if the obtained values are different from
425 the normal flash content. This is not perfectly bulletproof, they
426 could theoretically be the same by chance, causing us to fail. */
427 if (not_manu != manu || not_id != id) /* a value has changed */
429 *p_manufacturer = manu; /* return the results */
430 *p_device = id;
431 return true; /* success */
433 return false; /* fail */
435 #endif /* (CONFIG_CPU == SH7034 || CPU_COLDFIRE) */
437 #ifndef SIMULATOR
438 #ifdef CPU_PP
439 static int perfcheck(void)
441 int result;
443 asm (
444 "mrs r2, CPSR \n"
445 "orr r0, r2, #0xc0 \n" /* disable IRQ and FIQ */
446 "msr CPSR_c, r0 \n"
447 "mov %[res], #0 \n"
448 "ldr r0, [%[timr]] \n"
449 "add r0, r0, %[tmo] \n"
450 "1: \n"
451 "add %[res], %[res], #1 \n"
452 "ldr r1, [%[timr]] \n"
453 "cmp r1, r0 \n"
454 "bmi 1b \n"
455 "msr CPSR_c, r2 \n" /* reset IRQ and FIQ state */
457 [res]"=&r"(result)
459 [timr]"r"(&USEC_TIMER),
460 [tmo]"r"(
461 #if CONFIG_CPU == PP5002
462 16000
463 #else /* PP5020/5022/5024 */
464 10226
465 #endif
468 "r0", "r1", "r2"
470 return result;
472 #endif
474 #ifdef HAVE_LCD_BITMAP
475 static bool dbg_hw_info(void)
477 #if CONFIG_CPU == SH7034
478 char buf[32];
479 int bitmask = HW_MASK;
480 int rom_version = ROM_VERSION;
481 unsigned manu, id; /* flash IDs */
482 bool got_id; /* flag if we managed to get the flash IDs */
483 unsigned rom_crc = 0xffffffff; /* CRC32 of the boot ROM */
484 bool has_bootrom; /* flag for boot ROM present */
485 int oldmode; /* saved memory guard mode */
487 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
489 /* get flash ROM type */
490 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
491 if (!got_id)
492 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
494 /* check if the boot ROM area is a flash mirror */
495 has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0);
496 if (has_bootrom) /* if ROM and Flash different */
498 /* calculate CRC16 checksum of boot ROM */
499 rom_crc = crc_32((unsigned char*)0x0000, 64*1024, 0xffffffff);
502 system_memory_guard(oldmode); /* re-enable memory guard */
504 lcd_setmargins(0, 0);
505 lcd_setfont(FONT_SYSFIXED);
506 lcd_clear_display();
508 lcd_puts(0, 0, "[Hardware info]");
510 snprintf(buf, 32, "ROM: %d.%02d", rom_version/100, rom_version%100);
511 lcd_puts(0, 1, buf);
513 snprintf(buf, 32, "Mask: 0x%04x", bitmask);
514 lcd_puts(0, 2, buf);
516 if (got_id)
517 snprintf(buf, 32, "Flash: M=%02x D=%02x", manu, id);
518 else
519 snprintf(buf, 32, "Flash: M=?? D=??"); /* unknown, sorry */
520 lcd_puts(0, 3, buf);
522 if (has_bootrom)
524 if (rom_crc == 0x56DBA4EE) /* known Version 1 */
525 snprintf(buf, 32, "Boot ROM: V1");
526 else
527 snprintf(buf, 32, "ROMcrc: 0x%08x", rom_crc);
529 else
531 snprintf(buf, 32, "Boot ROM: none");
533 lcd_puts(0, 4, buf);
535 lcd_update();
537 while (!(action_userabort(TIMEOUT_BLOCK)));
539 #elif CONFIG_CPU == MCF5249 || CONFIG_CPU == MCF5250
540 char buf[32];
541 unsigned manu, id; /* flash IDs */
542 int got_id; /* flag if we managed to get the flash IDs */
543 int oldmode; /* saved memory guard mode */
544 int line = 0;
546 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
548 /* get flash ROM type */
549 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
550 if (!got_id)
551 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
553 system_memory_guard(oldmode); /* re-enable memory guard */
555 lcd_setmargins(0, 0);
556 lcd_setfont(FONT_SYSFIXED);
557 lcd_clear_display();
559 lcd_puts(0, line++, "[Hardware info]");
561 if (got_id)
562 snprintf(buf, 32, "Flash: M=%04x D=%04x", manu, id);
563 else
564 snprintf(buf, 32, "Flash: M=???? D=????"); /* unknown, sorry */
565 lcd_puts(0, line++, buf);
567 #ifdef IAUDIO_X5
569 struct ds2411_id id;
571 lcd_puts(0, ++line, "Serial Number:");
573 got_id = ds2411_read_id(&id);
575 if (got_id == DS2411_OK)
577 snprintf(buf, 32, " FC=%02x", (unsigned)id.family_code);
578 lcd_puts(0, ++line, buf);
579 snprintf(buf, 32, " ID=%02X %02X %02X %02X %02X %02X",
580 (unsigned)id.uid[0], (unsigned)id.uid[1], (unsigned)id.uid[2],
581 (unsigned)id.uid[3], (unsigned)id.uid[4], (unsigned)id.uid[5]);
582 lcd_puts(0, ++line, buf);
583 snprintf(buf, 32, " CRC=%02X", (unsigned)id.crc);
585 else
587 snprintf(buf, 32, "READ ERR=%d", got_id);
590 lcd_puts(0, ++line, buf);
592 #endif
594 lcd_update();
596 while (!(action_userabort(TIMEOUT_BLOCK)));
598 #elif defined(CPU_PP502x)
599 int line = 0;
600 char buf[32];
601 char pp_version[] = { (PP_VER2 >> 24) & 0xff, (PP_VER2 >> 16) & 0xff,
602 (PP_VER2 >> 8) & 0xff, (PP_VER2) & 0xff,
603 (PP_VER1 >> 24) & 0xff, (PP_VER1 >> 16) & 0xff,
604 (PP_VER1 >> 8) & 0xff, (PP_VER1) & 0xff, '\0' };
606 lcd_setmargins(0, 0);
607 lcd_setfont(FONT_SYSFIXED);
608 lcd_clear_display();
610 lcd_puts(0, line++, "[Hardware info]");
612 #ifdef IPOD_ARCH
613 snprintf(buf, sizeof(buf), "HW rev: 0x%08lx", IPOD_HW_REVISION);
614 lcd_puts(0, line++, buf);
615 #endif
617 #ifdef IPOD_COLOR
618 extern int lcd_type; /* Defined in lcd-colornano.c */
620 snprintf(buf, sizeof(buf), "LCD type: %d", lcd_type);
621 lcd_puts(0, line++, buf);
622 #endif
624 snprintf(buf, sizeof(buf), "PP version: %s", pp_version);
625 lcd_puts(0, line++, buf);
627 snprintf(buf, sizeof(buf), "Est. clock (kHz): %d", perfcheck());
628 lcd_puts(0, line++, buf);
630 lcd_update();
632 while (!(action_userabort(TIMEOUT_BLOCK)));
634 #elif CONFIG_CPU == PP5002
635 int line = 0;
636 char buf[32];
637 char pp_version[] = { (PP_VER4 >> 8) & 0xff, PP_VER4 & 0xff,
638 (PP_VER3 >> 8) & 0xff, PP_VER3 & 0xff,
639 (PP_VER2 >> 8) & 0xff, PP_VER2 & 0xff,
640 (PP_VER1 >> 8) & 0xff, PP_VER1 & 0xff, '\0' };
643 lcd_setmargins(0, 0);
644 lcd_setfont(FONT_SYSFIXED);
645 lcd_clear_display();
647 lcd_puts(0, line++, "[Hardware info]");
649 #ifdef IPOD_ARCH
650 snprintf(buf, sizeof(buf), "HW rev: 0x%08lx", IPOD_HW_REVISION);
651 lcd_puts(0, line++, buf);
652 #endif
654 snprintf(buf, sizeof(buf), "PP version: %s", pp_version);
655 lcd_puts(0, line++, buf);
657 snprintf(buf, sizeof(buf), "Est. clock (kHz): %d", perfcheck());
658 lcd_puts(0, line++, buf);
660 lcd_update();
662 while (!(action_userabort(TIMEOUT_BLOCK)));
663 #else
664 /* Define this function in your target tree */
665 return __dbg_hw_info();
666 #endif /* CONFIG_CPU */
667 return false;
669 #else /* !HAVE_LCD_BITMAP */
670 static bool dbg_hw_info(void)
672 char buf[32];
673 int button;
674 int currval = 0;
675 int rom_version = ROM_VERSION;
676 unsigned manu, id; /* flash IDs */
677 bool got_id; /* flag if we managed to get the flash IDs */
678 unsigned rom_crc = 0xffffffff; /* CRC32 of the boot ROM */
679 bool has_bootrom; /* flag for boot ROM present */
680 int oldmode; /* saved memory guard mode */
682 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
684 /* get flash ROM type */
685 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
686 if (!got_id)
687 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
689 /* check if the boot ROM area is a flash mirror */
690 has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0);
691 if (has_bootrom) /* if ROM and Flash different */
693 /* calculate CRC16 checksum of boot ROM */
694 rom_crc = crc_32((unsigned char*)0x0000, 64*1024, 0xffffffff);
697 system_memory_guard(oldmode); /* re-enable memory guard */
699 lcd_clear_display();
701 lcd_puts(0, 0, "[HW Info]");
702 while(1)
704 switch(currval)
706 case 0:
707 snprintf(buf, 32, "ROM: %d.%02d",
708 rom_version/100, rom_version%100);
709 break;
710 case 1:
711 if (got_id)
712 snprintf(buf, 32, "Flash:%02x,%02x", manu, id);
713 else
714 snprintf(buf, 32, "Flash:??,??"); /* unknown, sorry */
715 break;
716 case 2:
717 if (has_bootrom)
719 if (rom_crc == 0x56DBA4EE) /* known Version 1 */
720 snprintf(buf, 32, "BootROM: V1");
721 else if (rom_crc == 0x358099E8)
722 snprintf(buf, 32, "BootROM: V2");
723 /* alternative boot ROM found in one single player so far */
724 else
725 snprintf(buf, 32, "R: %08x", rom_crc);
727 else
728 snprintf(buf, 32, "BootROM: no");
731 lcd_puts(0, 1, buf);
732 lcd_update();
734 button = get_action(CONTEXT_SETTINGS,TIMEOUT_BLOCK);
736 switch(button)
738 case ACTION_STD_CANCEL:
739 return false;
741 case ACTION_SETTINGS_DEC:
742 currval--;
743 if(currval < 0)
744 currval = 2;
745 break;
747 case ACTION_SETTINGS_INC:
748 currval++;
749 if(currval > 2)
750 currval = 0;
751 break;
754 return false;
756 #endif /* !HAVE_LCD_BITMAP */
757 #endif /* !SIMULATOR */
759 #ifndef SIMULATOR
760 static char* dbg_partitions_getname(int selected_item, void * data, char *buffer)
762 (void)data;
763 int partition = selected_item/2;
764 struct partinfo* p = disk_partinfo(partition);
765 if (selected_item%2)
767 snprintf(buffer, MAX_PATH, " T:%x %ld MB", p->type, p->size / 2048);
769 else
771 snprintf(buffer, MAX_PATH, "P%d: S:%lx", partition, p->start);
773 return buffer;
776 bool dbg_partitions(void)
778 struct simplelist_info info;
779 simplelist_info_init(&info, "Partition Info", 4, NULL);
780 info.selection_size = 2;
781 info.hide_selection = true;
782 info.get_name = dbg_partitions_getname;
783 return simplelist_show_list(&info);
785 #endif
787 #if defined(CPU_COLDFIRE) && defined(HAVE_SPDIF_OUT)
788 static bool dbg_spdif(void)
790 char buf[128];
791 int line;
792 unsigned int control;
793 int x;
794 char *s;
795 int category;
796 int generation;
797 unsigned int interruptstat;
798 bool valnogood, symbolerr, parityerr;
799 bool done = false;
800 bool spdif_src_on;
801 int spdif_source = spdif_get_output_source(&spdif_src_on);
802 spdif_set_output_source(AUDIO_SRC_SPDIF IF_SPDIF_POWER_(, true));
804 lcd_setmargins(0, 0);
805 lcd_clear_display();
806 lcd_setfont(FONT_SYSFIXED);
808 #ifdef HAVE_SPDIF_POWER
809 spdif_power_enable(true); /* We need SPDIF power for both sending & receiving */
810 #endif
812 while (!done)
814 line = 0;
816 control = EBU1RCVCCHANNEL1;
817 interruptstat = INTERRUPTSTAT;
818 INTERRUPTCLEAR = 0x03c00000;
820 valnogood = (interruptstat & 0x01000000)?true:false;
821 symbolerr = (interruptstat & 0x00800000)?true:false;
822 parityerr = (interruptstat & 0x00400000)?true:false;
824 snprintf(buf, sizeof(buf), "Val: %s Sym: %s Par: %s",
825 valnogood?"--":"OK",
826 symbolerr?"--":"OK",
827 parityerr?"--":"OK");
828 lcd_puts(0, line++, buf);
830 snprintf(buf, sizeof(buf), "Status word: %08x", (int)control);
831 lcd_puts(0, line++, buf);
833 line++;
835 x = control >> 31;
836 snprintf(buf, sizeof(buf), "PRO: %d (%s)",
837 x, x?"Professional":"Consumer");
838 lcd_puts(0, line++, buf);
840 x = (control >> 30) & 1;
841 snprintf(buf, sizeof(buf), "Audio: %d (%s)",
842 x, x?"Non-PCM":"PCM");
843 lcd_puts(0, line++, buf);
845 x = (control >> 29) & 1;
846 snprintf(buf, sizeof(buf), "Copy: %d (%s)",
847 x, x?"Permitted":"Inhibited");
848 lcd_puts(0, line++, buf);
850 x = (control >> 27) & 7;
851 switch(x)
853 case 0:
854 s = "None";
855 break;
856 case 1:
857 s = "50/15us";
858 break;
859 default:
860 s = "Reserved";
861 break;
863 snprintf(buf, sizeof(buf), "Preemphasis: %d (%s)", x, s);
864 lcd_puts(0, line++, buf);
866 x = (control >> 24) & 3;
867 snprintf(buf, sizeof(buf), "Mode: %d", x);
868 lcd_puts(0, line++, buf);
870 category = (control >> 17) & 127;
871 switch(category)
873 case 0x00:
874 s = "General";
875 break;
876 case 0x40:
877 s = "Audio CD";
878 break;
879 default:
880 s = "Unknown";
882 snprintf(buf, sizeof(buf), "Category: 0x%02x (%s)", category, s);
883 lcd_puts(0, line++, buf);
885 x = (control >> 16) & 1;
886 generation = x;
887 if(((category & 0x70) == 0x10) ||
888 ((category & 0x70) == 0x40) ||
889 ((category & 0x78) == 0x38))
891 generation = !generation;
893 snprintf(buf, sizeof(buf), "Generation: %d (%s)",
894 x, generation?"Original":"No ind.");
895 lcd_puts(0, line++, buf);
897 x = (control >> 12) & 15;
898 snprintf(buf, sizeof(buf), "Source: %d", x);
899 lcd_puts(0, line++, buf);
901 x = (control >> 8) & 15;
902 switch(x)
904 case 0:
905 s = "Unspecified";
906 break;
907 case 8:
908 s = "A (Left)";
909 break;
910 case 4:
911 s = "B (Right)";
912 break;
913 default:
914 s = "";
915 break;
917 snprintf(buf, sizeof(buf), "Channel: %d (%s)", x, s);
918 lcd_puts(0, line++, buf);
920 x = (control >> 4) & 15;
921 switch(x)
923 case 0:
924 s = "44.1kHz";
925 break;
926 case 0x4:
927 s = "48kHz";
928 break;
929 case 0xc:
930 s = "32kHz";
931 break;
933 snprintf(buf, sizeof(buf), "Frequency: %d (%s)", x, s);
934 lcd_puts(0, line++, buf);
936 x = (control >> 2) & 3;
937 snprintf(buf, sizeof(buf), "Clock accuracy: %d", x);
938 lcd_puts(0, line++, buf);
939 line++;
941 #ifndef SIMULATOR
942 snprintf(buf, sizeof(buf), "Measured freq: %ldHz",
943 spdif_measure_frequency());
944 lcd_puts(0, line++, buf);
945 #endif
947 lcd_update();
949 if (action_userabort(HZ/10))
950 break;
953 spdif_set_output_source(spdif_source IF_SPDIF_POWER_(, spdif_src_on));
955 #ifdef HAVE_SPDIF_POWER
956 spdif_power_enable(global_settings.spdif_enable);
957 #endif
959 return false;
961 #endif /* CPU_COLDFIRE */
963 #ifndef SIMULATOR
964 #ifdef HAVE_LCD_BITMAP
965 /* button definitions */
966 #if (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
967 (CONFIG_KEYPAD == IRIVER_H300_PAD)
968 # define DEBUG_CANCEL BUTTON_OFF
970 #elif CONFIG_KEYPAD == RECORDER_PAD
971 # define DEBUG_CANCEL BUTTON_OFF
973 #elif CONFIG_KEYPAD == ONDIO_PAD
974 # define DEBUG_CANCEL BUTTON_MENU
976 #elif (CONFIG_KEYPAD == IPOD_1G2G_PAD) || \
977 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
978 (CONFIG_KEYPAD == IPOD_4G_PAD)
979 # define DEBUG_CANCEL BUTTON_MENU
981 #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
982 # define DEBUG_CANCEL BUTTON_PLAY
984 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
985 # define DEBUG_CANCEL BUTTON_REC
987 #elif CONFIG_KEYPAD == IRIVER_H10_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->gui_list[SCREEN_MAIN].data;
1454 if (action == ACTION_STD_OK)
1456 *page = (*page+1)%3;
1457 snprintf(lists->gui_list[SCREEN_MAIN].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->gui_list[SCREEN_MAIN].data;
1672 unsigned char card_name[7];
1673 unsigned char pbuf[32];
1674 char *title = lists->gui_list[SCREEN_MAIN].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);