only build the clipcounter for targets with recording
[maemo-rb.git] / apps / debug_menu.c
blob41507708d4f0996064509954ce459bb2890904aa
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 "pcm_playback.h"
79 #if defined(HAVE_SPDIF_OUT) || defined(HAVE_SPDIF_IN)
80 #include "spdif.h"
81 #endif
82 #endif
83 #ifdef IRIVER_H300_SERIES
84 #include "pcf50606.h" /* for pcf50606_read */
85 #endif
86 #ifdef IAUDIO_X5
87 #include "ds2411.h"
88 #endif
89 #include "hwcompat.h"
91 #if defined(HAVE_DIRCACHE) || defined(HAVE_TAGCACHE) || CONFIG_TUNER
92 #define MAX_DEBUG_MESSAGES 16
93 #define DEBUG_MSG_LEN 32
94 int debug_listmessage_lines;
95 char debug_list_messages[MAX_DEBUG_MESSAGES][DEBUG_MSG_LEN];
96 static void dbg_listmessage_setlines(int lines)
98 if (lines < 0)
99 lines = 0;
100 else if (lines > MAX_DEBUG_MESSAGES)
101 lines = MAX_DEBUG_MESSAGES;
102 debug_listmessage_lines = lines;
104 #ifndef SIMULATOR
105 static int dbg_listmessage_getlines(void)
107 return debug_listmessage_lines;
109 #endif
110 static void dbg_listmessage_addline(const char *fmt, ...)
112 va_list ap;
114 if (debug_listmessage_lines >= MAX_DEBUG_MESSAGES)
115 return;
117 va_start(ap, fmt);
118 vsnprintf(debug_list_messages[debug_listmessage_lines++], DEBUG_MSG_LEN, fmt, ap);
119 va_end(ap);
121 static char* dbg_listmessage_getname(int item, void * data, char *buffer)
123 (void)buffer; (void)data;
124 return debug_list_messages[item];
126 #endif
128 struct action_callback_info;
129 struct action_callback_info
131 char *title;
132 int count;
133 int selection_size;
134 int (*action_callback)(int btn, struct action_callback_info *info);
135 char* (*dbg_getname)(int item, void * data, char *buffer);
136 intptr_t cbdata; /* extra callback data (pointer, int, whatever) */
137 struct gui_synclist *lists; /* passed back to the callback */
140 static char* dbg_menu_getname(int item, void * data, char *buffer);
141 static bool dbg_list(struct action_callback_info *info)
143 struct gui_synclist lists;
144 int action;
146 info->lists = &lists;
148 gui_synclist_init(&lists, info->dbg_getname, NULL, false,
149 info->selection_size);
150 gui_synclist_set_title(&lists, info->title, NOICON);
151 gui_synclist_set_icon_callback(&lists, NULL);
152 gui_synclist_set_nb_items(&lists, info->count*info->selection_size);
153 if (info->dbg_getname != dbg_menu_getname)
154 gui_synclist_hide_selection_marker(&lists, true);
156 if (info->action_callback)
157 info->action_callback(ACTION_REDRAW, info);
159 gui_synclist_draw(&lists);
161 while(1)
163 gui_syncstatusbar_draw(&statusbars, true);
164 action = get_action(CONTEXT_STD, HZ/5);
165 if (gui_synclist_do_button(&lists, action, LIST_WRAP_UNLESS_HELD))
166 continue;
167 if (info->action_callback)
168 action = info->action_callback(action, info);
169 if (action == ACTION_STD_CANCEL)
170 break;
171 else if (action == ACTION_REDRAW)
172 gui_synclist_draw(&lists);
173 else if(default_event_handler(action) == SYS_USB_CONNECTED)
174 return true;
176 return false;
178 /*---------------------------------------------------*/
179 /* SPECIAL DEBUG STUFF */
180 /*---------------------------------------------------*/
181 extern struct thread_entry threads[MAXTHREADS];
184 #ifndef SIMULATOR
185 static char thread_status_char(int status)
187 switch (status)
189 case STATE_RUNNING : return 'R';
190 case STATE_BLOCKED : return 'B';
191 case STATE_SLEEPING : return 'S';
192 case STATE_BLOCKED_W_TMO: return 'T';
195 return '?';
197 #if NUM_CORES > 1
198 #define IF_COP2(...) __VA_ARGS__
199 #else
200 #define IF_COP2(...)
201 #endif
202 static char* threads_getname(int selected_item, void * data, char *buffer)
204 (void)data;
205 struct thread_entry *thread = NULL;
206 int status, usage;
207 thread = &threads[selected_item];
209 if (thread->name == NULL)
211 snprintf(buffer, MAX_PATH, "%2d: ---", selected_item);
212 return buffer;
215 usage = thread_stack_usage(thread);
216 status = thread_get_status(thread);
217 #ifdef HAVE_PRIORITY_SCHEDULING
218 snprintf(buffer, MAX_PATH, "%2d: " IF_COP2("(%d) ") "%c%c %d %2d%% %s",
219 selected_item,
220 IF_COP2(thread->core,)
221 (status == STATE_RUNNING) ? '*' : ' ',
222 thread_status_char(status),
223 thread->priority,
224 usage, thread->name);
225 #else
226 snprintf(buffer, MAX_PATH, "%2d: " IF_COP2("(%d) ") "%c%c %2d%% %s",
227 selected_item,
228 IF_COP2(thread->core,)
229 (status == STATE_RUNNING) ? '*' : ' ',
230 thread_status_char(status),
231 usage, thread->name);
232 #endif
233 return buffer;
235 static int dbg_threads_action_callback(int action, struct action_callback_info *info)
237 #ifdef ROCKBOX_HAS_LOGF
238 if (action == ACTION_STD_OK)
240 struct thread_entry *thread = &threads[gui_synclist_get_sel_pos(info->lists)];
241 if (thread->name != NULL)
242 remove_thread(thread);
244 #endif
245 gui_synclist_draw(info->lists);
246 return action;
248 /* Test code!!! */
249 static bool dbg_os(void)
251 struct action_callback_info info;
252 info.title = IF_COP2("Core and ") "Stack usage:";
253 info.count = MAXTHREADS;
254 info.selection_size = 1;
255 info.action_callback = dbg_threads_action_callback;
256 info.dbg_getname = threads_getname;
257 return dbg_list(&info);
259 #endif /* !SIMULATOR */
261 #ifdef HAVE_LCD_BITMAP
262 #if CONFIG_CODEC != SWCODEC
263 #ifndef SIMULATOR
264 static bool dbg_audio_thread(void)
266 char buf[32];
267 struct audio_debug d;
269 lcd_setmargins(0, 0);
270 lcd_setfont(FONT_SYSFIXED);
272 while(1)
274 if (action_userabort(HZ/5))
275 return false;
277 audio_get_debugdata(&d);
279 lcd_clear_display();
281 snprintf(buf, sizeof(buf), "read: %x", d.audiobuf_read);
282 lcd_puts(0, 0, buf);
283 snprintf(buf, sizeof(buf), "write: %x", d.audiobuf_write);
284 lcd_puts(0, 1, buf);
285 snprintf(buf, sizeof(buf), "swap: %x", d.audiobuf_swapwrite);
286 lcd_puts(0, 2, buf);
287 snprintf(buf, sizeof(buf), "playing: %d", d.playing);
288 lcd_puts(0, 3, buf);
289 snprintf(buf, sizeof(buf), "playable: %x", d.playable_space);
290 lcd_puts(0, 4, buf);
291 snprintf(buf, sizeof(buf), "unswapped: %x", d.unswapped_space);
292 lcd_puts(0, 5, buf);
294 /* Playable space left */
295 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, 6*8, 112, 4, d.audiobuflen, 0,
296 d.playable_space, HORIZONTAL);
298 /* Show the watermark limit */
299 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, 6*8+4, 112, 4, d.audiobuflen, 0,
300 d.low_watermark_level, HORIZONTAL);
302 snprintf(buf, sizeof(buf), "wm: %x - %x",
303 d.low_watermark_level, d.lowest_watermark_level);
304 lcd_puts(0, 7, buf);
306 lcd_update();
308 return false;
310 #endif /* !SIMULATOR */
311 #else /* CONFIG_CODEC == SWCODEC */
312 extern size_t filebuflen;
313 /* This is a size_t, but call it a long so it puts a - when it's bad. */
315 static unsigned int ticks, boost_ticks;
317 static void dbg_audio_task(void)
319 #ifndef SIMULATOR
320 if(FREQ > CPUFREQ_NORMAL)
321 boost_ticks++;
322 #endif
324 ticks++;
327 static bool dbg_audio_thread(void)
329 char buf[32];
330 int button;
331 int line;
332 bool done = false;
333 size_t bufused;
334 size_t bufsize = pcmbuf_get_bufsize();
335 int pcmbufdescs = pcmbuf_descs();
337 ticks = boost_ticks = 0;
339 tick_add_task(dbg_audio_task);
341 lcd_setmargins(0, 0);
342 lcd_setfont(FONT_SYSFIXED);
343 while(!done)
345 button = get_action(CONTEXT_STD,HZ/5);
346 switch(button)
348 case ACTION_STD_NEXT:
349 audio_next();
350 break;
351 case ACTION_STD_PREV:
352 audio_prev();
353 break;
354 case ACTION_STD_CANCEL:
355 done = true;
356 break;
358 line = 0;
359 lcd_clear_display();
361 bufused = bufsize - pcmbuf_free();
363 snprintf(buf, sizeof(buf), "pcm: %7ld/%7ld", (long) bufused, (long) bufsize);
364 lcd_puts(0, line++, buf);
366 /* Playable space left */
367 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6, bufsize, 0, bufused, HORIZONTAL);
368 line++;
370 snprintf(buf, sizeof(buf), "codec: %8ld/%8ld", audio_filebufused(), (long) filebuflen);
371 lcd_puts(0, line++, buf);
373 /* Playable space left */
374 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6, filebuflen, 0,
375 audio_filebufused(), HORIZONTAL);
376 line++;
378 snprintf(buf, sizeof(buf), "track count: %2d", audio_track_count());
379 lcd_puts(0, line++, buf);
381 #ifndef SIMULATOR
382 snprintf(buf, sizeof(buf), "cpu freq: %3dMHz",
383 (int)((FREQ + 500000) / 1000000));
384 lcd_puts(0, line++, buf);
385 #endif
387 if (ticks > 0)
389 snprintf(buf, sizeof(buf), "boost ratio: %3d%%",
390 boost_ticks * 100 / ticks);
391 lcd_puts(0, line++, buf);
394 snprintf(buf, sizeof(buf), "pcmbufdesc: %2d/%2d",
395 pcmbuf_used_descs(), pcmbufdescs);
396 lcd_puts(0, line++, buf);
398 lcd_update();
401 tick_remove_task(dbg_audio_task);
403 return false;
405 #endif /* CONFIG_CODEC */
406 #endif /* HAVE_LCD_BITMAP */
409 #if (CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE))
410 /* Tool function to read the flash manufacturer and type, if available.
411 Only chips which could be reprogrammed in system will return values.
412 (The mode switch addresses vary between flash manufacturers, hence addr1/2) */
413 /* In IRAM to avoid problems when running directly from Flash */
414 static bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
415 unsigned addr1, unsigned addr2)
416 ICODE_ATTR __attribute__((noinline));
417 static bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
418 unsigned addr1, unsigned addr2)
421 unsigned not_manu, not_id; /* read values before switching to ID mode */
422 unsigned manu, id; /* read values when in ID mode */
424 #if CONFIG_CPU == SH7034
425 volatile unsigned char* flash = (unsigned char*)0x2000000; /* flash mapping */
426 #elif defined(CPU_COLDFIRE)
427 volatile unsigned short* flash = (unsigned short*)0; /* flash mapping */
428 #endif
429 int old_level; /* saved interrupt level */
431 not_manu = flash[0]; /* read the normal content */
432 not_id = flash[1]; /* should be 'A' (0x41) and 'R' (0x52) from the "ARCH" marker */
434 /* disable interrupts, prevent any stray flash access */
435 old_level = set_irq_level(HIGHEST_IRQ_LEVEL);
437 flash[addr1] = 0xAA; /* enter command mode */
438 flash[addr2] = 0x55;
439 flash[addr1] = 0x90; /* ID command */
440 /* Atmel wants 20ms pause here */
441 /* sleep(HZ/50); no sleeping possible while interrupts are disabled */
443 manu = flash[0]; /* read the IDs */
444 id = flash[1];
446 flash[0] = 0xF0; /* reset flash (back to normal read mode) */
447 /* Atmel wants 20ms pause here */
448 /* sleep(HZ/50); no sleeping possible while interrupts are disabled */
450 set_irq_level(old_level); /* enable interrupts again */
452 /* I assume success if the obtained values are different from
453 the normal flash content. This is not perfectly bulletproof, they
454 could theoretically be the same by chance, causing us to fail. */
455 if (not_manu != manu || not_id != id) /* a value has changed */
457 *p_manufacturer = manu; /* return the results */
458 *p_device = id;
459 return true; /* success */
461 return false; /* fail */
463 #endif /* (CONFIG_CPU == SH7034 || CPU_COLDFIRE) */
465 #ifndef SIMULATOR
466 #ifdef CPU_PP
467 static int perfcheck(void)
469 int result;
471 asm (
472 "mrs r2, CPSR \n"
473 "orr r0, r2, #0xc0 \n" /* disable IRQ and FIQ */
474 "msr CPSR_c, r0 \n"
475 "mov %[res], #0 \n"
476 "ldr r0, [%[timr]] \n"
477 "add r0, r0, %[tmo] \n"
478 "1: \n"
479 "add %[res], %[res], #1 \n"
480 "ldr r1, [%[timr]] \n"
481 "cmp r1, r0 \n"
482 "bmi 1b \n"
483 "msr CPSR_c, r2 \n" /* reset IRQ and FIQ state */
485 [res]"=&r"(result)
487 [timr]"r"(&USEC_TIMER),
488 [tmo]"r"(
489 #if CONFIG_CPU == PP5002
490 16000
491 #else /* PP5020/5022/5024 */
492 10226
493 #endif
496 "r0", "r1", "r2"
498 return result;
500 #endif
502 #ifdef HAVE_LCD_BITMAP
503 static bool dbg_hw_info(void)
505 #if CONFIG_CPU == SH7034
506 char buf[32];
507 int bitmask = HW_MASK;
508 int rom_version = ROM_VERSION;
509 unsigned manu, id; /* flash IDs */
510 bool got_id; /* flag if we managed to get the flash IDs */
511 unsigned rom_crc = 0xffffffff; /* CRC32 of the boot ROM */
512 bool has_bootrom; /* flag for boot ROM present */
513 int oldmode; /* saved memory guard mode */
515 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
517 /* get flash ROM type */
518 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
519 if (!got_id)
520 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
522 /* check if the boot ROM area is a flash mirror */
523 has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0);
524 if (has_bootrom) /* if ROM and Flash different */
526 /* calculate CRC16 checksum of boot ROM */
527 rom_crc = crc_32((unsigned char*)0x0000, 64*1024, 0xffffffff);
530 system_memory_guard(oldmode); /* re-enable memory guard */
532 lcd_setmargins(0, 0);
533 lcd_setfont(FONT_SYSFIXED);
534 lcd_clear_display();
536 lcd_puts(0, 0, "[Hardware info]");
538 snprintf(buf, 32, "ROM: %d.%02d", rom_version/100, rom_version%100);
539 lcd_puts(0, 1, buf);
541 snprintf(buf, 32, "Mask: 0x%04x", bitmask);
542 lcd_puts(0, 2, buf);
544 if (got_id)
545 snprintf(buf, 32, "Flash: M=%02x D=%02x", manu, id);
546 else
547 snprintf(buf, 32, "Flash: M=?? D=??"); /* unknown, sorry */
548 lcd_puts(0, 3, buf);
550 if (has_bootrom)
552 if (rom_crc == 0x56DBA4EE) /* known Version 1 */
553 snprintf(buf, 32, "Boot ROM: V1");
554 else
555 snprintf(buf, 32, "ROMcrc: 0x%08x", rom_crc);
557 else
559 snprintf(buf, 32, "Boot ROM: none");
561 lcd_puts(0, 4, buf);
563 lcd_update();
565 while (!(action_userabort(TIMEOUT_BLOCK)));
567 #elif CONFIG_CPU == MCF5249 || CONFIG_CPU == MCF5250
568 char buf[32];
569 unsigned manu, id; /* flash IDs */
570 int got_id; /* flag if we managed to get the flash IDs */
571 int oldmode; /* saved memory guard mode */
572 int line = 0;
574 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
576 /* get flash ROM type */
577 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
578 if (!got_id)
579 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
581 system_memory_guard(oldmode); /* re-enable memory guard */
583 lcd_setmargins(0, 0);
584 lcd_setfont(FONT_SYSFIXED);
585 lcd_clear_display();
587 lcd_puts(0, line++, "[Hardware info]");
589 if (got_id)
590 snprintf(buf, 32, "Flash: M=%04x D=%04x", manu, id);
591 else
592 snprintf(buf, 32, "Flash: M=???? D=????"); /* unknown, sorry */
593 lcd_puts(0, line++, buf);
595 #ifdef IAUDIO_X5
597 struct ds2411_id id;
599 lcd_puts(0, ++line, "Serial Number:");
601 got_id = ds2411_read_id(&id);
603 if (got_id == DS2411_OK)
605 snprintf(buf, 32, " FC=%02x", (unsigned)id.family_code);
606 lcd_puts(0, ++line, buf);
607 snprintf(buf, 32, " ID=%02X %02X %02X %02X %02X %02X",
608 (unsigned)id.uid[0], (unsigned)id.uid[1], (unsigned)id.uid[2],
609 (unsigned)id.uid[3], (unsigned)id.uid[4], (unsigned)id.uid[5]);
610 lcd_puts(0, ++line, buf);
611 snprintf(buf, 32, " CRC=%02X", (unsigned)id.crc);
613 else
615 snprintf(buf, 32, "READ ERR=%d", got_id);
618 lcd_puts(0, ++line, buf);
620 #endif
622 lcd_update();
624 while (!(action_userabort(TIMEOUT_BLOCK)));
626 #elif defined(CPU_PP502x)
627 int line = 0;
628 char buf[32];
629 char pp_version[] = { (PP_VER2 >> 24) & 0xff, (PP_VER2 >> 16) & 0xff,
630 (PP_VER2 >> 8) & 0xff, (PP_VER2) & 0xff,
631 (PP_VER1 >> 24) & 0xff, (PP_VER1 >> 16) & 0xff,
632 (PP_VER1 >> 8) & 0xff, (PP_VER1) & 0xff, '\0' };
634 lcd_setmargins(0, 0);
635 lcd_setfont(FONT_SYSFIXED);
636 lcd_clear_display();
638 lcd_puts(0, line++, "[Hardware info]");
640 #ifdef IPOD_ARCH
641 snprintf(buf, sizeof(buf), "HW rev: 0x%08lx", IPOD_HW_REVISION);
642 lcd_puts(0, line++, buf);
643 #endif
645 #ifdef IPOD_COLOR
646 extern int lcd_type; /* Defined in lcd-colornano.c */
648 snprintf(buf, sizeof(buf), "LCD type: %d", lcd_type);
649 lcd_puts(0, line++, buf);
650 #endif
652 snprintf(buf, sizeof(buf), "PP version: %s", pp_version);
653 lcd_puts(0, line++, buf);
655 snprintf(buf, sizeof(buf), "Est. clock (kHz): %d", perfcheck());
656 lcd_puts(0, line++, buf);
658 lcd_update();
660 while (!(action_userabort(TIMEOUT_BLOCK)));
662 #elif CONFIG_CPU == PP5002
663 int line = 0;
664 char buf[32];
666 lcd_setmargins(0, 0);
667 lcd_setfont(FONT_SYSFIXED);
668 lcd_clear_display();
670 lcd_puts(0, line++, "[Hardware info]");
672 #ifdef IPOD_ARCH
673 snprintf(buf, sizeof(buf), "HW rev: 0x%08lx", IPOD_HW_REVISION);
674 lcd_puts(0, line++, buf);
675 #endif
677 snprintf(buf, sizeof(buf), "Est. clock (kHz): %d", perfcheck());
678 lcd_puts(0, line++, buf);
680 lcd_update();
682 while (!(action_userabort(TIMEOUT_BLOCK)));
684 #endif /* CONFIG_CPU */
685 return false;
687 #else /* !HAVE_LCD_BITMAP */
688 static bool dbg_hw_info(void)
690 char buf[32];
691 int button;
692 int currval = 0;
693 int rom_version = ROM_VERSION;
694 unsigned manu, id; /* flash IDs */
695 bool got_id; /* flag if we managed to get the flash IDs */
696 unsigned rom_crc = 0xffffffff; /* CRC32 of the boot ROM */
697 bool has_bootrom; /* flag for boot ROM present */
698 int oldmode; /* saved memory guard mode */
700 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
702 /* get flash ROM type */
703 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
704 if (!got_id)
705 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
707 /* check if the boot ROM area is a flash mirror */
708 has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0);
709 if (has_bootrom) /* if ROM and Flash different */
711 /* calculate CRC16 checksum of boot ROM */
712 rom_crc = crc_32((unsigned char*)0x0000, 64*1024, 0xffffffff);
715 system_memory_guard(oldmode); /* re-enable memory guard */
717 lcd_clear_display();
719 lcd_puts(0, 0, "[HW Info]");
720 while(1)
722 switch(currval)
724 case 0:
725 snprintf(buf, 32, "ROM: %d.%02d",
726 rom_version/100, rom_version%100);
727 break;
728 case 1:
729 if (got_id)
730 snprintf(buf, 32, "Flash:%02x,%02x", manu, id);
731 else
732 snprintf(buf, 32, "Flash:??,??"); /* unknown, sorry */
733 break;
734 case 2:
735 if (has_bootrom)
737 if (rom_crc == 0x56DBA4EE) /* known Version 1 */
738 snprintf(buf, 32, "BootROM: V1");
739 else if (rom_crc == 0x358099E8)
740 snprintf(buf, 32, "BootROM: V2");
741 /* alternative boot ROM found in one single player so far */
742 else
743 snprintf(buf, 32, "R: %08x", rom_crc);
745 else
746 snprintf(buf, 32, "BootROM: no");
749 lcd_puts(0, 1, buf);
750 lcd_update();
752 button = get_action(CONTEXT_SETTINGS,TIMEOUT_BLOCK);
754 switch(button)
756 case ACTION_STD_CANCEL:
757 return false;
759 case ACTION_SETTINGS_DEC:
760 currval--;
761 if(currval < 0)
762 currval = 2;
763 break;
765 case ACTION_SETTINGS_INC:
766 currval++;
767 if(currval > 2)
768 currval = 0;
769 break;
772 return false;
774 #endif /* !HAVE_LCD_BITMAP */
775 #endif /* !SIMULATOR */
777 #ifndef SIMULATOR
778 static char* dbg_partitions_getname(int selected_item, void * data, char *buffer)
780 (void)data;
781 int partition = selected_item/2;
782 struct partinfo* p = disk_partinfo(partition);
783 if (selected_item%2)
785 snprintf(buffer, MAX_PATH, " T:%x %ld MB", p->type, p->size / 2048);
787 else
789 snprintf(buffer, MAX_PATH, "P%d: S:%lx", partition, p->start);
791 return buffer;
794 bool dbg_partitions(void)
796 struct action_callback_info info;
797 info.title = "Partition Info";
798 info.count = 4;
799 info.selection_size = 2;
800 info.action_callback = NULL;
801 info.dbg_getname = dbg_partitions_getname;
802 dbg_list(&info);
803 return false;
805 #endif
807 #if defined(CPU_COLDFIRE) && defined(HAVE_SPDIF_OUT)
808 static bool dbg_spdif(void)
810 char buf[128];
811 int line;
812 unsigned int control;
813 int x;
814 char *s;
815 int category;
816 int generation;
817 unsigned int interruptstat;
818 bool valnogood, symbolerr, parityerr;
819 bool done = false;
820 bool spdif_src_on;
821 int spdif_source = spdif_get_output_source(&spdif_src_on);
822 spdif_set_output_source(AUDIO_SRC_SPDIF IF_SPDIF_POWER_(, true));
824 lcd_setmargins(0, 0);
825 lcd_clear_display();
826 lcd_setfont(FONT_SYSFIXED);
828 #ifdef HAVE_SPDIF_POWER
829 spdif_power_enable(true); /* We need SPDIF power for both sending & receiving */
830 #endif
832 while (!done)
834 line = 0;
836 control = EBU1RCVCCHANNEL1;
837 interruptstat = INTERRUPTSTAT;
838 INTERRUPTCLEAR = 0x03c00000;
840 valnogood = (interruptstat & 0x01000000)?true:false;
841 symbolerr = (interruptstat & 0x00800000)?true:false;
842 parityerr = (interruptstat & 0x00400000)?true:false;
844 snprintf(buf, sizeof(buf), "Val: %s Sym: %s Par: %s",
845 valnogood?"--":"OK",
846 symbolerr?"--":"OK",
847 parityerr?"--":"OK");
848 lcd_puts(0, line++, buf);
850 snprintf(buf, sizeof(buf), "Status word: %08x", (int)control);
851 lcd_puts(0, line++, buf);
853 line++;
855 x = control >> 31;
856 snprintf(buf, sizeof(buf), "PRO: %d (%s)",
857 x, x?"Professional":"Consumer");
858 lcd_puts(0, line++, buf);
860 x = (control >> 30) & 1;
861 snprintf(buf, sizeof(buf), "Audio: %d (%s)",
862 x, x?"Non-PCM":"PCM");
863 lcd_puts(0, line++, buf);
865 x = (control >> 29) & 1;
866 snprintf(buf, sizeof(buf), "Copy: %d (%s)",
867 x, x?"Permitted":"Inhibited");
868 lcd_puts(0, line++, buf);
870 x = (control >> 27) & 7;
871 switch(x)
873 case 0:
874 s = "None";
875 break;
876 case 1:
877 s = "50/15us";
878 break;
879 default:
880 s = "Reserved";
881 break;
883 snprintf(buf, sizeof(buf), "Preemphasis: %d (%s)", x, s);
884 lcd_puts(0, line++, buf);
886 x = (control >> 24) & 3;
887 snprintf(buf, sizeof(buf), "Mode: %d", x);
888 lcd_puts(0, line++, buf);
890 category = (control >> 17) & 127;
891 switch(category)
893 case 0x00:
894 s = "General";
895 break;
896 case 0x40:
897 s = "Audio CD";
898 break;
899 default:
900 s = "Unknown";
902 snprintf(buf, sizeof(buf), "Category: 0x%02x (%s)", category, s);
903 lcd_puts(0, line++, buf);
905 x = (control >> 16) & 1;
906 generation = x;
907 if(((category & 0x70) == 0x10) ||
908 ((category & 0x70) == 0x40) ||
909 ((category & 0x78) == 0x38))
911 generation = !generation;
913 snprintf(buf, sizeof(buf), "Generation: %d (%s)",
914 x, generation?"Original":"No ind.");
915 lcd_puts(0, line++, buf);
917 x = (control >> 12) & 15;
918 snprintf(buf, sizeof(buf), "Source: %d", x);
919 lcd_puts(0, line++, buf);
921 x = (control >> 8) & 15;
922 switch(x)
924 case 0:
925 s = "Unspecified";
926 break;
927 case 8:
928 s = "A (Left)";
929 break;
930 case 4:
931 s = "B (Right)";
932 break;
933 default:
934 s = "";
935 break;
937 snprintf(buf, sizeof(buf), "Channel: %d (%s)", x, s);
938 lcd_puts(0, line++, buf);
940 x = (control >> 4) & 15;
941 switch(x)
943 case 0:
944 s = "44.1kHz";
945 break;
946 case 0x4:
947 s = "48kHz";
948 break;
949 case 0xc:
950 s = "32kHz";
951 break;
953 snprintf(buf, sizeof(buf), "Frequency: %d (%s)", x, s);
954 lcd_puts(0, line++, buf);
956 x = (control >> 2) & 3;
957 snprintf(buf, sizeof(buf), "Clock accuracy: %d", x);
958 lcd_puts(0, line++, buf);
959 line++;
961 #ifndef SIMULATOR
962 snprintf(buf, sizeof(buf), "Measured freq: %ldHz",
963 spdif_measure_frequency());
964 lcd_puts(0, line++, buf);
965 #endif
967 lcd_update();
969 if (action_userabort(HZ/10))
970 break;
973 spdif_set_output_source(spdif_source IF_SPDIF_POWER_(, spdif_src_on));
975 #ifdef HAVE_SPDIF_POWER
976 spdif_power_enable(global_settings.spdif_enable);
977 #endif
979 return false;
981 #endif /* CPU_COLDFIRE */
983 #ifndef SIMULATOR
984 #ifdef HAVE_LCD_BITMAP
985 /* button definitions */
986 #if (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
987 (CONFIG_KEYPAD == IRIVER_H300_PAD)
988 # define DEBUG_CANCEL BUTTON_OFF
990 #elif CONFIG_KEYPAD == RECORDER_PAD
991 # define DEBUG_CANCEL BUTTON_OFF
993 #elif CONFIG_KEYPAD == ONDIO_PAD
994 # define DEBUG_CANCEL BUTTON_MENU
996 #elif (CONFIG_KEYPAD == IPOD_1G2G_PAD) || \
997 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
998 (CONFIG_KEYPAD == IPOD_4G_PAD)
999 # define DEBUG_CANCEL BUTTON_MENU
1001 #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
1002 # define DEBUG_CANCEL BUTTON_PLAY
1004 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
1005 # define DEBUG_CANCEL BUTTON_REC
1007 #elif CONFIG_KEYPAD == GIGABEAT_PAD
1008 # define DEBUG_CANCEL BUTTON_A
1010 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
1011 # define DEBUG_CANCEL BUTTON_REW
1013 #elif CONFIG_KEYPAD == SANSA_E200_PAD
1014 # define DEBUG_CANCEL BUTTON_LEFT
1015 #endif /* key definitios */
1017 /* Test code!!! */
1018 bool dbg_ports(void)
1020 #if CONFIG_CPU == SH7034
1021 unsigned short porta;
1022 unsigned short portb;
1023 unsigned char portc;
1024 char buf[32];
1025 int adc_battery_voltage, adc_battery_level;
1027 lcd_setfont(FONT_SYSFIXED);
1028 lcd_setmargins(0, 0);
1029 lcd_clear_display();
1031 while(1)
1033 porta = PADR;
1034 portb = PBDR;
1035 portc = PCDR;
1037 snprintf(buf, 32, "PADR: %04x", porta);
1038 lcd_puts(0, 0, buf);
1039 snprintf(buf, 32, "PBDR: %04x", portb);
1040 lcd_puts(0, 1, buf);
1042 snprintf(buf, 32, "AN0: %03x AN4: %03x", adc_read(0), adc_read(4));
1043 lcd_puts(0, 2, buf);
1044 snprintf(buf, 32, "AN1: %03x AN5: %03x", adc_read(1), adc_read(5));
1045 lcd_puts(0, 3, buf);
1046 snprintf(buf, 32, "AN2: %03x AN6: %03x", adc_read(2), adc_read(6));
1047 lcd_puts(0, 4, buf);
1048 snprintf(buf, 32, "AN3: %03x AN7: %03x", adc_read(3), adc_read(7));
1049 lcd_puts(0, 5, buf);
1051 battery_read_info(&adc_battery_voltage, &adc_battery_level);
1052 snprintf(buf, 32, "Batt: %d.%03dV %d%% ", adc_battery_voltage / 1000,
1053 adc_battery_voltage % 1000, adc_battery_level);
1054 lcd_puts(0, 6, buf);
1056 lcd_update();
1057 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1058 return false;
1060 #elif defined(CPU_COLDFIRE)
1061 unsigned int gpio_out;
1062 unsigned int gpio1_out;
1063 unsigned int gpio_read;
1064 unsigned int gpio1_read;
1065 unsigned int gpio_function;
1066 unsigned int gpio1_function;
1067 unsigned int gpio_enable;
1068 unsigned int gpio1_enable;
1069 int adc_buttons, adc_remote;
1070 int adc_battery_voltage, adc_battery_level;
1071 char buf[128];
1072 int line;
1074 lcd_setmargins(0, 0);
1075 lcd_clear_display();
1076 lcd_setfont(FONT_SYSFIXED);
1078 while(1)
1080 line = 0;
1081 gpio_read = GPIO_READ;
1082 gpio1_read = GPIO1_READ;
1083 gpio_out = GPIO_OUT;
1084 gpio1_out = GPIO1_OUT;
1085 gpio_function = GPIO_FUNCTION;
1086 gpio1_function = GPIO1_FUNCTION;
1087 gpio_enable = GPIO_ENABLE;
1088 gpio1_enable = GPIO1_ENABLE;
1090 snprintf(buf, sizeof(buf), "GPIO_READ: %08x", gpio_read);
1091 lcd_puts(0, line++, buf);
1092 snprintf(buf, sizeof(buf), "GPIO_OUT: %08x", gpio_out);
1093 lcd_puts(0, line++, buf);
1094 snprintf(buf, sizeof(buf), "GPIO_FUNCTION: %08x", gpio_function);
1095 lcd_puts(0, line++, buf);
1096 snprintf(buf, sizeof(buf), "GPIO_ENABLE: %08x", gpio_enable);
1097 lcd_puts(0, line++, buf);
1099 snprintf(buf, sizeof(buf), "GPIO1_READ: %08x", gpio1_read);
1100 lcd_puts(0, line++, buf);
1101 snprintf(buf, sizeof(buf), "GPIO1_OUT: %08x", gpio1_out);
1102 lcd_puts(0, line++, buf);
1103 snprintf(buf, sizeof(buf), "GPIO1_FUNCTION: %08x", gpio1_function);
1104 lcd_puts(0, line++, buf);
1105 snprintf(buf, sizeof(buf), "GPIO1_ENABLE: %08x", gpio1_enable);
1106 lcd_puts(0, line++, buf);
1108 adc_buttons = adc_read(ADC_BUTTONS);
1109 adc_remote = adc_read(ADC_REMOTE);
1110 battery_read_info(&adc_battery_voltage, &adc_battery_level);
1111 #if defined(IAUDIO_X5) || defined(IAUDIO_M5) || defined(IRIVER_H300_SERIES)
1112 snprintf(buf, sizeof(buf), "ADC_BUTTONS (%c): %02x",
1113 button_scan_enabled() ? '+' : '-', adc_buttons);
1114 #else
1115 snprintf(buf, sizeof(buf), "ADC_BUTTONS: %02x", adc_buttons);
1116 #endif
1117 lcd_puts(0, line++, buf);
1118 #if defined(IAUDIO_X5) || defined(IAUDIO_M5)
1119 snprintf(buf, sizeof(buf), "ADC_REMOTE (%c): %02x",
1120 remote_detect() ? '+' : '-', adc_remote);
1121 #else
1122 snprintf(buf, sizeof(buf), "ADC_REMOTE: %02x", adc_remote);
1123 #endif
1124 lcd_puts(0, line++, buf);
1125 #if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES)
1126 snprintf(buf, sizeof(buf), "ADC_REMOTEDETECT: %02x",
1127 adc_read(ADC_REMOTEDETECT));
1128 lcd_puts(0, line++, buf);
1129 #endif
1131 snprintf(buf, 32, "Batt: %d.%03dV %d%% ", adc_battery_voltage / 1000,
1132 adc_battery_voltage % 1000, adc_battery_level);
1133 lcd_puts(0, line++, buf);
1135 #if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES)
1136 snprintf(buf, sizeof(buf), "remotetype: %d", remote_type());
1137 lcd_puts(0, line++, buf);
1138 #endif
1140 lcd_update();
1141 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1142 return false;
1145 #elif defined(CPU_PP502x)
1147 unsigned int gpio_a, gpio_b, gpio_c, gpio_d;
1148 unsigned int gpio_e, gpio_f, gpio_g, gpio_h;
1149 unsigned int gpio_i, gpio_j, gpio_k, gpio_l;
1151 char buf[128];
1152 int line;
1154 lcd_setmargins(0, 0);
1155 lcd_clear_display();
1156 lcd_setfont(FONT_SYSFIXED);
1158 while(1)
1160 gpio_a = GPIOA_INPUT_VAL;
1161 gpio_b = GPIOB_INPUT_VAL;
1162 gpio_c = GPIOC_INPUT_VAL;
1164 gpio_g = GPIOG_INPUT_VAL;
1165 gpio_h = GPIOH_INPUT_VAL;
1166 gpio_i = GPIOI_INPUT_VAL;
1168 line = 0;
1169 snprintf(buf, sizeof(buf), "GPIO_A: %02x GPIO_G: %02x", gpio_a, gpio_g);
1170 lcd_puts(0, line++, buf);
1171 snprintf(buf, sizeof(buf), "GPIO_B: %02x GPIO_H: %02x", gpio_b, gpio_h);
1172 lcd_puts(0, line++, buf);
1173 snprintf(buf, sizeof(buf), "GPIO_C: %02x GPIO_I: %02x", gpio_c, gpio_i);
1174 lcd_puts(0, line++, buf);
1176 gpio_d = GPIOD_INPUT_VAL;
1177 gpio_e = GPIOE_INPUT_VAL;
1178 gpio_f = GPIOF_INPUT_VAL;
1180 gpio_j = GPIOJ_INPUT_VAL;
1181 gpio_k = GPIOK_INPUT_VAL;
1182 gpio_l = GPIOL_INPUT_VAL;
1184 snprintf(buf, sizeof(buf), "GPIO_D: %02x GPIO_J: %02x", gpio_d, gpio_j);
1185 lcd_puts(0, line++, buf);
1186 snprintf(buf, sizeof(buf), "GPIO_E: %02x GPIO_K: %02x", gpio_e, gpio_k);
1187 lcd_puts(0, line++, buf);
1188 snprintf(buf, sizeof(buf), "GPIO_F: %02x GPIO_L: %02x", gpio_f, gpio_l);
1189 lcd_puts(0, line++, buf);
1190 line++;
1192 snprintf(buf, sizeof(buf), "DEV_EN: %08lx", DEV_EN);
1193 lcd_puts(0, line++, buf);
1194 snprintf(buf, sizeof(buf), "CLOCK_SRC: %08lx", CLOCK_SOURCE);
1195 lcd_puts(0, line++, buf);
1196 snprintf(buf, sizeof(buf), "CLCD_CLK_SRC: %08lx", CLCD_CLOCK_SRC);
1197 lcd_puts(0, line++, buf);
1198 snprintf(buf, sizeof(buf), "PLL_CONTROL: %08lx", PLL_CONTROL);
1199 lcd_puts(0, line++, buf);
1200 snprintf(buf, sizeof(buf), "PLL_STATUS: %08lx", PLL_STATUS);
1201 lcd_puts(0, line++, buf);
1202 snprintf(buf, sizeof(buf), "DEV_TIMING1: %08lx", DEV_TIMING1);
1203 lcd_puts(0, line++, buf);
1205 #if defined(IRIVER_H10) || defined(IRIVER_H10_5GB)
1206 line++;
1207 snprintf(buf, sizeof(buf), "BATT: %03x UNK1: %03x", adc_read(ADC_BATTERY),
1208 adc_read(ADC_UNKNOWN_1));
1209 lcd_puts(0, line++, buf);
1210 snprintf(buf, sizeof(buf), "REM: %03x PAD: %03x", adc_read(ADC_REMOTE),
1211 adc_read(ADC_SCROLLPAD));
1212 lcd_puts(0, line++, buf);
1213 #elif defined(SANSA_E200)
1214 line++;
1215 snprintf(buf, sizeof(buf), "ADC_BVDD: %02x", adc_read(ADC_BVDD));
1216 lcd_puts(0, line++, buf);
1217 snprintf(buf, sizeof(buf), "ADC_RTCSUP: %02x", adc_read(ADC_RTCSUP));
1218 lcd_puts(0, line++, buf);
1219 snprintf(buf, sizeof(buf), "ADC_UVDD: %02x", adc_read(ADC_UVDD));
1220 lcd_puts(0, line++, buf);
1221 snprintf(buf, sizeof(buf), "ADC_CHG_IN: %02x", adc_read(ADC_CHG_IN));
1222 lcd_puts(0, line++, buf);
1223 snprintf(buf, sizeof(buf), "ADC_CVDD: %02x", adc_read(ADC_CVDD));
1224 lcd_puts(0, line++, buf);
1225 snprintf(buf, sizeof(buf), "ADC_BATTEMP: %02x", adc_read(ADC_BATTEMP));
1226 lcd_puts(0, line++, buf);
1227 snprintf(buf, sizeof(buf), "ADC_MICSUP1: %02x", adc_read(ADC_MICSUP1));
1228 lcd_puts(0, line++, buf);
1229 snprintf(buf, sizeof(buf), "ADC_MICSUP2: %02x", adc_read(ADC_MICSUP2));
1230 lcd_puts(0, line++, buf);
1231 snprintf(buf, sizeof(buf), "ADC_VBE1: %02x", adc_read(ADC_VBE1));
1232 lcd_puts(0, line++, buf);
1233 snprintf(buf, sizeof(buf), "ADC_VBE2: %02x", adc_read(ADC_VBE2));
1234 lcd_puts(0, line++, buf);
1235 snprintf(buf, sizeof(buf), "ADC_I_MICSUP1: %02x", adc_read(ADC_I_MICSUP1));
1236 lcd_puts(0, line++, buf);
1237 snprintf(buf, sizeof(buf), "ADC_I_MICSUP2: %02x", adc_read(ADC_I_MICSUP2));
1238 lcd_puts(0, line++, buf);
1239 snprintf(buf, sizeof(buf), "ADC_VBAT: %02x", adc_read(ADC_VBAT));
1240 lcd_puts(0, line++, buf);
1241 #endif
1242 lcd_update();
1243 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1244 return false;
1247 #elif CONFIG_CPU == PP5002
1248 unsigned int gpio_a, gpio_b, gpio_c, gpio_d;
1250 char buf[128];
1251 int line;
1253 lcd_setmargins(0, 0);
1254 lcd_clear_display();
1255 lcd_setfont(FONT_SYSFIXED);
1257 while(1)
1259 gpio_a = GPIOA_INPUT_VAL;
1260 gpio_b = GPIOB_INPUT_VAL;
1261 gpio_c = GPIOC_INPUT_VAL;
1262 gpio_d = GPIOD_INPUT_VAL;
1264 line = 0;
1265 snprintf(buf, sizeof(buf), "GPIO_A: %02x GPIO_B: %02x", gpio_a, gpio_b);
1266 lcd_puts(0, line++, buf);
1267 snprintf(buf, sizeof(buf), "GPIO_C: %02x GPIO_D: %02x", gpio_c, gpio_d);
1268 lcd_puts(0, line++, buf);
1270 snprintf(buf, sizeof(buf), "DEV_EN: %08lx", DEV_EN);
1271 lcd_puts(0, line++, buf);
1272 snprintf(buf, sizeof(buf), "CLOCK_ENABLE: %08lx", CLOCK_ENABLE);
1273 lcd_puts(0, line++, buf);
1274 snprintf(buf, sizeof(buf), "CLOCK_SOURCE: %08lx", CLOCK_SOURCE);
1275 lcd_puts(0, line++, buf);
1276 snprintf(buf, sizeof(buf), "PLL_CONTROL: %08lx", PLL_CONTROL);
1277 lcd_puts(0, line++, buf);
1278 snprintf(buf, sizeof(buf), "PLL_DIV: %08lx", PLL_DIV);
1279 lcd_puts(0, line++, buf);
1280 snprintf(buf, sizeof(buf), "PLL_MULT: %08lx", PLL_MULT);
1281 lcd_puts(0, line++, buf);
1282 snprintf(buf, sizeof(buf), "TIMING1_CTL: %08lx", TIMING1_CTL);
1283 lcd_puts(0, line++, buf);
1284 snprintf(buf, sizeof(buf), "TIMING2_CTL: %08lx", TIMING2_CTL);
1285 lcd_puts(0, line++, buf);
1287 lcd_update();
1288 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1289 return false;
1291 #elif CONFIG_CPU == S3C2440
1292 char buf[50];
1293 int line;
1295 lcd_setmargins(0, 0);
1296 lcd_clear_display();
1297 lcd_setfont(FONT_SYSFIXED);
1299 while(1)
1301 line = 0;
1302 snprintf(buf, sizeof(buf), "[Ports and Registers]"); lcd_puts(0, line++, buf);
1304 snprintf(buf, sizeof(buf), "GPACON: %08x GPBCON: %08x", GPACON, GPBCON); lcd_puts(0, line++, buf);
1305 snprintf(buf, sizeof(buf), "GPADAT: %08x GPBDAT: %08x", GPADAT, GPBDAT); lcd_puts(0, line++, buf);
1306 snprintf(buf, sizeof(buf), "GPAUP: %08x GPBUP: %08x", 0, GPBUP); lcd_puts(0, line++, buf);
1307 snprintf(buf, sizeof(buf), "GPCCON: %08x GPDCON: %08x", GPCCON, GPDCON); lcd_puts(0, line++, buf);
1308 snprintf(buf, sizeof(buf), "GPCDAT: %08x GPDDAT: %08x", GPCDAT, GPDDAT); lcd_puts(0, line++, buf);
1309 snprintf(buf, sizeof(buf), "GPCUP: %08x GPDUP: %08x", GPCUP, GPDUP); lcd_puts(0, line++, buf);
1311 snprintf(buf, sizeof(buf), "GPCCON: %08x GPDCON: %08x", GPCCON, GPDCON); lcd_puts(0, line++, buf);
1312 snprintf(buf, sizeof(buf), "GPCDAT: %08x GPDDAT: %08x", GPCDAT, GPDDAT); lcd_puts(0, line++, buf);
1313 snprintf(buf, sizeof(buf), "GPCUP: %08x GPDUP: %08x", GPCUP, GPDUP); lcd_puts(0, line++, buf);
1315 snprintf(buf, sizeof(buf), "GPECON: %08x GPFCON: %08x", GPECON, GPFCON); lcd_puts(0, line++, buf);
1316 snprintf(buf, sizeof(buf), "GPEDAT: %08x GPFDAT: %08x", GPEDAT, GPFDAT); lcd_puts(0, line++, buf);
1317 snprintf(buf, sizeof(buf), "GPEUP: %08x GPFUP: %08x", GPEUP, GPFUP); lcd_puts(0, line++, buf);
1319 snprintf(buf, sizeof(buf), "GPGCON: %08x GPHCON: %08x", GPGCON, GPHCON); lcd_puts(0, line++, buf);
1320 snprintf(buf, sizeof(buf), "GPGDAT: %08x GPHDAT: %08x", GPGDAT, GPHDAT); lcd_puts(0, line++, buf);
1321 snprintf(buf, sizeof(buf), "GPGUP: %08x GPHUP: %08x", GPGUP, GPHUP); lcd_puts(0, line++, buf);
1323 snprintf(buf, sizeof(buf), "GPJCON: %08x", GPJCON); lcd_puts(0, line++, buf);
1324 snprintf(buf, sizeof(buf), "GPJDAT: %08x", GPJDAT); lcd_puts(0, line++, buf);
1325 snprintf(buf, sizeof(buf), "GPJUP: %08x", GPJUP); lcd_puts(0, line++, buf);
1327 line++;
1329 snprintf(buf, sizeof(buf), "SRCPND: %08x INTMOD: %08x", SRCPND, INTMOD); lcd_puts(0, line++, buf);
1330 snprintf(buf, sizeof(buf), "INTMSK: %08x INTPND: %08x", INTMSK, INTPND); lcd_puts(0, line++, buf);
1331 snprintf(buf, sizeof(buf), "CLKCON: %08x CLKSLOW: %08x", CLKCON, CLKSLOW); lcd_puts(0, line++, buf);
1332 snprintf(buf, sizeof(buf), "MPLLCON: %08x UPLLCON: %08x", MPLLCON, UPLLCON); lcd_puts(0, line++, buf);
1333 snprintf(buf, sizeof(buf), "CLKDIVN: %08x", CLKDIVN); lcd_puts(0, line++, buf);
1335 lcd_update();
1336 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1337 return false;
1339 #endif /* CPU */
1340 return false;
1342 #else /* !HAVE_LCD_BITMAP */
1343 bool dbg_ports(void)
1345 unsigned short porta;
1346 unsigned short portb;
1347 unsigned char portc;
1348 char buf[32];
1349 int button;
1350 int adc_battery_voltage;
1351 int currval = 0;
1353 lcd_clear_display();
1355 while(1)
1357 porta = PADR;
1358 portb = PBDR;
1359 portc = PCDR;
1361 switch(currval)
1363 case 0:
1364 snprintf(buf, 32, "PADR: %04x", porta);
1365 break;
1366 case 1:
1367 snprintf(buf, 32, "PBDR: %04x", portb);
1368 break;
1369 case 2:
1370 snprintf(buf, 32, "AN0: %03x", adc_read(0));
1371 break;
1372 case 3:
1373 snprintf(buf, 32, "AN1: %03x", adc_read(1));
1374 break;
1375 case 4:
1376 snprintf(buf, 32, "AN2: %03x", adc_read(2));
1377 break;
1378 case 5:
1379 snprintf(buf, 32, "AN3: %03x", adc_read(3));
1380 break;
1381 case 6:
1382 snprintf(buf, 32, "AN4: %03x", adc_read(4));
1383 break;
1384 case 7:
1385 snprintf(buf, 32, "AN5: %03x", adc_read(5));
1386 break;
1387 case 8:
1388 snprintf(buf, 32, "AN6: %03x", adc_read(6));
1389 break;
1390 case 9:
1391 snprintf(buf, 32, "AN7: %03x", adc_read(7));
1392 break;
1393 break;
1395 lcd_puts(0, 0, buf);
1397 battery_read_info(&adc_battery_voltage, NULL);
1398 snprintf(buf, 32, "Batt: %d.%03dV", adc_battery_voltage / 1000,
1399 adc_battery_voltage % 1000);
1400 lcd_puts(0, 1, buf);
1401 lcd_update();
1403 button = get_action(CONTEXT_SETTINGS,HZ/5);
1405 switch(button)
1407 case ACTION_STD_CANCEL:
1408 return false;
1410 case ACTION_SETTINGS_DEC:
1411 currval--;
1412 if(currval < 0)
1413 currval = 9;
1414 break;
1416 case ACTION_SETTINGS_INC:
1417 currval++;
1418 if(currval > 9)
1419 currval = 0;
1420 break;
1423 return false;
1425 #endif /* !HAVE_LCD_BITMAP */
1426 #endif /* !SIMULATOR */
1428 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
1429 static bool dbg_cpufreq(void)
1431 char buf[128];
1432 int line;
1433 int button;
1435 #ifdef HAVE_LCD_BITMAP
1436 lcd_setmargins(0, 0);
1437 lcd_setfont(FONT_SYSFIXED);
1438 #endif
1439 lcd_clear_display();
1441 while(1)
1443 line = 0;
1445 snprintf(buf, sizeof(buf), "Frequency: %ld", FREQ);
1446 lcd_puts(0, line++, buf);
1448 snprintf(buf, sizeof(buf), "boost_counter: %d", get_cpu_boost_counter());
1449 lcd_puts(0, line++, buf);
1451 lcd_update();
1452 button = get_action(CONTEXT_STD,HZ/10);
1454 switch(button)
1456 case ACTION_STD_PREV:
1457 cpu_boost(true);
1458 break;
1460 case ACTION_STD_NEXT:
1461 cpu_boost(false);
1462 break;
1464 case ACTION_STD_OK:
1465 while (get_cpu_boost_counter() > 0)
1466 cpu_boost(false);
1467 set_cpu_frequency(CPUFREQ_DEFAULT);
1468 break;
1470 case ACTION_STD_CANCEL:
1471 return false;
1475 return false;
1477 #endif /* HAVE_ADJUSTABLE_CPU_FREQ */
1479 #ifndef SIMULATOR
1480 #ifdef HAVE_LCD_BITMAP
1482 * view_battery() shows a automatically scaled graph of the battery voltage
1483 * over time. Usable for estimating battery life / charging rate.
1484 * The power_history array is updated in power_thread of powermgmt.c.
1487 #define BAT_LAST_VAL MIN(LCD_WIDTH, POWER_HISTORY_LEN)
1488 #define BAT_YSPACE (LCD_HEIGHT - 20)
1490 static bool view_battery(void)
1492 int view = 0;
1493 int i, x, y;
1494 unsigned short maxv, minv;
1495 char buf[32];
1497 lcd_setmargins(0, 0);
1498 lcd_setfont(FONT_SYSFIXED);
1500 while(1)
1502 lcd_clear_display();
1503 switch (view) {
1504 case 0: /* voltage history graph */
1505 /* Find maximum and minimum voltage for scaling */
1506 minv = power_history[0];
1507 maxv = minv + 1;
1508 for (i = 1; i < BAT_LAST_VAL && power_history[i]; i++) {
1509 if (power_history[i] > maxv)
1510 maxv = power_history[i];
1511 if (power_history[i] < minv)
1512 minv = power_history[i];
1515 snprintf(buf, 30, "Battery %d.%03d", power_history[0] / 1000,
1516 power_history[0] % 1000);
1517 lcd_puts(0, 0, buf);
1518 snprintf(buf, 30, "scale %d.%03d-%d.%03dV",
1519 minv / 1000, minv % 1000, maxv / 1000, maxv % 1000);
1520 lcd_puts(0, 1, buf);
1522 x = 0;
1523 for (i = BAT_LAST_VAL - 1; i >= 0; i--) {
1524 y = (power_history[i] - minv) * BAT_YSPACE / (maxv - minv);
1525 lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
1526 lcd_vline(x, LCD_HEIGHT-1, 20);
1527 lcd_set_drawmode(DRMODE_SOLID);
1528 lcd_vline(x, LCD_HEIGHT-1,
1529 MIN(MAX(LCD_HEIGHT-1 - y, 20), LCD_HEIGHT-1));
1530 x++;
1533 break;
1535 case 1: /* status: */
1536 lcd_puts(0, 0, "Power status:");
1538 battery_read_info(&y, NULL);
1539 snprintf(buf, 30, "Battery: %d.%03d V", y / 1000, y % 1000);
1540 lcd_puts(0, 1, buf);
1541 #ifdef ADC_EXT_POWER
1542 y = (adc_read(ADC_EXT_POWER) * EXT_SCALE_FACTOR) / 1000;
1543 snprintf(buf, 30, "External: %d.%03d V", y / 1000, y % 1000);
1544 lcd_puts(0, 2, buf);
1545 #endif
1546 #if CONFIG_CHARGING
1547 #if CONFIG_CHARGING == CHARGING_CONTROL
1548 snprintf(buf, 30, "Chgr: %s %s",
1549 charger_inserted() ? "present" : "absent",
1550 charger_enabled ? "on" : "off");
1551 lcd_puts(0, 3, buf);
1552 snprintf(buf, 30, "short delta: %d", short_delta);
1553 lcd_puts(0, 5, buf);
1554 snprintf(buf, 30, "long delta: %d", long_delta);
1555 lcd_puts(0, 6, buf);
1556 lcd_puts(0, 7, power_message);
1557 snprintf(buf, 30, "USB Inserted: %s",
1558 usb_inserted() ? "yes" : "no");
1559 lcd_puts(0, 8, buf);
1560 #if defined IRIVER_H300_SERIES
1561 snprintf(buf, 30, "USB Charging Enabled: %s",
1562 usb_charging_enabled() ? "yes" : "no");
1563 lcd_puts(0, 9, buf);
1564 #endif
1565 #else /* CONFIG_CHARGING != CHARGING_CONTROL */
1566 #if defined IPOD_NANO || defined IPOD_VIDEO
1567 int usb_pwr = (GPIOL_INPUT_VAL & 0x10)?true:false;
1568 int ext_pwr = (GPIOL_INPUT_VAL & 0x08)?false:true;
1569 int dock = (GPIOA_INPUT_VAL & 0x10)?true:false;
1570 int charging = (GPIOB_INPUT_VAL & 0x01)?false:true;
1571 int headphone= (GPIOA_INPUT_VAL & 0x80)?true:false;
1573 snprintf(buf, 30, "USB pwr: %s",
1574 usb_pwr ? "present" : "absent");
1575 lcd_puts(0, 3, buf);
1576 snprintf(buf, 30, "EXT pwr: %s",
1577 ext_pwr ? "present" : "absent");
1578 lcd_puts(0, 4, buf);
1579 snprintf(buf, 30, "Battery: %s",
1580 charging ? "charging" : (usb_pwr||ext_pwr) ? "charged" : "discharging");
1581 lcd_puts(0, 5, buf);
1582 snprintf(buf, 30, "Dock mode: %s",
1583 dock ? "enabled" : "disabled");
1584 lcd_puts(0, 6, buf);
1585 snprintf(buf, 30, "Headphone: %s",
1586 headphone ? "connected" : "disconnected");
1587 lcd_puts(0, 7, buf);
1588 #else
1589 snprintf(buf, 30, "Charger: %s",
1590 charger_inserted() ? "present" : "absent");
1591 lcd_puts(0, 3, buf);
1592 #endif
1593 #endif /* CONFIG_CHARGING != CHARGING_CONTROL */
1594 #endif /* CONFIG_CHARGING */
1595 break;
1597 case 2: /* voltage deltas: */
1598 lcd_puts(0, 0, "Voltage deltas:");
1600 for (i = 0; i <= 6; i++) {
1601 y = power_history[i] - power_history[i+1];
1602 snprintf(buf, 30, "-%d min: %s%d.%03d V", i,
1603 (y < 0) ? "-" : "", ((y < 0) ? y * -1 : y) / 1000,
1604 ((y < 0) ? y * -1 : y ) % 1000);
1605 lcd_puts(0, i+1, buf);
1607 break;
1609 case 3: /* remaining time estimation: */
1611 #if CONFIG_CHARGING == CHARGING_CONTROL
1612 snprintf(buf, 30, "charge_state: %d", charge_state);
1613 lcd_puts(0, 0, buf);
1615 snprintf(buf, 30, "Cycle time: %d m", powermgmt_last_cycle_startstop_min);
1616 lcd_puts(0, 1, buf);
1618 snprintf(buf, 30, "Lvl@cyc st: %d%%", powermgmt_last_cycle_level);
1619 lcd_puts(0, 2, buf);
1621 snprintf(buf, 30, "P=%2d I=%2d", pid_p, pid_i);
1622 lcd_puts(0, 3, buf);
1624 snprintf(buf, 30, "Trickle sec: %d/60", trickle_sec);
1625 lcd_puts(0, 4, buf);
1626 #endif /* CONFIG_CHARGING == CHARGING_CONTROL */
1628 snprintf(buf, 30, "Last PwrHist: %d.%03dV",
1629 power_history[0] / 1000,
1630 power_history[0] % 1000);
1631 lcd_puts(0, 5, buf);
1633 snprintf(buf, 30, "battery level: %d%%", battery_level());
1634 lcd_puts(0, 6, buf);
1636 snprintf(buf, 30, "Est. remain: %d m", battery_time());
1637 lcd_puts(0, 7, buf);
1638 break;
1641 lcd_update();
1643 switch(get_action(CONTEXT_SETTINGS,HZ/2))
1645 case ACTION_SETTINGS_DEC:
1646 if (view)
1647 view--;
1648 break;
1650 case ACTION_SETTINGS_INC:
1651 if (view < 3)
1652 view++;
1653 break;
1655 case ACTION_STD_CANCEL:
1656 return false;
1659 return false;
1662 #endif /* HAVE_LCD_BITMAP */
1663 #endif
1665 #ifndef SIMULATOR
1666 #if defined(HAVE_MMC) || defined(HAVE_HOTSWAP)
1667 #if defined(HAVE_MMC)
1668 #define CARDTYPE "MMC"
1669 #else
1670 #define CARDTYPE "microSD"
1671 #endif
1672 static int cardinfo_callback(int btn, struct action_callback_info *info)
1674 tCardInfo *card;
1675 unsigned char card_name[7];
1676 unsigned char pbuf[32];
1677 static const unsigned char i_vmin[] = { 0, 1, 5, 10, 25, 35, 60, 100 };
1678 static const unsigned char i_vmax[] = { 1, 5, 10, 25, 35, 45, 80, 200 };
1679 static const unsigned char *kbit_units[] = { "kBit/s", "MBit/s", "GBit/s" };
1680 static const unsigned char *nsec_units[] = { "ns", "µs", "ms" };
1681 static const char *spec_vers[] = { "1.0-1.2", "1.4", "2.0-2.2",
1682 "3.1-3.31", "4.0" };
1683 if ((btn == ACTION_STD_OK) || (btn == SYS_FS_CHANGED) || (btn == ACTION_REDRAW))
1685 if (btn == ACTION_STD_OK)
1686 info->cbdata ^= 0x1; /* change cards */
1688 dbg_listmessage_setlines(0);
1690 card = card_get_info(info->cbdata);
1692 if (card->initialized > 0)
1694 card_name[6] = '\0';
1695 strncpy(card_name, ((unsigned char*)card->cid) + 3, 6);
1696 dbg_listmessage_addline(
1697 "%s Rev %d.%d", card_name,
1698 (int) card_extract_bits(card->cid, 72, 4),
1699 (int) card_extract_bits(card->cid, 76, 4));
1700 dbg_listmessage_addline(
1701 "Prod: %d/%d",
1702 (int) card_extract_bits(card->cid, 112, 4),
1703 (int) card_extract_bits(card->cid, 116, 4) + 1997);
1704 dbg_listmessage_addline(
1705 "Ser#: 0x%08lx",
1706 card_extract_bits(card->cid, 80, 32));
1707 dbg_listmessage_addline(
1708 "M=%02x, O=%04x",
1709 (int) card_extract_bits(card->cid, 0, 8),
1710 (int) card_extract_bits(card->cid, 8, 16));
1711 int temp = card_extract_bits(card->csd, 2, 4);
1712 dbg_listmessage_addline(
1713 CARDTYPE " v%s", temp < 5 ?
1714 spec_vers[temp] : "?.?");
1715 dbg_listmessage_addline(
1716 "Blocks: 0x%06lx", card->numblocks);
1717 dbg_listmessage_addline(
1718 "Blksz.: %d P:%c%c", card->blocksize,
1719 card_extract_bits(card->csd, 48, 1) ? 'R' : '-',
1720 card_extract_bits(card->csd, 106, 1) ? 'W' : '-');
1721 output_dyn_value(pbuf, sizeof pbuf, card->speed / 1000,
1722 kbit_units, false);
1723 dbg_listmessage_addline(
1724 "Speed: %s", pbuf);
1725 output_dyn_value(pbuf, sizeof pbuf, card->tsac,
1726 nsec_units, false);
1727 dbg_listmessage_addline(
1728 "Tsac: %s", pbuf);
1729 dbg_listmessage_addline(
1730 "Nsac: %d clk", card->nsac);
1731 dbg_listmessage_addline(
1732 "R2W: *%d", card->r2w_factor);
1733 dbg_listmessage_addline(
1734 "IRmax: %d..%d mA",
1735 i_vmin[card_extract_bits(card->csd, 66, 3)],
1736 i_vmax[card_extract_bits(card->csd, 69, 3)]);
1737 dbg_listmessage_addline(
1738 "IWmax: %d..%d mA",
1739 i_vmin[card_extract_bits(card->csd, 72, 3)],
1740 i_vmax[card_extract_bits(card->csd, 75, 3)]);
1742 else if (card->initialized == 0)
1744 dbg_listmessage_addline("Not Found!");
1746 #ifndef HAVE_MMC
1747 else /* card->initialized < 0 */
1749 dbg_listmessage_addline("Init Error! (%d)", card->initialized);
1751 #endif
1752 snprintf(info->title, 16, "[" CARDTYPE " %d]", (int)info->cbdata);
1753 gui_synclist_set_nb_items(info->lists, dbg_listmessage_getlines());
1754 gui_synclist_select_item(info->lists, 0);
1755 btn = ACTION_REDRAW;
1757 return btn;
1759 static bool dbg_disk_info(void)
1761 char listtitle[16];
1762 struct action_callback_info info;
1763 info.title = listtitle;
1764 info.count = 1;
1765 info.selection_size = 1;
1766 info.action_callback = cardinfo_callback;
1767 info.dbg_getname = dbg_listmessage_getname;
1768 info.cbdata = 0;
1769 dbg_list(&info);
1770 return false;
1772 #else /* !defined(HAVE_MMC) && !defined(HAVE_HOTSWAP) */
1773 static int disk_callback(int btn, struct action_callback_info *info)
1775 int i;
1776 char buf[128];
1777 unsigned short* identify_info = ata_get_identify();
1778 bool timing_info_present = false;
1779 (void)btn;
1781 dbg_listmessage_setlines(0);
1783 for (i=0; i < 20; i++)
1784 ((unsigned short*)buf)[i]=htobe16(identify_info[i+27]);
1785 buf[40]=0;
1786 /* kill trailing space */
1787 for (i=39; i && buf[i]==' '; i--)
1788 buf[i] = 0;
1789 dbg_listmessage_addline(
1790 "Model: %s", buf);
1791 for (i=0; i < 4; i++)
1792 ((unsigned short*)buf)[i]=htobe16(identify_info[i+23]);
1793 buf[8]=0;
1794 dbg_listmessage_addline(
1795 "Firmware: %s", buf);
1796 snprintf(buf, sizeof buf, "%ld MB",
1797 ((unsigned long)identify_info[61] << 16 |
1798 (unsigned long)identify_info[60]) / 2048 );
1799 dbg_listmessage_addline(
1800 "Size: %s", buf);
1801 unsigned long free;
1802 fat_size( IF_MV2(0,) NULL, &free );
1803 dbg_listmessage_addline(
1804 "Free: %ld MB", free / 1024);
1805 dbg_listmessage_addline(
1806 "Spinup time: %d ms", ata_spinup_time * (1000/HZ));
1807 i = identify_info[83] & (1<<3);
1808 dbg_listmessage_addline(
1809 "Power mgmt: %s", i ? "enabled" : "unsupported");
1810 i = identify_info[83] & (1<<9);
1811 dbg_listmessage_addline(
1812 "Noise mgmt: %s", i ? "enabled" : "unsupported");
1813 i = identify_info[82] & (1<<6);
1814 dbg_listmessage_addline(
1815 "Read-ahead: %s", i ? "enabled" : "unsupported");
1816 timing_info_present = identify_info[53] & (1<<1);
1817 if(timing_info_present) {
1818 char pio3[2], pio4[2];pio3[1] = 0;
1819 pio4[1] = 0;
1820 pio3[0] = (identify_info[64] & (1<<0)) ? '3' : 0;
1821 pio4[0] = (identify_info[64] & (1<<1)) ? '4' : 0;
1822 dbg_listmessage_addline(
1823 "PIO modes: 0 1 2 %s %s", pio3, pio4);
1825 else {
1826 dbg_listmessage_addline(
1827 "No PIO mode info");
1829 timing_info_present = identify_info[53] & (1<<1);
1830 if(timing_info_present) {
1831 dbg_listmessage_addline(
1832 "Cycle times %dns/%dns",
1833 identify_info[67],
1834 identify_info[68] );
1835 } else {
1836 dbg_listmessage_addline(
1837 "No timing info");
1839 timing_info_present = identify_info[53] & (1<<1);
1840 if(timing_info_present) {
1841 i = identify_info[49] & (1<<11);
1842 dbg_listmessage_addline(
1843 "IORDY support: %s", i ? "yes" : "no");
1844 i = identify_info[49] & (1<<10);
1845 dbg_listmessage_addline(
1846 "IORDY disable: %s", i ? "yes" : "no");
1847 } else {
1848 dbg_listmessage_addline(
1849 "No timing info");
1851 dbg_listmessage_addline(
1852 "Cluster size: %d bytes", fat_get_cluster_size(IF_MV(0)));
1853 gui_synclist_set_nb_items(info->lists, dbg_listmessage_getlines());
1854 return btn;
1856 static bool dbg_disk_info(void)
1858 struct action_callback_info info;
1859 info.title = "Disk Info";
1860 info.count = 1;
1861 info.selection_size = 1;
1862 info.action_callback = disk_callback;
1863 info.dbg_getname = dbg_listmessage_getname;
1864 dbg_list(&info);
1865 return false;
1867 #endif /* !defined(HAVE_MMC) && !defined(HAVE_HOTSWAP) */
1868 #endif /* !SIMULATOR */
1870 #ifdef HAVE_DIRCACHE
1871 static int dircache_callback(int btn, struct action_callback_info *info)
1873 (void)btn; (void)info;
1874 dbg_listmessage_setlines(0);
1875 dbg_listmessage_addline("Cache initialized: %s",
1876 dircache_is_enabled() ? "Yes" : "No");
1877 dbg_listmessage_addline("Cache size: %d B",
1878 dircache_get_cache_size());
1879 dbg_listmessage_addline("Last size: %d B",
1880 global_status.dircache_size);
1881 dbg_listmessage_addline("Limit: %d B",
1882 DIRCACHE_LIMIT);
1883 dbg_listmessage_addline("Reserve: %d/%d B",
1884 dircache_get_reserve_used(), DIRCACHE_RESERVE);
1885 dbg_listmessage_addline("Scanning took: %d s",
1886 dircache_get_build_ticks() / HZ);
1887 dbg_listmessage_addline("Entry count: %d",
1888 dircache_get_entry_count());
1889 return btn;
1892 static bool dbg_dircache_info(void)
1894 struct action_callback_info info;
1895 info.title = "Dircache Info";
1896 info.count = 7;
1897 info.selection_size = 1;
1898 info.action_callback = dircache_callback;
1899 info.dbg_getname = dbg_listmessage_getname;
1900 dbg_list(&info);
1901 return false;
1904 #endif /* HAVE_DIRCACHE */
1906 #ifdef HAVE_TAGCACHE
1907 static int database_callback(int btn, struct action_callback_info *info)
1909 (void)btn; (void)info;
1910 struct tagcache_stat *stat = tagcache_get_stat();
1911 dbg_listmessage_setlines(0);
1912 dbg_listmessage_addline("Initialized: %s",
1913 stat->initialized ? "Yes" : "No");
1914 dbg_listmessage_addline("DB Ready: %s",
1915 stat->ready ? "Yes" : "No");
1916 dbg_listmessage_addline("RAM Cache: %s",
1917 stat->ramcache ? "Yes" : "No");
1918 dbg_listmessage_addline("RAM: %d/%d B",
1919 stat->ramcache_used, stat->ramcache_allocated);
1920 dbg_listmessage_addline("Progress: %d%% (%d entries)",
1921 stat->progress, stat->processed_entries);
1922 dbg_listmessage_addline("Commit step: %d",
1923 stat->commit_step);
1924 dbg_listmessage_addline("Commit delayed: %s",
1925 stat->commit_delayed ? "Yes" : "No");
1926 return btn;
1928 static bool dbg_tagcache_info(void)
1930 struct action_callback_info info;
1931 info.title = "Database Info";
1932 info.count = 7;
1933 info.selection_size = 1;
1934 info.action_callback = database_callback;
1935 info.dbg_getname = dbg_listmessage_getname;
1936 dbg_list(&info);
1937 return false;
1939 #endif
1941 #if CONFIG_CPU == SH7034
1942 static bool dbg_save_roms(void)
1944 int fd;
1945 int oldmode = system_memory_guard(MEMGUARD_NONE);
1947 fd = creat("/internal_rom_0000-FFFF.bin");
1948 if(fd >= 0)
1950 write(fd, (void *)0, 0x10000);
1951 close(fd);
1954 fd = creat("/internal_rom_2000000-203FFFF.bin");
1955 if(fd >= 0)
1957 write(fd, (void *)0x2000000, 0x40000);
1958 close(fd);
1961 system_memory_guard(oldmode);
1962 return false;
1964 #elif defined CPU_COLDFIRE
1965 static bool dbg_save_roms(void)
1967 int fd;
1968 int oldmode = system_memory_guard(MEMGUARD_NONE);
1970 #if defined(IRIVER_H100_SERIES)
1971 fd = creat("/internal_rom_000000-1FFFFF.bin");
1972 #elif defined(IRIVER_H300_SERIES)
1973 fd = creat("/internal_rom_000000-3FFFFF.bin");
1974 #elif defined(IAUDIO_X5) || defined(IAUDIO_M5)
1975 fd = creat("/internal_rom_000000-3FFFFF.bin");
1976 #endif
1977 if(fd >= 0)
1979 write(fd, (void *)0, FLASH_SIZE);
1980 close(fd);
1982 system_memory_guard(oldmode);
1984 #ifdef HAVE_EEPROM
1985 fd = creat("/internal_eeprom.bin");
1986 if (fd >= 0)
1988 int old_irq_level;
1989 char buf[EEPROM_SIZE];
1990 int err;
1992 old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL);
1994 err = eeprom_24cxx_read(0, buf, sizeof buf);
1995 if (err)
1996 gui_syncsplash(HZ*3, "Eeprom read failure (%d)",err);
1997 else
1999 write(fd, buf, sizeof buf);
2002 set_irq_level(old_irq_level);
2004 close(fd);
2006 #endif
2008 return false;
2010 #elif defined(CPU_PP) && !defined(SANSA_E200)
2011 static bool dbg_save_roms(void)
2013 int fd;
2015 fd = creat("/internal_rom_000000-0FFFFF.bin");
2016 if(fd >= 0)
2018 write(fd, (void *)0x20000000, FLASH_SIZE);
2019 close(fd);
2022 return false;
2024 #endif /* CPU */
2026 #ifndef SIMULATOR
2027 #if CONFIG_TUNER
2028 static int radio_callback(int btn, struct action_callback_info *info)
2030 dbg_listmessage_setlines(1);
2032 #if (CONFIG_TUNER & LV24020LP)
2033 dbg_listmessage_addline("CTRL_STAT: %02X", lv24020lp_get(LV24020LP_CTRL_STAT) );
2034 dbg_listmessage_addline("RADIO_STAT: %02X", lv24020lp_get(LV24020LP_REG_STAT) );
2035 dbg_listmessage_addline("MSS_FM: %d kHz", lv24020lp_get(LV24020LP_MSS_FM) );
2036 dbg_listmessage_addline("MSS_IF: %d Hz", lv24020lp_get(LV24020LP_MSS_IF) );
2037 dbg_listmessage_addline("MSS_SD: %d Hz", lv24020lp_get(LV24020LP_MSS_SD) );
2038 dbg_listmessage_addline("if_set: %d Hz", lv24020lp_get(LV24020LP_IF_SET) );
2039 dbg_listmessage_addline("sd_set: %d Hz", lv24020lp_get(LV24020LP_SD_SET) );
2040 #endif
2041 #if (CONFIG_TUNER & S1A0903X01)
2042 dbg_listmessage_addline("Samsung regs: %08X", s1a0903x01_get(RADIO_ALL));
2043 /* This one doesn't return dynamic data atm */
2044 #endif
2045 #if (CONFIG_TUNER & TEA5767)
2046 struct tea5767_dbg_info nfo;
2047 tea5767_dbg_info(&nfo);
2048 dbg_listmessage_addline("Philips regs:");
2049 dbg_listmessage_addline(
2050 " Read: %02X %02X %02X %02X %02X",
2051 (unsigned)nfo.read_regs[0], (unsigned)nfo.read_regs[1],
2052 (unsigned)nfo.read_regs[2], (unsigned)nfo.read_regs[3],
2053 (unsigned)nfo.read_regs[4]);
2054 dbg_listmessage_addline(
2055 " Write: %02X %02X %02X %02X %02X",
2056 (unsigned)nfo.write_regs[0], (unsigned)nfo.write_regs[1],
2057 (unsigned)nfo.write_regs[2], (unsigned)nfo.write_regs[3],
2058 (unsigned)nfo.write_regs[4]);
2059 #endif
2061 if (btn != ACTION_STD_CANCEL)
2062 btn = ACTION_REDRAW;
2064 gui_synclist_set_nb_items(info->lists, dbg_listmessage_getlines());
2065 return btn;
2067 static bool dbg_fm_radio(void)
2069 struct action_callback_info info;
2071 info.title = "FM Radio";
2072 info.count = 1;
2073 info.selection_size = 1;
2074 info.cbdata = radio_hardware_present();
2075 info.action_callback = info.cbdata ? radio_callback : NULL;
2076 info.dbg_getname = dbg_listmessage_getname;
2078 dbg_listmessage_setlines(0);
2079 dbg_listmessage_addline("HW detected: %s", info.cbdata ? "yes" : "no");
2081 dbg_list(&info);
2082 return false;
2084 #endif /* CONFIG_TUNER */
2085 #endif /* !SIMULATOR */
2087 #ifdef HAVE_LCD_BITMAP
2088 extern bool do_screendump_instead_of_usb;
2090 static bool dbg_screendump(void)
2092 do_screendump_instead_of_usb = !do_screendump_instead_of_usb;
2093 gui_syncsplash(HZ, "Screendump %s",
2094 do_screendump_instead_of_usb?"enabled":"disabled");
2095 return false;
2097 #endif /* HAVE_LCD_BITMAP */
2099 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
2100 static bool dbg_set_memory_guard(void)
2102 static const struct opt_items names[MAXMEMGUARD] = {
2103 { "None", -1 },
2104 { "Flash ROM writes", -1 },
2105 { "Zero area (all)", -1 }
2107 int mode = system_memory_guard(MEMGUARD_KEEP);
2109 set_option( "Catch mem accesses", &mode, INT, names, MAXMEMGUARD, NULL);
2110 system_memory_guard(mode);
2112 return false;
2114 #endif /* CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) */
2116 #if defined(TOSHIBA_GIGABEAT_F) && !defined(SIMULATOR)
2118 extern volatile bool lcd_poweroff;
2120 static bool dbg_lcd_power_off(void)
2122 lcd_setmargins(0, 0);
2124 while(1)
2126 int button;
2128 lcd_clear_display();
2129 lcd_puts(0, 0, "LCD Power Off");
2130 if(lcd_poweroff)
2131 lcd_puts(1, 1, "Yes");
2132 else
2133 lcd_puts(1, 1, "No");
2135 lcd_update();
2137 button = get_action(CONTEXT_STD,HZ/5);
2138 switch(button)
2140 case ACTION_STD_PREV:
2141 case ACTION_STD_NEXT:
2142 lcd_poweroff = !lcd_poweroff;
2143 break;
2144 case ACTION_STD_OK:
2145 case ACTION_STD_CANCEL:
2146 return false;
2147 default:
2148 sleep(HZ/10);
2149 break;
2152 return false;
2154 #endif
2156 #if defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS)
2157 static bool dbg_write_eeprom(void)
2159 int fd;
2160 int rc;
2161 int old_irq_level;
2162 char buf[EEPROM_SIZE];
2163 int err;
2165 fd = open("/internal_eeprom.bin", O_RDONLY);
2167 if (fd >= 0)
2169 rc = read(fd, buf, EEPROM_SIZE);
2171 if(rc == EEPROM_SIZE)
2173 old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL);
2175 err = eeprom_24cxx_write(0, buf, sizeof buf);
2176 if (err)
2177 gui_syncsplash(HZ*3, "Eeprom write failure (%d)",err);
2178 else
2179 gui_syncsplash(HZ*3, "Eeprom written successfully");
2181 set_irq_level(old_irq_level);
2183 else
2185 gui_syncsplash(HZ*3, "File read error (%d)",rc);
2187 close(fd);
2189 else
2191 gui_syncsplash(HZ*3, "Failed to open 'internal_eeprom.bin'");
2194 return false;
2196 #endif /* defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS) */
2197 #ifdef CPU_BOOST_LOGGING
2198 static bool cpu_boost_log(void)
2200 int i = 0,j=0;
2201 int count = cpu_boost_log_getcount();
2202 int lines = LCD_HEIGHT/SYSFONT_HEIGHT;
2203 char *str;
2204 bool done;
2205 lcd_setmargins(0, 0);
2206 lcd_setfont(FONT_SYSFIXED);
2207 str = cpu_boost_log_getlog_first();
2208 while (i < count)
2210 lcd_clear_display();
2211 for(j=0; j<lines; j++,i++)
2213 if (!str)
2214 str = cpu_boost_log_getlog_next();
2215 if (str)
2217 lcd_puts(0, j,str);
2219 str = NULL;
2221 lcd_update();
2222 done = false;
2223 while (!done)
2225 switch(get_action(CONTEXT_STD,TIMEOUT_BLOCK))
2227 case ACTION_STD_OK:
2228 case ACTION_STD_PREV:
2229 case ACTION_STD_NEXT:
2230 done = true;
2231 break;
2232 case ACTION_STD_CANCEL:
2233 i = count;
2234 done = true;
2235 break;
2239 get_action(CONTEXT_STD,TIMEOUT_BLOCK);
2240 lcd_setfont(FONT_UI);
2241 return false;
2243 #endif
2247 /****** The menu *********/
2248 struct the_menu_item {
2249 unsigned char *desc; /* string or ID */
2250 bool (*function) (void); /* return true if USB was connected */
2252 static const struct the_menu_item menuitems[] = {
2253 #if defined(TOSHIBA_GIGABEAT_F) && !defined(SIMULATOR)
2254 { "LCD Power Off", dbg_lcd_power_off },
2255 #endif
2256 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || \
2257 (defined(CPU_PP) && !defined(SANSA_E200))
2258 { "Dump ROM contents", dbg_save_roms },
2259 #endif
2260 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || defined(CPU_PP) || CONFIG_CPU == S3C2440
2261 { "View I/O ports", dbg_ports },
2262 #endif
2263 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
2264 { "CPU frequency", dbg_cpufreq },
2265 #endif
2266 #if defined(IRIVER_H100_SERIES) && !defined(SIMULATOR)
2267 { "S/PDIF analyzer", dbg_spdif },
2268 #endif
2269 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
2270 { "Catch mem accesses", dbg_set_memory_guard },
2271 #endif
2272 #ifndef SIMULATOR
2273 { "View OS stacks", dbg_os },
2274 #endif
2275 #ifdef HAVE_LCD_BITMAP
2276 #ifndef SIMULATOR
2277 { "View battery", view_battery },
2278 #endif
2279 { "Screendump", dbg_screendump },
2280 #endif
2281 #ifndef SIMULATOR
2282 { "View HW info", dbg_hw_info },
2283 #endif
2284 #ifndef SIMULATOR
2285 { "View partitions", dbg_partitions },
2286 #endif
2287 #ifndef SIMULATOR
2288 { "View disk info", dbg_disk_info },
2289 #endif
2290 #ifdef HAVE_DIRCACHE
2291 { "View dircache info", dbg_dircache_info },
2292 #endif
2293 #ifdef HAVE_TAGCACHE
2294 { "View database info", dbg_tagcache_info },
2295 #endif
2296 #ifdef HAVE_LCD_BITMAP
2297 #if CONFIG_CODEC == SWCODEC || !defined(SIMULATOR)
2298 { "View audio thread", dbg_audio_thread },
2299 #endif
2300 #ifdef PM_DEBUG
2301 { "pm histogram", peak_meter_histogram},
2302 #endif /* PM_DEBUG */
2303 #endif /* HAVE_LCD_BITMAP */
2304 #ifndef SIMULATOR
2305 #if CONFIG_TUNER
2306 { "FM Radio", dbg_fm_radio },
2307 #endif
2308 #endif
2309 #if defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS)
2310 { "Write back EEPROM", dbg_write_eeprom },
2311 #endif
2312 #ifdef ROCKBOX_HAS_LOGF
2313 {"logf", logfdisplay },
2314 {"logfdump", logfdump },
2315 #endif
2316 #ifdef CPU_BOOST_LOGGING
2317 {"cpu_boost log",cpu_boost_log},
2318 #endif
2320 static int menu_action_callback(int btn, struct action_callback_info *info)
2322 if (btn == ACTION_STD_OK)
2324 menuitems[gui_synclist_get_sel_pos(info->lists)].function();
2325 gui_synclist_draw(info->lists);
2327 return btn;
2329 static char* dbg_menu_getname(int item, void * data, char *buffer)
2331 (void)data; (void)buffer;
2332 return menuitems[item].desc;
2334 bool debug_menu(void)
2336 struct action_callback_info info;
2337 info.title = "Debug Menu";
2338 info.count = ARRAYLEN(menuitems);
2339 info.selection_size = 1;
2340 info.action_callback = menu_action_callback;
2341 info.dbg_getname = dbg_menu_getname;
2342 dbg_list(&info);
2343 return false;