httpget class: if a request is cancelled before a response is available give a hint...
[Rockbox.git] / apps / debug_menu.c
blobbb9a00c57b60161dff4a2540c52349a7526e67af
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 "structec.h"
30 #include "action.h"
31 #include "debug.h"
32 #include "thread.h"
33 #include "powermgmt.h"
34 #include "system.h"
35 #include "font.h"
36 #include "audio.h"
37 #include "mp3_playback.h"
38 #include "settings.h"
39 #include "list.h"
40 #include "statusbar.h"
41 #include "dir.h"
42 #include "panic.h"
43 #include "screens.h"
44 #include "misc.h"
45 #include "splash.h"
46 #include "dircache.h"
47 #ifdef HAVE_TAGCACHE
48 #include "tagcache.h"
49 #endif
50 #include "lcd-remote.h"
51 #include "crc32.h"
52 #include "logf.h"
53 #ifndef SIMULATOR
54 #include "disk.h"
55 #include "adc.h"
56 #include "power.h"
57 #include "usb.h"
58 #include "rtc.h"
59 #include "ata.h"
60 #include "fat.h"
61 #include "mas.h"
62 #include "eeprom_24cxx.h"
63 #if defined(HAVE_MMC) || defined(HAVE_HOTSWAP)
64 #include "ata_mmc.h"
65 #endif
66 #if CONFIG_TUNER
67 #include "tuner.h"
68 #include "radio.h"
69 #endif
70 #endif
72 #ifdef HAVE_LCD_BITMAP
73 #include "scrollbar.h"
74 #include "peakmeter.h"
75 #endif
76 #include "logfdisp.h"
77 #if CONFIG_CODEC == SWCODEC
78 #include "pcmbuf.h"
79 #include "buffering.h"
80 #if defined(HAVE_SPDIF_OUT) || defined(HAVE_SPDIF_IN)
81 #include "spdif.h"
82 #endif
83 #endif
84 #ifdef IRIVER_H300_SERIES
85 #include "pcf50606.h" /* for pcf50606_read */
86 #endif
87 #ifdef IAUDIO_X5
88 #include "ds2411.h"
89 #endif
90 #include "hwcompat.h"
91 #include "button.h"
92 #if CONFIG_RTC == RTC_PCF50605
93 #include "pcf50605.h"
94 #endif
96 #if CONFIG_CPU == DM320 || CONFIG_CPU == S3C2440 || CONFIG_CPU == TCC7801
97 #include "debug-target.h"
98 #endif
100 /*---------------------------------------------------*/
101 /* SPECIAL DEBUG STUFF */
102 /*---------------------------------------------------*/
103 extern struct thread_entry threads[MAXTHREADS];
105 static char thread_status_char(unsigned status)
107 static const char thread_status_chars[THREAD_NUM_STATES+1] =
109 [0 ... THREAD_NUM_STATES] = '?',
110 [STATE_RUNNING] = 'R',
111 [STATE_BLOCKED] = 'B',
112 [STATE_SLEEPING] = 'S',
113 [STATE_BLOCKED_W_TMO] = 'T',
114 [STATE_FROZEN] = 'F',
115 [STATE_KILLED] = 'K',
118 #if NUM_CORES > 1
119 if (status == STATE_BUSY) /* Not a state index */
120 return '.';
121 #endif
123 if (status > THREAD_NUM_STATES)
124 status = THREAD_NUM_STATES;
126 return thread_status_chars[status];
129 static char* threads_getname(int selected_item, void * data, char *buffer)
131 (void)data;
132 struct thread_entry *thread;
133 char name[32];
135 #if NUM_CORES > 1
136 if (selected_item < (int)NUM_CORES)
138 snprintf(buffer, MAX_PATH, "Idle (%d): %2d%%", selected_item,
139 idle_stack_usage(selected_item));
140 return buffer;
143 selected_item -= NUM_CORES;
144 #endif
146 thread = &threads[selected_item];
148 if (thread->state == STATE_KILLED)
150 snprintf(buffer, MAX_PATH, "%2d: ---", selected_item);
151 return buffer;
154 thread_get_name(name, 32, thread);
156 snprintf(buffer, MAX_PATH,
157 "%2d: " IF_COP("(%d) ") "%c%c " IF_PRIO("%d ") "%2d%% %s",
158 selected_item,
159 IF_COP(thread->core,)
160 #ifdef HAVE_SCHEDULER_BOOSTCTRL
161 (thread->boosted) ? '+' :
162 #endif
163 ((thread->state == STATE_RUNNING) ? '*' : ' '),
164 thread_status_char(thread->state),
165 IF_PRIO(thread->priority,)
166 thread_stack_usage(thread), name);
168 return buffer;
170 static int dbg_threads_action_callback(int action, struct gui_synclist *lists)
172 (void)lists;
173 #ifdef ROCKBOX_HAS_LOGF
174 if (action == ACTION_STD_OK)
176 int selpos = gui_synclist_get_sel_pos(lists);
177 #if NUM_CORES > 1
178 if (selpos >= NUM_CORES)
179 remove_thread(&threads[selpos - NUM_CORES]);
180 #else
181 remove_thread(&threads[selpos]);
182 #endif
183 return ACTION_REDRAW;
185 #endif /* ROCKBOX_HAS_LOGF */
186 if (action == ACTION_NONE)
187 action = ACTION_REDRAW;
188 return action;
190 /* Test code!!! */
191 static bool dbg_os(void)
193 struct simplelist_info info;
194 simplelist_info_init(&info, IF_COP("Core and ") "Stack usage:",
195 #if NUM_CORES == 1
196 MAXTHREADS,
197 #else
198 MAXTHREADS+NUM_CORES,
199 #endif
200 NULL);
201 #ifndef ROCKBOX_HAS_LOGF
202 info.hide_selection = true;
203 #endif
204 info.action_callback = dbg_threads_action_callback;
205 info.get_name = threads_getname;
206 return simplelist_show_list(&info);
209 #ifdef HAVE_LCD_BITMAP
210 #if CONFIG_CODEC != SWCODEC
211 #ifndef SIMULATOR
212 static bool dbg_audio_thread(void)
214 char buf[32];
215 struct audio_debug d;
217 lcd_setmargins(0, 0);
218 lcd_setfont(FONT_SYSFIXED);
220 while(1)
222 if (action_userabort(HZ/5))
223 return false;
225 audio_get_debugdata(&d);
227 lcd_clear_display();
229 snprintf(buf, sizeof(buf), "read: %x", d.audiobuf_read);
230 lcd_puts(0, 0, buf);
231 snprintf(buf, sizeof(buf), "write: %x", d.audiobuf_write);
232 lcd_puts(0, 1, buf);
233 snprintf(buf, sizeof(buf), "swap: %x", d.audiobuf_swapwrite);
234 lcd_puts(0, 2, buf);
235 snprintf(buf, sizeof(buf), "playing: %d", d.playing);
236 lcd_puts(0, 3, buf);
237 snprintf(buf, sizeof(buf), "playable: %x", d.playable_space);
238 lcd_puts(0, 4, buf);
239 snprintf(buf, sizeof(buf), "unswapped: %x", d.unswapped_space);
240 lcd_puts(0, 5, buf);
242 /* Playable space left */
243 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, 6*8, 112, 4, d.audiobuflen, 0,
244 d.playable_space, HORIZONTAL);
246 /* Show the watermark limit */
247 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, 6*8+4, 112, 4, d.audiobuflen, 0,
248 d.low_watermark_level, HORIZONTAL);
250 snprintf(buf, sizeof(buf), "wm: %x - %x",
251 d.low_watermark_level, d.lowest_watermark_level);
252 lcd_puts(0, 7, buf);
254 lcd_update();
256 return false;
258 #endif /* !SIMULATOR */
259 #else /* CONFIG_CODEC == SWCODEC */
260 extern size_t filebuflen;
261 /* This is a size_t, but call it a long so it puts a - when it's bad. */
263 static unsigned int ticks, boost_ticks;
265 static void dbg_audio_task(void)
267 #ifndef SIMULATOR
268 if(FREQ > CPUFREQ_NORMAL)
269 boost_ticks++;
270 #endif
272 ticks++;
275 static bool dbg_buffering_thread(void)
277 char buf[32];
278 int button;
279 int line;
280 bool done = false;
281 size_t bufused;
282 size_t bufsize = pcmbuf_get_bufsize();
283 int pcmbufdescs = pcmbuf_descs();
284 struct buffering_debug d;
286 ticks = boost_ticks = 0;
288 tick_add_task(dbg_audio_task);
290 lcd_setmargins(0, 0);
291 lcd_setfont(FONT_SYSFIXED);
292 while(!done)
294 button = get_action(CONTEXT_STD,HZ/5);
295 switch(button)
297 case ACTION_STD_NEXT:
298 audio_next();
299 break;
300 case ACTION_STD_PREV:
301 audio_prev();
302 break;
303 case ACTION_STD_CANCEL:
304 done = true;
305 break;
308 buffering_get_debugdata(&d);
310 line = 0;
311 lcd_clear_display();
313 bufused = bufsize - pcmbuf_free();
315 snprintf(buf, sizeof(buf), "pcm: %7ld/%7ld", (long) bufused, (long) bufsize);
316 lcd_puts(0, line++, buf);
318 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6,
319 bufsize, 0, bufused, HORIZONTAL);
320 line++;
322 snprintf(buf, sizeof(buf), "alloc: %8ld/%8ld", audio_filebufused(),
323 (long) filebuflen);
324 lcd_puts(0, line++, buf);
326 #if LCD_HEIGHT > 80
327 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6,
328 filebuflen, 0, audio_filebufused(), HORIZONTAL);
329 line++;
331 snprintf(buf, sizeof(buf), "real: %8ld/%8ld", (long)d.buffered_data,
332 (long)filebuflen);
333 lcd_puts(0, line++, buf);
335 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6,
336 filebuflen, 0, (long)d.buffered_data, HORIZONTAL);
337 line++;
338 #endif
340 snprintf(buf, sizeof(buf), "usefl: %8ld/%8ld", (long)(d.useful_data),
341 (long)filebuflen);
342 lcd_puts(0, line++, buf);
344 #if LCD_HEIGHT > 80
345 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6,
346 filebuflen, 0, d.useful_data, HORIZONTAL);
347 line++;
348 #endif
350 snprintf(buf, sizeof(buf), "data_rem: %ld", (long)d.data_rem);
351 lcd_puts(0, line++, buf);
353 snprintf(buf, sizeof(buf), "track count: %2d", audio_track_count());
354 lcd_puts(0, line++, buf);
356 snprintf(buf, sizeof(buf), "handle count: %d", (int)d.num_handles);
357 lcd_puts(0, line++, buf);
359 #ifndef SIMULATOR
360 snprintf(buf, sizeof(buf), "cpu freq: %3dMHz",
361 (int)((FREQ + 500000) / 1000000));
362 lcd_puts(0, line++, buf);
363 #endif
365 if (ticks > 0)
367 snprintf(buf, sizeof(buf), "boost ratio: %3d%%",
368 boost_ticks * 100 / ticks);
369 lcd_puts(0, line++, buf);
372 snprintf(buf, sizeof(buf), "pcmbufdesc: %2d/%2d",
373 pcmbuf_used_descs(), pcmbufdescs);
374 lcd_puts(0, line++, buf);
376 lcd_update();
379 tick_remove_task(dbg_audio_task);
381 return false;
383 #endif /* CONFIG_CODEC */
384 #endif /* HAVE_LCD_BITMAP */
387 #if (CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE))
388 /* Tool function to read the flash manufacturer and type, if available.
389 Only chips which could be reprogrammed in system will return values.
390 (The mode switch addresses vary between flash manufacturers, hence addr1/2) */
391 /* In IRAM to avoid problems when running directly from Flash */
392 static bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
393 unsigned addr1, unsigned addr2)
394 ICODE_ATTR __attribute__((noinline));
395 static bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
396 unsigned addr1, unsigned addr2)
399 unsigned not_manu, not_id; /* read values before switching to ID mode */
400 unsigned manu, id; /* read values when in ID mode */
402 #if CONFIG_CPU == SH7034
403 volatile unsigned char* flash = (unsigned char*)0x2000000; /* flash mapping */
404 #elif defined(CPU_COLDFIRE)
405 volatile unsigned short* flash = (unsigned short*)0; /* flash mapping */
406 #endif
407 int old_level; /* saved interrupt level */
409 not_manu = flash[0]; /* read the normal content */
410 not_id = flash[1]; /* should be 'A' (0x41) and 'R' (0x52) from the "ARCH" marker */
412 /* disable interrupts, prevent any stray flash access */
413 old_level = set_irq_level(HIGHEST_IRQ_LEVEL);
415 flash[addr1] = 0xAA; /* enter command mode */
416 flash[addr2] = 0x55;
417 flash[addr1] = 0x90; /* ID command */
418 /* Atmel wants 20ms pause here */
419 /* sleep(HZ/50); no sleeping possible while interrupts are disabled */
421 manu = flash[0]; /* read the IDs */
422 id = flash[1];
424 flash[0] = 0xF0; /* reset flash (back to normal read mode) */
425 /* Atmel wants 20ms pause here */
426 /* sleep(HZ/50); no sleeping possible while interrupts are disabled */
428 set_irq_level(old_level); /* enable interrupts again */
430 /* I assume success if the obtained values are different from
431 the normal flash content. This is not perfectly bulletproof, they
432 could theoretically be the same by chance, causing us to fail. */
433 if (not_manu != manu || not_id != id) /* a value has changed */
435 *p_manufacturer = manu; /* return the results */
436 *p_device = id;
437 return true; /* success */
439 return false; /* fail */
441 #endif /* (CONFIG_CPU == SH7034 || CPU_COLDFIRE) */
443 #ifndef SIMULATOR
444 #ifdef CPU_PP
445 static int perfcheck(void)
447 int result;
449 asm (
450 "mrs r2, CPSR \n"
451 "orr r0, r2, #0xc0 \n" /* disable IRQ and FIQ */
452 "msr CPSR_c, r0 \n"
453 "mov %[res], #0 \n"
454 "ldr r0, [%[timr]] \n"
455 "add r0, r0, %[tmo] \n"
456 "1: \n"
457 "add %[res], %[res], #1 \n"
458 "ldr r1, [%[timr]] \n"
459 "cmp r1, r0 \n"
460 "bmi 1b \n"
461 "msr CPSR_c, r2 \n" /* reset IRQ and FIQ state */
463 [res]"=&r"(result)
465 [timr]"r"(&USEC_TIMER),
466 [tmo]"r"(
467 #if CONFIG_CPU == PP5002
468 16000
469 #else /* PP5020/5022/5024 */
470 10226
471 #endif
474 "r0", "r1", "r2"
476 return result;
478 #endif
480 #ifdef HAVE_LCD_BITMAP
481 static bool dbg_hw_info(void)
483 #if CONFIG_CPU == SH7034
484 char buf[32];
485 int bitmask = HW_MASK;
486 int rom_version = ROM_VERSION;
487 unsigned manu, id; /* flash IDs */
488 bool got_id; /* flag if we managed to get the flash IDs */
489 unsigned rom_crc = 0xffffffff; /* CRC32 of the boot ROM */
490 bool has_bootrom; /* flag for boot ROM present */
491 int oldmode; /* saved memory guard mode */
493 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
495 /* get flash ROM type */
496 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
497 if (!got_id)
498 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
500 /* check if the boot ROM area is a flash mirror */
501 has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0);
502 if (has_bootrom) /* if ROM and Flash different */
504 /* calculate CRC16 checksum of boot ROM */
505 rom_crc = crc_32((unsigned char*)0x0000, 64*1024, 0xffffffff);
508 system_memory_guard(oldmode); /* re-enable memory guard */
510 lcd_setmargins(0, 0);
511 lcd_setfont(FONT_SYSFIXED);
512 lcd_clear_display();
514 lcd_puts(0, 0, "[Hardware info]");
516 snprintf(buf, 32, "ROM: %d.%02d", rom_version/100, rom_version%100);
517 lcd_puts(0, 1, buf);
519 snprintf(buf, 32, "Mask: 0x%04x", bitmask);
520 lcd_puts(0, 2, buf);
522 if (got_id)
523 snprintf(buf, 32, "Flash: M=%02x D=%02x", manu, id);
524 else
525 snprintf(buf, 32, "Flash: M=?? D=??"); /* unknown, sorry */
526 lcd_puts(0, 3, buf);
528 if (has_bootrom)
530 if (rom_crc == 0x56DBA4EE) /* known Version 1 */
531 snprintf(buf, 32, "Boot ROM: V1");
532 else
533 snprintf(buf, 32, "ROMcrc: 0x%08x", rom_crc);
535 else
537 snprintf(buf, 32, "Boot ROM: none");
539 lcd_puts(0, 4, buf);
541 lcd_update();
543 while (!(action_userabort(TIMEOUT_BLOCK)));
545 #elif CONFIG_CPU == MCF5249 || CONFIG_CPU == MCF5250
546 char buf[32];
547 unsigned manu, id; /* flash IDs */
548 int got_id; /* flag if we managed to get the flash IDs */
549 int oldmode; /* saved memory guard mode */
550 int line = 0;
552 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
554 /* get flash ROM type */
555 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
556 if (!got_id)
557 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
559 system_memory_guard(oldmode); /* re-enable memory guard */
561 lcd_setmargins(0, 0);
562 lcd_setfont(FONT_SYSFIXED);
563 lcd_clear_display();
565 lcd_puts(0, line++, "[Hardware info]");
567 if (got_id)
568 snprintf(buf, 32, "Flash: M=%04x D=%04x", manu, id);
569 else
570 snprintf(buf, 32, "Flash: M=???? D=????"); /* unknown, sorry */
571 lcd_puts(0, line++, buf);
573 #ifdef IAUDIO_X5
575 struct ds2411_id id;
577 lcd_puts(0, ++line, "Serial Number:");
579 got_id = ds2411_read_id(&id);
581 if (got_id == DS2411_OK)
583 snprintf(buf, 32, " FC=%02x", (unsigned)id.family_code);
584 lcd_puts(0, ++line, buf);
585 snprintf(buf, 32, " ID=%02X %02X %02X %02X %02X %02X",
586 (unsigned)id.uid[0], (unsigned)id.uid[1], (unsigned)id.uid[2],
587 (unsigned)id.uid[3], (unsigned)id.uid[4], (unsigned)id.uid[5]);
588 lcd_puts(0, ++line, buf);
589 snprintf(buf, 32, " CRC=%02X", (unsigned)id.crc);
591 else
593 snprintf(buf, 32, "READ ERR=%d", got_id);
596 lcd_puts(0, ++line, buf);
598 #endif
600 lcd_update();
602 while (!(action_userabort(TIMEOUT_BLOCK)));
604 #elif defined(CPU_PP502x)
605 int line = 0;
606 char buf[32];
607 char pp_version[] = { (PP_VER2 >> 24) & 0xff, (PP_VER2 >> 16) & 0xff,
608 (PP_VER2 >> 8) & 0xff, (PP_VER2) & 0xff,
609 (PP_VER1 >> 24) & 0xff, (PP_VER1 >> 16) & 0xff,
610 (PP_VER1 >> 8) & 0xff, (PP_VER1) & 0xff, '\0' };
612 lcd_setmargins(0, 0);
613 lcd_setfont(FONT_SYSFIXED);
614 lcd_clear_display();
616 lcd_puts(0, line++, "[Hardware info]");
618 #ifdef IPOD_ARCH
619 snprintf(buf, sizeof(buf), "HW rev: 0x%08lx", IPOD_HW_REVISION);
620 lcd_puts(0, line++, buf);
621 #endif
623 #ifdef IPOD_COLOR
624 extern int lcd_type; /* Defined in lcd-colornano.c */
626 snprintf(buf, sizeof(buf), "LCD type: %d", lcd_type);
627 lcd_puts(0, line++, buf);
628 #endif
630 snprintf(buf, sizeof(buf), "PP version: %s", pp_version);
631 lcd_puts(0, line++, buf);
633 snprintf(buf, sizeof(buf), "Est. clock (kHz): %d", perfcheck());
634 lcd_puts(0, line++, buf);
636 lcd_update();
638 while (!(action_userabort(TIMEOUT_BLOCK)));
640 #elif CONFIG_CPU == PP5002
641 int line = 0;
642 char buf[32];
643 char pp_version[] = { (PP_VER4 >> 8) & 0xff, PP_VER4 & 0xff,
644 (PP_VER3 >> 8) & 0xff, PP_VER3 & 0xff,
645 (PP_VER2 >> 8) & 0xff, PP_VER2 & 0xff,
646 (PP_VER1 >> 8) & 0xff, PP_VER1 & 0xff, '\0' };
649 lcd_setmargins(0, 0);
650 lcd_setfont(FONT_SYSFIXED);
651 lcd_clear_display();
653 lcd_puts(0, line++, "[Hardware info]");
655 #ifdef IPOD_ARCH
656 snprintf(buf, sizeof(buf), "HW rev: 0x%08lx", IPOD_HW_REVISION);
657 lcd_puts(0, line++, buf);
658 #endif
660 snprintf(buf, sizeof(buf), "PP version: %s", pp_version);
661 lcd_puts(0, line++, buf);
663 snprintf(buf, sizeof(buf), "Est. clock (kHz): %d", perfcheck());
664 lcd_puts(0, line++, buf);
666 lcd_update();
668 while (!(action_userabort(TIMEOUT_BLOCK)));
669 #else
670 /* Define this function in your target tree */
671 return __dbg_hw_info();
672 #endif /* CONFIG_CPU */
673 return false;
675 #else /* !HAVE_LCD_BITMAP */
676 static bool dbg_hw_info(void)
678 char buf[32];
679 int button;
680 int currval = 0;
681 int rom_version = ROM_VERSION;
682 unsigned manu, id; /* flash IDs */
683 bool got_id; /* flag if we managed to get the flash IDs */
684 unsigned rom_crc = 0xffffffff; /* CRC32 of the boot ROM */
685 bool has_bootrom; /* flag for boot ROM present */
686 int oldmode; /* saved memory guard mode */
688 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
690 /* get flash ROM type */
691 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
692 if (!got_id)
693 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
695 /* check if the boot ROM area is a flash mirror */
696 has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0);
697 if (has_bootrom) /* if ROM and Flash different */
699 /* calculate CRC16 checksum of boot ROM */
700 rom_crc = crc_32((unsigned char*)0x0000, 64*1024, 0xffffffff);
703 system_memory_guard(oldmode); /* re-enable memory guard */
705 lcd_clear_display();
707 lcd_puts(0, 0, "[HW Info]");
708 while(1)
710 switch(currval)
712 case 0:
713 snprintf(buf, 32, "ROM: %d.%02d",
714 rom_version/100, rom_version%100);
715 break;
716 case 1:
717 if (got_id)
718 snprintf(buf, 32, "Flash:%02x,%02x", manu, id);
719 else
720 snprintf(buf, 32, "Flash:??,??"); /* unknown, sorry */
721 break;
722 case 2:
723 if (has_bootrom)
725 if (rom_crc == 0x56DBA4EE) /* known Version 1 */
726 snprintf(buf, 32, "BootROM: V1");
727 else if (rom_crc == 0x358099E8)
728 snprintf(buf, 32, "BootROM: V2");
729 /* alternative boot ROM found in one single player so far */
730 else
731 snprintf(buf, 32, "R: %08x", rom_crc);
733 else
734 snprintf(buf, 32, "BootROM: no");
737 lcd_puts(0, 1, buf);
738 lcd_update();
740 button = get_action(CONTEXT_SETTINGS,TIMEOUT_BLOCK);
742 switch(button)
744 case ACTION_STD_CANCEL:
745 return false;
747 case ACTION_SETTINGS_DEC:
748 currval--;
749 if(currval < 0)
750 currval = 2;
751 break;
753 case ACTION_SETTINGS_INC:
754 currval++;
755 if(currval > 2)
756 currval = 0;
757 break;
760 return false;
762 #endif /* !HAVE_LCD_BITMAP */
763 #endif /* !SIMULATOR */
765 #ifndef SIMULATOR
766 static char* dbg_partitions_getname(int selected_item, void * data, char *buffer)
768 (void)data;
769 int partition = selected_item/2;
770 struct partinfo* p = disk_partinfo(partition);
771 if (selected_item%2)
773 snprintf(buffer, MAX_PATH, " T:%x %ld MB", p->type, p->size / 2048);
775 else
777 snprintf(buffer, MAX_PATH, "P%d: S:%lx", partition, p->start);
779 return buffer;
782 bool dbg_partitions(void)
784 struct simplelist_info info;
785 simplelist_info_init(&info, "Partition Info", 4, NULL);
786 info.selection_size = 2;
787 info.hide_selection = true;
788 info.get_name = dbg_partitions_getname;
789 return simplelist_show_list(&info);
791 #endif
793 #if defined(CPU_COLDFIRE) && defined(HAVE_SPDIF_OUT)
794 static bool dbg_spdif(void)
796 char buf[128];
797 int line;
798 unsigned int control;
799 int x;
800 char *s;
801 int category;
802 int generation;
803 unsigned int interruptstat;
804 bool valnogood, symbolerr, parityerr;
805 bool done = false;
806 bool spdif_src_on;
807 int spdif_source = spdif_get_output_source(&spdif_src_on);
808 spdif_set_output_source(AUDIO_SRC_SPDIF IF_SPDIF_POWER_(, true));
810 lcd_setmargins(0, 0);
811 lcd_clear_display();
812 lcd_setfont(FONT_SYSFIXED);
814 #ifdef HAVE_SPDIF_POWER
815 spdif_power_enable(true); /* We need SPDIF power for both sending & receiving */
816 #endif
818 while (!done)
820 line = 0;
822 control = EBU1RCVCCHANNEL1;
823 interruptstat = INTERRUPTSTAT;
824 INTERRUPTCLEAR = 0x03c00000;
826 valnogood = (interruptstat & 0x01000000)?true:false;
827 symbolerr = (interruptstat & 0x00800000)?true:false;
828 parityerr = (interruptstat & 0x00400000)?true:false;
830 snprintf(buf, sizeof(buf), "Val: %s Sym: %s Par: %s",
831 valnogood?"--":"OK",
832 symbolerr?"--":"OK",
833 parityerr?"--":"OK");
834 lcd_puts(0, line++, buf);
836 snprintf(buf, sizeof(buf), "Status word: %08x", (int)control);
837 lcd_puts(0, line++, buf);
839 line++;
841 x = control >> 31;
842 snprintf(buf, sizeof(buf), "PRO: %d (%s)",
843 x, x?"Professional":"Consumer");
844 lcd_puts(0, line++, buf);
846 x = (control >> 30) & 1;
847 snprintf(buf, sizeof(buf), "Audio: %d (%s)",
848 x, x?"Non-PCM":"PCM");
849 lcd_puts(0, line++, buf);
851 x = (control >> 29) & 1;
852 snprintf(buf, sizeof(buf), "Copy: %d (%s)",
853 x, x?"Permitted":"Inhibited");
854 lcd_puts(0, line++, buf);
856 x = (control >> 27) & 7;
857 switch(x)
859 case 0:
860 s = "None";
861 break;
862 case 1:
863 s = "50/15us";
864 break;
865 default:
866 s = "Reserved";
867 break;
869 snprintf(buf, sizeof(buf), "Preemphasis: %d (%s)", x, s);
870 lcd_puts(0, line++, buf);
872 x = (control >> 24) & 3;
873 snprintf(buf, sizeof(buf), "Mode: %d", x);
874 lcd_puts(0, line++, buf);
876 category = (control >> 17) & 127;
877 switch(category)
879 case 0x00:
880 s = "General";
881 break;
882 case 0x40:
883 s = "Audio CD";
884 break;
885 default:
886 s = "Unknown";
888 snprintf(buf, sizeof(buf), "Category: 0x%02x (%s)", category, s);
889 lcd_puts(0, line++, buf);
891 x = (control >> 16) & 1;
892 generation = x;
893 if(((category & 0x70) == 0x10) ||
894 ((category & 0x70) == 0x40) ||
895 ((category & 0x78) == 0x38))
897 generation = !generation;
899 snprintf(buf, sizeof(buf), "Generation: %d (%s)",
900 x, generation?"Original":"No ind.");
901 lcd_puts(0, line++, buf);
903 x = (control >> 12) & 15;
904 snprintf(buf, sizeof(buf), "Source: %d", x);
905 lcd_puts(0, line++, buf);
907 x = (control >> 8) & 15;
908 switch(x)
910 case 0:
911 s = "Unspecified";
912 break;
913 case 8:
914 s = "A (Left)";
915 break;
916 case 4:
917 s = "B (Right)";
918 break;
919 default:
920 s = "";
921 break;
923 snprintf(buf, sizeof(buf), "Channel: %d (%s)", x, s);
924 lcd_puts(0, line++, buf);
926 x = (control >> 4) & 15;
927 switch(x)
929 case 0:
930 s = "44.1kHz";
931 break;
932 case 0x4:
933 s = "48kHz";
934 break;
935 case 0xc:
936 s = "32kHz";
937 break;
939 snprintf(buf, sizeof(buf), "Frequency: %d (%s)", x, s);
940 lcd_puts(0, line++, buf);
942 x = (control >> 2) & 3;
943 snprintf(buf, sizeof(buf), "Clock accuracy: %d", x);
944 lcd_puts(0, line++, buf);
945 line++;
947 #ifndef SIMULATOR
948 snprintf(buf, sizeof(buf), "Measured freq: %ldHz",
949 spdif_measure_frequency());
950 lcd_puts(0, line++, buf);
951 #endif
953 lcd_update();
955 if (action_userabort(HZ/10))
956 break;
959 spdif_set_output_source(spdif_source IF_SPDIF_POWER_(, spdif_src_on));
961 #ifdef HAVE_SPDIF_POWER
962 spdif_power_enable(global_settings.spdif_enable);
963 #endif
965 return false;
967 #endif /* CPU_COLDFIRE */
969 #ifndef SIMULATOR
970 #ifdef HAVE_LCD_BITMAP
971 /* button definitions */
972 #if (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
973 (CONFIG_KEYPAD == IRIVER_H300_PAD)
974 # define DEBUG_CANCEL BUTTON_OFF
976 #elif CONFIG_KEYPAD == RECORDER_PAD
977 # define DEBUG_CANCEL BUTTON_OFF
979 #elif CONFIG_KEYPAD == ONDIO_PAD
980 # define DEBUG_CANCEL BUTTON_MENU
982 #elif (CONFIG_KEYPAD == IPOD_1G2G_PAD) || \
983 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
984 (CONFIG_KEYPAD == IPOD_4G_PAD)
985 # define DEBUG_CANCEL BUTTON_MENU
987 #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
988 # define DEBUG_CANCEL BUTTON_PLAY
990 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
991 # define DEBUG_CANCEL BUTTON_REC
993 #elif (CONFIG_KEYPAD == IRIVER_H10_PAD)
994 # define DEBUG_CANCEL BUTTON_REW
996 #elif (CONFIG_KEYPAD == MROBE100_PAD)
997 # define DEBUG_CANCEL BUTTON_MENU
999 #elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \
1000 (CONFIG_KEYPAD == SANSA_C200_PAD)
1001 # define DEBUG_CANCEL BUTTON_LEFT
1002 #endif /* key definitions */
1004 /* Test code!!! */
1005 bool dbg_ports(void)
1007 #if CONFIG_CPU == SH7034
1008 char buf[32];
1009 int adc_battery_voltage, adc_battery_level;
1011 lcd_setfont(FONT_SYSFIXED);
1012 lcd_setmargins(0, 0);
1013 lcd_clear_display();
1015 while(1)
1017 snprintf(buf, 32, "PADR: %04x", (unsigned short)PADR);
1018 lcd_puts(0, 0, buf);
1019 snprintf(buf, 32, "PBDR: %04x", (unsigned short)PBDR);
1020 lcd_puts(0, 1, buf);
1022 snprintf(buf, 32, "AN0: %03x AN4: %03x", adc_read(0), adc_read(4));
1023 lcd_puts(0, 2, buf);
1024 snprintf(buf, 32, "AN1: %03x AN5: %03x", adc_read(1), adc_read(5));
1025 lcd_puts(0, 3, buf);
1026 snprintf(buf, 32, "AN2: %03x AN6: %03x", adc_read(2), adc_read(6));
1027 lcd_puts(0, 4, buf);
1028 snprintf(buf, 32, "AN3: %03x AN7: %03x", adc_read(3), adc_read(7));
1029 lcd_puts(0, 5, buf);
1031 battery_read_info(&adc_battery_voltage, &adc_battery_level);
1032 snprintf(buf, 32, "Batt: %d.%03dV %d%% ", adc_battery_voltage / 1000,
1033 adc_battery_voltage % 1000, adc_battery_level);
1034 lcd_puts(0, 6, buf);
1036 lcd_update();
1037 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1038 return false;
1040 #elif defined(CPU_COLDFIRE)
1041 unsigned int gpio_out;
1042 unsigned int gpio1_out;
1043 unsigned int gpio_read;
1044 unsigned int gpio1_read;
1045 unsigned int gpio_function;
1046 unsigned int gpio1_function;
1047 unsigned int gpio_enable;
1048 unsigned int gpio1_enable;
1049 int adc_buttons, adc_remote;
1050 int adc_battery_voltage, adc_battery_level;
1051 char buf[128];
1052 int line;
1054 lcd_setmargins(0, 0);
1055 lcd_clear_display();
1056 lcd_setfont(FONT_SYSFIXED);
1058 while(1)
1060 line = 0;
1061 gpio_read = GPIO_READ;
1062 gpio1_read = GPIO1_READ;
1063 gpio_out = GPIO_OUT;
1064 gpio1_out = GPIO1_OUT;
1065 gpio_function = GPIO_FUNCTION;
1066 gpio1_function = GPIO1_FUNCTION;
1067 gpio_enable = GPIO_ENABLE;
1068 gpio1_enable = GPIO1_ENABLE;
1070 snprintf(buf, sizeof(buf), "GPIO_READ: %08x", gpio_read);
1071 lcd_puts(0, line++, buf);
1072 snprintf(buf, sizeof(buf), "GPIO_OUT: %08x", gpio_out);
1073 lcd_puts(0, line++, buf);
1074 snprintf(buf, sizeof(buf), "GPIO_FUNCTION: %08x", gpio_function);
1075 lcd_puts(0, line++, buf);
1076 snprintf(buf, sizeof(buf), "GPIO_ENABLE: %08x", gpio_enable);
1077 lcd_puts(0, line++, buf);
1079 snprintf(buf, sizeof(buf), "GPIO1_READ: %08x", gpio1_read);
1080 lcd_puts(0, line++, buf);
1081 snprintf(buf, sizeof(buf), "GPIO1_OUT: %08x", gpio1_out);
1082 lcd_puts(0, line++, buf);
1083 snprintf(buf, sizeof(buf), "GPIO1_FUNCTION: %08x", gpio1_function);
1084 lcd_puts(0, line++, buf);
1085 snprintf(buf, sizeof(buf), "GPIO1_ENABLE: %08x", gpio1_enable);
1086 lcd_puts(0, line++, buf);
1088 adc_buttons = adc_read(ADC_BUTTONS);
1089 adc_remote = adc_read(ADC_REMOTE);
1090 battery_read_info(&adc_battery_voltage, &adc_battery_level);
1091 #if defined(IAUDIO_X5) || defined(IAUDIO_M5) || defined(IRIVER_H300_SERIES)
1092 snprintf(buf, sizeof(buf), "ADC_BUTTONS (%c): %02x",
1093 button_scan_enabled() ? '+' : '-', adc_buttons);
1094 #else
1095 snprintf(buf, sizeof(buf), "ADC_BUTTONS: %02x", adc_buttons);
1096 #endif
1097 lcd_puts(0, line++, buf);
1098 #if defined(IAUDIO_X5) || defined(IAUDIO_M5)
1099 snprintf(buf, sizeof(buf), "ADC_REMOTE (%c): %02x",
1100 remote_detect() ? '+' : '-', adc_remote);
1101 #else
1102 snprintf(buf, sizeof(buf), "ADC_REMOTE: %02x", adc_remote);
1103 #endif
1104 lcd_puts(0, line++, buf);
1105 #if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES)
1106 snprintf(buf, sizeof(buf), "ADC_REMOTEDETECT: %02x",
1107 adc_read(ADC_REMOTEDETECT));
1108 lcd_puts(0, line++, buf);
1109 #endif
1111 snprintf(buf, 32, "Batt: %d.%03dV %d%% ", adc_battery_voltage / 1000,
1112 adc_battery_voltage % 1000, adc_battery_level);
1113 lcd_puts(0, line++, buf);
1115 #if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES)
1116 snprintf(buf, sizeof(buf), "remotetype: %d", remote_type());
1117 lcd_puts(0, line++, buf);
1118 #endif
1120 lcd_update();
1121 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1122 return false;
1125 #elif defined(CPU_PP502x)
1127 char buf[128];
1128 int line;
1130 lcd_setmargins(0, 0);
1131 lcd_clear_display();
1132 lcd_setfont(FONT_SYSFIXED);
1134 while(1)
1136 line = 0;
1137 lcd_puts(0, line++, "GPIO STATES:");
1138 snprintf(buf, sizeof(buf), "A: %02x E: %02x I: %02x",
1139 (unsigned int)GPIOA_INPUT_VAL,
1140 (unsigned int)GPIOE_INPUT_VAL,
1141 (unsigned int)GPIOI_INPUT_VAL);
1142 lcd_puts(0, line++, buf);
1143 snprintf(buf, sizeof(buf), "B: %02x F: %02x J: %02x",
1144 (unsigned int)GPIOB_INPUT_VAL,
1145 (unsigned int)GPIOF_INPUT_VAL,
1146 (unsigned int)GPIOJ_INPUT_VAL);
1147 lcd_puts(0, line++, buf);
1148 snprintf(buf, sizeof(buf), "C: %02x G: %02x K: %02x",
1149 (unsigned int)GPIOC_INPUT_VAL,
1150 (unsigned int)GPIOG_INPUT_VAL,
1151 (unsigned int)GPIOK_INPUT_VAL);
1152 lcd_puts(0, line++, buf);
1153 snprintf(buf, sizeof(buf), "D: %02x H: %02x L: %02x",
1154 (unsigned int)GPIOD_INPUT_VAL,
1155 (unsigned int)GPIOH_INPUT_VAL,
1156 (unsigned int)GPIOL_INPUT_VAL);
1157 lcd_puts(0, line++, buf);
1158 line++;
1159 snprintf(buf, sizeof(buf), "GPO32_VAL: %08lx", GPO32_VAL);
1160 lcd_puts(0, line++, buf);
1161 snprintf(buf, sizeof(buf), "GPO32_EN: %08lx", GPO32_ENABLE);
1162 lcd_puts(0, line++, buf);
1163 snprintf(buf, sizeof(buf), "DEV_EN: %08lx", DEV_EN);
1164 lcd_puts(0, line++, buf);
1165 snprintf(buf, sizeof(buf), "DEV_EN2: %08lx", DEV_EN2);
1166 lcd_puts(0, line++, buf);
1167 snprintf(buf, sizeof(buf), "DEV_EN3: %08lx", inl(0x60006044));
1168 lcd_puts(0, line++, buf); /* to be verified */
1169 snprintf(buf, sizeof(buf), "DEV_INIT1: %08lx", DEV_INIT1);
1170 lcd_puts(0, line++, buf);
1171 snprintf(buf, sizeof(buf), "DEV_INIT2: %08lx", DEV_INIT2);
1172 lcd_puts(0, line++, buf);
1174 #if defined(IRIVER_H10) || defined(IRIVER_H10_5GB)
1175 line++;
1176 snprintf(buf, sizeof(buf), "BATT: %03x UNK1: %03x",
1177 adc_read(ADC_BATTERY), adc_read(ADC_UNKNOWN_1));
1178 lcd_puts(0, line++, buf);
1179 snprintf(buf, sizeof(buf), "REM: %03x PAD: %03x",
1180 adc_read(ADC_REMOTE), adc_read(ADC_SCROLLPAD));
1181 lcd_puts(0, line++, buf);
1182 #elif defined(SANSA_E200)
1183 line++;
1184 snprintf(buf, sizeof(buf), "ADC_BVDD: %4d", adc_read(ADC_BVDD));
1185 lcd_puts(0, line++, buf);
1186 snprintf(buf, sizeof(buf), "ADC_RTCSUP: %4d", adc_read(ADC_RTCSUP));
1187 lcd_puts(0, line++, buf);
1188 snprintf(buf, sizeof(buf), "ADC_UVDD: %4d", adc_read(ADC_UVDD));
1189 lcd_puts(0, line++, buf);
1190 snprintf(buf, sizeof(buf), "ADC_CHG_IN: %4d", adc_read(ADC_CHG_IN));
1191 lcd_puts(0, line++, buf);
1192 snprintf(buf, sizeof(buf), "ADC_CVDD: %4d", adc_read(ADC_CVDD));
1193 lcd_puts(0, line++, buf);
1194 snprintf(buf, sizeof(buf), "ADC_BATTEMP: %4d", adc_read(ADC_BATTEMP));
1195 lcd_puts(0, line++, buf);
1196 snprintf(buf, sizeof(buf), "ADC_MICSUP1: %4d", adc_read(ADC_MICSUP1));
1197 lcd_puts(0, line++, buf);
1198 snprintf(buf, sizeof(buf), "ADC_MICSUP2: %4d", adc_read(ADC_MICSUP2));
1199 lcd_puts(0, line++, buf);
1200 snprintf(buf, sizeof(buf), "ADC_VBE1: %4d", adc_read(ADC_VBE1));
1201 lcd_puts(0, line++, buf);
1202 snprintf(buf, sizeof(buf), "ADC_VBE2: %4d", adc_read(ADC_VBE2));
1203 lcd_puts(0, line++, buf);
1204 snprintf(buf, sizeof(buf), "ADC_I_MICSUP1:%4d", adc_read(ADC_I_MICSUP1));
1205 lcd_puts(0, line++, buf);
1206 snprintf(buf, sizeof(buf), "ADC_I_MICSUP2:%4d", adc_read(ADC_I_MICSUP2));
1207 lcd_puts(0, line++, buf);
1208 snprintf(buf, sizeof(buf), "ADC_VBAT: %4d", adc_read(ADC_VBAT));
1209 lcd_puts(0, line++, buf);
1210 #endif
1211 lcd_update();
1212 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1213 return false;
1216 #elif CONFIG_CPU == PP5002
1217 char buf[128];
1218 int line;
1220 lcd_setmargins(0, 0);
1221 lcd_clear_display();
1222 lcd_setfont(FONT_SYSFIXED);
1224 while(1)
1226 line = 0;
1227 snprintf(buf, sizeof(buf), "GPIO_A: %02x GPIO_B: %02x",
1228 (unsigned int)GPIOA_INPUT_VAL, (unsigned int)GPIOB_INPUT_VAL);
1229 lcd_puts(0, line++, buf);
1230 snprintf(buf, sizeof(buf), "GPIO_C: %02x GPIO_D: %02x",
1231 (unsigned int)GPIOC_INPUT_VAL, (unsigned int)GPIOD_INPUT_VAL);
1232 lcd_puts(0, line++, buf);
1234 snprintf(buf, sizeof(buf), "DEV_EN: %08lx", DEV_EN);
1235 lcd_puts(0, line++, buf);
1236 snprintf(buf, sizeof(buf), "CLOCK_ENABLE: %08lx", CLOCK_ENABLE);
1237 lcd_puts(0, line++, buf);
1238 snprintf(buf, sizeof(buf), "CLOCK_SOURCE: %08lx", CLOCK_SOURCE);
1239 lcd_puts(0, line++, buf);
1240 snprintf(buf, sizeof(buf), "PLL_CONTROL: %08lx", PLL_CONTROL);
1241 lcd_puts(0, line++, buf);
1242 snprintf(buf, sizeof(buf), "PLL_DIV: %08lx", PLL_DIV);
1243 lcd_puts(0, line++, buf);
1244 snprintf(buf, sizeof(buf), "PLL_MULT: %08lx", PLL_MULT);
1245 lcd_puts(0, line++, buf);
1246 snprintf(buf, sizeof(buf), "TIMING1_CTL: %08lx", TIMING1_CTL);
1247 lcd_puts(0, line++, buf);
1248 snprintf(buf, sizeof(buf), "TIMING2_CTL: %08lx", TIMING2_CTL);
1249 lcd_puts(0, line++, buf);
1251 lcd_update();
1252 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1253 return false;
1255 #else
1256 return __dbg_ports();
1257 #endif /* CPU */
1258 return false;
1260 #else /* !HAVE_LCD_BITMAP */
1261 bool dbg_ports(void)
1263 char buf[32];
1264 int button;
1265 int adc_battery_voltage;
1266 int currval = 0;
1268 lcd_clear_display();
1270 while(1)
1272 switch(currval)
1274 case 0:
1275 snprintf(buf, 32, "PADR: %04x", (unsigned short)PADR);
1276 break;
1277 case 1:
1278 snprintf(buf, 32, "PBDR: %04x", (unsigned short)PBDR);
1279 break;
1280 case 2:
1281 snprintf(buf, 32, "AN0: %03x", adc_read(0));
1282 break;
1283 case 3:
1284 snprintf(buf, 32, "AN1: %03x", adc_read(1));
1285 break;
1286 case 4:
1287 snprintf(buf, 32, "AN2: %03x", adc_read(2));
1288 break;
1289 case 5:
1290 snprintf(buf, 32, "AN3: %03x", adc_read(3));
1291 break;
1292 case 6:
1293 snprintf(buf, 32, "AN4: %03x", adc_read(4));
1294 break;
1295 case 7:
1296 snprintf(buf, 32, "AN5: %03x", adc_read(5));
1297 break;
1298 case 8:
1299 snprintf(buf, 32, "AN6: %03x", adc_read(6));
1300 break;
1301 case 9:
1302 snprintf(buf, 32, "AN7: %03x", adc_read(7));
1303 break;
1304 break;
1306 lcd_puts(0, 0, buf);
1308 battery_read_info(&adc_battery_voltage, NULL);
1309 snprintf(buf, 32, "Batt: %d.%03dV", adc_battery_voltage / 1000,
1310 adc_battery_voltage % 1000);
1311 lcd_puts(0, 1, buf);
1312 lcd_update();
1314 button = get_action(CONTEXT_SETTINGS,HZ/5);
1316 switch(button)
1318 case ACTION_STD_CANCEL:
1319 return false;
1321 case ACTION_SETTINGS_DEC:
1322 currval--;
1323 if(currval < 0)
1324 currval = 9;
1325 break;
1327 case ACTION_SETTINGS_INC:
1328 currval++;
1329 if(currval > 9)
1330 currval = 0;
1331 break;
1334 return false;
1336 #endif /* !HAVE_LCD_BITMAP */
1337 #endif /* !SIMULATOR */
1339 #if (CONFIG_RTC == RTC_PCF50605) && !defined(SIMULATOR)
1340 static bool dbg_pcf(void)
1342 char buf[128];
1343 int line;
1345 #ifdef HAVE_LCD_BITMAP
1346 lcd_setmargins(0, 0);
1347 lcd_setfont(FONT_SYSFIXED);
1348 #endif
1349 lcd_clear_display();
1351 while(1)
1353 line = 0;
1355 snprintf(buf, sizeof(buf), "DCDC1: %02x", pcf50605_read(0x1b));
1356 lcd_puts(0, line++, buf);
1357 snprintf(buf, sizeof(buf), "DCDC2: %02x", pcf50605_read(0x1c));
1358 lcd_puts(0, line++, buf);
1359 snprintf(buf, sizeof(buf), "DCDC3: %02x", pcf50605_read(0x1d));
1360 lcd_puts(0, line++, buf);
1361 snprintf(buf, sizeof(buf), "DCDC4: %02x", pcf50605_read(0x1e));
1362 lcd_puts(0, line++, buf);
1363 snprintf(buf, sizeof(buf), "DCDEC1: %02x", pcf50605_read(0x1f));
1364 lcd_puts(0, line++, buf);
1365 snprintf(buf, sizeof(buf), "DCDEC2: %02x", pcf50605_read(0x20));
1366 lcd_puts(0, line++, buf);
1367 snprintf(buf, sizeof(buf), "DCUDC1: %02x", pcf50605_read(0x21));
1368 lcd_puts(0, line++, buf);
1369 snprintf(buf, sizeof(buf), "DCUDC2: %02x", pcf50605_read(0x22));
1370 lcd_puts(0, line++, buf);
1371 snprintf(buf, sizeof(buf), "IOREGC: %02x", pcf50605_read(0x23));
1372 lcd_puts(0, line++, buf);
1373 snprintf(buf, sizeof(buf), "D1REGC: %02x", pcf50605_read(0x24));
1374 lcd_puts(0, line++, buf);
1375 snprintf(buf, sizeof(buf), "D2REGC: %02x", pcf50605_read(0x25));
1376 lcd_puts(0, line++, buf);
1377 snprintf(buf, sizeof(buf), "D3REGC: %02x", pcf50605_read(0x26));
1378 lcd_puts(0, line++, buf);
1379 snprintf(buf, sizeof(buf), "LPREG1: %02x", pcf50605_read(0x27));
1380 lcd_puts(0, line++, buf);
1382 lcd_update();
1383 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1385 return false;
1389 return false;
1391 #endif
1393 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
1394 static bool dbg_cpufreq(void)
1396 char buf[128];
1397 int line;
1398 int button;
1400 #ifdef HAVE_LCD_BITMAP
1401 lcd_setmargins(0, 0);
1402 lcd_setfont(FONT_SYSFIXED);
1403 #endif
1404 lcd_clear_display();
1406 while(1)
1408 line = 0;
1410 snprintf(buf, sizeof(buf), "Frequency: %ld", FREQ);
1411 lcd_puts(0, line++, buf);
1413 snprintf(buf, sizeof(buf), "boost_counter: %d", get_cpu_boost_counter());
1414 lcd_puts(0, line++, buf);
1416 lcd_update();
1417 button = get_action(CONTEXT_STD,HZ/10);
1419 switch(button)
1421 case ACTION_STD_PREV:
1422 cpu_boost(true);
1423 break;
1425 case ACTION_STD_NEXT:
1426 cpu_boost(false);
1427 break;
1429 case ACTION_STD_OK:
1430 while (get_cpu_boost_counter() > 0)
1431 cpu_boost(false);
1432 set_cpu_frequency(CPUFREQ_DEFAULT);
1433 break;
1435 case ACTION_STD_CANCEL:
1436 return false;
1440 return false;
1442 #endif /* HAVE_ADJUSTABLE_CPU_FREQ */
1444 #if defined(HAVE_TSC2100) && !defined(SIMULATOR)
1445 #include "tsc2100.h"
1446 char *itob(int n, int len)
1448 static char binary[64];
1449 int i,j;
1450 for (i=1, j=0;i<=len;i++)
1452 binary[j++] = n&(1<<(len-i))?'1':'0';
1453 if (i%4 == 0)
1454 binary[j++] = ' ';
1456 binary[j] = '\0';
1457 return binary;
1459 static char* tsc2100_debug_getname(int selected_item, void * data, char *buffer)
1461 int *page = (int*)data;
1462 bool reserved = false;
1463 switch (*page)
1465 case 0:
1466 if ((selected_item > 0x0a) ||
1467 (selected_item == 0x04) ||
1468 (selected_item == 0x08))
1469 reserved = true;
1470 break;
1471 case 1:
1472 if ((selected_item > 0x05) ||
1473 (selected_item == 0x02))
1474 reserved = true;
1475 break;
1476 case 2:
1477 if (selected_item > 0x1e)
1478 reserved = true;
1479 break;
1481 if (reserved)
1482 snprintf(buffer, MAX_PATH, "%02x: RESERVED", selected_item);
1483 else
1484 snprintf(buffer, MAX_PATH, "%02x: %s", selected_item,
1485 itob(tsc2100_readreg(*page, selected_item)&0xffff,16));
1486 return buffer;
1488 static int tsc2100debug_action_callback(int action, struct gui_synclist *lists)
1490 int *page = (int*)lists->data;
1491 if (action == ACTION_STD_OK)
1493 *page = (*page+1)%3;
1494 snprintf(lists->title, 32,
1495 "tsc2100 registers - Page %d", *page);
1496 return ACTION_REDRAW;
1498 return action;
1500 bool tsc2100_debug(void)
1502 int page = 0;
1503 char title[32] = "tsc2100 registers - Page 0";
1504 struct simplelist_info info;
1505 simplelist_info_init(&info, title, 32, &page);
1506 info.timeout = HZ/100;
1507 info.get_name = tsc2100_debug_getname;
1508 info.action_callback= tsc2100debug_action_callback;
1509 return simplelist_show_list(&info);
1511 #endif
1512 #ifndef SIMULATOR
1513 #ifdef HAVE_LCD_BITMAP
1515 * view_battery() shows a automatically scaled graph of the battery voltage
1516 * over time. Usable for estimating battery life / charging rate.
1517 * The power_history array is updated in power_thread of powermgmt.c.
1520 #define BAT_LAST_VAL MIN(LCD_WIDTH, POWER_HISTORY_LEN)
1521 #define BAT_YSPACE (LCD_HEIGHT - 20)
1523 static bool view_battery(void)
1525 int view = 0;
1526 int i, x, y;
1527 unsigned short maxv, minv;
1528 char buf[32];
1530 lcd_setmargins(0, 0);
1531 lcd_setfont(FONT_SYSFIXED);
1533 while(1)
1535 lcd_clear_display();
1536 switch (view) {
1537 case 0: /* voltage history graph */
1538 /* Find maximum and minimum voltage for scaling */
1539 minv = power_history[0];
1540 maxv = minv + 1;
1541 for (i = 1; i < BAT_LAST_VAL && power_history[i]; i++) {
1542 if (power_history[i] > maxv)
1543 maxv = power_history[i];
1544 if (power_history[i] < minv)
1545 minv = power_history[i];
1548 snprintf(buf, 30, "Battery %d.%03d", power_history[0] / 1000,
1549 power_history[0] % 1000);
1550 lcd_puts(0, 0, buf);
1551 snprintf(buf, 30, "scale %d.%03d-%d.%03dV",
1552 minv / 1000, minv % 1000, maxv / 1000, maxv % 1000);
1553 lcd_puts(0, 1, buf);
1555 x = 0;
1556 for (i = BAT_LAST_VAL - 1; i >= 0; i--) {
1557 y = (power_history[i] - minv) * BAT_YSPACE / (maxv - minv);
1558 lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
1559 lcd_vline(x, LCD_HEIGHT-1, 20);
1560 lcd_set_drawmode(DRMODE_SOLID);
1561 lcd_vline(x, LCD_HEIGHT-1,
1562 MIN(MAX(LCD_HEIGHT-1 - y, 20), LCD_HEIGHT-1));
1563 x++;
1566 break;
1568 case 1: /* status: */
1569 lcd_puts(0, 0, "Power status:");
1571 battery_read_info(&y, NULL);
1572 snprintf(buf, 30, "Battery: %d.%03d V", y / 1000, y % 1000);
1573 lcd_puts(0, 1, buf);
1574 #ifdef ADC_EXT_POWER
1575 y = (adc_read(ADC_EXT_POWER) * EXT_SCALE_FACTOR) / 1000;
1576 snprintf(buf, 30, "External: %d.%03d V", y / 1000, y % 1000);
1577 lcd_puts(0, 2, buf);
1578 #endif
1579 #if CONFIG_CHARGING
1580 #if CONFIG_CHARGING == CHARGING_CONTROL
1581 snprintf(buf, 30, "Chgr: %s %s",
1582 charger_inserted() ? "present" : "absent",
1583 charger_enabled ? "on" : "off");
1584 lcd_puts(0, 3, buf);
1585 snprintf(buf, 30, "short delta: %d", short_delta);
1586 lcd_puts(0, 5, buf);
1587 snprintf(buf, 30, "long delta: %d", long_delta);
1588 lcd_puts(0, 6, buf);
1589 lcd_puts(0, 7, power_message);
1590 snprintf(buf, 30, "USB Inserted: %s",
1591 usb_inserted() ? "yes" : "no");
1592 lcd_puts(0, 8, buf);
1593 #if defined IRIVER_H300_SERIES
1594 snprintf(buf, 30, "USB Charging Enabled: %s",
1595 usb_charging_enabled() ? "yes" : "no");
1596 lcd_puts(0, 9, buf);
1597 #endif
1598 #else /* CONFIG_CHARGING != CHARGING_CONTROL */
1599 #if defined IPOD_NANO || defined IPOD_VIDEO
1600 int usb_pwr = (GPIOL_INPUT_VAL & 0x10)?true:false;
1601 int ext_pwr = (GPIOL_INPUT_VAL & 0x08)?false:true;
1602 int dock = (GPIOA_INPUT_VAL & 0x10)?true:false;
1603 int charging = (GPIOB_INPUT_VAL & 0x01)?false:true;
1604 int headphone= (GPIOA_INPUT_VAL & 0x80)?true:false;
1606 snprintf(buf, 30, "USB pwr: %s",
1607 usb_pwr ? "present" : "absent");
1608 lcd_puts(0, 3, buf);
1609 snprintf(buf, 30, "EXT pwr: %s",
1610 ext_pwr ? "present" : "absent");
1611 lcd_puts(0, 4, buf);
1612 snprintf(buf, 30, "Battery: %s",
1613 charging ? "charging" : (usb_pwr||ext_pwr) ? "charged" : "discharging");
1614 lcd_puts(0, 5, buf);
1615 snprintf(buf, 30, "Dock mode: %s",
1616 dock ? "enabled" : "disabled");
1617 lcd_puts(0, 6, buf);
1618 snprintf(buf, 30, "Headphone: %s",
1619 headphone ? "connected" : "disconnected");
1620 lcd_puts(0, 7, buf);
1621 #else
1622 snprintf(buf, 30, "Charger: %s",
1623 charger_inserted() ? "present" : "absent");
1624 lcd_puts(0, 3, buf);
1625 #endif
1626 #endif /* CONFIG_CHARGING != CHARGING_CONTROL */
1627 #endif /* CONFIG_CHARGING */
1628 break;
1630 case 2: /* voltage deltas: */
1631 lcd_puts(0, 0, "Voltage deltas:");
1633 for (i = 0; i <= 6; i++) {
1634 y = power_history[i] - power_history[i+1];
1635 snprintf(buf, 30, "-%d min: %s%d.%03d V", i,
1636 (y < 0) ? "-" : "", ((y < 0) ? y * -1 : y) / 1000,
1637 ((y < 0) ? y * -1 : y ) % 1000);
1638 lcd_puts(0, i+1, buf);
1640 break;
1642 case 3: /* remaining time estimation: */
1644 #if CONFIG_CHARGING == CHARGING_CONTROL
1645 snprintf(buf, 30, "charge_state: %d", charge_state);
1646 lcd_puts(0, 0, buf);
1648 snprintf(buf, 30, "Cycle time: %d m", powermgmt_last_cycle_startstop_min);
1649 lcd_puts(0, 1, buf);
1651 snprintf(buf, 30, "Lvl@cyc st: %d%%", powermgmt_last_cycle_level);
1652 lcd_puts(0, 2, buf);
1654 snprintf(buf, 30, "P=%2d I=%2d", pid_p, pid_i);
1655 lcd_puts(0, 3, buf);
1657 snprintf(buf, 30, "Trickle sec: %d/60", trickle_sec);
1658 lcd_puts(0, 4, buf);
1659 #endif /* CONFIG_CHARGING == CHARGING_CONTROL */
1661 snprintf(buf, 30, "Last PwrHist: %d.%03dV",
1662 power_history[0] / 1000,
1663 power_history[0] % 1000);
1664 lcd_puts(0, 5, buf);
1666 snprintf(buf, 30, "battery level: %d%%", battery_level());
1667 lcd_puts(0, 6, buf);
1669 snprintf(buf, 30, "Est. remain: %d m", battery_time());
1670 lcd_puts(0, 7, buf);
1671 break;
1674 lcd_update();
1676 switch(get_action(CONTEXT_SETTINGS,HZ/2))
1678 case ACTION_SETTINGS_DEC:
1679 if (view)
1680 view--;
1681 break;
1683 case ACTION_SETTINGS_INC:
1684 if (view < 3)
1685 view++;
1686 break;
1688 case ACTION_STD_CANCEL:
1689 return false;
1692 return false;
1695 #endif /* HAVE_LCD_BITMAP */
1696 #endif
1698 #ifndef SIMULATOR
1699 #if defined(HAVE_MMC) || defined(HAVE_HOTSWAP)
1700 #if defined(HAVE_MMC)
1701 #define CARDTYPE "MMC"
1702 #else
1703 #define CARDTYPE "microSD"
1704 #endif
1705 static int disk_callback(int btn, struct gui_synclist *lists)
1707 tCardInfo *card;
1708 int *cardnum = (int*)lists->data;
1709 unsigned char card_name[7];
1710 unsigned char pbuf[32];
1711 char *title = lists->title;
1712 static const unsigned char i_vmin[] = { 0, 1, 5, 10, 25, 35, 60, 100 };
1713 static const unsigned char i_vmax[] = { 1, 5, 10, 25, 35, 45, 80, 200 };
1714 static const unsigned char *kbit_units[] = { "kBit/s", "MBit/s", "GBit/s" };
1715 static const unsigned char *nsec_units[] = { "ns", "�s", "ms" };
1716 static const char *spec_vers[] = { "1.0-1.2", "1.4", "2.0-2.2",
1717 "3.1-3.31", "4.0" };
1718 if ((btn == ACTION_STD_OK) || (btn == SYS_FS_CHANGED) || (btn == ACTION_REDRAW))
1720 if (btn == ACTION_STD_OK)
1722 *cardnum ^= 0x1; /* change cards */
1725 simplelist_set_line_count(0);
1727 card = card_get_info(*cardnum);
1729 if (card->initialized > 0)
1731 card_name[6] = '\0';
1732 strncpy(card_name, ((unsigned char*)card->cid) + 3, 6);
1733 simplelist_addline(SIMPLELIST_ADD_LINE,
1734 "%s Rev %d.%d", card_name,
1735 (int) card_extract_bits(card->cid, 72, 4),
1736 (int) card_extract_bits(card->cid, 76, 4));
1737 simplelist_addline(SIMPLELIST_ADD_LINE,
1738 "Prod: %d/%d",
1739 (int) card_extract_bits(card->cid, 112, 4),
1740 (int) card_extract_bits(card->cid, 116, 4) + 1997);
1741 simplelist_addline(SIMPLELIST_ADD_LINE,
1742 "Ser#: 0x%08lx",
1743 card_extract_bits(card->cid, 80, 32));
1744 simplelist_addline(SIMPLELIST_ADD_LINE,
1745 "M=%02x, O=%04x",
1746 (int) card_extract_bits(card->cid, 0, 8),
1747 (int) card_extract_bits(card->cid, 8, 16));
1748 int temp = card_extract_bits(card->csd, 2, 4);
1749 simplelist_addline(SIMPLELIST_ADD_LINE,
1750 CARDTYPE " v%s", temp < 5 ?
1751 spec_vers[temp] : "?.?");
1752 simplelist_addline(SIMPLELIST_ADD_LINE,
1753 "Blocks: 0x%06lx", card->numblocks);
1754 simplelist_addline(SIMPLELIST_ADD_LINE,
1755 "Blksz.: %d P:%c%c", card->blocksize,
1756 card_extract_bits(card->csd, 48, 1) ? 'R' : '-',
1757 card_extract_bits(card->csd, 106, 1) ? 'W' : '-');
1758 output_dyn_value(pbuf, sizeof pbuf, card->speed / 1000,
1759 kbit_units, false);
1760 simplelist_addline(SIMPLELIST_ADD_LINE,
1761 "Speed: %s", pbuf);
1762 output_dyn_value(pbuf, sizeof pbuf, card->tsac,
1763 nsec_units, false);
1764 simplelist_addline(SIMPLELIST_ADD_LINE,
1765 "Tsac: %s", pbuf);
1766 simplelist_addline(SIMPLELIST_ADD_LINE,
1767 "Nsac: %d clk", card->nsac);
1768 simplelist_addline(SIMPLELIST_ADD_LINE,
1769 "R2W: *%d", card->r2w_factor);
1770 simplelist_addline(SIMPLELIST_ADD_LINE,
1771 "IRmax: %d..%d mA",
1772 i_vmin[card_extract_bits(card->csd, 66, 3)],
1773 i_vmax[card_extract_bits(card->csd, 69, 3)]);
1774 simplelist_addline(SIMPLELIST_ADD_LINE,
1775 "IWmax: %d..%d mA",
1776 i_vmin[card_extract_bits(card->csd, 72, 3)],
1777 i_vmax[card_extract_bits(card->csd, 75, 3)]);
1779 else if (card->initialized == 0)
1781 simplelist_addline(SIMPLELIST_ADD_LINE, "Not Found!");
1783 #ifndef HAVE_MMC
1784 else /* card->initialized < 0 */
1786 simplelist_addline(SIMPLELIST_ADD_LINE, "Init Error! (%d)", card->initialized);
1788 #endif
1789 snprintf(title, 16, "[" CARDTYPE " %d]", *cardnum);
1790 gui_synclist_set_title(lists, title, Icon_NOICON);
1791 gui_synclist_set_nb_items(lists, simplelist_get_line_count());
1792 gui_synclist_select_item(lists, 0);
1793 btn = ACTION_REDRAW;
1795 return btn;
1797 #else /* !defined(HAVE_MMC) && !defined(HAVE_HOTSWAP) */
1798 static int disk_callback(int btn, struct gui_synclist *lists)
1800 (void)lists;
1801 int i;
1802 char buf[128];
1803 unsigned short* identify_info = ata_get_identify();
1804 bool timing_info_present = false;
1805 (void)btn;
1807 simplelist_set_line_count(0);
1809 for (i=0; i < 20; i++)
1810 ((unsigned short*)buf)[i]=htobe16(identify_info[i+27]);
1811 buf[40]=0;
1812 /* kill trailing space */
1813 for (i=39; i && buf[i]==' '; i--)
1814 buf[i] = 0;
1815 simplelist_addline(SIMPLELIST_ADD_LINE, "Model: %s", buf);
1816 for (i=0; i < 4; i++)
1817 ((unsigned short*)buf)[i]=htobe16(identify_info[i+23]);
1818 buf[8]=0;
1819 simplelist_addline(SIMPLELIST_ADD_LINE,
1820 "Firmware: %s", buf);
1821 snprintf(buf, sizeof buf, "%ld MB",
1822 ((unsigned long)identify_info[61] << 16 |
1823 (unsigned long)identify_info[60]) / 2048 );
1824 simplelist_addline(SIMPLELIST_ADD_LINE,
1825 "Size: %s", buf);
1826 unsigned long free;
1827 fat_size( IF_MV2(0,) NULL, &free );
1828 simplelist_addline(SIMPLELIST_ADD_LINE,
1829 "Free: %ld MB", free / 1024);
1830 simplelist_addline(SIMPLELIST_ADD_LINE,
1831 "Spinup time: %d ms", ata_spinup_time * (1000/HZ));
1832 i = identify_info[83] & (1<<3);
1833 simplelist_addline(SIMPLELIST_ADD_LINE,
1834 "Power mgmt: %s", i ? "enabled" : "unsupported");
1835 i = identify_info[83] & (1<<9);
1836 simplelist_addline(SIMPLELIST_ADD_LINE,
1837 "Noise mgmt: %s", i ? "enabled" : "unsupported");
1838 i = identify_info[82] & (1<<6);
1839 simplelist_addline(SIMPLELIST_ADD_LINE,
1840 "Read-ahead: %s", i ? "enabled" : "unsupported");
1841 timing_info_present = identify_info[53] & (1<<1);
1842 if(timing_info_present) {
1843 char pio3[2], pio4[2];pio3[1] = 0;
1844 pio4[1] = 0;
1845 pio3[0] = (identify_info[64] & (1<<0)) ? '3' : 0;
1846 pio4[0] = (identify_info[64] & (1<<1)) ? '4' : 0;
1847 simplelist_addline(SIMPLELIST_ADD_LINE,
1848 "PIO modes: 0 1 2 %s %s", pio3, pio4);
1850 else {
1851 simplelist_addline(SIMPLELIST_ADD_LINE,
1852 "No PIO mode info");
1854 timing_info_present = identify_info[53] & (1<<1);
1855 if(timing_info_present) {
1856 simplelist_addline(SIMPLELIST_ADD_LINE,
1857 "Cycle times %dns/%dns",
1858 identify_info[67],
1859 identify_info[68] );
1860 } else {
1861 simplelist_addline(SIMPLELIST_ADD_LINE,
1862 "No timing info");
1864 timing_info_present = identify_info[53] & (1<<1);
1865 if(timing_info_present) {
1866 i = identify_info[49] & (1<<11);
1867 simplelist_addline(SIMPLELIST_ADD_LINE,
1868 "IORDY support: %s", i ? "yes" : "no");
1869 i = identify_info[49] & (1<<10);
1870 simplelist_addline(SIMPLELIST_ADD_LINE,
1871 "IORDY disable: %s", i ? "yes" : "no");
1872 } else {
1873 simplelist_addline(SIMPLELIST_ADD_LINE,
1874 "No timing info");
1876 simplelist_addline(SIMPLELIST_ADD_LINE,
1877 "Cluster size: %d bytes", fat_get_cluster_size(IF_MV(0)));
1878 return btn;
1881 static bool dbg_identify_info(void)
1883 int fd = creat("/identify_info.bin");
1884 if(fd >= 0)
1886 #ifdef ROCKBOX_LITTLE_ENDIAN
1887 ecwrite(fd, ata_get_identify(), SECTOR_SIZE/2, "s", true);
1888 #else
1889 write(fd, ata_get_identify(), SECTOR_SIZE);
1890 #endif
1891 close(fd);
1893 return false;
1895 #endif /* !defined(HAVE_MMC) && !defined(HAVE_HOTSWAP) */
1896 static bool dbg_disk_info(void)
1898 struct simplelist_info info;
1899 simplelist_info_init(&info, "Disk Info", 1, NULL);
1900 #if defined(HAVE_MMC) || defined(HAVE_HOTSWAP)
1901 char title[16];
1902 int card = 0;
1903 info.callback_data = (void*)&card;
1904 info.title = title;
1905 #endif
1906 info.action_callback = disk_callback;
1907 info.hide_selection = true;
1908 return simplelist_show_list(&info);
1910 #endif /* !SIMULATOR */
1912 #ifdef HAVE_DIRCACHE
1913 static int dircache_callback(int btn, struct gui_synclist *lists)
1915 (void)btn; (void)lists;
1916 simplelist_set_line_count(0);
1917 simplelist_addline(SIMPLELIST_ADD_LINE, "Cache initialized: %s",
1918 dircache_is_enabled() ? "Yes" : "No");
1919 simplelist_addline(SIMPLELIST_ADD_LINE, "Cache size: %d B",
1920 dircache_get_cache_size());
1921 simplelist_addline(SIMPLELIST_ADD_LINE, "Last size: %d B",
1922 global_status.dircache_size);
1923 simplelist_addline(SIMPLELIST_ADD_LINE, "Limit: %d B",
1924 DIRCACHE_LIMIT);
1925 simplelist_addline(SIMPLELIST_ADD_LINE, "Reserve: %d/%d B",
1926 dircache_get_reserve_used(), DIRCACHE_RESERVE);
1927 simplelist_addline(SIMPLELIST_ADD_LINE, "Scanning took: %d s",
1928 dircache_get_build_ticks() / HZ);
1929 simplelist_addline(SIMPLELIST_ADD_LINE, "Entry count: %d",
1930 dircache_get_entry_count());
1931 return btn;
1934 static bool dbg_dircache_info(void)
1936 struct simplelist_info info;
1937 simplelist_info_init(&info, "Dircache Info", 7, NULL);
1938 info.action_callback = dircache_callback;
1939 info.hide_selection = true;
1940 return simplelist_show_list(&info);
1943 #endif /* HAVE_DIRCACHE */
1945 #ifdef HAVE_TAGCACHE
1946 static int database_callback(int btn, struct gui_synclist *lists)
1948 (void)lists;
1949 struct tagcache_stat *stat = tagcache_get_stat();
1950 static bool synced = false;
1952 simplelist_set_line_count(0);
1954 simplelist_addline(SIMPLELIST_ADD_LINE, "Initialized: %s",
1955 stat->initialized ? "Yes" : "No");
1956 simplelist_addline(SIMPLELIST_ADD_LINE, "DB Ready: %s",
1957 stat->ready ? "Yes" : "No");
1958 simplelist_addline(SIMPLELIST_ADD_LINE, "RAM Cache: %s",
1959 stat->ramcache ? "Yes" : "No");
1960 simplelist_addline(SIMPLELIST_ADD_LINE, "RAM: %d/%d B",
1961 stat->ramcache_used, stat->ramcache_allocated);
1962 simplelist_addline(SIMPLELIST_ADD_LINE, "Progress: %d%% (%d entries)",
1963 stat->progress, stat->processed_entries);
1964 simplelist_addline(SIMPLELIST_ADD_LINE, "Curfile: %s",
1965 stat->curentry ? stat->curentry : "---");
1966 simplelist_addline(SIMPLELIST_ADD_LINE, "Commit step: %d",
1967 stat->commit_step);
1968 simplelist_addline(SIMPLELIST_ADD_LINE, "Commit delayed: %s",
1969 stat->commit_delayed ? "Yes" : "No");
1971 simplelist_addline(SIMPLELIST_ADD_LINE, "Queue length: %d",
1972 stat->queue_length);
1974 if (synced)
1976 synced = false;
1977 tagcache_screensync_event();
1980 if (!btn && stat->curentry)
1982 synced = true;
1983 return ACTION_REDRAW;
1986 if (btn == ACTION_STD_CANCEL)
1987 tagcache_screensync_enable(false);
1989 return btn;
1991 static bool dbg_tagcache_info(void)
1993 struct simplelist_info info;
1994 simplelist_info_init(&info, "Database Info", 8, NULL);
1995 info.action_callback = database_callback;
1996 info.hide_selection = true;
1998 /* Don't do nonblock here, must give enough processing time
1999 for tagcache thread. */
2000 /* info.timeout = TIMEOUT_NOBLOCK; */
2001 info.timeout = 1;
2002 tagcache_screensync_enable(true);
2003 return simplelist_show_list(&info);
2005 #endif
2007 #if CONFIG_CPU == SH7034
2008 static bool dbg_save_roms(void)
2010 int fd;
2011 int oldmode = system_memory_guard(MEMGUARD_NONE);
2013 fd = creat("/internal_rom_0000-FFFF.bin");
2014 if(fd >= 0)
2016 write(fd, (void *)0, 0x10000);
2017 close(fd);
2020 fd = creat("/internal_rom_2000000-203FFFF.bin");
2021 if(fd >= 0)
2023 write(fd, (void *)0x2000000, 0x40000);
2024 close(fd);
2027 system_memory_guard(oldmode);
2028 return false;
2030 #elif defined CPU_COLDFIRE
2031 static bool dbg_save_roms(void)
2033 int fd;
2034 int oldmode = system_memory_guard(MEMGUARD_NONE);
2036 #if defined(IRIVER_H100_SERIES)
2037 fd = creat("/internal_rom_000000-1FFFFF.bin");
2038 #elif defined(IRIVER_H300_SERIES)
2039 fd = creat("/internal_rom_000000-3FFFFF.bin");
2040 #elif defined(IAUDIO_X5) || defined(IAUDIO_M5)
2041 fd = creat("/internal_rom_000000-3FFFFF.bin");
2042 #endif
2043 if(fd >= 0)
2045 write(fd, (void *)0, FLASH_SIZE);
2046 close(fd);
2048 system_memory_guard(oldmode);
2050 #ifdef HAVE_EEPROM
2051 fd = creat("/internal_eeprom.bin");
2052 if (fd >= 0)
2054 int old_irq_level;
2055 char buf[EEPROM_SIZE];
2056 int err;
2058 old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL);
2060 err = eeprom_24cxx_read(0, buf, sizeof buf);
2061 if (err)
2062 gui_syncsplash(HZ*3, "Eeprom read failure (%d)",err);
2063 else
2065 write(fd, buf, sizeof buf);
2068 set_irq_level(old_irq_level);
2070 close(fd);
2072 #endif
2074 return false;
2076 #elif defined(CPU_PP) && !(defined(SANSA_E200) || defined(SANSA_C200))
2077 static bool dbg_save_roms(void)
2079 int fd;
2081 fd = creat("/internal_rom_000000-0FFFFF.bin");
2082 if(fd >= 0)
2084 write(fd, (void *)0x20000000, FLASH_SIZE);
2085 close(fd);
2088 return false;
2090 #endif /* CPU */
2092 #ifndef SIMULATOR
2093 #if CONFIG_TUNER
2094 static int radio_callback(int btn, struct gui_synclist *lists)
2096 (void)lists;
2097 if (btn == ACTION_STD_CANCEL)
2098 return btn;
2099 simplelist_set_line_count(1);
2101 #if (CONFIG_TUNER & LV24020LP)
2102 simplelist_addline(SIMPLELIST_ADD_LINE,
2103 "CTRL_STAT: %02X", lv24020lp_get(LV24020LP_CTRL_STAT) );
2104 simplelist_addline(SIMPLELIST_ADD_LINE,
2105 "RADIO_STAT: %02X", lv24020lp_get(LV24020LP_REG_STAT) );
2106 simplelist_addline(SIMPLELIST_ADD_LINE,
2107 "MSS_FM: %d kHz", lv24020lp_get(LV24020LP_MSS_FM) );
2108 simplelist_addline(SIMPLELIST_ADD_LINE,
2109 "MSS_IF: %d Hz", lv24020lp_get(LV24020LP_MSS_IF) );
2110 simplelist_addline(SIMPLELIST_ADD_LINE,
2111 "MSS_SD: %d Hz", lv24020lp_get(LV24020LP_MSS_SD) );
2112 simplelist_addline(SIMPLELIST_ADD_LINE,
2113 "if_set: %d Hz", lv24020lp_get(LV24020LP_IF_SET) );
2114 simplelist_addline(SIMPLELIST_ADD_LINE,
2115 "sd_set: %d Hz", lv24020lp_get(LV24020LP_SD_SET) );
2116 #endif
2117 #if (CONFIG_TUNER & S1A0903X01)
2118 simplelist_addline(SIMPLELIST_ADD_LINE,
2119 "Samsung regs: %08X", s1a0903x01_get(RADIO_ALL));
2120 /* This one doesn't return dynamic data atm */
2121 #endif
2122 #if (CONFIG_TUNER & TEA5767)
2123 struct tea5767_dbg_info nfo;
2124 tea5767_dbg_info(&nfo);
2125 simplelist_addline(SIMPLELIST_ADD_LINE, "Philips regs:");
2126 simplelist_addline(SIMPLELIST_ADD_LINE,
2127 " Read: %02X %02X %02X %02X %02X",
2128 (unsigned)nfo.read_regs[0], (unsigned)nfo.read_regs[1],
2129 (unsigned)nfo.read_regs[2], (unsigned)nfo.read_regs[3],
2130 (unsigned)nfo.read_regs[4]);
2131 simplelist_addline(SIMPLELIST_ADD_LINE,
2132 " Write: %02X %02X %02X %02X %02X",
2133 (unsigned)nfo.write_regs[0], (unsigned)nfo.write_regs[1],
2134 (unsigned)nfo.write_regs[2], (unsigned)nfo.write_regs[3],
2135 (unsigned)nfo.write_regs[4]);
2136 #endif
2137 return ACTION_REDRAW;
2139 static bool dbg_fm_radio(void)
2141 struct simplelist_info info;
2142 simplelist_info_init(&info, "FM Radio", 1, NULL);
2143 simplelist_set_line_count(0);
2144 simplelist_addline(SIMPLELIST_ADD_LINE, "HW detected: %s",
2145 radio_hardware_present() ? "yes" : "no");
2147 info.action_callback = radio_hardware_present()?radio_callback : NULL;
2148 info.hide_selection = true;
2149 return simplelist_show_list(&info);
2151 #endif /* CONFIG_TUNER */
2152 #endif /* !SIMULATOR */
2154 #ifdef HAVE_LCD_BITMAP
2155 extern bool do_screendump_instead_of_usb;
2157 static bool dbg_screendump(void)
2159 do_screendump_instead_of_usb = !do_screendump_instead_of_usb;
2160 gui_syncsplash(HZ, "Screendump %s",
2161 do_screendump_instead_of_usb?"enabled":"disabled");
2162 return false;
2164 #endif /* HAVE_LCD_BITMAP */
2166 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
2167 static bool dbg_set_memory_guard(void)
2169 static const struct opt_items names[MAXMEMGUARD] = {
2170 { "None", -1 },
2171 { "Flash ROM writes", -1 },
2172 { "Zero area (all)", -1 }
2174 int mode = system_memory_guard(MEMGUARD_KEEP);
2176 set_option( "Catch mem accesses", &mode, INT, names, MAXMEMGUARD, NULL);
2177 system_memory_guard(mode);
2179 return false;
2181 #endif /* CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) */
2183 #if defined(TOSHIBA_GIGABEAT_F) && !defined(SIMULATOR)
2185 extern volatile bool lcd_poweroff;
2187 static bool dbg_lcd_power_off(void)
2189 lcd_setmargins(0, 0);
2191 while(1)
2193 int button;
2195 lcd_clear_display();
2196 lcd_puts(0, 0, "LCD Power Off");
2197 if(lcd_poweroff)
2198 lcd_puts(1, 1, "Yes");
2199 else
2200 lcd_puts(1, 1, "No");
2202 lcd_update();
2204 button = get_action(CONTEXT_STD,HZ/5);
2205 switch(button)
2207 case ACTION_STD_PREV:
2208 case ACTION_STD_NEXT:
2209 lcd_poweroff = !lcd_poweroff;
2210 break;
2211 case ACTION_STD_OK:
2212 case ACTION_STD_CANCEL:
2213 return false;
2214 default:
2215 sleep(HZ/10);
2216 break;
2219 return false;
2221 #endif
2223 #if defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS)
2224 static bool dbg_write_eeprom(void)
2226 int fd;
2227 int rc;
2228 int old_irq_level;
2229 char buf[EEPROM_SIZE];
2230 int err;
2232 fd = open("/internal_eeprom.bin", O_RDONLY);
2234 if (fd >= 0)
2236 rc = read(fd, buf, EEPROM_SIZE);
2238 if(rc == EEPROM_SIZE)
2240 old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL);
2242 err = eeprom_24cxx_write(0, buf, sizeof buf);
2243 if (err)
2244 gui_syncsplash(HZ*3, "Eeprom write failure (%d)",err);
2245 else
2246 gui_syncsplash(HZ*3, "Eeprom written successfully");
2248 set_irq_level(old_irq_level);
2250 else
2252 gui_syncsplash(HZ*3, "File read error (%d)",rc);
2254 close(fd);
2256 else
2258 gui_syncsplash(HZ*3, "Failed to open 'internal_eeprom.bin'");
2261 return false;
2263 #endif /* defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS) */
2264 #ifdef CPU_BOOST_LOGGING
2265 static bool cpu_boost_log(void)
2267 int i = 0,j=0;
2268 int count = cpu_boost_log_getcount();
2269 int lines = LCD_HEIGHT/SYSFONT_HEIGHT;
2270 char *str;
2271 bool done;
2272 lcd_setmargins(0, 0);
2273 lcd_setfont(FONT_SYSFIXED);
2274 str = cpu_boost_log_getlog_first();
2275 while (i < count)
2277 lcd_clear_display();
2278 for(j=0; j<lines; j++,i++)
2280 if (!str)
2281 str = cpu_boost_log_getlog_next();
2282 if (str)
2284 lcd_puts(0, j,str);
2286 str = NULL;
2288 lcd_update();
2289 done = false;
2290 while (!done)
2292 switch(get_action(CONTEXT_STD,TIMEOUT_BLOCK))
2294 case ACTION_STD_OK:
2295 case ACTION_STD_PREV:
2296 case ACTION_STD_NEXT:
2297 done = true;
2298 break;
2299 case ACTION_STD_CANCEL:
2300 i = count;
2301 done = true;
2302 break;
2306 get_action(CONTEXT_STD,TIMEOUT_BLOCK);
2307 lcd_setfont(FONT_UI);
2308 return false;
2310 #endif
2312 #if (defined(HAVE_SCROLLWHEEL) && (CONFIG_KEYPAD==IPOD_4G_PAD) && !defined(SIMULATOR))
2313 extern bool wheel_is_touched;
2314 extern int old_wheel_value;
2315 extern int new_wheel_value;
2316 extern int wheel_delta;
2317 extern unsigned int accumulated_wheel_delta;
2318 extern unsigned int wheel_velocity;
2320 static bool dbg_scrollwheel(void)
2322 char buf[64];
2323 unsigned int speed;
2325 lcd_setmargins(0, 0);
2326 lcd_setfont(FONT_SYSFIXED);
2328 while (1)
2330 if (action_userabort(HZ/10))
2331 return false;
2333 lcd_clear_display();
2335 /* show internal variables of scrollwheel driver */
2336 snprintf(buf, sizeof(buf), "wheel touched: %s", (wheel_is_touched) ? "true" : "false");
2337 lcd_puts(0, 0, buf);
2338 snprintf(buf, sizeof(buf), "new position: %2d", new_wheel_value);
2339 lcd_puts(0, 1, buf);
2340 snprintf(buf, sizeof(buf), "old position: %2d", old_wheel_value);
2341 lcd_puts(0, 2, buf);
2342 snprintf(buf, sizeof(buf), "wheel delta: %2d", wheel_delta);
2343 lcd_puts(0, 3, buf);
2344 snprintf(buf, sizeof(buf), "accumulated delta: %2d", accumulated_wheel_delta);
2345 lcd_puts(0, 4, buf);
2346 snprintf(buf, sizeof(buf), "velo [deg/s]: %4d", (int)wheel_velocity);
2347 lcd_puts(0, 5, buf);
2349 /* show effective accelerated scrollspeed */
2350 speed = button_apply_acceleration( (1<<31)|(1<<24)|wheel_velocity);
2351 snprintf(buf, sizeof(buf), "accel. speed: %4d", speed);
2352 lcd_puts(0, 6, buf);
2354 lcd_update();
2356 return false;
2358 #endif
2361 /****** The menu *********/
2362 struct the_menu_item {
2363 unsigned char *desc; /* string or ID */
2364 bool (*function) (void); /* return true if USB was connected */
2366 static const struct the_menu_item menuitems[] = {
2367 #if defined(TOSHIBA_GIGABEAT_F) && !defined(SIMULATOR)
2368 { "LCD Power Off", dbg_lcd_power_off },
2369 #endif
2370 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || \
2371 (defined(CPU_PP) && !(defined(SANSA_E200) || defined(SANSA_C200)))
2372 { "Dump ROM contents", dbg_save_roms },
2373 #endif
2374 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || defined(CPU_PP) || CONFIG_CPU == S3C2440
2375 { "View I/O ports", dbg_ports },
2376 #endif
2377 #if (CONFIG_RTC == RTC_PCF50605) && !defined(SIMULATOR)
2378 { "View PCF registers", dbg_pcf },
2379 #endif
2380 #if defined(HAVE_TSC2100) && !defined(SIMULATOR)
2381 { "TSC2100 debug", tsc2100_debug },
2382 #endif
2383 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
2384 { "CPU frequency", dbg_cpufreq },
2385 #endif
2386 #if defined(IRIVER_H100_SERIES) && !defined(SIMULATOR)
2387 { "S/PDIF analyzer", dbg_spdif },
2388 #endif
2389 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
2390 { "Catch mem accesses", dbg_set_memory_guard },
2391 #endif
2392 { "View OS stacks", dbg_os },
2393 #ifdef HAVE_LCD_BITMAP
2394 #ifndef SIMULATOR
2395 { "View battery", view_battery },
2396 #endif
2397 { "Screendump", dbg_screendump },
2398 #endif
2399 #ifndef SIMULATOR
2400 { "View HW info", dbg_hw_info },
2401 #endif
2402 #ifndef SIMULATOR
2403 { "View partitions", dbg_partitions },
2404 #endif
2405 #ifndef SIMULATOR
2406 { "View disk info", dbg_disk_info },
2407 #if !defined(HAVE_MMC) && !defined(HAVE_HOTSWAP)
2408 { "Dump ATA identify info", dbg_identify_info},
2409 #endif
2410 #endif
2411 #ifdef HAVE_DIRCACHE
2412 { "View dircache info", dbg_dircache_info },
2413 #endif
2414 #ifdef HAVE_TAGCACHE
2415 { "View database info", dbg_tagcache_info },
2416 #endif
2417 #ifdef HAVE_LCD_BITMAP
2418 #if CONFIG_CODEC == SWCODEC
2419 { "View buffering thread", dbg_buffering_thread },
2420 #elif !defined(SIMULATOR)
2421 { "View audio thread", dbg_audio_thread },
2422 #endif
2423 #ifdef PM_DEBUG
2424 { "pm histogram", peak_meter_histogram},
2425 #endif /* PM_DEBUG */
2426 #endif /* HAVE_LCD_BITMAP */
2427 #ifndef SIMULATOR
2428 #if CONFIG_TUNER
2429 { "FM Radio", dbg_fm_radio },
2430 #endif
2431 #endif
2432 #if defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS)
2433 { "Write back EEPROM", dbg_write_eeprom },
2434 #endif
2435 #ifdef ROCKBOX_HAS_LOGF
2436 {"logf", logfdisplay },
2437 {"logfdump", logfdump },
2438 #endif
2439 #ifdef CPU_BOOST_LOGGING
2440 {"cpu_boost log",cpu_boost_log},
2441 #endif
2442 #if (defined(HAVE_SCROLLWHEEL) && (CONFIG_KEYPAD==IPOD_4G_PAD) && !defined(SIMULATOR))
2443 {"Debug scrollwheel", dbg_scrollwheel},
2444 #endif
2446 static int menu_action_callback(int btn, struct gui_synclist *lists)
2448 if (btn == ACTION_STD_OK)
2450 menuitems[gui_synclist_get_sel_pos(lists)].function();
2451 btn = ACTION_REDRAW;
2453 return btn;
2455 static char* dbg_menu_getname(int item, void * data, char *buffer)
2457 (void)data; (void)buffer;
2458 return menuitems[item].desc;
2460 bool debug_menu(void)
2462 struct simplelist_info info;
2464 simplelist_info_init(&info, "Debug Menu", ARRAYLEN(menuitems), NULL);
2465 info.action_callback = menu_action_callback;
2466 info.get_name = dbg_menu_getname;
2468 return simplelist_show_list(&info);