No bufclosing of handles after track change
[Rockbox.git] / apps / debug_menu.c
blob8107409a3cf1cd3278574e76fed2703ec338a17b
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2002 Heikki Hannikainen
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
20 #include "config.h"
21 #include <stdio.h>
22 #include <stdbool.h>
23 #include <string.h>
24 #include "lcd.h"
25 #include "menu.h"
26 #include "debug_menu.h"
27 #include "kernel.h"
28 #include "sprintf.h"
29 #include "action.h"
30 #include "debug.h"
31 #include "thread.h"
32 #include "powermgmt.h"
33 #include "system.h"
34 #include "font.h"
35 #include "audio.h"
36 #include "mp3_playback.h"
37 #include "settings.h"
38 #include "list.h"
39 #include "statusbar.h"
40 #include "dir.h"
41 #include "panic.h"
42 #include "screens.h"
43 #include "misc.h"
44 #include "splash.h"
45 #include "dircache.h"
46 #ifdef HAVE_TAGCACHE
47 #include "tagcache.h"
48 #endif
49 #include "lcd-remote.h"
50 #include "crc32.h"
51 #include "logf.h"
52 #ifndef SIMULATOR
53 #include "disk.h"
54 #include "adc.h"
55 #include "power.h"
56 #include "usb.h"
57 #include "rtc.h"
58 #include "ata.h"
59 #include "fat.h"
60 #include "mas.h"
61 #include "eeprom_24cxx.h"
62 #if defined(HAVE_MMC) || defined(HAVE_HOTSWAP)
63 #include "ata_mmc.h"
64 #endif
65 #if CONFIG_TUNER
66 #include "tuner.h"
67 #include "radio.h"
68 #endif
69 #endif
71 #ifdef HAVE_LCD_BITMAP
72 #include "scrollbar.h"
73 #include "peakmeter.h"
74 #endif
75 #include "logfdisp.h"
76 #if CONFIG_CODEC == SWCODEC
77 #include "pcmbuf.h"
78 #include "buffering.h"
79 #if defined(HAVE_SPDIF_OUT) || defined(HAVE_SPDIF_IN)
80 #include "spdif.h"
81 #endif
82 #endif
83 #ifdef IRIVER_H300_SERIES
84 #include "pcf50606.h" /* for pcf50606_read */
85 #endif
86 #ifdef IAUDIO_X5
87 #include "ds2411.h"
88 #endif
89 #include "hwcompat.h"
91 /*---------------------------------------------------*/
92 /* SPECIAL DEBUG STUFF */
93 /*---------------------------------------------------*/
94 extern struct thread_entry threads[MAXTHREADS];
96 static char thread_status_char(unsigned status)
98 static const char thread_status_chars[THREAD_NUM_STATES+1] =
100 [0 ... THREAD_NUM_STATES] = '?',
101 [STATE_RUNNING] = 'R',
102 [STATE_BLOCKED] = 'B',
103 [STATE_SLEEPING] = 'S',
104 [STATE_BLOCKED_W_TMO] = 'T',
105 [STATE_FROZEN] = 'F',
106 [STATE_KILLED] = 'K',
109 #if NUM_CORES > 1
110 if (status == STATE_BUSY) /* Not a state index */
111 return '.';
112 #endif
114 if (status > THREAD_NUM_STATES)
115 status = THREAD_NUM_STATES;
117 return thread_status_chars[status];
120 static char* threads_getname(int selected_item, void * data, char *buffer)
122 (void)data;
123 char name[32];
124 struct thread_entry *thread = NULL;
125 unsigned status;
126 int usage;
128 #if NUM_CORES > 1
129 if (selected_item < (int)NUM_CORES)
131 usage = idle_stack_usage(selected_item);
132 snprintf(buffer, MAX_PATH, "Idle (%d): %2d%%", selected_item, usage);
133 return buffer;
136 selected_item -= NUM_CORES;
137 #endif
139 thread = &threads[selected_item];
140 status = thread_get_status(thread);
142 if (status == STATE_KILLED)
144 snprintf(buffer, MAX_PATH, "%2d: ---", selected_item);
145 return buffer;
148 thread_get_name(name, 32, thread);
149 usage = thread_stack_usage(thread);
151 snprintf(buffer, MAX_PATH,
152 "%2d: " IF_COP("(%d) ") "%c%c " IF_PRIO("%d ") "%2d%% %s",
153 selected_item,
154 IF_COP(thread->core,)
155 (status == STATE_RUNNING) ? '*' : ' ',
156 thread_status_char(status),
157 IF_PRIO(thread->priority,)
158 usage, name);
160 return buffer;
162 static int dbg_threads_action_callback(int action, struct gui_synclist *lists)
164 (void)lists;
165 #ifdef ROCKBOX_HAS_LOGF
166 if (action == ACTION_STD_OK)
168 int selpos = gui_synclist_get_sel_pos(lists);
169 #if NUM_CORES > 1
170 if (selpos >= NUM_CORES)
171 remove_thread(&threads[selpos - NUM_CORES]);
172 #else
173 remove_thread(&threads[selpos]);
174 #endif
175 return ACTION_REDRAW;
177 #endif /* ROCKBOX_HAS_LOGF */
178 return action;
180 /* Test code!!! */
181 static bool dbg_os(void)
183 struct simplelist_info info;
184 simplelist_info_init(&info, IF_COP("Core and ") "Stack usage:",
185 #if NUM_CORES == 1
186 MAXTHREADS,
187 #else
188 MAXTHREADS+NUM_CORES,
189 #endif
190 NULL);
191 #ifndef ROCKBOX_HAS_LOGF
192 info.hide_selection = true;
193 #endif
194 info.action_callback = dbg_threads_action_callback;
195 info.get_name = threads_getname;
196 return simplelist_show_list(&info);
199 #ifdef HAVE_LCD_BITMAP
200 #if CONFIG_CODEC != SWCODEC
201 #ifndef SIMULATOR
202 static bool dbg_audio_thread(void)
204 char buf[32];
205 struct audio_debug d;
207 lcd_setmargins(0, 0);
208 lcd_setfont(FONT_SYSFIXED);
210 while(1)
212 if (action_userabort(HZ/5))
213 return false;
215 audio_get_debugdata(&d);
217 lcd_clear_display();
219 snprintf(buf, sizeof(buf), "read: %x", d.audiobuf_read);
220 lcd_puts(0, 0, buf);
221 snprintf(buf, sizeof(buf), "write: %x", d.audiobuf_write);
222 lcd_puts(0, 1, buf);
223 snprintf(buf, sizeof(buf), "swap: %x", d.audiobuf_swapwrite);
224 lcd_puts(0, 2, buf);
225 snprintf(buf, sizeof(buf), "playing: %d", d.playing);
226 lcd_puts(0, 3, buf);
227 snprintf(buf, sizeof(buf), "playable: %x", d.playable_space);
228 lcd_puts(0, 4, buf);
229 snprintf(buf, sizeof(buf), "unswapped: %x", d.unswapped_space);
230 lcd_puts(0, 5, buf);
232 /* Playable space left */
233 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, 6*8, 112, 4, d.audiobuflen, 0,
234 d.playable_space, HORIZONTAL);
236 /* Show the watermark limit */
237 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, 6*8+4, 112, 4, d.audiobuflen, 0,
238 d.low_watermark_level, HORIZONTAL);
240 snprintf(buf, sizeof(buf), "wm: %x - %x",
241 d.low_watermark_level, d.lowest_watermark_level);
242 lcd_puts(0, 7, buf);
244 lcd_update();
246 return false;
248 #endif /* !SIMULATOR */
249 #else /* CONFIG_CODEC == SWCODEC */
250 extern size_t filebuflen;
251 /* This is a size_t, but call it a long so it puts a - when it's bad. */
253 static unsigned int ticks, boost_ticks;
255 static void dbg_audio_task(void)
257 #ifndef SIMULATOR
258 if(FREQ > CPUFREQ_NORMAL)
259 boost_ticks++;
260 #endif
262 ticks++;
265 static bool dbg_audio_thread(void)
267 char buf[32];
268 int button;
269 int line;
270 bool done = false;
271 size_t bufused;
272 size_t bufsize = pcmbuf_get_bufsize();
273 int pcmbufdescs = pcmbuf_descs();
275 ticks = boost_ticks = 0;
277 tick_add_task(dbg_audio_task);
279 lcd_setmargins(0, 0);
280 lcd_setfont(FONT_SYSFIXED);
281 while(!done)
283 button = get_action(CONTEXT_STD,HZ/5);
284 switch(button)
286 case ACTION_STD_NEXT:
287 audio_next();
288 break;
289 case ACTION_STD_PREV:
290 audio_prev();
291 break;
292 case ACTION_STD_CANCEL:
293 done = true;
294 break;
296 line = 0;
297 lcd_clear_display();
299 bufused = bufsize - pcmbuf_free();
301 snprintf(buf, sizeof(buf), "pcm: %7ld/%7ld", (long) bufused, (long) bufsize);
302 lcd_puts(0, line++, buf);
304 /* Playable space left */
305 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6, bufsize, 0, bufused, HORIZONTAL);
306 line++;
308 snprintf(buf, sizeof(buf), "codec: %8ld/%8ld", audio_filebufused(), (long) filebuflen);
309 lcd_puts(0, line++, buf);
311 /* Playable space left */
312 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6, filebuflen, 0,
313 audio_filebufused(), HORIZONTAL);
314 line++;
316 snprintf(buf, sizeof(buf), "track count: %2d", audio_track_count());
317 lcd_puts(0, line++, buf);
319 #ifndef SIMULATOR
320 snprintf(buf, sizeof(buf), "cpu freq: %3dMHz",
321 (int)((FREQ + 500000) / 1000000));
322 lcd_puts(0, line++, buf);
323 #endif
325 if (ticks > 0)
327 snprintf(buf, sizeof(buf), "boost ratio: %3d%%",
328 boost_ticks * 100 / ticks);
329 lcd_puts(0, line++, buf);
332 snprintf(buf, sizeof(buf), "pcmbufdesc: %2d/%2d",
333 pcmbuf_used_descs(), pcmbufdescs);
334 lcd_puts(0, line++, buf);
336 lcd_update();
339 tick_remove_task(dbg_audio_task);
341 return false;
344 static bool dbg_buffering_thread(void)
346 char buf[32];
347 int button;
348 int line;
349 bool done = false;
350 size_t bufused;
351 size_t bufsize = pcmbuf_get_bufsize();
352 struct buffering_debug d;
354 lcd_setmargins(0, 0);
355 lcd_setfont(FONT_SYSFIXED);
356 while(!done)
358 button = get_action(CONTEXT_STD,HZ/5);
359 switch(button)
361 case ACTION_STD_NEXT:
362 audio_next();
363 break;
364 case ACTION_STD_PREV:
365 audio_prev();
366 break;
367 case ACTION_STD_CANCEL:
368 done = true;
369 break;
372 buffering_get_debugdata(&d);
374 line = 0;
375 lcd_clear_display();
377 bufused = bufsize - pcmbuf_free();
379 snprintf(buf, sizeof(buf), "pcm: %7ld/%7ld", (long) bufused, (long) bufsize);
380 lcd_puts(0, line++, buf);
382 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6,
383 bufsize, 0, bufused, HORIZONTAL);
384 line++;
386 snprintf(buf, sizeof(buf), "handle count: %d", (int)d.num_handles);
387 lcd_puts(0, line++, buf);
389 snprintf(buf, sizeof(buf), "track count: %2d", audio_track_count()-1);
390 lcd_puts(0, line++, buf);
392 snprintf(buf, sizeof(buf), "data_rem: %8ld", (long)d.data_rem);
393 lcd_puts(0, line++, buf);
395 snprintf(buf, sizeof(buf), "alloc: %8ld/%8ld", audio_filebufused(),
396 (long) filebuflen);
397 lcd_puts(0, line++, buf);
399 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6,
400 filebuflen, 0, audio_filebufused(), HORIZONTAL);
401 line++;
403 snprintf(buf, sizeof(buf), "real: %8ld/%8ld", (long)d.buffered_data,
404 (long)filebuflen);
405 lcd_puts(0, line++, buf);
407 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6,
408 filebuflen, 0, d.buffered_data, HORIZONTAL);
409 line++;
411 snprintf(buf, sizeof(buf), "usefl: %8ld/%8ld", (long)(d.useful_data),
412 (long)filebuflen);
413 lcd_puts(0, line++, buf);
415 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6,
416 filebuflen, 0, d.useful_data, HORIZONTAL);
417 line++;
419 #ifndef SIMULATOR
420 snprintf(buf, sizeof(buf), "cpu freq: %3dMHz",
421 (int)((FREQ + 500000) / 1000000));
422 lcd_puts(0, line++, buf);
423 #endif
425 lcd_update();
428 return false;
430 #endif /* CONFIG_CODEC */
431 #endif /* HAVE_LCD_BITMAP */
434 #if (CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE))
435 /* Tool function to read the flash manufacturer and type, if available.
436 Only chips which could be reprogrammed in system will return values.
437 (The mode switch addresses vary between flash manufacturers, hence addr1/2) */
438 /* In IRAM to avoid problems when running directly from Flash */
439 static bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
440 unsigned addr1, unsigned addr2)
441 ICODE_ATTR __attribute__((noinline));
442 static bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
443 unsigned addr1, unsigned addr2)
446 unsigned not_manu, not_id; /* read values before switching to ID mode */
447 unsigned manu, id; /* read values when in ID mode */
449 #if CONFIG_CPU == SH7034
450 volatile unsigned char* flash = (unsigned char*)0x2000000; /* flash mapping */
451 #elif defined(CPU_COLDFIRE)
452 volatile unsigned short* flash = (unsigned short*)0; /* flash mapping */
453 #endif
454 int old_level; /* saved interrupt level */
456 not_manu = flash[0]; /* read the normal content */
457 not_id = flash[1]; /* should be 'A' (0x41) and 'R' (0x52) from the "ARCH" marker */
459 /* disable interrupts, prevent any stray flash access */
460 old_level = set_irq_level(HIGHEST_IRQ_LEVEL);
462 flash[addr1] = 0xAA; /* enter command mode */
463 flash[addr2] = 0x55;
464 flash[addr1] = 0x90; /* ID command */
465 /* Atmel wants 20ms pause here */
466 /* sleep(HZ/50); no sleeping possible while interrupts are disabled */
468 manu = flash[0]; /* read the IDs */
469 id = flash[1];
471 flash[0] = 0xF0; /* reset flash (back to normal read mode) */
472 /* Atmel wants 20ms pause here */
473 /* sleep(HZ/50); no sleeping possible while interrupts are disabled */
475 set_irq_level(old_level); /* enable interrupts again */
477 /* I assume success if the obtained values are different from
478 the normal flash content. This is not perfectly bulletproof, they
479 could theoretically be the same by chance, causing us to fail. */
480 if (not_manu != manu || not_id != id) /* a value has changed */
482 *p_manufacturer = manu; /* return the results */
483 *p_device = id;
484 return true; /* success */
486 return false; /* fail */
488 #endif /* (CONFIG_CPU == SH7034 || CPU_COLDFIRE) */
490 #ifndef SIMULATOR
491 #ifdef CPU_PP
492 static int perfcheck(void)
494 int result;
496 asm (
497 "mrs r2, CPSR \n"
498 "orr r0, r2, #0xc0 \n" /* disable IRQ and FIQ */
499 "msr CPSR_c, r0 \n"
500 "mov %[res], #0 \n"
501 "ldr r0, [%[timr]] \n"
502 "add r0, r0, %[tmo] \n"
503 "1: \n"
504 "add %[res], %[res], #1 \n"
505 "ldr r1, [%[timr]] \n"
506 "cmp r1, r0 \n"
507 "bmi 1b \n"
508 "msr CPSR_c, r2 \n" /* reset IRQ and FIQ state */
510 [res]"=&r"(result)
512 [timr]"r"(&USEC_TIMER),
513 [tmo]"r"(
514 #if CONFIG_CPU == PP5002
515 16000
516 #else /* PP5020/5022/5024 */
517 10226
518 #endif
521 "r0", "r1", "r2"
523 return result;
525 #endif
527 #ifdef HAVE_LCD_BITMAP
528 static bool dbg_hw_info(void)
530 #if CONFIG_CPU == SH7034
531 char buf[32];
532 int bitmask = HW_MASK;
533 int rom_version = ROM_VERSION;
534 unsigned manu, id; /* flash IDs */
535 bool got_id; /* flag if we managed to get the flash IDs */
536 unsigned rom_crc = 0xffffffff; /* CRC32 of the boot ROM */
537 bool has_bootrom; /* flag for boot ROM present */
538 int oldmode; /* saved memory guard mode */
540 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
542 /* get flash ROM type */
543 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
544 if (!got_id)
545 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
547 /* check if the boot ROM area is a flash mirror */
548 has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0);
549 if (has_bootrom) /* if ROM and Flash different */
551 /* calculate CRC16 checksum of boot ROM */
552 rom_crc = crc_32((unsigned char*)0x0000, 64*1024, 0xffffffff);
555 system_memory_guard(oldmode); /* re-enable memory guard */
557 lcd_setmargins(0, 0);
558 lcd_setfont(FONT_SYSFIXED);
559 lcd_clear_display();
561 lcd_puts(0, 0, "[Hardware info]");
563 snprintf(buf, 32, "ROM: %d.%02d", rom_version/100, rom_version%100);
564 lcd_puts(0, 1, buf);
566 snprintf(buf, 32, "Mask: 0x%04x", bitmask);
567 lcd_puts(0, 2, buf);
569 if (got_id)
570 snprintf(buf, 32, "Flash: M=%02x D=%02x", manu, id);
571 else
572 snprintf(buf, 32, "Flash: M=?? D=??"); /* unknown, sorry */
573 lcd_puts(0, 3, buf);
575 if (has_bootrom)
577 if (rom_crc == 0x56DBA4EE) /* known Version 1 */
578 snprintf(buf, 32, "Boot ROM: V1");
579 else
580 snprintf(buf, 32, "ROMcrc: 0x%08x", rom_crc);
582 else
584 snprintf(buf, 32, "Boot ROM: none");
586 lcd_puts(0, 4, buf);
588 lcd_update();
590 while (!(action_userabort(TIMEOUT_BLOCK)));
592 #elif CONFIG_CPU == MCF5249 || CONFIG_CPU == MCF5250
593 char buf[32];
594 unsigned manu, id; /* flash IDs */
595 int got_id; /* flag if we managed to get the flash IDs */
596 int oldmode; /* saved memory guard mode */
597 int line = 0;
599 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
601 /* get flash ROM type */
602 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
603 if (!got_id)
604 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
606 system_memory_guard(oldmode); /* re-enable memory guard */
608 lcd_setmargins(0, 0);
609 lcd_setfont(FONT_SYSFIXED);
610 lcd_clear_display();
612 lcd_puts(0, line++, "[Hardware info]");
614 if (got_id)
615 snprintf(buf, 32, "Flash: M=%04x D=%04x", manu, id);
616 else
617 snprintf(buf, 32, "Flash: M=???? D=????"); /* unknown, sorry */
618 lcd_puts(0, line++, buf);
620 #ifdef IAUDIO_X5
622 struct ds2411_id id;
624 lcd_puts(0, ++line, "Serial Number:");
626 got_id = ds2411_read_id(&id);
628 if (got_id == DS2411_OK)
630 snprintf(buf, 32, " FC=%02x", (unsigned)id.family_code);
631 lcd_puts(0, ++line, buf);
632 snprintf(buf, 32, " ID=%02X %02X %02X %02X %02X %02X",
633 (unsigned)id.uid[0], (unsigned)id.uid[1], (unsigned)id.uid[2],
634 (unsigned)id.uid[3], (unsigned)id.uid[4], (unsigned)id.uid[5]);
635 lcd_puts(0, ++line, buf);
636 snprintf(buf, 32, " CRC=%02X", (unsigned)id.crc);
638 else
640 snprintf(buf, 32, "READ ERR=%d", got_id);
643 lcd_puts(0, ++line, buf);
645 #endif
647 lcd_update();
649 while (!(action_userabort(TIMEOUT_BLOCK)));
651 #elif defined(CPU_PP502x)
652 int line = 0;
653 char buf[32];
654 char pp_version[] = { (PP_VER2 >> 24) & 0xff, (PP_VER2 >> 16) & 0xff,
655 (PP_VER2 >> 8) & 0xff, (PP_VER2) & 0xff,
656 (PP_VER1 >> 24) & 0xff, (PP_VER1 >> 16) & 0xff,
657 (PP_VER1 >> 8) & 0xff, (PP_VER1) & 0xff, '\0' };
659 lcd_setmargins(0, 0);
660 lcd_setfont(FONT_SYSFIXED);
661 lcd_clear_display();
663 lcd_puts(0, line++, "[Hardware info]");
665 #ifdef IPOD_ARCH
666 snprintf(buf, sizeof(buf), "HW rev: 0x%08lx", IPOD_HW_REVISION);
667 lcd_puts(0, line++, buf);
668 #endif
670 #ifdef IPOD_COLOR
671 extern int lcd_type; /* Defined in lcd-colornano.c */
673 snprintf(buf, sizeof(buf), "LCD type: %d", lcd_type);
674 lcd_puts(0, line++, buf);
675 #endif
677 snprintf(buf, sizeof(buf), "PP version: %s", pp_version);
678 lcd_puts(0, line++, buf);
680 snprintf(buf, sizeof(buf), "Est. clock (kHz): %d", perfcheck());
681 lcd_puts(0, line++, buf);
683 lcd_update();
685 while (!(action_userabort(TIMEOUT_BLOCK)));
687 #elif CONFIG_CPU == PP5002
688 int line = 0;
689 char buf[32];
691 lcd_setmargins(0, 0);
692 lcd_setfont(FONT_SYSFIXED);
693 lcd_clear_display();
695 lcd_puts(0, line++, "[Hardware info]");
697 #ifdef IPOD_ARCH
698 snprintf(buf, sizeof(buf), "HW rev: 0x%08lx", IPOD_HW_REVISION);
699 lcd_puts(0, line++, buf);
700 #endif
702 snprintf(buf, sizeof(buf), "Est. clock (kHz): %d", perfcheck());
703 lcd_puts(0, line++, buf);
705 lcd_update();
707 while (!(action_userabort(TIMEOUT_BLOCK)));
709 #endif /* CONFIG_CPU */
710 return false;
712 #else /* !HAVE_LCD_BITMAP */
713 static bool dbg_hw_info(void)
715 char buf[32];
716 int button;
717 int currval = 0;
718 int rom_version = ROM_VERSION;
719 unsigned manu, id; /* flash IDs */
720 bool got_id; /* flag if we managed to get the flash IDs */
721 unsigned rom_crc = 0xffffffff; /* CRC32 of the boot ROM */
722 bool has_bootrom; /* flag for boot ROM present */
723 int oldmode; /* saved memory guard mode */
725 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
727 /* get flash ROM type */
728 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
729 if (!got_id)
730 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
732 /* check if the boot ROM area is a flash mirror */
733 has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0);
734 if (has_bootrom) /* if ROM and Flash different */
736 /* calculate CRC16 checksum of boot ROM */
737 rom_crc = crc_32((unsigned char*)0x0000, 64*1024, 0xffffffff);
740 system_memory_guard(oldmode); /* re-enable memory guard */
742 lcd_clear_display();
744 lcd_puts(0, 0, "[HW Info]");
745 while(1)
747 switch(currval)
749 case 0:
750 snprintf(buf, 32, "ROM: %d.%02d",
751 rom_version/100, rom_version%100);
752 break;
753 case 1:
754 if (got_id)
755 snprintf(buf, 32, "Flash:%02x,%02x", manu, id);
756 else
757 snprintf(buf, 32, "Flash:??,??"); /* unknown, sorry */
758 break;
759 case 2:
760 if (has_bootrom)
762 if (rom_crc == 0x56DBA4EE) /* known Version 1 */
763 snprintf(buf, 32, "BootROM: V1");
764 else if (rom_crc == 0x358099E8)
765 snprintf(buf, 32, "BootROM: V2");
766 /* alternative boot ROM found in one single player so far */
767 else
768 snprintf(buf, 32, "R: %08x", rom_crc);
770 else
771 snprintf(buf, 32, "BootROM: no");
774 lcd_puts(0, 1, buf);
775 lcd_update();
777 button = get_action(CONTEXT_SETTINGS,TIMEOUT_BLOCK);
779 switch(button)
781 case ACTION_STD_CANCEL:
782 return false;
784 case ACTION_SETTINGS_DEC:
785 currval--;
786 if(currval < 0)
787 currval = 2;
788 break;
790 case ACTION_SETTINGS_INC:
791 currval++;
792 if(currval > 2)
793 currval = 0;
794 break;
797 return false;
799 #endif /* !HAVE_LCD_BITMAP */
800 #endif /* !SIMULATOR */
802 #ifndef SIMULATOR
803 static char* dbg_partitions_getname(int selected_item, void * data, char *buffer)
805 (void)data;
806 int partition = selected_item/2;
807 struct partinfo* p = disk_partinfo(partition);
808 if (selected_item%2)
810 snprintf(buffer, MAX_PATH, " T:%x %ld MB", p->type, p->size / 2048);
812 else
814 snprintf(buffer, MAX_PATH, "P%d: S:%lx", partition, p->start);
816 return buffer;
819 bool dbg_partitions(void)
821 struct simplelist_info info;
822 simplelist_info_init(&info, "Partition Info", 4, NULL);
823 info.selection_size = 2;
824 info.hide_selection = true;
825 info.get_name = dbg_partitions_getname;
826 return simplelist_show_list(&info);
828 #endif
830 #if defined(CPU_COLDFIRE) && defined(HAVE_SPDIF_OUT)
831 static bool dbg_spdif(void)
833 char buf[128];
834 int line;
835 unsigned int control;
836 int x;
837 char *s;
838 int category;
839 int generation;
840 unsigned int interruptstat;
841 bool valnogood, symbolerr, parityerr;
842 bool done = false;
843 bool spdif_src_on;
844 int spdif_source = spdif_get_output_source(&spdif_src_on);
845 spdif_set_output_source(AUDIO_SRC_SPDIF IF_SPDIF_POWER_(, true));
847 lcd_setmargins(0, 0);
848 lcd_clear_display();
849 lcd_setfont(FONT_SYSFIXED);
851 #ifdef HAVE_SPDIF_POWER
852 spdif_power_enable(true); /* We need SPDIF power for both sending & receiving */
853 #endif
855 while (!done)
857 line = 0;
859 control = EBU1RCVCCHANNEL1;
860 interruptstat = INTERRUPTSTAT;
861 INTERRUPTCLEAR = 0x03c00000;
863 valnogood = (interruptstat & 0x01000000)?true:false;
864 symbolerr = (interruptstat & 0x00800000)?true:false;
865 parityerr = (interruptstat & 0x00400000)?true:false;
867 snprintf(buf, sizeof(buf), "Val: %s Sym: %s Par: %s",
868 valnogood?"--":"OK",
869 symbolerr?"--":"OK",
870 parityerr?"--":"OK");
871 lcd_puts(0, line++, buf);
873 snprintf(buf, sizeof(buf), "Status word: %08x", (int)control);
874 lcd_puts(0, line++, buf);
876 line++;
878 x = control >> 31;
879 snprintf(buf, sizeof(buf), "PRO: %d (%s)",
880 x, x?"Professional":"Consumer");
881 lcd_puts(0, line++, buf);
883 x = (control >> 30) & 1;
884 snprintf(buf, sizeof(buf), "Audio: %d (%s)",
885 x, x?"Non-PCM":"PCM");
886 lcd_puts(0, line++, buf);
888 x = (control >> 29) & 1;
889 snprintf(buf, sizeof(buf), "Copy: %d (%s)",
890 x, x?"Permitted":"Inhibited");
891 lcd_puts(0, line++, buf);
893 x = (control >> 27) & 7;
894 switch(x)
896 case 0:
897 s = "None";
898 break;
899 case 1:
900 s = "50/15us";
901 break;
902 default:
903 s = "Reserved";
904 break;
906 snprintf(buf, sizeof(buf), "Preemphasis: %d (%s)", x, s);
907 lcd_puts(0, line++, buf);
909 x = (control >> 24) & 3;
910 snprintf(buf, sizeof(buf), "Mode: %d", x);
911 lcd_puts(0, line++, buf);
913 category = (control >> 17) & 127;
914 switch(category)
916 case 0x00:
917 s = "General";
918 break;
919 case 0x40:
920 s = "Audio CD";
921 break;
922 default:
923 s = "Unknown";
925 snprintf(buf, sizeof(buf), "Category: 0x%02x (%s)", category, s);
926 lcd_puts(0, line++, buf);
928 x = (control >> 16) & 1;
929 generation = x;
930 if(((category & 0x70) == 0x10) ||
931 ((category & 0x70) == 0x40) ||
932 ((category & 0x78) == 0x38))
934 generation = !generation;
936 snprintf(buf, sizeof(buf), "Generation: %d (%s)",
937 x, generation?"Original":"No ind.");
938 lcd_puts(0, line++, buf);
940 x = (control >> 12) & 15;
941 snprintf(buf, sizeof(buf), "Source: %d", x);
942 lcd_puts(0, line++, buf);
944 x = (control >> 8) & 15;
945 switch(x)
947 case 0:
948 s = "Unspecified";
949 break;
950 case 8:
951 s = "A (Left)";
952 break;
953 case 4:
954 s = "B (Right)";
955 break;
956 default:
957 s = "";
958 break;
960 snprintf(buf, sizeof(buf), "Channel: %d (%s)", x, s);
961 lcd_puts(0, line++, buf);
963 x = (control >> 4) & 15;
964 switch(x)
966 case 0:
967 s = "44.1kHz";
968 break;
969 case 0x4:
970 s = "48kHz";
971 break;
972 case 0xc:
973 s = "32kHz";
974 break;
976 snprintf(buf, sizeof(buf), "Frequency: %d (%s)", x, s);
977 lcd_puts(0, line++, buf);
979 x = (control >> 2) & 3;
980 snprintf(buf, sizeof(buf), "Clock accuracy: %d", x);
981 lcd_puts(0, line++, buf);
982 line++;
984 #ifndef SIMULATOR
985 snprintf(buf, sizeof(buf), "Measured freq: %ldHz",
986 spdif_measure_frequency());
987 lcd_puts(0, line++, buf);
988 #endif
990 lcd_update();
992 if (action_userabort(HZ/10))
993 break;
996 spdif_set_output_source(spdif_source IF_SPDIF_POWER_(, spdif_src_on));
998 #ifdef HAVE_SPDIF_POWER
999 spdif_power_enable(global_settings.spdif_enable);
1000 #endif
1002 return false;
1004 #endif /* CPU_COLDFIRE */
1006 #ifndef SIMULATOR
1007 #ifdef HAVE_LCD_BITMAP
1008 /* button definitions */
1009 #if (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
1010 (CONFIG_KEYPAD == IRIVER_H300_PAD)
1011 # define DEBUG_CANCEL BUTTON_OFF
1013 #elif CONFIG_KEYPAD == RECORDER_PAD
1014 # define DEBUG_CANCEL BUTTON_OFF
1016 #elif CONFIG_KEYPAD == ONDIO_PAD
1017 # define DEBUG_CANCEL BUTTON_MENU
1019 #elif (CONFIG_KEYPAD == IPOD_1G2G_PAD) || \
1020 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
1021 (CONFIG_KEYPAD == IPOD_4G_PAD)
1022 # define DEBUG_CANCEL BUTTON_MENU
1024 #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
1025 # define DEBUG_CANCEL BUTTON_PLAY
1027 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
1028 # define DEBUG_CANCEL BUTTON_REC
1030 #elif CONFIG_KEYPAD == GIGABEAT_PAD
1031 # define DEBUG_CANCEL BUTTON_A
1033 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
1034 # define DEBUG_CANCEL BUTTON_REW
1036 #elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \
1037 (CONFIG_KEYPAD == SANSA_C200_PAD)
1038 # define DEBUG_CANCEL BUTTON_LEFT
1039 #endif /* key definitios */
1041 /* Test code!!! */
1042 bool dbg_ports(void)
1044 #if CONFIG_CPU == SH7034
1045 unsigned short porta;
1046 unsigned short portb;
1047 unsigned char portc;
1048 char buf[32];
1049 int adc_battery_voltage, adc_battery_level;
1051 lcd_setfont(FONT_SYSFIXED);
1052 lcd_setmargins(0, 0);
1053 lcd_clear_display();
1055 while(1)
1057 porta = PADR;
1058 portb = PBDR;
1059 portc = PCDR;
1061 snprintf(buf, 32, "PADR: %04x", porta);
1062 lcd_puts(0, 0, buf);
1063 snprintf(buf, 32, "PBDR: %04x", portb);
1064 lcd_puts(0, 1, buf);
1066 snprintf(buf, 32, "AN0: %03x AN4: %03x", adc_read(0), adc_read(4));
1067 lcd_puts(0, 2, buf);
1068 snprintf(buf, 32, "AN1: %03x AN5: %03x", adc_read(1), adc_read(5));
1069 lcd_puts(0, 3, buf);
1070 snprintf(buf, 32, "AN2: %03x AN6: %03x", adc_read(2), adc_read(6));
1071 lcd_puts(0, 4, buf);
1072 snprintf(buf, 32, "AN3: %03x AN7: %03x", adc_read(3), adc_read(7));
1073 lcd_puts(0, 5, buf);
1075 battery_read_info(&adc_battery_voltage, &adc_battery_level);
1076 snprintf(buf, 32, "Batt: %d.%03dV %d%% ", adc_battery_voltage / 1000,
1077 adc_battery_voltage % 1000, adc_battery_level);
1078 lcd_puts(0, 6, buf);
1080 lcd_update();
1081 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1082 return false;
1084 #elif defined(CPU_COLDFIRE)
1085 unsigned int gpio_out;
1086 unsigned int gpio1_out;
1087 unsigned int gpio_read;
1088 unsigned int gpio1_read;
1089 unsigned int gpio_function;
1090 unsigned int gpio1_function;
1091 unsigned int gpio_enable;
1092 unsigned int gpio1_enable;
1093 int adc_buttons, adc_remote;
1094 int adc_battery_voltage, adc_battery_level;
1095 char buf[128];
1096 int line;
1098 lcd_setmargins(0, 0);
1099 lcd_clear_display();
1100 lcd_setfont(FONT_SYSFIXED);
1102 while(1)
1104 line = 0;
1105 gpio_read = GPIO_READ;
1106 gpio1_read = GPIO1_READ;
1107 gpio_out = GPIO_OUT;
1108 gpio1_out = GPIO1_OUT;
1109 gpio_function = GPIO_FUNCTION;
1110 gpio1_function = GPIO1_FUNCTION;
1111 gpio_enable = GPIO_ENABLE;
1112 gpio1_enable = GPIO1_ENABLE;
1114 snprintf(buf, sizeof(buf), "GPIO_READ: %08x", gpio_read);
1115 lcd_puts(0, line++, buf);
1116 snprintf(buf, sizeof(buf), "GPIO_OUT: %08x", gpio_out);
1117 lcd_puts(0, line++, buf);
1118 snprintf(buf, sizeof(buf), "GPIO_FUNCTION: %08x", gpio_function);
1119 lcd_puts(0, line++, buf);
1120 snprintf(buf, sizeof(buf), "GPIO_ENABLE: %08x", gpio_enable);
1121 lcd_puts(0, line++, buf);
1123 snprintf(buf, sizeof(buf), "GPIO1_READ: %08x", gpio1_read);
1124 lcd_puts(0, line++, buf);
1125 snprintf(buf, sizeof(buf), "GPIO1_OUT: %08x", gpio1_out);
1126 lcd_puts(0, line++, buf);
1127 snprintf(buf, sizeof(buf), "GPIO1_FUNCTION: %08x", gpio1_function);
1128 lcd_puts(0, line++, buf);
1129 snprintf(buf, sizeof(buf), "GPIO1_ENABLE: %08x", gpio1_enable);
1130 lcd_puts(0, line++, buf);
1132 adc_buttons = adc_read(ADC_BUTTONS);
1133 adc_remote = adc_read(ADC_REMOTE);
1134 battery_read_info(&adc_battery_voltage, &adc_battery_level);
1135 #if defined(IAUDIO_X5) || defined(IAUDIO_M5) || defined(IRIVER_H300_SERIES)
1136 snprintf(buf, sizeof(buf), "ADC_BUTTONS (%c): %02x",
1137 button_scan_enabled() ? '+' : '-', adc_buttons);
1138 #else
1139 snprintf(buf, sizeof(buf), "ADC_BUTTONS: %02x", adc_buttons);
1140 #endif
1141 lcd_puts(0, line++, buf);
1142 #if defined(IAUDIO_X5) || defined(IAUDIO_M5)
1143 snprintf(buf, sizeof(buf), "ADC_REMOTE (%c): %02x",
1144 remote_detect() ? '+' : '-', adc_remote);
1145 #else
1146 snprintf(buf, sizeof(buf), "ADC_REMOTE: %02x", adc_remote);
1147 #endif
1148 lcd_puts(0, line++, buf);
1149 #if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES)
1150 snprintf(buf, sizeof(buf), "ADC_REMOTEDETECT: %02x",
1151 adc_read(ADC_REMOTEDETECT));
1152 lcd_puts(0, line++, buf);
1153 #endif
1155 snprintf(buf, 32, "Batt: %d.%03dV %d%% ", adc_battery_voltage / 1000,
1156 adc_battery_voltage % 1000, adc_battery_level);
1157 lcd_puts(0, line++, buf);
1159 #if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES)
1160 snprintf(buf, sizeof(buf), "remotetype: %d", remote_type());
1161 lcd_puts(0, line++, buf);
1162 #endif
1164 lcd_update();
1165 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1166 return false;
1169 #elif defined(CPU_PP502x)
1171 unsigned int gpio_a, gpio_b, gpio_c, gpio_d;
1172 unsigned int gpio_e, gpio_f, gpio_g, gpio_h;
1173 unsigned int gpio_i, gpio_j, gpio_k, gpio_l;
1175 char buf[128];
1176 int line;
1178 lcd_setmargins(0, 0);
1179 lcd_clear_display();
1180 lcd_setfont(FONT_SYSFIXED);
1182 while(1)
1184 gpio_a = GPIOA_INPUT_VAL;
1185 gpio_b = GPIOB_INPUT_VAL;
1186 gpio_c = GPIOC_INPUT_VAL;
1188 gpio_g = GPIOG_INPUT_VAL;
1189 gpio_h = GPIOH_INPUT_VAL;
1190 gpio_i = GPIOI_INPUT_VAL;
1192 line = 0;
1193 snprintf(buf, sizeof(buf), "GPIO_A: %02x GPIO_G: %02x", gpio_a, gpio_g);
1194 lcd_puts(0, line++, buf);
1195 snprintf(buf, sizeof(buf), "GPIO_B: %02x GPIO_H: %02x", gpio_b, gpio_h);
1196 lcd_puts(0, line++, buf);
1197 snprintf(buf, sizeof(buf), "GPIO_C: %02x GPIO_I: %02x", gpio_c, gpio_i);
1198 lcd_puts(0, line++, buf);
1200 gpio_d = GPIOD_INPUT_VAL;
1201 gpio_e = GPIOE_INPUT_VAL;
1202 gpio_f = GPIOF_INPUT_VAL;
1204 gpio_j = GPIOJ_INPUT_VAL;
1205 gpio_k = GPIOK_INPUT_VAL;
1206 gpio_l = GPIOL_INPUT_VAL;
1208 snprintf(buf, sizeof(buf), "GPIO_D: %02x GPIO_J: %02x", gpio_d, gpio_j);
1209 lcd_puts(0, line++, buf);
1210 snprintf(buf, sizeof(buf), "GPIO_E: %02x GPIO_K: %02x", gpio_e, gpio_k);
1211 lcd_puts(0, line++, buf);
1212 snprintf(buf, sizeof(buf), "GPIO_F: %02x GPIO_L: %02x", gpio_f, gpio_l);
1213 lcd_puts(0, line++, buf);
1214 line++;
1216 snprintf(buf, sizeof(buf), "DEV_EN: %08lx", DEV_EN);
1217 lcd_puts(0, line++, buf);
1218 snprintf(buf, sizeof(buf), "CLOCK_SRC: %08lx", CLOCK_SOURCE);
1219 lcd_puts(0, line++, buf);
1220 snprintf(buf, sizeof(buf), "CLCD_CLK_SRC: %08lx", CLCD_CLOCK_SRC);
1221 lcd_puts(0, line++, buf);
1222 snprintf(buf, sizeof(buf), "PLL_CONTROL: %08lx", PLL_CONTROL);
1223 lcd_puts(0, line++, buf);
1224 snprintf(buf, sizeof(buf), "PLL_STATUS: %08lx", PLL_STATUS);
1225 lcd_puts(0, line++, buf);
1226 snprintf(buf, sizeof(buf), "DEV_TIMING1: %08lx", DEV_TIMING1);
1227 lcd_puts(0, line++, buf);
1229 #if defined(IRIVER_H10) || defined(IRIVER_H10_5GB)
1230 line++;
1231 snprintf(buf, sizeof(buf), "BATT: %03x UNK1: %03x", adc_read(ADC_BATTERY),
1232 adc_read(ADC_UNKNOWN_1));
1233 lcd_puts(0, line++, buf);
1234 snprintf(buf, sizeof(buf), "REM: %03x PAD: %03x", adc_read(ADC_REMOTE),
1235 adc_read(ADC_SCROLLPAD));
1236 lcd_puts(0, line++, buf);
1237 #elif defined(SANSA_E200)
1238 line++;
1239 snprintf(buf, sizeof(buf), "ADC_BVDD: %4d", adc_read(ADC_BVDD));
1240 lcd_puts(0, line++, buf);
1241 snprintf(buf, sizeof(buf), "ADC_RTCSUP: %4d", adc_read(ADC_RTCSUP));
1242 lcd_puts(0, line++, buf);
1243 snprintf(buf, sizeof(buf), "ADC_UVDD: %4d", adc_read(ADC_UVDD));
1244 lcd_puts(0, line++, buf);
1245 snprintf(buf, sizeof(buf), "ADC_CHG_IN: %4d", adc_read(ADC_CHG_IN));
1246 lcd_puts(0, line++, buf);
1247 snprintf(buf, sizeof(buf), "ADC_CVDD: %4d", adc_read(ADC_CVDD));
1248 lcd_puts(0, line++, buf);
1249 snprintf(buf, sizeof(buf), "ADC_BATTEMP: %4d", adc_read(ADC_BATTEMP));
1250 lcd_puts(0, line++, buf);
1251 snprintf(buf, sizeof(buf), "ADC_MICSUP1: %4d", adc_read(ADC_MICSUP1));
1252 lcd_puts(0, line++, buf);
1253 snprintf(buf, sizeof(buf), "ADC_MICSUP2: %4d", adc_read(ADC_MICSUP2));
1254 lcd_puts(0, line++, buf);
1255 snprintf(buf, sizeof(buf), "ADC_VBE1: %4d", adc_read(ADC_VBE1));
1256 lcd_puts(0, line++, buf);
1257 snprintf(buf, sizeof(buf), "ADC_VBE2: %4d", adc_read(ADC_VBE2));
1258 lcd_puts(0, line++, buf);
1259 snprintf(buf, sizeof(buf), "ADC_I_MICSUP1:%4d", adc_read(ADC_I_MICSUP1));
1260 lcd_puts(0, line++, buf);
1261 snprintf(buf, sizeof(buf), "ADC_I_MICSUP2:%4d", adc_read(ADC_I_MICSUP2));
1262 lcd_puts(0, line++, buf);
1263 snprintf(buf, sizeof(buf), "ADC_VBAT: %4d", adc_read(ADC_VBAT));
1264 lcd_puts(0, line++, buf);
1265 #endif
1266 lcd_update();
1267 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1268 return false;
1271 #elif CONFIG_CPU == PP5002
1272 unsigned int gpio_a, gpio_b, gpio_c, gpio_d;
1274 char buf[128];
1275 int line;
1277 lcd_setmargins(0, 0);
1278 lcd_clear_display();
1279 lcd_setfont(FONT_SYSFIXED);
1281 while(1)
1283 gpio_a = GPIOA_INPUT_VAL;
1284 gpio_b = GPIOB_INPUT_VAL;
1285 gpio_c = GPIOC_INPUT_VAL;
1286 gpio_d = GPIOD_INPUT_VAL;
1288 line = 0;
1289 snprintf(buf, sizeof(buf), "GPIO_A: %02x GPIO_B: %02x", gpio_a, gpio_b);
1290 lcd_puts(0, line++, buf);
1291 snprintf(buf, sizeof(buf), "GPIO_C: %02x GPIO_D: %02x", gpio_c, gpio_d);
1292 lcd_puts(0, line++, buf);
1294 snprintf(buf, sizeof(buf), "DEV_EN: %08lx", DEV_EN);
1295 lcd_puts(0, line++, buf);
1296 snprintf(buf, sizeof(buf), "CLOCK_ENABLE: %08lx", CLOCK_ENABLE);
1297 lcd_puts(0, line++, buf);
1298 snprintf(buf, sizeof(buf), "CLOCK_SOURCE: %08lx", CLOCK_SOURCE);
1299 lcd_puts(0, line++, buf);
1300 snprintf(buf, sizeof(buf), "PLL_CONTROL: %08lx", PLL_CONTROL);
1301 lcd_puts(0, line++, buf);
1302 snprintf(buf, sizeof(buf), "PLL_DIV: %08lx", PLL_DIV);
1303 lcd_puts(0, line++, buf);
1304 snprintf(buf, sizeof(buf), "PLL_MULT: %08lx", PLL_MULT);
1305 lcd_puts(0, line++, buf);
1306 snprintf(buf, sizeof(buf), "TIMING1_CTL: %08lx", TIMING1_CTL);
1307 lcd_puts(0, line++, buf);
1308 snprintf(buf, sizeof(buf), "TIMING2_CTL: %08lx", TIMING2_CTL);
1309 lcd_puts(0, line++, buf);
1311 lcd_update();
1312 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1313 return false;
1315 #elif CONFIG_CPU == S3C2440
1316 char buf[50];
1317 int line;
1319 lcd_setmargins(0, 0);
1320 lcd_clear_display();
1321 lcd_setfont(FONT_SYSFIXED);
1323 while(1)
1325 line = 0;
1326 snprintf(buf, sizeof(buf), "[Ports and Registers]"); lcd_puts(0, line++, buf);
1328 snprintf(buf, sizeof(buf), "GPACON: %08x GPBCON: %08x", GPACON, GPBCON); lcd_puts(0, line++, buf);
1329 snprintf(buf, sizeof(buf), "GPADAT: %08x GPBDAT: %08x", GPADAT, GPBDAT); lcd_puts(0, line++, buf);
1330 snprintf(buf, sizeof(buf), "GPAUP: %08x GPBUP: %08x", 0, GPBUP); lcd_puts(0, line++, buf);
1331 snprintf(buf, sizeof(buf), "GPCCON: %08x GPDCON: %08x", GPCCON, GPDCON); lcd_puts(0, line++, buf);
1332 snprintf(buf, sizeof(buf), "GPCDAT: %08x GPDDAT: %08x", GPCDAT, GPDDAT); lcd_puts(0, line++, buf);
1333 snprintf(buf, sizeof(buf), "GPCUP: %08x GPDUP: %08x", GPCUP, GPDUP); lcd_puts(0, line++, buf);
1335 snprintf(buf, sizeof(buf), "GPCCON: %08x GPDCON: %08x", GPCCON, GPDCON); lcd_puts(0, line++, buf);
1336 snprintf(buf, sizeof(buf), "GPCDAT: %08x GPDDAT: %08x", GPCDAT, GPDDAT); lcd_puts(0, line++, buf);
1337 snprintf(buf, sizeof(buf), "GPCUP: %08x GPDUP: %08x", GPCUP, GPDUP); lcd_puts(0, line++, buf);
1339 snprintf(buf, sizeof(buf), "GPECON: %08x GPFCON: %08x", GPECON, GPFCON); lcd_puts(0, line++, buf);
1340 snprintf(buf, sizeof(buf), "GPEDAT: %08x GPFDAT: %08x", GPEDAT, GPFDAT); lcd_puts(0, line++, buf);
1341 snprintf(buf, sizeof(buf), "GPEUP: %08x GPFUP: %08x", GPEUP, GPFUP); lcd_puts(0, line++, buf);
1343 snprintf(buf, sizeof(buf), "GPGCON: %08x GPHCON: %08x", GPGCON, GPHCON); lcd_puts(0, line++, buf);
1344 snprintf(buf, sizeof(buf), "GPGDAT: %08x GPHDAT: %08x", GPGDAT, GPHDAT); lcd_puts(0, line++, buf);
1345 snprintf(buf, sizeof(buf), "GPGUP: %08x GPHUP: %08x", GPGUP, GPHUP); lcd_puts(0, line++, buf);
1347 snprintf(buf, sizeof(buf), "GPJCON: %08x", GPJCON); lcd_puts(0, line++, buf);
1348 snprintf(buf, sizeof(buf), "GPJDAT: %08x", GPJDAT); lcd_puts(0, line++, buf);
1349 snprintf(buf, sizeof(buf), "GPJUP: %08x", GPJUP); lcd_puts(0, line++, buf);
1351 line++;
1353 snprintf(buf, sizeof(buf), "SRCPND: %08x INTMOD: %08x", SRCPND, INTMOD); lcd_puts(0, line++, buf);
1354 snprintf(buf, sizeof(buf), "INTMSK: %08x INTPND: %08x", INTMSK, INTPND); lcd_puts(0, line++, buf);
1355 snprintf(buf, sizeof(buf), "CLKCON: %08x CLKSLOW: %08x", CLKCON, CLKSLOW); lcd_puts(0, line++, buf);
1356 snprintf(buf, sizeof(buf), "MPLLCON: %08x UPLLCON: %08x", MPLLCON, UPLLCON); lcd_puts(0, line++, buf);
1357 snprintf(buf, sizeof(buf), "CLKDIVN: %08x", CLKDIVN); lcd_puts(0, line++, buf);
1359 lcd_update();
1360 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1361 return false;
1363 #endif /* CPU */
1364 return false;
1366 #else /* !HAVE_LCD_BITMAP */
1367 bool dbg_ports(void)
1369 unsigned short porta;
1370 unsigned short portb;
1371 unsigned char portc;
1372 char buf[32];
1373 int button;
1374 int adc_battery_voltage;
1375 int currval = 0;
1377 lcd_clear_display();
1379 while(1)
1381 porta = PADR;
1382 portb = PBDR;
1383 portc = PCDR;
1385 switch(currval)
1387 case 0:
1388 snprintf(buf, 32, "PADR: %04x", porta);
1389 break;
1390 case 1:
1391 snprintf(buf, 32, "PBDR: %04x", portb);
1392 break;
1393 case 2:
1394 snprintf(buf, 32, "AN0: %03x", adc_read(0));
1395 break;
1396 case 3:
1397 snprintf(buf, 32, "AN1: %03x", adc_read(1));
1398 break;
1399 case 4:
1400 snprintf(buf, 32, "AN2: %03x", adc_read(2));
1401 break;
1402 case 5:
1403 snprintf(buf, 32, "AN3: %03x", adc_read(3));
1404 break;
1405 case 6:
1406 snprintf(buf, 32, "AN4: %03x", adc_read(4));
1407 break;
1408 case 7:
1409 snprintf(buf, 32, "AN5: %03x", adc_read(5));
1410 break;
1411 case 8:
1412 snprintf(buf, 32, "AN6: %03x", adc_read(6));
1413 break;
1414 case 9:
1415 snprintf(buf, 32, "AN7: %03x", adc_read(7));
1416 break;
1417 break;
1419 lcd_puts(0, 0, buf);
1421 battery_read_info(&adc_battery_voltage, NULL);
1422 snprintf(buf, 32, "Batt: %d.%03dV", adc_battery_voltage / 1000,
1423 adc_battery_voltage % 1000);
1424 lcd_puts(0, 1, buf);
1425 lcd_update();
1427 button = get_action(CONTEXT_SETTINGS,HZ/5);
1429 switch(button)
1431 case ACTION_STD_CANCEL:
1432 return false;
1434 case ACTION_SETTINGS_DEC:
1435 currval--;
1436 if(currval < 0)
1437 currval = 9;
1438 break;
1440 case ACTION_SETTINGS_INC:
1441 currval++;
1442 if(currval > 9)
1443 currval = 0;
1444 break;
1447 return false;
1449 #endif /* !HAVE_LCD_BITMAP */
1450 #endif /* !SIMULATOR */
1452 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
1453 static bool dbg_cpufreq(void)
1455 char buf[128];
1456 int line;
1457 int button;
1459 #ifdef HAVE_LCD_BITMAP
1460 lcd_setmargins(0, 0);
1461 lcd_setfont(FONT_SYSFIXED);
1462 #endif
1463 lcd_clear_display();
1465 while(1)
1467 line = 0;
1469 snprintf(buf, sizeof(buf), "Frequency: %ld", FREQ);
1470 lcd_puts(0, line++, buf);
1472 snprintf(buf, sizeof(buf), "boost_counter: %d", get_cpu_boost_counter());
1473 lcd_puts(0, line++, buf);
1475 lcd_update();
1476 button = get_action(CONTEXT_STD,HZ/10);
1478 switch(button)
1480 case ACTION_STD_PREV:
1481 cpu_boost(true);
1482 break;
1484 case ACTION_STD_NEXT:
1485 cpu_boost(false);
1486 break;
1488 case ACTION_STD_OK:
1489 while (get_cpu_boost_counter() > 0)
1490 cpu_boost(false);
1491 set_cpu_frequency(CPUFREQ_DEFAULT);
1492 break;
1494 case ACTION_STD_CANCEL:
1495 return false;
1499 return false;
1501 #endif /* HAVE_ADJUSTABLE_CPU_FREQ */
1503 #ifndef SIMULATOR
1504 #ifdef HAVE_LCD_BITMAP
1506 * view_battery() shows a automatically scaled graph of the battery voltage
1507 * over time. Usable for estimating battery life / charging rate.
1508 * The power_history array is updated in power_thread of powermgmt.c.
1511 #define BAT_LAST_VAL MIN(LCD_WIDTH, POWER_HISTORY_LEN)
1512 #define BAT_YSPACE (LCD_HEIGHT - 20)
1514 static bool view_battery(void)
1516 int view = 0;
1517 int i, x, y;
1518 unsigned short maxv, minv;
1519 char buf[32];
1521 lcd_setmargins(0, 0);
1522 lcd_setfont(FONT_SYSFIXED);
1524 while(1)
1526 lcd_clear_display();
1527 switch (view) {
1528 case 0: /* voltage history graph */
1529 /* Find maximum and minimum voltage for scaling */
1530 minv = power_history[0];
1531 maxv = minv + 1;
1532 for (i = 1; i < BAT_LAST_VAL && power_history[i]; i++) {
1533 if (power_history[i] > maxv)
1534 maxv = power_history[i];
1535 if (power_history[i] < minv)
1536 minv = power_history[i];
1539 snprintf(buf, 30, "Battery %d.%03d", power_history[0] / 1000,
1540 power_history[0] % 1000);
1541 lcd_puts(0, 0, buf);
1542 snprintf(buf, 30, "scale %d.%03d-%d.%03dV",
1543 minv / 1000, minv % 1000, maxv / 1000, maxv % 1000);
1544 lcd_puts(0, 1, buf);
1546 x = 0;
1547 for (i = BAT_LAST_VAL - 1; i >= 0; i--) {
1548 y = (power_history[i] - minv) * BAT_YSPACE / (maxv - minv);
1549 lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
1550 lcd_vline(x, LCD_HEIGHT-1, 20);
1551 lcd_set_drawmode(DRMODE_SOLID);
1552 lcd_vline(x, LCD_HEIGHT-1,
1553 MIN(MAX(LCD_HEIGHT-1 - y, 20), LCD_HEIGHT-1));
1554 x++;
1557 break;
1559 case 1: /* status: */
1560 lcd_puts(0, 0, "Power status:");
1562 battery_read_info(&y, NULL);
1563 snprintf(buf, 30, "Battery: %d.%03d V", y / 1000, y % 1000);
1564 lcd_puts(0, 1, buf);
1565 #ifdef ADC_EXT_POWER
1566 y = (adc_read(ADC_EXT_POWER) * EXT_SCALE_FACTOR) / 1000;
1567 snprintf(buf, 30, "External: %d.%03d V", y / 1000, y % 1000);
1568 lcd_puts(0, 2, buf);
1569 #endif
1570 #if CONFIG_CHARGING
1571 #if CONFIG_CHARGING == CHARGING_CONTROL
1572 snprintf(buf, 30, "Chgr: %s %s",
1573 charger_inserted() ? "present" : "absent",
1574 charger_enabled ? "on" : "off");
1575 lcd_puts(0, 3, buf);
1576 snprintf(buf, 30, "short delta: %d", short_delta);
1577 lcd_puts(0, 5, buf);
1578 snprintf(buf, 30, "long delta: %d", long_delta);
1579 lcd_puts(0, 6, buf);
1580 lcd_puts(0, 7, power_message);
1581 snprintf(buf, 30, "USB Inserted: %s",
1582 usb_inserted() ? "yes" : "no");
1583 lcd_puts(0, 8, buf);
1584 #if defined IRIVER_H300_SERIES
1585 snprintf(buf, 30, "USB Charging Enabled: %s",
1586 usb_charging_enabled() ? "yes" : "no");
1587 lcd_puts(0, 9, buf);
1588 #endif
1589 #else /* CONFIG_CHARGING != CHARGING_CONTROL */
1590 #if defined IPOD_NANO || defined IPOD_VIDEO
1591 int usb_pwr = (GPIOL_INPUT_VAL & 0x10)?true:false;
1592 int ext_pwr = (GPIOL_INPUT_VAL & 0x08)?false:true;
1593 int dock = (GPIOA_INPUT_VAL & 0x10)?true:false;
1594 int charging = (GPIOB_INPUT_VAL & 0x01)?false:true;
1595 int headphone= (GPIOA_INPUT_VAL & 0x80)?true:false;
1597 snprintf(buf, 30, "USB pwr: %s",
1598 usb_pwr ? "present" : "absent");
1599 lcd_puts(0, 3, buf);
1600 snprintf(buf, 30, "EXT pwr: %s",
1601 ext_pwr ? "present" : "absent");
1602 lcd_puts(0, 4, buf);
1603 snprintf(buf, 30, "Battery: %s",
1604 charging ? "charging" : (usb_pwr||ext_pwr) ? "charged" : "discharging");
1605 lcd_puts(0, 5, buf);
1606 snprintf(buf, 30, "Dock mode: %s",
1607 dock ? "enabled" : "disabled");
1608 lcd_puts(0, 6, buf);
1609 snprintf(buf, 30, "Headphone: %s",
1610 headphone ? "connected" : "disconnected");
1611 lcd_puts(0, 7, buf);
1612 #else
1613 snprintf(buf, 30, "Charger: %s",
1614 charger_inserted() ? "present" : "absent");
1615 lcd_puts(0, 3, buf);
1616 #endif
1617 #endif /* CONFIG_CHARGING != CHARGING_CONTROL */
1618 #endif /* CONFIG_CHARGING */
1619 break;
1621 case 2: /* voltage deltas: */
1622 lcd_puts(0, 0, "Voltage deltas:");
1624 for (i = 0; i <= 6; i++) {
1625 y = power_history[i] - power_history[i+1];
1626 snprintf(buf, 30, "-%d min: %s%d.%03d V", i,
1627 (y < 0) ? "-" : "", ((y < 0) ? y * -1 : y) / 1000,
1628 ((y < 0) ? y * -1 : y ) % 1000);
1629 lcd_puts(0, i+1, buf);
1631 break;
1633 case 3: /* remaining time estimation: */
1635 #if CONFIG_CHARGING == CHARGING_CONTROL
1636 snprintf(buf, 30, "charge_state: %d", charge_state);
1637 lcd_puts(0, 0, buf);
1639 snprintf(buf, 30, "Cycle time: %d m", powermgmt_last_cycle_startstop_min);
1640 lcd_puts(0, 1, buf);
1642 snprintf(buf, 30, "Lvl@cyc st: %d%%", powermgmt_last_cycle_level);
1643 lcd_puts(0, 2, buf);
1645 snprintf(buf, 30, "P=%2d I=%2d", pid_p, pid_i);
1646 lcd_puts(0, 3, buf);
1648 snprintf(buf, 30, "Trickle sec: %d/60", trickle_sec);
1649 lcd_puts(0, 4, buf);
1650 #endif /* CONFIG_CHARGING == CHARGING_CONTROL */
1652 snprintf(buf, 30, "Last PwrHist: %d.%03dV",
1653 power_history[0] / 1000,
1654 power_history[0] % 1000);
1655 lcd_puts(0, 5, buf);
1657 snprintf(buf, 30, "battery level: %d%%", battery_level());
1658 lcd_puts(0, 6, buf);
1660 snprintf(buf, 30, "Est. remain: %d m", battery_time());
1661 lcd_puts(0, 7, buf);
1662 break;
1665 lcd_update();
1667 switch(get_action(CONTEXT_SETTINGS,HZ/2))
1669 case ACTION_SETTINGS_DEC:
1670 if (view)
1671 view--;
1672 break;
1674 case ACTION_SETTINGS_INC:
1675 if (view < 3)
1676 view++;
1677 break;
1679 case ACTION_STD_CANCEL:
1680 return false;
1683 return false;
1686 #endif /* HAVE_LCD_BITMAP */
1687 #endif
1689 #ifndef SIMULATOR
1690 #if defined(HAVE_MMC) || defined(HAVE_HOTSWAP)
1691 #if defined(HAVE_MMC)
1692 #define CARDTYPE "MMC"
1693 #else
1694 #define CARDTYPE "microSD"
1695 #endif
1696 static int disk_callback(int btn, struct gui_synclist *lists)
1698 tCardInfo *card;
1699 int *cardnum = (int*)lists->gui_list[SCREEN_MAIN].data;
1700 unsigned char card_name[7];
1701 unsigned char pbuf[32];
1702 char *title = lists->gui_list[SCREEN_MAIN].title;
1703 static const unsigned char i_vmin[] = { 0, 1, 5, 10, 25, 35, 60, 100 };
1704 static const unsigned char i_vmax[] = { 1, 5, 10, 25, 35, 45, 80, 200 };
1705 static const unsigned char *kbit_units[] = { "kBit/s", "MBit/s", "GBit/s" };
1706 static const unsigned char *nsec_units[] = { "ns", "�s", "ms" };
1707 static const char *spec_vers[] = { "1.0-1.2", "1.4", "2.0-2.2",
1708 "3.1-3.31", "4.0" };
1709 if ((btn == ACTION_STD_OK) || (btn == SYS_FS_CHANGED) || (btn == ACTION_REDRAW))
1711 if (btn == ACTION_STD_OK)
1713 *cardnum ^= 0x1; /* change cards */
1716 simplelist_set_line_count(0);
1718 card = card_get_info(*cardnum);
1720 if (card->initialized > 0)
1722 card_name[6] = '\0';
1723 strncpy(card_name, ((unsigned char*)card->cid) + 3, 6);
1724 simplelist_addline(SIMPLELIST_ADD_LINE,
1725 "%s Rev %d.%d", card_name,
1726 (int) card_extract_bits(card->cid, 72, 4),
1727 (int) card_extract_bits(card->cid, 76, 4));
1728 simplelist_addline(SIMPLELIST_ADD_LINE,
1729 "Prod: %d/%d",
1730 (int) card_extract_bits(card->cid, 112, 4),
1731 (int) card_extract_bits(card->cid, 116, 4) + 1997);
1732 simplelist_addline(SIMPLELIST_ADD_LINE,
1733 "Ser#: 0x%08lx",
1734 card_extract_bits(card->cid, 80, 32));
1735 simplelist_addline(SIMPLELIST_ADD_LINE,
1736 "M=%02x, O=%04x",
1737 (int) card_extract_bits(card->cid, 0, 8),
1738 (int) card_extract_bits(card->cid, 8, 16));
1739 int temp = card_extract_bits(card->csd, 2, 4);
1740 simplelist_addline(SIMPLELIST_ADD_LINE,
1741 CARDTYPE " v%s", temp < 5 ?
1742 spec_vers[temp] : "?.?");
1743 simplelist_addline(SIMPLELIST_ADD_LINE,
1744 "Blocks: 0x%06lx", card->numblocks);
1745 simplelist_addline(SIMPLELIST_ADD_LINE,
1746 "Blksz.: %d P:%c%c", card->blocksize,
1747 card_extract_bits(card->csd, 48, 1) ? 'R' : '-',
1748 card_extract_bits(card->csd, 106, 1) ? 'W' : '-');
1749 output_dyn_value(pbuf, sizeof pbuf, card->speed / 1000,
1750 kbit_units, false);
1751 simplelist_addline(SIMPLELIST_ADD_LINE,
1752 "Speed: %s", pbuf);
1753 output_dyn_value(pbuf, sizeof pbuf, card->tsac,
1754 nsec_units, false);
1755 simplelist_addline(SIMPLELIST_ADD_LINE,
1756 "Tsac: %s", pbuf);
1757 simplelist_addline(SIMPLELIST_ADD_LINE,
1758 "Nsac: %d clk", card->nsac);
1759 simplelist_addline(SIMPLELIST_ADD_LINE,
1760 "R2W: *%d", card->r2w_factor);
1761 simplelist_addline(SIMPLELIST_ADD_LINE,
1762 "IRmax: %d..%d mA",
1763 i_vmin[card_extract_bits(card->csd, 66, 3)],
1764 i_vmax[card_extract_bits(card->csd, 69, 3)]);
1765 simplelist_addline(SIMPLELIST_ADD_LINE,
1766 "IWmax: %d..%d mA",
1767 i_vmin[card_extract_bits(card->csd, 72, 3)],
1768 i_vmax[card_extract_bits(card->csd, 75, 3)]);
1770 else if (card->initialized == 0)
1772 simplelist_addline(SIMPLELIST_ADD_LINE, "Not Found!");
1774 #ifndef HAVE_MMC
1775 else /* card->initialized < 0 */
1777 simplelist_addline(SIMPLELIST_ADD_LINE, "Init Error! (%d)", card->initialized);
1779 #endif
1780 snprintf(title, 16, "[" CARDTYPE " %d]", *cardnum);
1781 gui_synclist_set_title(lists, title, Icon_NOICON);
1782 gui_synclist_set_nb_items(lists, simplelist_get_line_count());
1783 gui_synclist_select_item(lists, 0);
1784 btn = ACTION_REDRAW;
1786 return btn;
1788 #else /* !defined(HAVE_MMC) && !defined(HAVE_HOTSWAP) */
1789 static int disk_callback(int btn, struct gui_synclist *lists)
1791 (void)lists;
1792 int i;
1793 char buf[128];
1794 unsigned short* identify_info = ata_get_identify();
1795 bool timing_info_present = false;
1796 (void)btn;
1798 simplelist_set_line_count(0);
1800 for (i=0; i < 20; i++)
1801 ((unsigned short*)buf)[i]=htobe16(identify_info[i+27]);
1802 buf[40]=0;
1803 /* kill trailing space */
1804 for (i=39; i && buf[i]==' '; i--)
1805 buf[i] = 0;
1806 simplelist_addline(SIMPLELIST_ADD_LINE, "Model: %s", buf);
1807 for (i=0; i < 4; i++)
1808 ((unsigned short*)buf)[i]=htobe16(identify_info[i+23]);
1809 buf[8]=0;
1810 simplelist_addline(SIMPLELIST_ADD_LINE,
1811 "Firmware: %s", buf);
1812 snprintf(buf, sizeof buf, "%ld MB",
1813 ((unsigned long)identify_info[61] << 16 |
1814 (unsigned long)identify_info[60]) / 2048 );
1815 simplelist_addline(SIMPLELIST_ADD_LINE,
1816 "Size: %s", buf);
1817 unsigned long free;
1818 fat_size( IF_MV2(0,) NULL, &free );
1819 simplelist_addline(SIMPLELIST_ADD_LINE,
1820 "Free: %ld MB", free / 1024);
1821 simplelist_addline(SIMPLELIST_ADD_LINE,
1822 "Spinup time: %d ms", ata_spinup_time * (1000/HZ));
1823 i = identify_info[83] & (1<<3);
1824 simplelist_addline(SIMPLELIST_ADD_LINE,
1825 "Power mgmt: %s", i ? "enabled" : "unsupported");
1826 i = identify_info[83] & (1<<9);
1827 simplelist_addline(SIMPLELIST_ADD_LINE,
1828 "Noise mgmt: %s", i ? "enabled" : "unsupported");
1829 i = identify_info[82] & (1<<6);
1830 simplelist_addline(SIMPLELIST_ADD_LINE,
1831 "Read-ahead: %s", i ? "enabled" : "unsupported");
1832 timing_info_present = identify_info[53] & (1<<1);
1833 if(timing_info_present) {
1834 char pio3[2], pio4[2];pio3[1] = 0;
1835 pio4[1] = 0;
1836 pio3[0] = (identify_info[64] & (1<<0)) ? '3' : 0;
1837 pio4[0] = (identify_info[64] & (1<<1)) ? '4' : 0;
1838 simplelist_addline(SIMPLELIST_ADD_LINE,
1839 "PIO modes: 0 1 2 %s %s", pio3, pio4);
1841 else {
1842 simplelist_addline(SIMPLELIST_ADD_LINE,
1843 "No PIO mode info");
1845 timing_info_present = identify_info[53] & (1<<1);
1846 if(timing_info_present) {
1847 simplelist_addline(SIMPLELIST_ADD_LINE,
1848 "Cycle times %dns/%dns",
1849 identify_info[67],
1850 identify_info[68] );
1851 } else {
1852 simplelist_addline(SIMPLELIST_ADD_LINE,
1853 "No timing info");
1855 timing_info_present = identify_info[53] & (1<<1);
1856 if(timing_info_present) {
1857 i = identify_info[49] & (1<<11);
1858 simplelist_addline(SIMPLELIST_ADD_LINE,
1859 "IORDY support: %s", i ? "yes" : "no");
1860 i = identify_info[49] & (1<<10);
1861 simplelist_addline(SIMPLELIST_ADD_LINE,
1862 "IORDY disable: %s", i ? "yes" : "no");
1863 } else {
1864 simplelist_addline(SIMPLELIST_ADD_LINE,
1865 "No timing info");
1867 simplelist_addline(SIMPLELIST_ADD_LINE,
1868 "Cluster size: %d bytes", fat_get_cluster_size(IF_MV(0)));
1869 return btn;
1871 #endif /* !defined(HAVE_MMC) && !defined(HAVE_HOTSWAP) */
1872 static bool dbg_disk_info(void)
1874 struct simplelist_info info;
1875 simplelist_info_init(&info, "Disk Info", 1, NULL);
1876 #if defined(HAVE_MMC) || defined(HAVE_HOTSWAP)
1877 char title[16];
1878 int card = 0;
1879 info.callback_data = (void*)&card;
1880 info.title = title;
1881 #endif
1882 info.action_callback = disk_callback;
1883 info.hide_selection = true;
1884 return simplelist_show_list(&info);
1886 #endif /* !SIMULATOR */
1888 #ifdef HAVE_DIRCACHE
1889 static int dircache_callback(int btn, struct gui_synclist *lists)
1891 (void)btn; (void)lists;
1892 simplelist_set_line_count(0);
1893 simplelist_addline(SIMPLELIST_ADD_LINE, "Cache initialized: %s",
1894 dircache_is_enabled() ? "Yes" : "No");
1895 simplelist_addline(SIMPLELIST_ADD_LINE, "Cache size: %d B",
1896 dircache_get_cache_size());
1897 simplelist_addline(SIMPLELIST_ADD_LINE, "Last size: %d B",
1898 global_status.dircache_size);
1899 simplelist_addline(SIMPLELIST_ADD_LINE, "Limit: %d B",
1900 DIRCACHE_LIMIT);
1901 simplelist_addline(SIMPLELIST_ADD_LINE, "Reserve: %d/%d B",
1902 dircache_get_reserve_used(), DIRCACHE_RESERVE);
1903 simplelist_addline(SIMPLELIST_ADD_LINE, "Scanning took: %d s",
1904 dircache_get_build_ticks() / HZ);
1905 simplelist_addline(SIMPLELIST_ADD_LINE, "Entry count: %d",
1906 dircache_get_entry_count());
1907 return btn;
1910 static bool dbg_dircache_info(void)
1912 struct simplelist_info info;
1913 simplelist_info_init(&info, "Dircache Info", 7, NULL);
1914 info.action_callback = dircache_callback;
1915 info.hide_selection = true;
1916 return simplelist_show_list(&info);
1919 #endif /* HAVE_DIRCACHE */
1921 #ifdef HAVE_TAGCACHE
1922 static int database_callback(int btn, struct gui_synclist *lists)
1924 (void)lists;
1925 struct tagcache_stat *stat = tagcache_get_stat();
1926 static bool synced = false;
1928 simplelist_set_line_count(0);
1930 simplelist_addline(SIMPLELIST_ADD_LINE, "Initialized: %s",
1931 stat->initialized ? "Yes" : "No");
1932 simplelist_addline(SIMPLELIST_ADD_LINE, "DB Ready: %s",
1933 stat->ready ? "Yes" : "No");
1934 simplelist_addline(SIMPLELIST_ADD_LINE, "RAM Cache: %s",
1935 stat->ramcache ? "Yes" : "No");
1936 simplelist_addline(SIMPLELIST_ADD_LINE, "RAM: %d/%d B",
1937 stat->ramcache_used, stat->ramcache_allocated);
1938 simplelist_addline(SIMPLELIST_ADD_LINE, "Progress: %d%% (%d entries)",
1939 stat->progress, stat->processed_entries);
1940 simplelist_addline(SIMPLELIST_ADD_LINE, "Curfile: %s",
1941 stat->curentry ? stat->curentry : "---");
1942 simplelist_addline(SIMPLELIST_ADD_LINE, "Commit step: %d",
1943 stat->commit_step);
1944 simplelist_addline(SIMPLELIST_ADD_LINE, "Commit delayed: %s",
1945 stat->commit_delayed ? "Yes" : "No");
1948 if (synced)
1950 synced = false;
1951 tagcache_screensync_event();
1954 if (!btn && stat->curentry)
1956 synced = true;
1957 return ACTION_REDRAW;
1960 if (btn == ACTION_STD_CANCEL)
1961 tagcache_screensync_enable(false);
1963 return btn;
1965 static bool dbg_tagcache_info(void)
1967 struct simplelist_info info;
1968 simplelist_info_init(&info, "Database Info", 8, NULL);
1969 info.action_callback = database_callback;
1970 info.hide_selection = true;
1971 info.timeout = TIMEOUT_NOBLOCK;
1972 tagcache_screensync_enable(true);
1973 return simplelist_show_list(&info);
1975 #endif
1977 #if CONFIG_CPU == SH7034
1978 static bool dbg_save_roms(void)
1980 int fd;
1981 int oldmode = system_memory_guard(MEMGUARD_NONE);
1983 fd = creat("/internal_rom_0000-FFFF.bin");
1984 if(fd >= 0)
1986 write(fd, (void *)0, 0x10000);
1987 close(fd);
1990 fd = creat("/internal_rom_2000000-203FFFF.bin");
1991 if(fd >= 0)
1993 write(fd, (void *)0x2000000, 0x40000);
1994 close(fd);
1997 system_memory_guard(oldmode);
1998 return false;
2000 #elif defined CPU_COLDFIRE
2001 static bool dbg_save_roms(void)
2003 int fd;
2004 int oldmode = system_memory_guard(MEMGUARD_NONE);
2006 #if defined(IRIVER_H100_SERIES)
2007 fd = creat("/internal_rom_000000-1FFFFF.bin");
2008 #elif defined(IRIVER_H300_SERIES)
2009 fd = creat("/internal_rom_000000-3FFFFF.bin");
2010 #elif defined(IAUDIO_X5) || defined(IAUDIO_M5)
2011 fd = creat("/internal_rom_000000-3FFFFF.bin");
2012 #endif
2013 if(fd >= 0)
2015 write(fd, (void *)0, FLASH_SIZE);
2016 close(fd);
2018 system_memory_guard(oldmode);
2020 #ifdef HAVE_EEPROM
2021 fd = creat("/internal_eeprom.bin");
2022 if (fd >= 0)
2024 int old_irq_level;
2025 char buf[EEPROM_SIZE];
2026 int err;
2028 old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL);
2030 err = eeprom_24cxx_read(0, buf, sizeof buf);
2031 if (err)
2032 gui_syncsplash(HZ*3, "Eeprom read failure (%d)",err);
2033 else
2035 write(fd, buf, sizeof buf);
2038 set_irq_level(old_irq_level);
2040 close(fd);
2042 #endif
2044 return false;
2046 #elif defined(CPU_PP) && !(defined(SANSA_E200) || defined(SANSA_C200))
2047 static bool dbg_save_roms(void)
2049 int fd;
2051 fd = creat("/internal_rom_000000-0FFFFF.bin");
2052 if(fd >= 0)
2054 write(fd, (void *)0x20000000, FLASH_SIZE);
2055 close(fd);
2058 return false;
2060 #endif /* CPU */
2062 #ifndef SIMULATOR
2063 #if CONFIG_TUNER
2064 static int radio_callback(int btn, struct gui_synclist *lists)
2066 (void)lists;
2067 if (btn == ACTION_STD_CANCEL)
2068 return btn;
2069 simplelist_set_line_count(1);
2071 #if (CONFIG_TUNER & LV24020LP)
2072 simplelist_addline(SIMPLELIST_ADD_LINE,
2073 "CTRL_STAT: %02X", lv24020lp_get(LV24020LP_CTRL_STAT) );
2074 simplelist_addline(SIMPLELIST_ADD_LINE,
2075 "RADIO_STAT: %02X", lv24020lp_get(LV24020LP_REG_STAT) );
2076 simplelist_addline(SIMPLELIST_ADD_LINE,
2077 "MSS_FM: %d kHz", lv24020lp_get(LV24020LP_MSS_FM) );
2078 simplelist_addline(SIMPLELIST_ADD_LINE,
2079 "MSS_IF: %d Hz", lv24020lp_get(LV24020LP_MSS_IF) );
2080 simplelist_addline(SIMPLELIST_ADD_LINE,
2081 "MSS_SD: %d Hz", lv24020lp_get(LV24020LP_MSS_SD) );
2082 simplelist_addline(SIMPLELIST_ADD_LINE,
2083 "if_set: %d Hz", lv24020lp_get(LV24020LP_IF_SET) );
2084 simplelist_addline(SIMPLELIST_ADD_LINE,
2085 "sd_set: %d Hz", lv24020lp_get(LV24020LP_SD_SET) );
2086 #endif
2087 #if (CONFIG_TUNER & S1A0903X01)
2088 simplelist_addline(SIMPLELIST_ADD_LINE,
2089 "Samsung regs: %08X", s1a0903x01_get(RADIO_ALL));
2090 /* This one doesn't return dynamic data atm */
2091 #endif
2092 #if (CONFIG_TUNER & TEA5767)
2093 struct tea5767_dbg_info nfo;
2094 tea5767_dbg_info(&nfo);
2095 simplelist_addline(SIMPLELIST_ADD_LINE, "Philips regs:");
2096 simplelist_addline(SIMPLELIST_ADD_LINE,
2097 " Read: %02X %02X %02X %02X %02X",
2098 (unsigned)nfo.read_regs[0], (unsigned)nfo.read_regs[1],
2099 (unsigned)nfo.read_regs[2], (unsigned)nfo.read_regs[3],
2100 (unsigned)nfo.read_regs[4]);
2101 simplelist_addline(SIMPLELIST_ADD_LINE,
2102 " Write: %02X %02X %02X %02X %02X",
2103 (unsigned)nfo.write_regs[0], (unsigned)nfo.write_regs[1],
2104 (unsigned)nfo.write_regs[2], (unsigned)nfo.write_regs[3],
2105 (unsigned)nfo.write_regs[4]);
2106 #endif
2107 return ACTION_REDRAW;
2109 static bool dbg_fm_radio(void)
2111 struct simplelist_info info;
2112 simplelist_info_init(&info, "FM Radio", 1, NULL);
2113 simplelist_set_line_count(0);
2114 simplelist_addline(SIMPLELIST_ADD_LINE, "HW detected: %s",
2115 radio_hardware_present() ? "yes" : "no");
2117 info.action_callback = radio_hardware_present()?radio_callback : NULL;
2118 info.hide_selection = true;
2119 return simplelist_show_list(&info);
2121 #endif /* CONFIG_TUNER */
2122 #endif /* !SIMULATOR */
2124 #ifdef HAVE_LCD_BITMAP
2125 extern bool do_screendump_instead_of_usb;
2127 static bool dbg_screendump(void)
2129 do_screendump_instead_of_usb = !do_screendump_instead_of_usb;
2130 gui_syncsplash(HZ, "Screendump %s",
2131 do_screendump_instead_of_usb?"enabled":"disabled");
2132 return false;
2134 #endif /* HAVE_LCD_BITMAP */
2136 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
2137 static bool dbg_set_memory_guard(void)
2139 static const struct opt_items names[MAXMEMGUARD] = {
2140 { "None", -1 },
2141 { "Flash ROM writes", -1 },
2142 { "Zero area (all)", -1 }
2144 int mode = system_memory_guard(MEMGUARD_KEEP);
2146 set_option( "Catch mem accesses", &mode, INT, names, MAXMEMGUARD, NULL);
2147 system_memory_guard(mode);
2149 return false;
2151 #endif /* CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) */
2153 #if defined(TOSHIBA_GIGABEAT_F) && !defined(SIMULATOR)
2155 extern volatile bool lcd_poweroff;
2157 static bool dbg_lcd_power_off(void)
2159 lcd_setmargins(0, 0);
2161 while(1)
2163 int button;
2165 lcd_clear_display();
2166 lcd_puts(0, 0, "LCD Power Off");
2167 if(lcd_poweroff)
2168 lcd_puts(1, 1, "Yes");
2169 else
2170 lcd_puts(1, 1, "No");
2172 lcd_update();
2174 button = get_action(CONTEXT_STD,HZ/5);
2175 switch(button)
2177 case ACTION_STD_PREV:
2178 case ACTION_STD_NEXT:
2179 lcd_poweroff = !lcd_poweroff;
2180 break;
2181 case ACTION_STD_OK:
2182 case ACTION_STD_CANCEL:
2183 return false;
2184 default:
2185 sleep(HZ/10);
2186 break;
2189 return false;
2191 #endif
2193 #if defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS)
2194 static bool dbg_write_eeprom(void)
2196 int fd;
2197 int rc;
2198 int old_irq_level;
2199 char buf[EEPROM_SIZE];
2200 int err;
2202 fd = open("/internal_eeprom.bin", O_RDONLY);
2204 if (fd >= 0)
2206 rc = read(fd, buf, EEPROM_SIZE);
2208 if(rc == EEPROM_SIZE)
2210 old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL);
2212 err = eeprom_24cxx_write(0, buf, sizeof buf);
2213 if (err)
2214 gui_syncsplash(HZ*3, "Eeprom write failure (%d)",err);
2215 else
2216 gui_syncsplash(HZ*3, "Eeprom written successfully");
2218 set_irq_level(old_irq_level);
2220 else
2222 gui_syncsplash(HZ*3, "File read error (%d)",rc);
2224 close(fd);
2226 else
2228 gui_syncsplash(HZ*3, "Failed to open 'internal_eeprom.bin'");
2231 return false;
2233 #endif /* defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS) */
2234 #ifdef CPU_BOOST_LOGGING
2235 static bool cpu_boost_log(void)
2237 int i = 0,j=0;
2238 int count = cpu_boost_log_getcount();
2239 int lines = LCD_HEIGHT/SYSFONT_HEIGHT;
2240 char *str;
2241 bool done;
2242 lcd_setmargins(0, 0);
2243 lcd_setfont(FONT_SYSFIXED);
2244 str = cpu_boost_log_getlog_first();
2245 while (i < count)
2247 lcd_clear_display();
2248 for(j=0; j<lines; j++,i++)
2250 if (!str)
2251 str = cpu_boost_log_getlog_next();
2252 if (str)
2254 lcd_puts(0, j,str);
2256 str = NULL;
2258 lcd_update();
2259 done = false;
2260 while (!done)
2262 switch(get_action(CONTEXT_STD,TIMEOUT_BLOCK))
2264 case ACTION_STD_OK:
2265 case ACTION_STD_PREV:
2266 case ACTION_STD_NEXT:
2267 done = true;
2268 break;
2269 case ACTION_STD_CANCEL:
2270 i = count;
2271 done = true;
2272 break;
2276 get_action(CONTEXT_STD,TIMEOUT_BLOCK);
2277 lcd_setfont(FONT_UI);
2278 return false;
2280 #endif
2284 /****** The menu *********/
2285 struct the_menu_item {
2286 unsigned char *desc; /* string or ID */
2287 bool (*function) (void); /* return true if USB was connected */
2289 static const struct the_menu_item menuitems[] = {
2290 #if defined(TOSHIBA_GIGABEAT_F) && !defined(SIMULATOR)
2291 { "LCD Power Off", dbg_lcd_power_off },
2292 #endif
2293 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || \
2294 (defined(CPU_PP) && !(defined(SANSA_E200) || defined(SANSA_C200)))
2295 { "Dump ROM contents", dbg_save_roms },
2296 #endif
2297 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || defined(CPU_PP) || CONFIG_CPU == S3C2440
2298 { "View I/O ports", dbg_ports },
2299 #endif
2300 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
2301 { "CPU frequency", dbg_cpufreq },
2302 #endif
2303 #if defined(IRIVER_H100_SERIES) && !defined(SIMULATOR)
2304 { "S/PDIF analyzer", dbg_spdif },
2305 #endif
2306 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
2307 { "Catch mem accesses", dbg_set_memory_guard },
2308 #endif
2309 { "View OS stacks", dbg_os },
2310 #ifdef HAVE_LCD_BITMAP
2311 #ifndef SIMULATOR
2312 { "View battery", view_battery },
2313 #endif
2314 { "Screendump", dbg_screendump },
2315 #endif
2316 #ifndef SIMULATOR
2317 { "View HW info", dbg_hw_info },
2318 #endif
2319 #ifndef SIMULATOR
2320 { "View partitions", dbg_partitions },
2321 #endif
2322 #ifndef SIMULATOR
2323 { "View disk info", dbg_disk_info },
2324 #endif
2325 #ifdef HAVE_DIRCACHE
2326 { "View dircache info", dbg_dircache_info },
2327 #endif
2328 #ifdef HAVE_TAGCACHE
2329 { "View database info", dbg_tagcache_info },
2330 #endif
2331 #ifdef HAVE_LCD_BITMAP
2332 #if CONFIG_CODEC == SWCODEC || !defined(SIMULATOR)
2333 { "View audio thread", dbg_audio_thread },
2334 { "View buffering thread", dbg_buffering_thread },
2335 #endif
2336 #ifdef PM_DEBUG
2337 { "pm histogram", peak_meter_histogram},
2338 #endif /* PM_DEBUG */
2339 #endif /* HAVE_LCD_BITMAP */
2340 #ifndef SIMULATOR
2341 #if CONFIG_TUNER
2342 { "FM Radio", dbg_fm_radio },
2343 #endif
2344 #endif
2345 #if defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS)
2346 { "Write back EEPROM", dbg_write_eeprom },
2347 #endif
2348 #ifdef ROCKBOX_HAS_LOGF
2349 {"logf", logfdisplay },
2350 {"logfdump", logfdump },
2351 #endif
2352 #ifdef CPU_BOOST_LOGGING
2353 {"cpu_boost log",cpu_boost_log},
2354 #endif
2356 static int menu_action_callback(int btn, struct gui_synclist *lists)
2358 if (btn == ACTION_STD_OK)
2360 menuitems[gui_synclist_get_sel_pos(lists)].function();
2361 btn = ACTION_REDRAW;
2363 return btn;
2365 static char* dbg_menu_getname(int item, void * data, char *buffer)
2367 (void)data; (void)buffer;
2368 return menuitems[item].desc;
2370 bool debug_menu(void)
2372 struct simplelist_info info;
2374 simplelist_info_init(&info, "Debug Menu", ARRAYLEN(menuitems), NULL);
2375 info.action_callback = menu_action_callback;
2376 info.get_name = dbg_menu_getname;
2378 return simplelist_show_list(&info);