minor update to gui_synclist_do_button() which will hopefully simplify things later.
[Rockbox.git] / apps / debug_menu.c
blob40c0fcc9b0ff1bf067a4c28b4035c73df83c89a5
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 static char thread_status_char(int status)
186 switch (status)
188 case STATE_RUNNING : return 'R';
189 case STATE_BLOCKED : return 'B';
190 case STATE_SLEEPING : return 'S';
191 case STATE_BLOCKED_W_TMO: return 'T';
194 return '?';
196 #if NUM_CORES > 1
197 #define IF_COP2(...) __VA_ARGS__
198 #else
199 #define IF_COP2(...)
200 #endif
201 static char* threads_getname(int selected_item, void * data, char *buffer)
203 (void)data;
204 struct thread_entry *thread = NULL;
205 int status, usage;
206 thread = &threads[selected_item];
208 if (thread->name == NULL)
210 snprintf(buffer, MAX_PATH, "%2d: ---", selected_item);
211 return buffer;
214 usage = thread_stack_usage(thread);
215 status = thread_get_status(thread);
216 #ifdef HAVE_PRIORITY_SCHEDULING
217 snprintf(buffer, MAX_PATH, "%2d: " IF_COP2("(%d) ") "%c%c %d %2d%% %s",
218 selected_item,
219 IF_COP2(thread->core,)
220 (status == STATE_RUNNING) ? '*' : ' ',
221 thread_status_char(status),
222 thread->priority,
223 usage, thread->name);
224 #else
225 snprintf(buffer, MAX_PATH, "%2d: " IF_COP2("(%d) ") "%c%c %2d%% %s",
226 selected_item,
227 IF_COP2(thread->core,)
228 (status == STATE_RUNNING) ? '*' : ' ',
229 thread_status_char(status),
230 usage, thread->name);
231 #endif
232 return buffer;
234 static int dbg_threads_action_callback(int action, struct action_callback_info *info)
236 #ifdef ROCKBOX_HAS_LOGF
237 if (action == ACTION_STD_OK)
239 struct thread_entry *thread = &threads[gui_synclist_get_sel_pos(info->lists)];
240 if (thread->name != NULL)
241 remove_thread(thread);
243 #endif
244 gui_synclist_draw(info->lists);
245 return action;
247 /* Test code!!! */
248 static bool dbg_os(void)
250 struct action_callback_info info;
251 info.title = IF_COP2("Core and ") "Stack usage:";
252 info.count = MAXTHREADS;
253 info.selection_size = 1;
254 info.action_callback = dbg_threads_action_callback;
255 info.dbg_getname = threads_getname;
256 return dbg_list(&info);
259 #ifdef HAVE_LCD_BITMAP
260 #if CONFIG_CODEC != SWCODEC
261 #ifndef SIMULATOR
262 static bool dbg_audio_thread(void)
264 char buf[32];
265 struct audio_debug d;
267 lcd_setmargins(0, 0);
268 lcd_setfont(FONT_SYSFIXED);
270 while(1)
272 if (action_userabort(HZ/5))
273 return false;
275 audio_get_debugdata(&d);
277 lcd_clear_display();
279 snprintf(buf, sizeof(buf), "read: %x", d.audiobuf_read);
280 lcd_puts(0, 0, buf);
281 snprintf(buf, sizeof(buf), "write: %x", d.audiobuf_write);
282 lcd_puts(0, 1, buf);
283 snprintf(buf, sizeof(buf), "swap: %x", d.audiobuf_swapwrite);
284 lcd_puts(0, 2, buf);
285 snprintf(buf, sizeof(buf), "playing: %d", d.playing);
286 lcd_puts(0, 3, buf);
287 snprintf(buf, sizeof(buf), "playable: %x", d.playable_space);
288 lcd_puts(0, 4, buf);
289 snprintf(buf, sizeof(buf), "unswapped: %x", d.unswapped_space);
290 lcd_puts(0, 5, buf);
292 /* Playable space left */
293 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, 6*8, 112, 4, d.audiobuflen, 0,
294 d.playable_space, HORIZONTAL);
296 /* Show the watermark limit */
297 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, 6*8+4, 112, 4, d.audiobuflen, 0,
298 d.low_watermark_level, HORIZONTAL);
300 snprintf(buf, sizeof(buf), "wm: %x - %x",
301 d.low_watermark_level, d.lowest_watermark_level);
302 lcd_puts(0, 7, buf);
304 lcd_update();
306 return false;
308 #endif /* !SIMULATOR */
309 #else /* CONFIG_CODEC == SWCODEC */
310 extern size_t filebuflen;
311 /* This is a size_t, but call it a long so it puts a - when it's bad. */
313 static unsigned int ticks, boost_ticks;
315 static void dbg_audio_task(void)
317 #ifndef SIMULATOR
318 if(FREQ > CPUFREQ_NORMAL)
319 boost_ticks++;
320 #endif
322 ticks++;
325 static bool dbg_audio_thread(void)
327 char buf[32];
328 int button;
329 int line;
330 bool done = false;
331 size_t bufused;
332 size_t bufsize = pcmbuf_get_bufsize();
333 int pcmbufdescs = pcmbuf_descs();
335 ticks = boost_ticks = 0;
337 tick_add_task(dbg_audio_task);
339 lcd_setmargins(0, 0);
340 lcd_setfont(FONT_SYSFIXED);
341 while(!done)
343 button = get_action(CONTEXT_STD,HZ/5);
344 switch(button)
346 case ACTION_STD_NEXT:
347 audio_next();
348 break;
349 case ACTION_STD_PREV:
350 audio_prev();
351 break;
352 case ACTION_STD_CANCEL:
353 done = true;
354 break;
356 line = 0;
357 lcd_clear_display();
359 bufused = bufsize - pcmbuf_free();
361 snprintf(buf, sizeof(buf), "pcm: %7ld/%7ld", (long) bufused, (long) bufsize);
362 lcd_puts(0, line++, buf);
364 /* Playable space left */
365 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6, bufsize, 0, bufused, HORIZONTAL);
366 line++;
368 snprintf(buf, sizeof(buf), "codec: %8ld/%8ld", audio_filebufused(), (long) filebuflen);
369 lcd_puts(0, line++, buf);
371 /* Playable space left */
372 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6, filebuflen, 0,
373 audio_filebufused(), HORIZONTAL);
374 line++;
376 snprintf(buf, sizeof(buf), "track count: %2d", audio_track_count());
377 lcd_puts(0, line++, buf);
379 #ifndef SIMULATOR
380 snprintf(buf, sizeof(buf), "cpu freq: %3dMHz",
381 (int)((FREQ + 500000) / 1000000));
382 lcd_puts(0, line++, buf);
383 #endif
385 if (ticks > 0)
387 snprintf(buf, sizeof(buf), "boost ratio: %3d%%",
388 boost_ticks * 100 / ticks);
389 lcd_puts(0, line++, buf);
392 snprintf(buf, sizeof(buf), "pcmbufdesc: %2d/%2d",
393 pcmbuf_used_descs(), pcmbufdescs);
394 lcd_puts(0, line++, buf);
396 lcd_update();
399 tick_remove_task(dbg_audio_task);
401 return false;
403 #endif /* CONFIG_CODEC */
404 #endif /* HAVE_LCD_BITMAP */
407 #if (CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE))
408 /* Tool function to read the flash manufacturer and type, if available.
409 Only chips which could be reprogrammed in system will return values.
410 (The mode switch addresses vary between flash manufacturers, hence addr1/2) */
411 /* In IRAM to avoid problems when running directly from Flash */
412 static bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
413 unsigned addr1, unsigned addr2)
414 ICODE_ATTR __attribute__((noinline));
415 static bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
416 unsigned addr1, unsigned addr2)
419 unsigned not_manu, not_id; /* read values before switching to ID mode */
420 unsigned manu, id; /* read values when in ID mode */
422 #if CONFIG_CPU == SH7034
423 volatile unsigned char* flash = (unsigned char*)0x2000000; /* flash mapping */
424 #elif defined(CPU_COLDFIRE)
425 volatile unsigned short* flash = (unsigned short*)0; /* flash mapping */
426 #endif
427 int old_level; /* saved interrupt level */
429 not_manu = flash[0]; /* read the normal content */
430 not_id = flash[1]; /* should be 'A' (0x41) and 'R' (0x52) from the "ARCH" marker */
432 /* disable interrupts, prevent any stray flash access */
433 old_level = set_irq_level(HIGHEST_IRQ_LEVEL);
435 flash[addr1] = 0xAA; /* enter command mode */
436 flash[addr2] = 0x55;
437 flash[addr1] = 0x90; /* ID command */
438 /* Atmel wants 20ms pause here */
439 /* sleep(HZ/50); no sleeping possible while interrupts are disabled */
441 manu = flash[0]; /* read the IDs */
442 id = flash[1];
444 flash[0] = 0xF0; /* reset flash (back to normal read mode) */
445 /* Atmel wants 20ms pause here */
446 /* sleep(HZ/50); no sleeping possible while interrupts are disabled */
448 set_irq_level(old_level); /* enable interrupts again */
450 /* I assume success if the obtained values are different from
451 the normal flash content. This is not perfectly bulletproof, they
452 could theoretically be the same by chance, causing us to fail. */
453 if (not_manu != manu || not_id != id) /* a value has changed */
455 *p_manufacturer = manu; /* return the results */
456 *p_device = id;
457 return true; /* success */
459 return false; /* fail */
461 #endif /* (CONFIG_CPU == SH7034 || CPU_COLDFIRE) */
463 #ifndef SIMULATOR
464 #ifdef CPU_PP
465 static int perfcheck(void)
467 int result;
469 asm (
470 "mrs r2, CPSR \n"
471 "orr r0, r2, #0xc0 \n" /* disable IRQ and FIQ */
472 "msr CPSR_c, r0 \n"
473 "mov %[res], #0 \n"
474 "ldr r0, [%[timr]] \n"
475 "add r0, r0, %[tmo] \n"
476 "1: \n"
477 "add %[res], %[res], #1 \n"
478 "ldr r1, [%[timr]] \n"
479 "cmp r1, r0 \n"
480 "bmi 1b \n"
481 "msr CPSR_c, r2 \n" /* reset IRQ and FIQ state */
483 [res]"=&r"(result)
485 [timr]"r"(&USEC_TIMER),
486 [tmo]"r"(
487 #if CONFIG_CPU == PP5002
488 16000
489 #else /* PP5020/5022/5024 */
490 10226
491 #endif
494 "r0", "r1", "r2"
496 return result;
498 #endif
500 #ifdef HAVE_LCD_BITMAP
501 static bool dbg_hw_info(void)
503 #if CONFIG_CPU == SH7034
504 char buf[32];
505 int bitmask = HW_MASK;
506 int rom_version = ROM_VERSION;
507 unsigned manu, id; /* flash IDs */
508 bool got_id; /* flag if we managed to get the flash IDs */
509 unsigned rom_crc = 0xffffffff; /* CRC32 of the boot ROM */
510 bool has_bootrom; /* flag for boot ROM present */
511 int oldmode; /* saved memory guard mode */
513 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
515 /* get flash ROM type */
516 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
517 if (!got_id)
518 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
520 /* check if the boot ROM area is a flash mirror */
521 has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0);
522 if (has_bootrom) /* if ROM and Flash different */
524 /* calculate CRC16 checksum of boot ROM */
525 rom_crc = crc_32((unsigned char*)0x0000, 64*1024, 0xffffffff);
528 system_memory_guard(oldmode); /* re-enable memory guard */
530 lcd_setmargins(0, 0);
531 lcd_setfont(FONT_SYSFIXED);
532 lcd_clear_display();
534 lcd_puts(0, 0, "[Hardware info]");
536 snprintf(buf, 32, "ROM: %d.%02d", rom_version/100, rom_version%100);
537 lcd_puts(0, 1, buf);
539 snprintf(buf, 32, "Mask: 0x%04x", bitmask);
540 lcd_puts(0, 2, buf);
542 if (got_id)
543 snprintf(buf, 32, "Flash: M=%02x D=%02x", manu, id);
544 else
545 snprintf(buf, 32, "Flash: M=?? D=??"); /* unknown, sorry */
546 lcd_puts(0, 3, buf);
548 if (has_bootrom)
550 if (rom_crc == 0x56DBA4EE) /* known Version 1 */
551 snprintf(buf, 32, "Boot ROM: V1");
552 else
553 snprintf(buf, 32, "ROMcrc: 0x%08x", rom_crc);
555 else
557 snprintf(buf, 32, "Boot ROM: none");
559 lcd_puts(0, 4, buf);
561 lcd_update();
563 while (!(action_userabort(TIMEOUT_BLOCK)));
565 #elif CONFIG_CPU == MCF5249 || CONFIG_CPU == MCF5250
566 char buf[32];
567 unsigned manu, id; /* flash IDs */
568 int got_id; /* flag if we managed to get the flash IDs */
569 int oldmode; /* saved memory guard mode */
570 int line = 0;
572 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
574 /* get flash ROM type */
575 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
576 if (!got_id)
577 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
579 system_memory_guard(oldmode); /* re-enable memory guard */
581 lcd_setmargins(0, 0);
582 lcd_setfont(FONT_SYSFIXED);
583 lcd_clear_display();
585 lcd_puts(0, line++, "[Hardware info]");
587 if (got_id)
588 snprintf(buf, 32, "Flash: M=%04x D=%04x", manu, id);
589 else
590 snprintf(buf, 32, "Flash: M=???? D=????"); /* unknown, sorry */
591 lcd_puts(0, line++, buf);
593 #ifdef IAUDIO_X5
595 struct ds2411_id id;
597 lcd_puts(0, ++line, "Serial Number:");
599 got_id = ds2411_read_id(&id);
601 if (got_id == DS2411_OK)
603 snprintf(buf, 32, " FC=%02x", (unsigned)id.family_code);
604 lcd_puts(0, ++line, buf);
605 snprintf(buf, 32, " ID=%02X %02X %02X %02X %02X %02X",
606 (unsigned)id.uid[0], (unsigned)id.uid[1], (unsigned)id.uid[2],
607 (unsigned)id.uid[3], (unsigned)id.uid[4], (unsigned)id.uid[5]);
608 lcd_puts(0, ++line, buf);
609 snprintf(buf, 32, " CRC=%02X", (unsigned)id.crc);
611 else
613 snprintf(buf, 32, "READ ERR=%d", got_id);
616 lcd_puts(0, ++line, buf);
618 #endif
620 lcd_update();
622 while (!(action_userabort(TIMEOUT_BLOCK)));
624 #elif defined(CPU_PP502x)
625 int line = 0;
626 char buf[32];
627 char pp_version[] = { (PP_VER2 >> 24) & 0xff, (PP_VER2 >> 16) & 0xff,
628 (PP_VER2 >> 8) & 0xff, (PP_VER2) & 0xff,
629 (PP_VER1 >> 24) & 0xff, (PP_VER1 >> 16) & 0xff,
630 (PP_VER1 >> 8) & 0xff, (PP_VER1) & 0xff, '\0' };
632 lcd_setmargins(0, 0);
633 lcd_setfont(FONT_SYSFIXED);
634 lcd_clear_display();
636 lcd_puts(0, line++, "[Hardware info]");
638 #ifdef IPOD_ARCH
639 snprintf(buf, sizeof(buf), "HW rev: 0x%08lx", IPOD_HW_REVISION);
640 lcd_puts(0, line++, buf);
641 #endif
643 #ifdef IPOD_COLOR
644 extern int lcd_type; /* Defined in lcd-colornano.c */
646 snprintf(buf, sizeof(buf), "LCD type: %d", lcd_type);
647 lcd_puts(0, line++, buf);
648 #endif
650 snprintf(buf, sizeof(buf), "PP version: %s", pp_version);
651 lcd_puts(0, line++, buf);
653 snprintf(buf, sizeof(buf), "Est. clock (kHz): %d", perfcheck());
654 lcd_puts(0, line++, buf);
656 lcd_update();
658 while (!(action_userabort(TIMEOUT_BLOCK)));
660 #elif CONFIG_CPU == PP5002
661 int line = 0;
662 char buf[32];
664 lcd_setmargins(0, 0);
665 lcd_setfont(FONT_SYSFIXED);
666 lcd_clear_display();
668 lcd_puts(0, line++, "[Hardware info]");
670 #ifdef IPOD_ARCH
671 snprintf(buf, sizeof(buf), "HW rev: 0x%08lx", IPOD_HW_REVISION);
672 lcd_puts(0, line++, buf);
673 #endif
675 snprintf(buf, sizeof(buf), "Est. clock (kHz): %d", perfcheck());
676 lcd_puts(0, line++, buf);
678 lcd_update();
680 while (!(action_userabort(TIMEOUT_BLOCK)));
682 #endif /* CONFIG_CPU */
683 return false;
685 #else /* !HAVE_LCD_BITMAP */
686 static bool dbg_hw_info(void)
688 char buf[32];
689 int button;
690 int currval = 0;
691 int rom_version = ROM_VERSION;
692 unsigned manu, id; /* flash IDs */
693 bool got_id; /* flag if we managed to get the flash IDs */
694 unsigned rom_crc = 0xffffffff; /* CRC32 of the boot ROM */
695 bool has_bootrom; /* flag for boot ROM present */
696 int oldmode; /* saved memory guard mode */
698 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
700 /* get flash ROM type */
701 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
702 if (!got_id)
703 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
705 /* check if the boot ROM area is a flash mirror */
706 has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0);
707 if (has_bootrom) /* if ROM and Flash different */
709 /* calculate CRC16 checksum of boot ROM */
710 rom_crc = crc_32((unsigned char*)0x0000, 64*1024, 0xffffffff);
713 system_memory_guard(oldmode); /* re-enable memory guard */
715 lcd_clear_display();
717 lcd_puts(0, 0, "[HW Info]");
718 while(1)
720 switch(currval)
722 case 0:
723 snprintf(buf, 32, "ROM: %d.%02d",
724 rom_version/100, rom_version%100);
725 break;
726 case 1:
727 if (got_id)
728 snprintf(buf, 32, "Flash:%02x,%02x", manu, id);
729 else
730 snprintf(buf, 32, "Flash:??,??"); /* unknown, sorry */
731 break;
732 case 2:
733 if (has_bootrom)
735 if (rom_crc == 0x56DBA4EE) /* known Version 1 */
736 snprintf(buf, 32, "BootROM: V1");
737 else if (rom_crc == 0x358099E8)
738 snprintf(buf, 32, "BootROM: V2");
739 /* alternative boot ROM found in one single player so far */
740 else
741 snprintf(buf, 32, "R: %08x", rom_crc);
743 else
744 snprintf(buf, 32, "BootROM: no");
747 lcd_puts(0, 1, buf);
748 lcd_update();
750 button = get_action(CONTEXT_SETTINGS,TIMEOUT_BLOCK);
752 switch(button)
754 case ACTION_STD_CANCEL:
755 return false;
757 case ACTION_SETTINGS_DEC:
758 currval--;
759 if(currval < 0)
760 currval = 2;
761 break;
763 case ACTION_SETTINGS_INC:
764 currval++;
765 if(currval > 2)
766 currval = 0;
767 break;
770 return false;
772 #endif /* !HAVE_LCD_BITMAP */
773 #endif /* !SIMULATOR */
775 #ifndef SIMULATOR
776 static char* dbg_partitions_getname(int selected_item, void * data, char *buffer)
778 (void)data;
779 int partition = selected_item/2;
780 struct partinfo* p = disk_partinfo(partition);
781 if (selected_item%2)
783 snprintf(buffer, MAX_PATH, " T:%x %ld MB", p->type, p->size / 2048);
785 else
787 snprintf(buffer, MAX_PATH, "P%d: S:%lx", partition, p->start);
789 return buffer;
792 bool dbg_partitions(void)
794 struct action_callback_info info;
795 info.title = "Partition Info";
796 info.count = 4;
797 info.selection_size = 2;
798 info.action_callback = NULL;
799 info.dbg_getname = dbg_partitions_getname;
800 dbg_list(&info);
801 return false;
803 #endif
805 #if defined(CPU_COLDFIRE) && defined(HAVE_SPDIF_OUT)
806 static bool dbg_spdif(void)
808 char buf[128];
809 int line;
810 unsigned int control;
811 int x;
812 char *s;
813 int category;
814 int generation;
815 unsigned int interruptstat;
816 bool valnogood, symbolerr, parityerr;
817 bool done = false;
818 bool spdif_src_on;
819 int spdif_source = spdif_get_output_source(&spdif_src_on);
820 spdif_set_output_source(AUDIO_SRC_SPDIF IF_SPDIF_POWER_(, true));
822 lcd_setmargins(0, 0);
823 lcd_clear_display();
824 lcd_setfont(FONT_SYSFIXED);
826 #ifdef HAVE_SPDIF_POWER
827 spdif_power_enable(true); /* We need SPDIF power for both sending & receiving */
828 #endif
830 while (!done)
832 line = 0;
834 control = EBU1RCVCCHANNEL1;
835 interruptstat = INTERRUPTSTAT;
836 INTERRUPTCLEAR = 0x03c00000;
838 valnogood = (interruptstat & 0x01000000)?true:false;
839 symbolerr = (interruptstat & 0x00800000)?true:false;
840 parityerr = (interruptstat & 0x00400000)?true:false;
842 snprintf(buf, sizeof(buf), "Val: %s Sym: %s Par: %s",
843 valnogood?"--":"OK",
844 symbolerr?"--":"OK",
845 parityerr?"--":"OK");
846 lcd_puts(0, line++, buf);
848 snprintf(buf, sizeof(buf), "Status word: %08x", (int)control);
849 lcd_puts(0, line++, buf);
851 line++;
853 x = control >> 31;
854 snprintf(buf, sizeof(buf), "PRO: %d (%s)",
855 x, x?"Professional":"Consumer");
856 lcd_puts(0, line++, buf);
858 x = (control >> 30) & 1;
859 snprintf(buf, sizeof(buf), "Audio: %d (%s)",
860 x, x?"Non-PCM":"PCM");
861 lcd_puts(0, line++, buf);
863 x = (control >> 29) & 1;
864 snprintf(buf, sizeof(buf), "Copy: %d (%s)",
865 x, x?"Permitted":"Inhibited");
866 lcd_puts(0, line++, buf);
868 x = (control >> 27) & 7;
869 switch(x)
871 case 0:
872 s = "None";
873 break;
874 case 1:
875 s = "50/15us";
876 break;
877 default:
878 s = "Reserved";
879 break;
881 snprintf(buf, sizeof(buf), "Preemphasis: %d (%s)", x, s);
882 lcd_puts(0, line++, buf);
884 x = (control >> 24) & 3;
885 snprintf(buf, sizeof(buf), "Mode: %d", x);
886 lcd_puts(0, line++, buf);
888 category = (control >> 17) & 127;
889 switch(category)
891 case 0x00:
892 s = "General";
893 break;
894 case 0x40:
895 s = "Audio CD";
896 break;
897 default:
898 s = "Unknown";
900 snprintf(buf, sizeof(buf), "Category: 0x%02x (%s)", category, s);
901 lcd_puts(0, line++, buf);
903 x = (control >> 16) & 1;
904 generation = x;
905 if(((category & 0x70) == 0x10) ||
906 ((category & 0x70) == 0x40) ||
907 ((category & 0x78) == 0x38))
909 generation = !generation;
911 snprintf(buf, sizeof(buf), "Generation: %d (%s)",
912 x, generation?"Original":"No ind.");
913 lcd_puts(0, line++, buf);
915 x = (control >> 12) & 15;
916 snprintf(buf, sizeof(buf), "Source: %d", x);
917 lcd_puts(0, line++, buf);
919 x = (control >> 8) & 15;
920 switch(x)
922 case 0:
923 s = "Unspecified";
924 break;
925 case 8:
926 s = "A (Left)";
927 break;
928 case 4:
929 s = "B (Right)";
930 break;
931 default:
932 s = "";
933 break;
935 snprintf(buf, sizeof(buf), "Channel: %d (%s)", x, s);
936 lcd_puts(0, line++, buf);
938 x = (control >> 4) & 15;
939 switch(x)
941 case 0:
942 s = "44.1kHz";
943 break;
944 case 0x4:
945 s = "48kHz";
946 break;
947 case 0xc:
948 s = "32kHz";
949 break;
951 snprintf(buf, sizeof(buf), "Frequency: %d (%s)", x, s);
952 lcd_puts(0, line++, buf);
954 x = (control >> 2) & 3;
955 snprintf(buf, sizeof(buf), "Clock accuracy: %d", x);
956 lcd_puts(0, line++, buf);
957 line++;
959 #ifndef SIMULATOR
960 snprintf(buf, sizeof(buf), "Measured freq: %ldHz",
961 spdif_measure_frequency());
962 lcd_puts(0, line++, buf);
963 #endif
965 lcd_update();
967 if (action_userabort(HZ/10))
968 break;
971 spdif_set_output_source(spdif_source IF_SPDIF_POWER_(, spdif_src_on));
973 #ifdef HAVE_SPDIF_POWER
974 spdif_power_enable(global_settings.spdif_enable);
975 #endif
977 return false;
979 #endif /* CPU_COLDFIRE */
981 #ifndef SIMULATOR
982 #ifdef HAVE_LCD_BITMAP
983 /* button definitions */
984 #if (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
985 (CONFIG_KEYPAD == IRIVER_H300_PAD)
986 # define DEBUG_CANCEL BUTTON_OFF
988 #elif CONFIG_KEYPAD == RECORDER_PAD
989 # define DEBUG_CANCEL BUTTON_OFF
991 #elif CONFIG_KEYPAD == ONDIO_PAD
992 # define DEBUG_CANCEL BUTTON_MENU
994 #elif (CONFIG_KEYPAD == IPOD_1G2G_PAD) || \
995 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
996 (CONFIG_KEYPAD == IPOD_4G_PAD)
997 # define DEBUG_CANCEL BUTTON_MENU
999 #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
1000 # define DEBUG_CANCEL BUTTON_PLAY
1002 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
1003 # define DEBUG_CANCEL BUTTON_REC
1005 #elif CONFIG_KEYPAD == GIGABEAT_PAD
1006 # define DEBUG_CANCEL BUTTON_A
1008 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
1009 # define DEBUG_CANCEL BUTTON_REW
1011 #elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \
1012 (CONFIG_KEYPAD == SANSA_C200_PAD)
1013 # define DEBUG_CANCEL BUTTON_LEFT
1014 #endif /* key definitios */
1016 /* Test code!!! */
1017 bool dbg_ports(void)
1019 #if CONFIG_CPU == SH7034
1020 unsigned short porta;
1021 unsigned short portb;
1022 unsigned char portc;
1023 char buf[32];
1024 int adc_battery_voltage, adc_battery_level;
1026 lcd_setfont(FONT_SYSFIXED);
1027 lcd_setmargins(0, 0);
1028 lcd_clear_display();
1030 while(1)
1032 porta = PADR;
1033 portb = PBDR;
1034 portc = PCDR;
1036 snprintf(buf, 32, "PADR: %04x", porta);
1037 lcd_puts(0, 0, buf);
1038 snprintf(buf, 32, "PBDR: %04x", portb);
1039 lcd_puts(0, 1, buf);
1041 snprintf(buf, 32, "AN0: %03x AN4: %03x", adc_read(0), adc_read(4));
1042 lcd_puts(0, 2, buf);
1043 snprintf(buf, 32, "AN1: %03x AN5: %03x", adc_read(1), adc_read(5));
1044 lcd_puts(0, 3, buf);
1045 snprintf(buf, 32, "AN2: %03x AN6: %03x", adc_read(2), adc_read(6));
1046 lcd_puts(0, 4, buf);
1047 snprintf(buf, 32, "AN3: %03x AN7: %03x", adc_read(3), adc_read(7));
1048 lcd_puts(0, 5, buf);
1050 battery_read_info(&adc_battery_voltage, &adc_battery_level);
1051 snprintf(buf, 32, "Batt: %d.%03dV %d%% ", adc_battery_voltage / 1000,
1052 adc_battery_voltage % 1000, adc_battery_level);
1053 lcd_puts(0, 6, buf);
1055 lcd_update();
1056 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1057 return false;
1059 #elif defined(CPU_COLDFIRE)
1060 unsigned int gpio_out;
1061 unsigned int gpio1_out;
1062 unsigned int gpio_read;
1063 unsigned int gpio1_read;
1064 unsigned int gpio_function;
1065 unsigned int gpio1_function;
1066 unsigned int gpio_enable;
1067 unsigned int gpio1_enable;
1068 int adc_buttons, adc_remote;
1069 int adc_battery_voltage, adc_battery_level;
1070 char buf[128];
1071 int line;
1073 lcd_setmargins(0, 0);
1074 lcd_clear_display();
1075 lcd_setfont(FONT_SYSFIXED);
1077 while(1)
1079 line = 0;
1080 gpio_read = GPIO_READ;
1081 gpio1_read = GPIO1_READ;
1082 gpio_out = GPIO_OUT;
1083 gpio1_out = GPIO1_OUT;
1084 gpio_function = GPIO_FUNCTION;
1085 gpio1_function = GPIO1_FUNCTION;
1086 gpio_enable = GPIO_ENABLE;
1087 gpio1_enable = GPIO1_ENABLE;
1089 snprintf(buf, sizeof(buf), "GPIO_READ: %08x", gpio_read);
1090 lcd_puts(0, line++, buf);
1091 snprintf(buf, sizeof(buf), "GPIO_OUT: %08x", gpio_out);
1092 lcd_puts(0, line++, buf);
1093 snprintf(buf, sizeof(buf), "GPIO_FUNCTION: %08x", gpio_function);
1094 lcd_puts(0, line++, buf);
1095 snprintf(buf, sizeof(buf), "GPIO_ENABLE: %08x", gpio_enable);
1096 lcd_puts(0, line++, buf);
1098 snprintf(buf, sizeof(buf), "GPIO1_READ: %08x", gpio1_read);
1099 lcd_puts(0, line++, buf);
1100 snprintf(buf, sizeof(buf), "GPIO1_OUT: %08x", gpio1_out);
1101 lcd_puts(0, line++, buf);
1102 snprintf(buf, sizeof(buf), "GPIO1_FUNCTION: %08x", gpio1_function);
1103 lcd_puts(0, line++, buf);
1104 snprintf(buf, sizeof(buf), "GPIO1_ENABLE: %08x", gpio1_enable);
1105 lcd_puts(0, line++, buf);
1107 adc_buttons = adc_read(ADC_BUTTONS);
1108 adc_remote = adc_read(ADC_REMOTE);
1109 battery_read_info(&adc_battery_voltage, &adc_battery_level);
1110 #if defined(IAUDIO_X5) || defined(IAUDIO_M5) || defined(IRIVER_H300_SERIES)
1111 snprintf(buf, sizeof(buf), "ADC_BUTTONS (%c): %02x",
1112 button_scan_enabled() ? '+' : '-', adc_buttons);
1113 #else
1114 snprintf(buf, sizeof(buf), "ADC_BUTTONS: %02x", adc_buttons);
1115 #endif
1116 lcd_puts(0, line++, buf);
1117 #if defined(IAUDIO_X5) || defined(IAUDIO_M5)
1118 snprintf(buf, sizeof(buf), "ADC_REMOTE (%c): %02x",
1119 remote_detect() ? '+' : '-', adc_remote);
1120 #else
1121 snprintf(buf, sizeof(buf), "ADC_REMOTE: %02x", adc_remote);
1122 #endif
1123 lcd_puts(0, line++, buf);
1124 #if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES)
1125 snprintf(buf, sizeof(buf), "ADC_REMOTEDETECT: %02x",
1126 adc_read(ADC_REMOTEDETECT));
1127 lcd_puts(0, line++, buf);
1128 #endif
1130 snprintf(buf, 32, "Batt: %d.%03dV %d%% ", adc_battery_voltage / 1000,
1131 adc_battery_voltage % 1000, adc_battery_level);
1132 lcd_puts(0, line++, buf);
1134 #if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES)
1135 snprintf(buf, sizeof(buf), "remotetype: %d", remote_type());
1136 lcd_puts(0, line++, buf);
1137 #endif
1139 lcd_update();
1140 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1141 return false;
1144 #elif defined(CPU_PP502x)
1146 unsigned int gpio_a, gpio_b, gpio_c, gpio_d;
1147 unsigned int gpio_e, gpio_f, gpio_g, gpio_h;
1148 unsigned int gpio_i, gpio_j, gpio_k, gpio_l;
1150 char buf[128];
1151 int line;
1153 lcd_setmargins(0, 0);
1154 lcd_clear_display();
1155 lcd_setfont(FONT_SYSFIXED);
1157 while(1)
1159 gpio_a = GPIOA_INPUT_VAL;
1160 gpio_b = GPIOB_INPUT_VAL;
1161 gpio_c = GPIOC_INPUT_VAL;
1163 gpio_g = GPIOG_INPUT_VAL;
1164 gpio_h = GPIOH_INPUT_VAL;
1165 gpio_i = GPIOI_INPUT_VAL;
1167 line = 0;
1168 snprintf(buf, sizeof(buf), "GPIO_A: %02x GPIO_G: %02x", gpio_a, gpio_g);
1169 lcd_puts(0, line++, buf);
1170 snprintf(buf, sizeof(buf), "GPIO_B: %02x GPIO_H: %02x", gpio_b, gpio_h);
1171 lcd_puts(0, line++, buf);
1172 snprintf(buf, sizeof(buf), "GPIO_C: %02x GPIO_I: %02x", gpio_c, gpio_i);
1173 lcd_puts(0, line++, buf);
1175 gpio_d = GPIOD_INPUT_VAL;
1176 gpio_e = GPIOE_INPUT_VAL;
1177 gpio_f = GPIOF_INPUT_VAL;
1179 gpio_j = GPIOJ_INPUT_VAL;
1180 gpio_k = GPIOK_INPUT_VAL;
1181 gpio_l = GPIOL_INPUT_VAL;
1183 snprintf(buf, sizeof(buf), "GPIO_D: %02x GPIO_J: %02x", gpio_d, gpio_j);
1184 lcd_puts(0, line++, buf);
1185 snprintf(buf, sizeof(buf), "GPIO_E: %02x GPIO_K: %02x", gpio_e, gpio_k);
1186 lcd_puts(0, line++, buf);
1187 snprintf(buf, sizeof(buf), "GPIO_F: %02x GPIO_L: %02x", gpio_f, gpio_l);
1188 lcd_puts(0, line++, buf);
1189 line++;
1191 snprintf(buf, sizeof(buf), "DEV_EN: %08lx", DEV_EN);
1192 lcd_puts(0, line++, buf);
1193 snprintf(buf, sizeof(buf), "CLOCK_SRC: %08lx", CLOCK_SOURCE);
1194 lcd_puts(0, line++, buf);
1195 snprintf(buf, sizeof(buf), "CLCD_CLK_SRC: %08lx", CLCD_CLOCK_SRC);
1196 lcd_puts(0, line++, buf);
1197 snprintf(buf, sizeof(buf), "PLL_CONTROL: %08lx", PLL_CONTROL);
1198 lcd_puts(0, line++, buf);
1199 snprintf(buf, sizeof(buf), "PLL_STATUS: %08lx", PLL_STATUS);
1200 lcd_puts(0, line++, buf);
1201 snprintf(buf, sizeof(buf), "DEV_TIMING1: %08lx", DEV_TIMING1);
1202 lcd_puts(0, line++, buf);
1204 #if defined(IRIVER_H10) || defined(IRIVER_H10_5GB)
1205 line++;
1206 snprintf(buf, sizeof(buf), "BATT: %03x UNK1: %03x", adc_read(ADC_BATTERY),
1207 adc_read(ADC_UNKNOWN_1));
1208 lcd_puts(0, line++, buf);
1209 snprintf(buf, sizeof(buf), "REM: %03x PAD: %03x", adc_read(ADC_REMOTE),
1210 adc_read(ADC_SCROLLPAD));
1211 lcd_puts(0, line++, buf);
1212 #elif defined(SANSA_E200)
1213 line++;
1214 snprintf(buf, sizeof(buf), "ADC_BVDD: %02x", adc_read(ADC_BVDD));
1215 lcd_puts(0, line++, buf);
1216 snprintf(buf, sizeof(buf), "ADC_RTCSUP: %02x", adc_read(ADC_RTCSUP));
1217 lcd_puts(0, line++, buf);
1218 snprintf(buf, sizeof(buf), "ADC_UVDD: %02x", adc_read(ADC_UVDD));
1219 lcd_puts(0, line++, buf);
1220 snprintf(buf, sizeof(buf), "ADC_CHG_IN: %02x", adc_read(ADC_CHG_IN));
1221 lcd_puts(0, line++, buf);
1222 snprintf(buf, sizeof(buf), "ADC_CVDD: %02x", adc_read(ADC_CVDD));
1223 lcd_puts(0, line++, buf);
1224 snprintf(buf, sizeof(buf), "ADC_BATTEMP: %02x", adc_read(ADC_BATTEMP));
1225 lcd_puts(0, line++, buf);
1226 snprintf(buf, sizeof(buf), "ADC_MICSUP1: %02x", adc_read(ADC_MICSUP1));
1227 lcd_puts(0, line++, buf);
1228 snprintf(buf, sizeof(buf), "ADC_MICSUP2: %02x", adc_read(ADC_MICSUP2));
1229 lcd_puts(0, line++, buf);
1230 snprintf(buf, sizeof(buf), "ADC_VBE1: %02x", adc_read(ADC_VBE1));
1231 lcd_puts(0, line++, buf);
1232 snprintf(buf, sizeof(buf), "ADC_VBE2: %02x", adc_read(ADC_VBE2));
1233 lcd_puts(0, line++, buf);
1234 snprintf(buf, sizeof(buf), "ADC_I_MICSUP1: %02x", adc_read(ADC_I_MICSUP1));
1235 lcd_puts(0, line++, buf);
1236 snprintf(buf, sizeof(buf), "ADC_I_MICSUP2: %02x", adc_read(ADC_I_MICSUP2));
1237 lcd_puts(0, line++, buf);
1238 snprintf(buf, sizeof(buf), "ADC_VBAT: %02x", adc_read(ADC_VBAT));
1239 lcd_puts(0, line++, buf);
1240 #endif
1241 lcd_update();
1242 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1243 return false;
1246 #elif CONFIG_CPU == PP5002
1247 unsigned int gpio_a, gpio_b, gpio_c, gpio_d;
1249 char buf[128];
1250 int line;
1252 lcd_setmargins(0, 0);
1253 lcd_clear_display();
1254 lcd_setfont(FONT_SYSFIXED);
1256 while(1)
1258 gpio_a = GPIOA_INPUT_VAL;
1259 gpio_b = GPIOB_INPUT_VAL;
1260 gpio_c = GPIOC_INPUT_VAL;
1261 gpio_d = GPIOD_INPUT_VAL;
1263 line = 0;
1264 snprintf(buf, sizeof(buf), "GPIO_A: %02x GPIO_B: %02x", gpio_a, gpio_b);
1265 lcd_puts(0, line++, buf);
1266 snprintf(buf, sizeof(buf), "GPIO_C: %02x GPIO_D: %02x", gpio_c, gpio_d);
1267 lcd_puts(0, line++, buf);
1269 snprintf(buf, sizeof(buf), "DEV_EN: %08lx", DEV_EN);
1270 lcd_puts(0, line++, buf);
1271 snprintf(buf, sizeof(buf), "CLOCK_ENABLE: %08lx", CLOCK_ENABLE);
1272 lcd_puts(0, line++, buf);
1273 snprintf(buf, sizeof(buf), "CLOCK_SOURCE: %08lx", CLOCK_SOURCE);
1274 lcd_puts(0, line++, buf);
1275 snprintf(buf, sizeof(buf), "PLL_CONTROL: %08lx", PLL_CONTROL);
1276 lcd_puts(0, line++, buf);
1277 snprintf(buf, sizeof(buf), "PLL_DIV: %08lx", PLL_DIV);
1278 lcd_puts(0, line++, buf);
1279 snprintf(buf, sizeof(buf), "PLL_MULT: %08lx", PLL_MULT);
1280 lcd_puts(0, line++, buf);
1281 snprintf(buf, sizeof(buf), "TIMING1_CTL: %08lx", TIMING1_CTL);
1282 lcd_puts(0, line++, buf);
1283 snprintf(buf, sizeof(buf), "TIMING2_CTL: %08lx", TIMING2_CTL);
1284 lcd_puts(0, line++, buf);
1286 lcd_update();
1287 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1288 return false;
1290 #elif CONFIG_CPU == S3C2440
1291 char buf[50];
1292 int line;
1294 lcd_setmargins(0, 0);
1295 lcd_clear_display();
1296 lcd_setfont(FONT_SYSFIXED);
1298 while(1)
1300 line = 0;
1301 snprintf(buf, sizeof(buf), "[Ports and Registers]"); lcd_puts(0, line++, buf);
1303 snprintf(buf, sizeof(buf), "GPACON: %08x GPBCON: %08x", GPACON, GPBCON); lcd_puts(0, line++, buf);
1304 snprintf(buf, sizeof(buf), "GPADAT: %08x GPBDAT: %08x", GPADAT, GPBDAT); lcd_puts(0, line++, buf);
1305 snprintf(buf, sizeof(buf), "GPAUP: %08x GPBUP: %08x", 0, GPBUP); lcd_puts(0, line++, buf);
1306 snprintf(buf, sizeof(buf), "GPCCON: %08x GPDCON: %08x", GPCCON, GPDCON); lcd_puts(0, line++, buf);
1307 snprintf(buf, sizeof(buf), "GPCDAT: %08x GPDDAT: %08x", GPCDAT, GPDDAT); lcd_puts(0, line++, buf);
1308 snprintf(buf, sizeof(buf), "GPCUP: %08x GPDUP: %08x", GPCUP, GPDUP); lcd_puts(0, line++, buf);
1310 snprintf(buf, sizeof(buf), "GPCCON: %08x GPDCON: %08x", GPCCON, GPDCON); lcd_puts(0, line++, buf);
1311 snprintf(buf, sizeof(buf), "GPCDAT: %08x GPDDAT: %08x", GPCDAT, GPDDAT); lcd_puts(0, line++, buf);
1312 snprintf(buf, sizeof(buf), "GPCUP: %08x GPDUP: %08x", GPCUP, GPDUP); lcd_puts(0, line++, buf);
1314 snprintf(buf, sizeof(buf), "GPECON: %08x GPFCON: %08x", GPECON, GPFCON); lcd_puts(0, line++, buf);
1315 snprintf(buf, sizeof(buf), "GPEDAT: %08x GPFDAT: %08x", GPEDAT, GPFDAT); lcd_puts(0, line++, buf);
1316 snprintf(buf, sizeof(buf), "GPEUP: %08x GPFUP: %08x", GPEUP, GPFUP); lcd_puts(0, line++, buf);
1318 snprintf(buf, sizeof(buf), "GPGCON: %08x GPHCON: %08x", GPGCON, GPHCON); lcd_puts(0, line++, buf);
1319 snprintf(buf, sizeof(buf), "GPGDAT: %08x GPHDAT: %08x", GPGDAT, GPHDAT); lcd_puts(0, line++, buf);
1320 snprintf(buf, sizeof(buf), "GPGUP: %08x GPHUP: %08x", GPGUP, GPHUP); lcd_puts(0, line++, buf);
1322 snprintf(buf, sizeof(buf), "GPJCON: %08x", GPJCON); lcd_puts(0, line++, buf);
1323 snprintf(buf, sizeof(buf), "GPJDAT: %08x", GPJDAT); lcd_puts(0, line++, buf);
1324 snprintf(buf, sizeof(buf), "GPJUP: %08x", GPJUP); lcd_puts(0, line++, buf);
1326 line++;
1328 snprintf(buf, sizeof(buf), "SRCPND: %08x INTMOD: %08x", SRCPND, INTMOD); lcd_puts(0, line++, buf);
1329 snprintf(buf, sizeof(buf), "INTMSK: %08x INTPND: %08x", INTMSK, INTPND); lcd_puts(0, line++, buf);
1330 snprintf(buf, sizeof(buf), "CLKCON: %08x CLKSLOW: %08x", CLKCON, CLKSLOW); lcd_puts(0, line++, buf);
1331 snprintf(buf, sizeof(buf), "MPLLCON: %08x UPLLCON: %08x", MPLLCON, UPLLCON); lcd_puts(0, line++, buf);
1332 snprintf(buf, sizeof(buf), "CLKDIVN: %08x", CLKDIVN); lcd_puts(0, line++, buf);
1334 lcd_update();
1335 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1336 return false;
1338 #endif /* CPU */
1339 return false;
1341 #else /* !HAVE_LCD_BITMAP */
1342 bool dbg_ports(void)
1344 unsigned short porta;
1345 unsigned short portb;
1346 unsigned char portc;
1347 char buf[32];
1348 int button;
1349 int adc_battery_voltage;
1350 int currval = 0;
1352 lcd_clear_display();
1354 while(1)
1356 porta = PADR;
1357 portb = PBDR;
1358 portc = PCDR;
1360 switch(currval)
1362 case 0:
1363 snprintf(buf, 32, "PADR: %04x", porta);
1364 break;
1365 case 1:
1366 snprintf(buf, 32, "PBDR: %04x", portb);
1367 break;
1368 case 2:
1369 snprintf(buf, 32, "AN0: %03x", adc_read(0));
1370 break;
1371 case 3:
1372 snprintf(buf, 32, "AN1: %03x", adc_read(1));
1373 break;
1374 case 4:
1375 snprintf(buf, 32, "AN2: %03x", adc_read(2));
1376 break;
1377 case 5:
1378 snprintf(buf, 32, "AN3: %03x", adc_read(3));
1379 break;
1380 case 6:
1381 snprintf(buf, 32, "AN4: %03x", adc_read(4));
1382 break;
1383 case 7:
1384 snprintf(buf, 32, "AN5: %03x", adc_read(5));
1385 break;
1386 case 8:
1387 snprintf(buf, 32, "AN6: %03x", adc_read(6));
1388 break;
1389 case 9:
1390 snprintf(buf, 32, "AN7: %03x", adc_read(7));
1391 break;
1392 break;
1394 lcd_puts(0, 0, buf);
1396 battery_read_info(&adc_battery_voltage, NULL);
1397 snprintf(buf, 32, "Batt: %d.%03dV", adc_battery_voltage / 1000,
1398 adc_battery_voltage % 1000);
1399 lcd_puts(0, 1, buf);
1400 lcd_update();
1402 button = get_action(CONTEXT_SETTINGS,HZ/5);
1404 switch(button)
1406 case ACTION_STD_CANCEL:
1407 return false;
1409 case ACTION_SETTINGS_DEC:
1410 currval--;
1411 if(currval < 0)
1412 currval = 9;
1413 break;
1415 case ACTION_SETTINGS_INC:
1416 currval++;
1417 if(currval > 9)
1418 currval = 0;
1419 break;
1422 return false;
1424 #endif /* !HAVE_LCD_BITMAP */
1425 #endif /* !SIMULATOR */
1427 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
1428 static bool dbg_cpufreq(void)
1430 char buf[128];
1431 int line;
1432 int button;
1434 #ifdef HAVE_LCD_BITMAP
1435 lcd_setmargins(0, 0);
1436 lcd_setfont(FONT_SYSFIXED);
1437 #endif
1438 lcd_clear_display();
1440 while(1)
1442 line = 0;
1444 snprintf(buf, sizeof(buf), "Frequency: %ld", FREQ);
1445 lcd_puts(0, line++, buf);
1447 snprintf(buf, sizeof(buf), "boost_counter: %d", get_cpu_boost_counter());
1448 lcd_puts(0, line++, buf);
1450 lcd_update();
1451 button = get_action(CONTEXT_STD,HZ/10);
1453 switch(button)
1455 case ACTION_STD_PREV:
1456 cpu_boost(true);
1457 break;
1459 case ACTION_STD_NEXT:
1460 cpu_boost(false);
1461 break;
1463 case ACTION_STD_OK:
1464 while (get_cpu_boost_counter() > 0)
1465 cpu_boost(false);
1466 set_cpu_frequency(CPUFREQ_DEFAULT);
1467 break;
1469 case ACTION_STD_CANCEL:
1470 return false;
1474 return false;
1476 #endif /* HAVE_ADJUSTABLE_CPU_FREQ */
1478 #ifndef SIMULATOR
1479 #ifdef HAVE_LCD_BITMAP
1481 * view_battery() shows a automatically scaled graph of the battery voltage
1482 * over time. Usable for estimating battery life / charging rate.
1483 * The power_history array is updated in power_thread of powermgmt.c.
1486 #define BAT_LAST_VAL MIN(LCD_WIDTH, POWER_HISTORY_LEN)
1487 #define BAT_YSPACE (LCD_HEIGHT - 20)
1489 static bool view_battery(void)
1491 int view = 0;
1492 int i, x, y;
1493 unsigned short maxv, minv;
1494 char buf[32];
1496 lcd_setmargins(0, 0);
1497 lcd_setfont(FONT_SYSFIXED);
1499 while(1)
1501 lcd_clear_display();
1502 switch (view) {
1503 case 0: /* voltage history graph */
1504 /* Find maximum and minimum voltage for scaling */
1505 minv = power_history[0];
1506 maxv = minv + 1;
1507 for (i = 1; i < BAT_LAST_VAL && power_history[i]; i++) {
1508 if (power_history[i] > maxv)
1509 maxv = power_history[i];
1510 if (power_history[i] < minv)
1511 minv = power_history[i];
1514 snprintf(buf, 30, "Battery %d.%03d", power_history[0] / 1000,
1515 power_history[0] % 1000);
1516 lcd_puts(0, 0, buf);
1517 snprintf(buf, 30, "scale %d.%03d-%d.%03dV",
1518 minv / 1000, minv % 1000, maxv / 1000, maxv % 1000);
1519 lcd_puts(0, 1, buf);
1521 x = 0;
1522 for (i = BAT_LAST_VAL - 1; i >= 0; i--) {
1523 y = (power_history[i] - minv) * BAT_YSPACE / (maxv - minv);
1524 lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
1525 lcd_vline(x, LCD_HEIGHT-1, 20);
1526 lcd_set_drawmode(DRMODE_SOLID);
1527 lcd_vline(x, LCD_HEIGHT-1,
1528 MIN(MAX(LCD_HEIGHT-1 - y, 20), LCD_HEIGHT-1));
1529 x++;
1532 break;
1534 case 1: /* status: */
1535 lcd_puts(0, 0, "Power status:");
1537 battery_read_info(&y, NULL);
1538 snprintf(buf, 30, "Battery: %d.%03d V", y / 1000, y % 1000);
1539 lcd_puts(0, 1, buf);
1540 #ifdef ADC_EXT_POWER
1541 y = (adc_read(ADC_EXT_POWER) * EXT_SCALE_FACTOR) / 1000;
1542 snprintf(buf, 30, "External: %d.%03d V", y / 1000, y % 1000);
1543 lcd_puts(0, 2, buf);
1544 #endif
1545 #if CONFIG_CHARGING
1546 #if CONFIG_CHARGING == CHARGING_CONTROL
1547 snprintf(buf, 30, "Chgr: %s %s",
1548 charger_inserted() ? "present" : "absent",
1549 charger_enabled ? "on" : "off");
1550 lcd_puts(0, 3, buf);
1551 snprintf(buf, 30, "short delta: %d", short_delta);
1552 lcd_puts(0, 5, buf);
1553 snprintf(buf, 30, "long delta: %d", long_delta);
1554 lcd_puts(0, 6, buf);
1555 lcd_puts(0, 7, power_message);
1556 snprintf(buf, 30, "USB Inserted: %s",
1557 usb_inserted() ? "yes" : "no");
1558 lcd_puts(0, 8, buf);
1559 #if defined IRIVER_H300_SERIES
1560 snprintf(buf, 30, "USB Charging Enabled: %s",
1561 usb_charging_enabled() ? "yes" : "no");
1562 lcd_puts(0, 9, buf);
1563 #endif
1564 #else /* CONFIG_CHARGING != CHARGING_CONTROL */
1565 #if defined IPOD_NANO || defined IPOD_VIDEO
1566 int usb_pwr = (GPIOL_INPUT_VAL & 0x10)?true:false;
1567 int ext_pwr = (GPIOL_INPUT_VAL & 0x08)?false:true;
1568 int dock = (GPIOA_INPUT_VAL & 0x10)?true:false;
1569 int charging = (GPIOB_INPUT_VAL & 0x01)?false:true;
1570 int headphone= (GPIOA_INPUT_VAL & 0x80)?true:false;
1572 snprintf(buf, 30, "USB pwr: %s",
1573 usb_pwr ? "present" : "absent");
1574 lcd_puts(0, 3, buf);
1575 snprintf(buf, 30, "EXT pwr: %s",
1576 ext_pwr ? "present" : "absent");
1577 lcd_puts(0, 4, buf);
1578 snprintf(buf, 30, "Battery: %s",
1579 charging ? "charging" : (usb_pwr||ext_pwr) ? "charged" : "discharging");
1580 lcd_puts(0, 5, buf);
1581 snprintf(buf, 30, "Dock mode: %s",
1582 dock ? "enabled" : "disabled");
1583 lcd_puts(0, 6, buf);
1584 snprintf(buf, 30, "Headphone: %s",
1585 headphone ? "connected" : "disconnected");
1586 lcd_puts(0, 7, buf);
1587 #else
1588 snprintf(buf, 30, "Charger: %s",
1589 charger_inserted() ? "present" : "absent");
1590 lcd_puts(0, 3, buf);
1591 #endif
1592 #endif /* CONFIG_CHARGING != CHARGING_CONTROL */
1593 #endif /* CONFIG_CHARGING */
1594 break;
1596 case 2: /* voltage deltas: */
1597 lcd_puts(0, 0, "Voltage deltas:");
1599 for (i = 0; i <= 6; i++) {
1600 y = power_history[i] - power_history[i+1];
1601 snprintf(buf, 30, "-%d min: %s%d.%03d V", i,
1602 (y < 0) ? "-" : "", ((y < 0) ? y * -1 : y) / 1000,
1603 ((y < 0) ? y * -1 : y ) % 1000);
1604 lcd_puts(0, i+1, buf);
1606 break;
1608 case 3: /* remaining time estimation: */
1610 #if CONFIG_CHARGING == CHARGING_CONTROL
1611 snprintf(buf, 30, "charge_state: %d", charge_state);
1612 lcd_puts(0, 0, buf);
1614 snprintf(buf, 30, "Cycle time: %d m", powermgmt_last_cycle_startstop_min);
1615 lcd_puts(0, 1, buf);
1617 snprintf(buf, 30, "Lvl@cyc st: %d%%", powermgmt_last_cycle_level);
1618 lcd_puts(0, 2, buf);
1620 snprintf(buf, 30, "P=%2d I=%2d", pid_p, pid_i);
1621 lcd_puts(0, 3, buf);
1623 snprintf(buf, 30, "Trickle sec: %d/60", trickle_sec);
1624 lcd_puts(0, 4, buf);
1625 #endif /* CONFIG_CHARGING == CHARGING_CONTROL */
1627 snprintf(buf, 30, "Last PwrHist: %d.%03dV",
1628 power_history[0] / 1000,
1629 power_history[0] % 1000);
1630 lcd_puts(0, 5, buf);
1632 snprintf(buf, 30, "battery level: %d%%", battery_level());
1633 lcd_puts(0, 6, buf);
1635 snprintf(buf, 30, "Est. remain: %d m", battery_time());
1636 lcd_puts(0, 7, buf);
1637 break;
1640 lcd_update();
1642 switch(get_action(CONTEXT_SETTINGS,HZ/2))
1644 case ACTION_SETTINGS_DEC:
1645 if (view)
1646 view--;
1647 break;
1649 case ACTION_SETTINGS_INC:
1650 if (view < 3)
1651 view++;
1652 break;
1654 case ACTION_STD_CANCEL:
1655 return false;
1658 return false;
1661 #endif /* HAVE_LCD_BITMAP */
1662 #endif
1664 #ifndef SIMULATOR
1665 #if defined(HAVE_MMC) || defined(HAVE_HOTSWAP)
1666 #if defined(HAVE_MMC)
1667 #define CARDTYPE "MMC"
1668 #else
1669 #define CARDTYPE "microSD"
1670 #endif
1671 static int cardinfo_callback(int btn, struct action_callback_info *info)
1673 tCardInfo *card;
1674 unsigned char card_name[7];
1675 unsigned char pbuf[32];
1676 static const unsigned char i_vmin[] = { 0, 1, 5, 10, 25, 35, 60, 100 };
1677 static const unsigned char i_vmax[] = { 1, 5, 10, 25, 35, 45, 80, 200 };
1678 static const unsigned char *kbit_units[] = { "kBit/s", "MBit/s", "GBit/s" };
1679 static const unsigned char *nsec_units[] = { "ns", "µs", "ms" };
1680 static const char *spec_vers[] = { "1.0-1.2", "1.4", "2.0-2.2",
1681 "3.1-3.31", "4.0" };
1682 if ((btn == ACTION_STD_OK) || (btn == SYS_FS_CHANGED) || (btn == ACTION_REDRAW))
1684 if (btn == ACTION_STD_OK)
1685 info->cbdata ^= 0x1; /* change cards */
1687 dbg_listmessage_setlines(0);
1689 card = card_get_info(info->cbdata);
1691 if (card->initialized > 0)
1693 card_name[6] = '\0';
1694 strncpy(card_name, ((unsigned char*)card->cid) + 3, 6);
1695 dbg_listmessage_addline(
1696 "%s Rev %d.%d", card_name,
1697 (int) card_extract_bits(card->cid, 72, 4),
1698 (int) card_extract_bits(card->cid, 76, 4));
1699 dbg_listmessage_addline(
1700 "Prod: %d/%d",
1701 (int) card_extract_bits(card->cid, 112, 4),
1702 (int) card_extract_bits(card->cid, 116, 4) + 1997);
1703 dbg_listmessage_addline(
1704 "Ser#: 0x%08lx",
1705 card_extract_bits(card->cid, 80, 32));
1706 dbg_listmessage_addline(
1707 "M=%02x, O=%04x",
1708 (int) card_extract_bits(card->cid, 0, 8),
1709 (int) card_extract_bits(card->cid, 8, 16));
1710 int temp = card_extract_bits(card->csd, 2, 4);
1711 dbg_listmessage_addline(
1712 CARDTYPE " v%s", temp < 5 ?
1713 spec_vers[temp] : "?.?");
1714 dbg_listmessage_addline(
1715 "Blocks: 0x%06lx", card->numblocks);
1716 dbg_listmessage_addline(
1717 "Blksz.: %d P:%c%c", card->blocksize,
1718 card_extract_bits(card->csd, 48, 1) ? 'R' : '-',
1719 card_extract_bits(card->csd, 106, 1) ? 'W' : '-');
1720 output_dyn_value(pbuf, sizeof pbuf, card->speed / 1000,
1721 kbit_units, false);
1722 dbg_listmessage_addline(
1723 "Speed: %s", pbuf);
1724 output_dyn_value(pbuf, sizeof pbuf, card->tsac,
1725 nsec_units, false);
1726 dbg_listmessage_addline(
1727 "Tsac: %s", pbuf);
1728 dbg_listmessage_addline(
1729 "Nsac: %d clk", card->nsac);
1730 dbg_listmessage_addline(
1731 "R2W: *%d", card->r2w_factor);
1732 dbg_listmessage_addline(
1733 "IRmax: %d..%d mA",
1734 i_vmin[card_extract_bits(card->csd, 66, 3)],
1735 i_vmax[card_extract_bits(card->csd, 69, 3)]);
1736 dbg_listmessage_addline(
1737 "IWmax: %d..%d mA",
1738 i_vmin[card_extract_bits(card->csd, 72, 3)],
1739 i_vmax[card_extract_bits(card->csd, 75, 3)]);
1741 else if (card->initialized == 0)
1743 dbg_listmessage_addline("Not Found!");
1745 #ifndef HAVE_MMC
1746 else /* card->initialized < 0 */
1748 dbg_listmessage_addline("Init Error! (%d)", card->initialized);
1750 #endif
1751 snprintf(info->title, 16, "[" CARDTYPE " %d]", (int)info->cbdata);
1752 gui_synclist_set_nb_items(info->lists, dbg_listmessage_getlines());
1753 gui_synclist_select_item(info->lists, 0);
1754 btn = ACTION_REDRAW;
1756 return btn;
1758 static bool dbg_disk_info(void)
1760 char listtitle[16];
1761 struct action_callback_info info;
1762 info.title = listtitle;
1763 info.count = 1;
1764 info.selection_size = 1;
1765 info.action_callback = cardinfo_callback;
1766 info.dbg_getname = dbg_listmessage_getname;
1767 info.cbdata = 0;
1768 dbg_list(&info);
1769 return false;
1771 #else /* !defined(HAVE_MMC) && !defined(HAVE_HOTSWAP) */
1772 static int disk_callback(int btn, struct action_callback_info *info)
1774 int i;
1775 char buf[128];
1776 unsigned short* identify_info = ata_get_identify();
1777 bool timing_info_present = false;
1778 (void)btn;
1780 dbg_listmessage_setlines(0);
1782 for (i=0; i < 20; i++)
1783 ((unsigned short*)buf)[i]=htobe16(identify_info[i+27]);
1784 buf[40]=0;
1785 /* kill trailing space */
1786 for (i=39; i && buf[i]==' '; i--)
1787 buf[i] = 0;
1788 dbg_listmessage_addline(
1789 "Model: %s", buf);
1790 for (i=0; i < 4; i++)
1791 ((unsigned short*)buf)[i]=htobe16(identify_info[i+23]);
1792 buf[8]=0;
1793 dbg_listmessage_addline(
1794 "Firmware: %s", buf);
1795 snprintf(buf, sizeof buf, "%ld MB",
1796 ((unsigned long)identify_info[61] << 16 |
1797 (unsigned long)identify_info[60]) / 2048 );
1798 dbg_listmessage_addline(
1799 "Size: %s", buf);
1800 unsigned long free;
1801 fat_size( IF_MV2(0,) NULL, &free );
1802 dbg_listmessage_addline(
1803 "Free: %ld MB", free / 1024);
1804 dbg_listmessage_addline(
1805 "Spinup time: %d ms", ata_spinup_time * (1000/HZ));
1806 i = identify_info[83] & (1<<3);
1807 dbg_listmessage_addline(
1808 "Power mgmt: %s", i ? "enabled" : "unsupported");
1809 i = identify_info[83] & (1<<9);
1810 dbg_listmessage_addline(
1811 "Noise mgmt: %s", i ? "enabled" : "unsupported");
1812 i = identify_info[82] & (1<<6);
1813 dbg_listmessage_addline(
1814 "Read-ahead: %s", i ? "enabled" : "unsupported");
1815 timing_info_present = identify_info[53] & (1<<1);
1816 if(timing_info_present) {
1817 char pio3[2], pio4[2];pio3[1] = 0;
1818 pio4[1] = 0;
1819 pio3[0] = (identify_info[64] & (1<<0)) ? '3' : 0;
1820 pio4[0] = (identify_info[64] & (1<<1)) ? '4' : 0;
1821 dbg_listmessage_addline(
1822 "PIO modes: 0 1 2 %s %s", pio3, pio4);
1824 else {
1825 dbg_listmessage_addline(
1826 "No PIO mode info");
1828 timing_info_present = identify_info[53] & (1<<1);
1829 if(timing_info_present) {
1830 dbg_listmessage_addline(
1831 "Cycle times %dns/%dns",
1832 identify_info[67],
1833 identify_info[68] );
1834 } else {
1835 dbg_listmessage_addline(
1836 "No timing info");
1838 timing_info_present = identify_info[53] & (1<<1);
1839 if(timing_info_present) {
1840 i = identify_info[49] & (1<<11);
1841 dbg_listmessage_addline(
1842 "IORDY support: %s", i ? "yes" : "no");
1843 i = identify_info[49] & (1<<10);
1844 dbg_listmessage_addline(
1845 "IORDY disable: %s", i ? "yes" : "no");
1846 } else {
1847 dbg_listmessage_addline(
1848 "No timing info");
1850 dbg_listmessage_addline(
1851 "Cluster size: %d bytes", fat_get_cluster_size(IF_MV(0)));
1852 gui_synclist_set_nb_items(info->lists, dbg_listmessage_getlines());
1853 return btn;
1855 static bool dbg_disk_info(void)
1857 struct action_callback_info info;
1858 info.title = "Disk Info";
1859 info.count = 1;
1860 info.selection_size = 1;
1861 info.action_callback = disk_callback;
1862 info.dbg_getname = dbg_listmessage_getname;
1863 dbg_list(&info);
1864 return false;
1866 #endif /* !defined(HAVE_MMC) && !defined(HAVE_HOTSWAP) */
1867 #endif /* !SIMULATOR */
1869 #ifdef HAVE_DIRCACHE
1870 static int dircache_callback(int btn, struct action_callback_info *info)
1872 (void)btn; (void)info;
1873 dbg_listmessage_setlines(0);
1874 dbg_listmessage_addline("Cache initialized: %s",
1875 dircache_is_enabled() ? "Yes" : "No");
1876 dbg_listmessage_addline("Cache size: %d B",
1877 dircache_get_cache_size());
1878 dbg_listmessage_addline("Last size: %d B",
1879 global_status.dircache_size);
1880 dbg_listmessage_addline("Limit: %d B",
1881 DIRCACHE_LIMIT);
1882 dbg_listmessage_addline("Reserve: %d/%d B",
1883 dircache_get_reserve_used(), DIRCACHE_RESERVE);
1884 dbg_listmessage_addline("Scanning took: %d s",
1885 dircache_get_build_ticks() / HZ);
1886 dbg_listmessage_addline("Entry count: %d",
1887 dircache_get_entry_count());
1888 return btn;
1891 static bool dbg_dircache_info(void)
1893 struct action_callback_info info;
1894 info.title = "Dircache Info";
1895 info.count = 7;
1896 info.selection_size = 1;
1897 info.action_callback = dircache_callback;
1898 info.dbg_getname = dbg_listmessage_getname;
1899 dbg_list(&info);
1900 return false;
1903 #endif /* HAVE_DIRCACHE */
1905 #ifdef HAVE_TAGCACHE
1906 static int database_callback(int btn, struct action_callback_info *info)
1908 (void)btn; (void)info;
1909 struct tagcache_stat *stat = tagcache_get_stat();
1910 dbg_listmessage_setlines(0);
1911 dbg_listmessage_addline("Initialized: %s",
1912 stat->initialized ? "Yes" : "No");
1913 dbg_listmessage_addline("DB Ready: %s",
1914 stat->ready ? "Yes" : "No");
1915 dbg_listmessage_addline("RAM Cache: %s",
1916 stat->ramcache ? "Yes" : "No");
1917 dbg_listmessage_addline("RAM: %d/%d B",
1918 stat->ramcache_used, stat->ramcache_allocated);
1919 dbg_listmessage_addline("Progress: %d%% (%d entries)",
1920 stat->progress, stat->processed_entries);
1921 dbg_listmessage_addline("Commit step: %d",
1922 stat->commit_step);
1923 dbg_listmessage_addline("Commit delayed: %s",
1924 stat->commit_delayed ? "Yes" : "No");
1925 return btn;
1927 static bool dbg_tagcache_info(void)
1929 struct action_callback_info info;
1930 info.title = "Database Info";
1931 info.count = 7;
1932 info.selection_size = 1;
1933 info.action_callback = database_callback;
1934 info.dbg_getname = dbg_listmessage_getname;
1935 dbg_list(&info);
1936 return false;
1938 #endif
1940 #if CONFIG_CPU == SH7034
1941 static bool dbg_save_roms(void)
1943 int fd;
1944 int oldmode = system_memory_guard(MEMGUARD_NONE);
1946 fd = creat("/internal_rom_0000-FFFF.bin");
1947 if(fd >= 0)
1949 write(fd, (void *)0, 0x10000);
1950 close(fd);
1953 fd = creat("/internal_rom_2000000-203FFFF.bin");
1954 if(fd >= 0)
1956 write(fd, (void *)0x2000000, 0x40000);
1957 close(fd);
1960 system_memory_guard(oldmode);
1961 return false;
1963 #elif defined CPU_COLDFIRE
1964 static bool dbg_save_roms(void)
1966 int fd;
1967 int oldmode = system_memory_guard(MEMGUARD_NONE);
1969 #if defined(IRIVER_H100_SERIES)
1970 fd = creat("/internal_rom_000000-1FFFFF.bin");
1971 #elif defined(IRIVER_H300_SERIES)
1972 fd = creat("/internal_rom_000000-3FFFFF.bin");
1973 #elif defined(IAUDIO_X5) || defined(IAUDIO_M5)
1974 fd = creat("/internal_rom_000000-3FFFFF.bin");
1975 #endif
1976 if(fd >= 0)
1978 write(fd, (void *)0, FLASH_SIZE);
1979 close(fd);
1981 system_memory_guard(oldmode);
1983 #ifdef HAVE_EEPROM
1984 fd = creat("/internal_eeprom.bin");
1985 if (fd >= 0)
1987 int old_irq_level;
1988 char buf[EEPROM_SIZE];
1989 int err;
1991 old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL);
1993 err = eeprom_24cxx_read(0, buf, sizeof buf);
1994 if (err)
1995 gui_syncsplash(HZ*3, "Eeprom read failure (%d)",err);
1996 else
1998 write(fd, buf, sizeof buf);
2001 set_irq_level(old_irq_level);
2003 close(fd);
2005 #endif
2007 return false;
2009 #elif defined(CPU_PP) && !(defined(SANSA_E200) || defined(SANSA_C200))
2010 static bool dbg_save_roms(void)
2012 int fd;
2014 fd = creat("/internal_rom_000000-0FFFFF.bin");
2015 if(fd >= 0)
2017 write(fd, (void *)0x20000000, FLASH_SIZE);
2018 close(fd);
2021 return false;
2023 #endif /* CPU */
2025 #ifndef SIMULATOR
2026 #if CONFIG_TUNER
2027 static int radio_callback(int btn, struct action_callback_info *info)
2029 dbg_listmessage_setlines(1);
2031 #if (CONFIG_TUNER & LV24020LP)
2032 dbg_listmessage_addline("CTRL_STAT: %02X", lv24020lp_get(LV24020LP_CTRL_STAT) );
2033 dbg_listmessage_addline("RADIO_STAT: %02X", lv24020lp_get(LV24020LP_REG_STAT) );
2034 dbg_listmessage_addline("MSS_FM: %d kHz", lv24020lp_get(LV24020LP_MSS_FM) );
2035 dbg_listmessage_addline("MSS_IF: %d Hz", lv24020lp_get(LV24020LP_MSS_IF) );
2036 dbg_listmessage_addline("MSS_SD: %d Hz", lv24020lp_get(LV24020LP_MSS_SD) );
2037 dbg_listmessage_addline("if_set: %d Hz", lv24020lp_get(LV24020LP_IF_SET) );
2038 dbg_listmessage_addline("sd_set: %d Hz", lv24020lp_get(LV24020LP_SD_SET) );
2039 #endif
2040 #if (CONFIG_TUNER & S1A0903X01)
2041 dbg_listmessage_addline("Samsung regs: %08X", s1a0903x01_get(RADIO_ALL));
2042 /* This one doesn't return dynamic data atm */
2043 #endif
2044 #if (CONFIG_TUNER & TEA5767)
2045 struct tea5767_dbg_info nfo;
2046 tea5767_dbg_info(&nfo);
2047 dbg_listmessage_addline("Philips regs:");
2048 dbg_listmessage_addline(
2049 " Read: %02X %02X %02X %02X %02X",
2050 (unsigned)nfo.read_regs[0], (unsigned)nfo.read_regs[1],
2051 (unsigned)nfo.read_regs[2], (unsigned)nfo.read_regs[3],
2052 (unsigned)nfo.read_regs[4]);
2053 dbg_listmessage_addline(
2054 " Write: %02X %02X %02X %02X %02X",
2055 (unsigned)nfo.write_regs[0], (unsigned)nfo.write_regs[1],
2056 (unsigned)nfo.write_regs[2], (unsigned)nfo.write_regs[3],
2057 (unsigned)nfo.write_regs[4]);
2058 #endif
2060 if (btn != ACTION_STD_CANCEL)
2061 btn = ACTION_REDRAW;
2063 gui_synclist_set_nb_items(info->lists, dbg_listmessage_getlines());
2064 return btn;
2066 static bool dbg_fm_radio(void)
2068 struct action_callback_info info;
2070 info.title = "FM Radio";
2071 info.count = 1;
2072 info.selection_size = 1;
2073 info.cbdata = radio_hardware_present();
2074 info.action_callback = info.cbdata ? radio_callback : NULL;
2075 info.dbg_getname = dbg_listmessage_getname;
2077 dbg_listmessage_setlines(0);
2078 dbg_listmessage_addline("HW detected: %s", info.cbdata ? "yes" : "no");
2080 dbg_list(&info);
2081 return false;
2083 #endif /* CONFIG_TUNER */
2084 #endif /* !SIMULATOR */
2086 #ifdef HAVE_LCD_BITMAP
2087 extern bool do_screendump_instead_of_usb;
2089 static bool dbg_screendump(void)
2091 do_screendump_instead_of_usb = !do_screendump_instead_of_usb;
2092 gui_syncsplash(HZ, "Screendump %s",
2093 do_screendump_instead_of_usb?"enabled":"disabled");
2094 return false;
2096 #endif /* HAVE_LCD_BITMAP */
2098 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
2099 static bool dbg_set_memory_guard(void)
2101 static const struct opt_items names[MAXMEMGUARD] = {
2102 { "None", -1 },
2103 { "Flash ROM writes", -1 },
2104 { "Zero area (all)", -1 }
2106 int mode = system_memory_guard(MEMGUARD_KEEP);
2108 set_option( "Catch mem accesses", &mode, INT, names, MAXMEMGUARD, NULL);
2109 system_memory_guard(mode);
2111 return false;
2113 #endif /* CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) */
2115 #if defined(TOSHIBA_GIGABEAT_F) && !defined(SIMULATOR)
2117 extern volatile bool lcd_poweroff;
2119 static bool dbg_lcd_power_off(void)
2121 lcd_setmargins(0, 0);
2123 while(1)
2125 int button;
2127 lcd_clear_display();
2128 lcd_puts(0, 0, "LCD Power Off");
2129 if(lcd_poweroff)
2130 lcd_puts(1, 1, "Yes");
2131 else
2132 lcd_puts(1, 1, "No");
2134 lcd_update();
2136 button = get_action(CONTEXT_STD,HZ/5);
2137 switch(button)
2139 case ACTION_STD_PREV:
2140 case ACTION_STD_NEXT:
2141 lcd_poweroff = !lcd_poweroff;
2142 break;
2143 case ACTION_STD_OK:
2144 case ACTION_STD_CANCEL:
2145 return false;
2146 default:
2147 sleep(HZ/10);
2148 break;
2151 return false;
2153 #endif
2155 #if defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS)
2156 static bool dbg_write_eeprom(void)
2158 int fd;
2159 int rc;
2160 int old_irq_level;
2161 char buf[EEPROM_SIZE];
2162 int err;
2164 fd = open("/internal_eeprom.bin", O_RDONLY);
2166 if (fd >= 0)
2168 rc = read(fd, buf, EEPROM_SIZE);
2170 if(rc == EEPROM_SIZE)
2172 old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL);
2174 err = eeprom_24cxx_write(0, buf, sizeof buf);
2175 if (err)
2176 gui_syncsplash(HZ*3, "Eeprom write failure (%d)",err);
2177 else
2178 gui_syncsplash(HZ*3, "Eeprom written successfully");
2180 set_irq_level(old_irq_level);
2182 else
2184 gui_syncsplash(HZ*3, "File read error (%d)",rc);
2186 close(fd);
2188 else
2190 gui_syncsplash(HZ*3, "Failed to open 'internal_eeprom.bin'");
2193 return false;
2195 #endif /* defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS) */
2196 #ifdef CPU_BOOST_LOGGING
2197 static bool cpu_boost_log(void)
2199 int i = 0,j=0;
2200 int count = cpu_boost_log_getcount();
2201 int lines = LCD_HEIGHT/SYSFONT_HEIGHT;
2202 char *str;
2203 bool done;
2204 lcd_setmargins(0, 0);
2205 lcd_setfont(FONT_SYSFIXED);
2206 str = cpu_boost_log_getlog_first();
2207 while (i < count)
2209 lcd_clear_display();
2210 for(j=0; j<lines; j++,i++)
2212 if (!str)
2213 str = cpu_boost_log_getlog_next();
2214 if (str)
2216 lcd_puts(0, j,str);
2218 str = NULL;
2220 lcd_update();
2221 done = false;
2222 while (!done)
2224 switch(get_action(CONTEXT_STD,TIMEOUT_BLOCK))
2226 case ACTION_STD_OK:
2227 case ACTION_STD_PREV:
2228 case ACTION_STD_NEXT:
2229 done = true;
2230 break;
2231 case ACTION_STD_CANCEL:
2232 i = count;
2233 done = true;
2234 break;
2238 get_action(CONTEXT_STD,TIMEOUT_BLOCK);
2239 lcd_setfont(FONT_UI);
2240 return false;
2242 #endif
2246 /****** The menu *********/
2247 struct the_menu_item {
2248 unsigned char *desc; /* string or ID */
2249 bool (*function) (void); /* return true if USB was connected */
2251 static const struct the_menu_item menuitems[] = {
2252 #if defined(TOSHIBA_GIGABEAT_F) && !defined(SIMULATOR)
2253 { "LCD Power Off", dbg_lcd_power_off },
2254 #endif
2255 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || \
2256 (defined(CPU_PP) && !(defined(SANSA_E200) || defined(SANSA_C200)))
2257 { "Dump ROM contents", dbg_save_roms },
2258 #endif
2259 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || defined(CPU_PP) || CONFIG_CPU == S3C2440
2260 { "View I/O ports", dbg_ports },
2261 #endif
2262 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
2263 { "CPU frequency", dbg_cpufreq },
2264 #endif
2265 #if defined(IRIVER_H100_SERIES) && !defined(SIMULATOR)
2266 { "S/PDIF analyzer", dbg_spdif },
2267 #endif
2268 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
2269 { "Catch mem accesses", dbg_set_memory_guard },
2270 #endif
2271 { "View OS stacks", dbg_os },
2272 #ifdef HAVE_LCD_BITMAP
2273 #ifndef SIMULATOR
2274 { "View battery", view_battery },
2275 #endif
2276 { "Screendump", dbg_screendump },
2277 #endif
2278 #ifndef SIMULATOR
2279 { "View HW info", dbg_hw_info },
2280 #endif
2281 #ifndef SIMULATOR
2282 { "View partitions", dbg_partitions },
2283 #endif
2284 #ifndef SIMULATOR
2285 { "View disk info", dbg_disk_info },
2286 #endif
2287 #ifdef HAVE_DIRCACHE
2288 { "View dircache info", dbg_dircache_info },
2289 #endif
2290 #ifdef HAVE_TAGCACHE
2291 { "View database info", dbg_tagcache_info },
2292 #endif
2293 #ifdef HAVE_LCD_BITMAP
2294 #if CONFIG_CODEC == SWCODEC || !defined(SIMULATOR)
2295 { "View audio thread", dbg_audio_thread },
2296 #endif
2297 #ifdef PM_DEBUG
2298 { "pm histogram", peak_meter_histogram},
2299 #endif /* PM_DEBUG */
2300 #endif /* HAVE_LCD_BITMAP */
2301 #ifndef SIMULATOR
2302 #if CONFIG_TUNER
2303 { "FM Radio", dbg_fm_radio },
2304 #endif
2305 #endif
2306 #if defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS)
2307 { "Write back EEPROM", dbg_write_eeprom },
2308 #endif
2309 #ifdef ROCKBOX_HAS_LOGF
2310 {"logf", logfdisplay },
2311 {"logfdump", logfdump },
2312 #endif
2313 #ifdef CPU_BOOST_LOGGING
2314 {"cpu_boost log",cpu_boost_log},
2315 #endif
2317 static int menu_action_callback(int btn, struct action_callback_info *info)
2319 if (btn == ACTION_STD_OK)
2321 menuitems[gui_synclist_get_sel_pos(info->lists)].function();
2322 gui_synclist_draw(info->lists);
2324 return btn;
2326 static char* dbg_menu_getname(int item, void * data, char *buffer)
2328 (void)data; (void)buffer;
2329 return menuitems[item].desc;
2331 bool debug_menu(void)
2333 struct action_callback_info info;
2334 info.title = "Debug Menu";
2335 info.count = ARRAYLEN(menuitems);
2336 info.selection_size = 1;
2337 info.action_callback = menu_action_callback;
2338 info.dbg_getname = dbg_menu_getname;
2339 dbg_list(&info);
2340 return false;