Fixes a problem where the sim would try to start the WPS on HAVE_RTC_ALARM sims ...
[Rockbox.git] / apps / debug_menu.c
blobb3b6fe3eca7f9945c06b810c341b2b24a81dc1e6
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 #if defined(HAVE_SPDIF_OUT) || defined(HAVE_SPDIF_IN)
79 #include "spdif.h"
80 #endif
81 #endif
82 #ifdef IRIVER_H300_SERIES
83 #include "pcf50606.h" /* for pcf50606_read */
84 #endif
85 #ifdef IAUDIO_X5
86 #include "ds2411.h"
87 #endif
88 #include "hwcompat.h"
90 #if defined(HAVE_DIRCACHE) || defined(HAVE_TAGCACHE) || CONFIG_TUNER
91 #define MAX_DEBUG_MESSAGES 16
92 #define DEBUG_MSG_LEN 32
93 int debug_listmessage_lines;
94 char debug_list_messages[MAX_DEBUG_MESSAGES][DEBUG_MSG_LEN];
95 static void dbg_listmessage_setlines(int lines)
97 if (lines < 0)
98 lines = 0;
99 else if (lines > MAX_DEBUG_MESSAGES)
100 lines = MAX_DEBUG_MESSAGES;
101 debug_listmessage_lines = lines;
103 #ifndef SIMULATOR
104 static int dbg_listmessage_getlines(void)
106 return debug_listmessage_lines;
108 #endif
109 static void dbg_listmessage_addline(const char *fmt, ...)
111 va_list ap;
113 if (debug_listmessage_lines >= MAX_DEBUG_MESSAGES)
114 return;
116 va_start(ap, fmt);
117 vsnprintf(debug_list_messages[debug_listmessage_lines++], DEBUG_MSG_LEN, fmt, ap);
118 va_end(ap);
120 static char* dbg_listmessage_getname(int item, void * data, char *buffer)
122 (void)buffer; (void)data;
123 return debug_list_messages[item];
125 #endif
127 struct action_callback_info;
128 struct action_callback_info
130 char *title;
131 int count;
132 int selection_size;
133 int (*action_callback)(int btn, struct action_callback_info *info);
134 char* (*dbg_getname)(int item, void * data, char *buffer);
135 intptr_t cbdata; /* extra callback data (pointer, int, whatever) */
136 struct gui_synclist *lists; /* passed back to the callback */
139 static char* dbg_menu_getname(int item, void * data, char *buffer);
140 static bool dbg_list(struct action_callback_info *info)
142 struct gui_synclist lists;
143 int action;
145 info->lists = &lists;
147 gui_synclist_init(&lists, info->dbg_getname, NULL, false,
148 info->selection_size);
149 gui_synclist_set_title(&lists, info->title, NOICON);
150 gui_synclist_set_icon_callback(&lists, NULL);
151 gui_synclist_set_nb_items(&lists, info->count*info->selection_size);
152 if (info->dbg_getname != dbg_menu_getname)
153 gui_synclist_hide_selection_marker(&lists, true);
155 if (info->action_callback)
156 info->action_callback(ACTION_REDRAW, info);
158 gui_synclist_draw(&lists);
160 while(1)
162 gui_syncstatusbar_draw(&statusbars, true);
163 action = get_action(CONTEXT_STD, HZ/5);
164 if (gui_synclist_do_button(&lists, &action, LIST_WRAP_UNLESS_HELD))
165 continue;
166 if (info->action_callback)
167 action = info->action_callback(action, info);
168 if (action == ACTION_STD_CANCEL)
169 break;
170 else if (action == ACTION_REDRAW)
171 gui_synclist_draw(&lists);
172 else if(default_event_handler(action) == SYS_USB_CONNECTED)
173 return true;
175 return false;
177 /*---------------------------------------------------*/
178 /* SPECIAL DEBUG STUFF */
179 /*---------------------------------------------------*/
180 extern struct thread_entry threads[MAXTHREADS];
182 static char thread_status_char(int status)
184 switch (status)
186 case STATE_RUNNING : return 'R';
187 case STATE_BLOCKED : return 'B';
188 case STATE_SLEEPING : return 'S';
189 case STATE_BLOCKED_W_TMO: return 'T';
192 return '?';
195 static char* threads_getname(int selected_item, void * data, char *buffer)
197 (void)data;
198 char name[32];
199 struct thread_entry *thread = NULL;
200 unsigned status;
201 int usage;
203 #if NUM_CORES > 1
204 if (selected_item < (int)NUM_CORES)
206 usage = idle_stack_usage(selected_item);
207 snprintf(buffer, MAX_PATH, "Idle (%d): %2d%%", selected_item, usage);
208 return buffer;
211 selected_item -= NUM_CORES;
212 #endif
214 thread = &threads[selected_item];
215 status = thread_get_status(thread);
217 if (thread->name == NULL)
219 snprintf(buffer, MAX_PATH, "%2d: ---", selected_item);
220 return buffer;
223 thread_get_name(name, 32, thread);
224 usage = thread_stack_usage(thread);
225 status = thread_get_status(thread);
227 snprintf(buffer, MAX_PATH,
228 "%2d: " IF_COP("(%d) ") "%c%c " IF_PRIO("%d ") "%2d%% %s",
229 selected_item,
230 IF_COP(thread->core,)
231 (status == STATE_RUNNING) ? '*' : ' ',
232 thread_status_char(status),
233 IF_PRIO(thread->priority,)
234 usage, name);
236 return buffer;
238 static int dbg_threads_action_callback(int action, struct action_callback_info *info)
240 #ifdef ROCKBOX_HAS_LOGF
241 if (action == ACTION_STD_OK)
243 int selpos = gui_synclist_get_sel_pos(info->lists);
244 #if NUM_CORES > 1
245 if (selpos >= NUM_CORES)
246 remove_thread(&threads[selpos - NUM_CORES]);
247 #else
248 remove_thread(&threads[selpos]);
249 #endif
251 gui_synclist_hide_selection_marker(info->lists, false);
252 #endif /* ROCKBOX_HAS_LOGF */
253 gui_synclist_draw(info->lists);
254 return action;
256 /* Test code!!! */
257 static bool dbg_os(void)
259 struct action_callback_info info;
260 info.title = IF_COP("Core and ") "Stack usage:";
261 #if NUM_CORES == 1
262 info.count = MAXTHREADS;
263 #else
264 info.count = MAXTHREADS+NUM_CORES;
265 #endif
266 info.selection_size = 1;
267 info.action_callback = dbg_threads_action_callback;
268 info.dbg_getname = threads_getname;
269 return dbg_list(&info);
272 #ifdef HAVE_LCD_BITMAP
273 #if CONFIG_CODEC != SWCODEC
274 #ifndef SIMULATOR
275 static bool dbg_audio_thread(void)
277 char buf[32];
278 struct audio_debug d;
280 lcd_setmargins(0, 0);
281 lcd_setfont(FONT_SYSFIXED);
283 while(1)
285 if (action_userabort(HZ/5))
286 return false;
288 audio_get_debugdata(&d);
290 lcd_clear_display();
292 snprintf(buf, sizeof(buf), "read: %x", d.audiobuf_read);
293 lcd_puts(0, 0, buf);
294 snprintf(buf, sizeof(buf), "write: %x", d.audiobuf_write);
295 lcd_puts(0, 1, buf);
296 snprintf(buf, sizeof(buf), "swap: %x", d.audiobuf_swapwrite);
297 lcd_puts(0, 2, buf);
298 snprintf(buf, sizeof(buf), "playing: %d", d.playing);
299 lcd_puts(0, 3, buf);
300 snprintf(buf, sizeof(buf), "playable: %x", d.playable_space);
301 lcd_puts(0, 4, buf);
302 snprintf(buf, sizeof(buf), "unswapped: %x", d.unswapped_space);
303 lcd_puts(0, 5, buf);
305 /* Playable space left */
306 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, 6*8, 112, 4, d.audiobuflen, 0,
307 d.playable_space, HORIZONTAL);
309 /* Show the watermark limit */
310 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, 6*8+4, 112, 4, d.audiobuflen, 0,
311 d.low_watermark_level, HORIZONTAL);
313 snprintf(buf, sizeof(buf), "wm: %x - %x",
314 d.low_watermark_level, d.lowest_watermark_level);
315 lcd_puts(0, 7, buf);
317 lcd_update();
319 return false;
321 #endif /* !SIMULATOR */
322 #else /* CONFIG_CODEC == SWCODEC */
323 extern size_t filebuflen;
324 /* This is a size_t, but call it a long so it puts a - when it's bad. */
326 static unsigned int ticks, boost_ticks;
328 static void dbg_audio_task(void)
330 #ifndef SIMULATOR
331 if(FREQ > CPUFREQ_NORMAL)
332 boost_ticks++;
333 #endif
335 ticks++;
338 static bool dbg_audio_thread(void)
340 char buf[32];
341 int button;
342 int line;
343 bool done = false;
344 size_t bufused;
345 size_t bufsize = pcmbuf_get_bufsize();
346 int pcmbufdescs = pcmbuf_descs();
348 ticks = boost_ticks = 0;
350 tick_add_task(dbg_audio_task);
352 lcd_setmargins(0, 0);
353 lcd_setfont(FONT_SYSFIXED);
354 while(!done)
356 button = get_action(CONTEXT_STD,HZ/5);
357 switch(button)
359 case ACTION_STD_NEXT:
360 audio_next();
361 break;
362 case ACTION_STD_PREV:
363 audio_prev();
364 break;
365 case ACTION_STD_CANCEL:
366 done = true;
367 break;
369 line = 0;
370 lcd_clear_display();
372 bufused = bufsize - pcmbuf_free();
374 snprintf(buf, sizeof(buf), "pcm: %7ld/%7ld", (long) bufused, (long) bufsize);
375 lcd_puts(0, line++, buf);
377 /* Playable space left */
378 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6, bufsize, 0, bufused, HORIZONTAL);
379 line++;
381 snprintf(buf, sizeof(buf), "codec: %8ld/%8ld", audio_filebufused(), (long) filebuflen);
382 lcd_puts(0, line++, buf);
384 /* Playable space left */
385 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6, filebuflen, 0,
386 audio_filebufused(), HORIZONTAL);
387 line++;
389 snprintf(buf, sizeof(buf), "track count: %2d", audio_track_count());
390 lcd_puts(0, line++, buf);
392 #ifndef SIMULATOR
393 snprintf(buf, sizeof(buf), "cpu freq: %3dMHz",
394 (int)((FREQ + 500000) / 1000000));
395 lcd_puts(0, line++, buf);
396 #endif
398 if (ticks > 0)
400 snprintf(buf, sizeof(buf), "boost ratio: %3d%%",
401 boost_ticks * 100 / ticks);
402 lcd_puts(0, line++, buf);
405 snprintf(buf, sizeof(buf), "pcmbufdesc: %2d/%2d",
406 pcmbuf_used_descs(), pcmbufdescs);
407 lcd_puts(0, line++, buf);
409 lcd_update();
412 tick_remove_task(dbg_audio_task);
414 return false;
416 #endif /* CONFIG_CODEC */
417 #endif /* HAVE_LCD_BITMAP */
420 #if (CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE))
421 /* Tool function to read the flash manufacturer and type, if available.
422 Only chips which could be reprogrammed in system will return values.
423 (The mode switch addresses vary between flash manufacturers, hence addr1/2) */
424 /* In IRAM to avoid problems when running directly from Flash */
425 static bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
426 unsigned addr1, unsigned addr2)
427 ICODE_ATTR __attribute__((noinline));
428 static bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
429 unsigned addr1, unsigned addr2)
432 unsigned not_manu, not_id; /* read values before switching to ID mode */
433 unsigned manu, id; /* read values when in ID mode */
435 #if CONFIG_CPU == SH7034
436 volatile unsigned char* flash = (unsigned char*)0x2000000; /* flash mapping */
437 #elif defined(CPU_COLDFIRE)
438 volatile unsigned short* flash = (unsigned short*)0; /* flash mapping */
439 #endif
440 int old_level; /* saved interrupt level */
442 not_manu = flash[0]; /* read the normal content */
443 not_id = flash[1]; /* should be 'A' (0x41) and 'R' (0x52) from the "ARCH" marker */
445 /* disable interrupts, prevent any stray flash access */
446 old_level = set_irq_level(HIGHEST_IRQ_LEVEL);
448 flash[addr1] = 0xAA; /* enter command mode */
449 flash[addr2] = 0x55;
450 flash[addr1] = 0x90; /* ID command */
451 /* Atmel wants 20ms pause here */
452 /* sleep(HZ/50); no sleeping possible while interrupts are disabled */
454 manu = flash[0]; /* read the IDs */
455 id = flash[1];
457 flash[0] = 0xF0; /* reset flash (back to normal read mode) */
458 /* Atmel wants 20ms pause here */
459 /* sleep(HZ/50); no sleeping possible while interrupts are disabled */
461 set_irq_level(old_level); /* enable interrupts again */
463 /* I assume success if the obtained values are different from
464 the normal flash content. This is not perfectly bulletproof, they
465 could theoretically be the same by chance, causing us to fail. */
466 if (not_manu != manu || not_id != id) /* a value has changed */
468 *p_manufacturer = manu; /* return the results */
469 *p_device = id;
470 return true; /* success */
472 return false; /* fail */
474 #endif /* (CONFIG_CPU == SH7034 || CPU_COLDFIRE) */
476 #ifndef SIMULATOR
477 #ifdef CPU_PP
478 static int perfcheck(void)
480 int result;
482 asm (
483 "mrs r2, CPSR \n"
484 "orr r0, r2, #0xc0 \n" /* disable IRQ and FIQ */
485 "msr CPSR_c, r0 \n"
486 "mov %[res], #0 \n"
487 "ldr r0, [%[timr]] \n"
488 "add r0, r0, %[tmo] \n"
489 "1: \n"
490 "add %[res], %[res], #1 \n"
491 "ldr r1, [%[timr]] \n"
492 "cmp r1, r0 \n"
493 "bmi 1b \n"
494 "msr CPSR_c, r2 \n" /* reset IRQ and FIQ state */
496 [res]"=&r"(result)
498 [timr]"r"(&USEC_TIMER),
499 [tmo]"r"(
500 #if CONFIG_CPU == PP5002
501 16000
502 #else /* PP5020/5022/5024 */
503 10226
504 #endif
507 "r0", "r1", "r2"
509 return result;
511 #endif
513 #ifdef HAVE_LCD_BITMAP
514 static bool dbg_hw_info(void)
516 #if CONFIG_CPU == SH7034
517 char buf[32];
518 int bitmask = HW_MASK;
519 int rom_version = ROM_VERSION;
520 unsigned manu, id; /* flash IDs */
521 bool got_id; /* flag if we managed to get the flash IDs */
522 unsigned rom_crc = 0xffffffff; /* CRC32 of the boot ROM */
523 bool has_bootrom; /* flag for boot ROM present */
524 int oldmode; /* saved memory guard mode */
526 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
528 /* get flash ROM type */
529 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
530 if (!got_id)
531 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
533 /* check if the boot ROM area is a flash mirror */
534 has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0);
535 if (has_bootrom) /* if ROM and Flash different */
537 /* calculate CRC16 checksum of boot ROM */
538 rom_crc = crc_32((unsigned char*)0x0000, 64*1024, 0xffffffff);
541 system_memory_guard(oldmode); /* re-enable memory guard */
543 lcd_setmargins(0, 0);
544 lcd_setfont(FONT_SYSFIXED);
545 lcd_clear_display();
547 lcd_puts(0, 0, "[Hardware info]");
549 snprintf(buf, 32, "ROM: %d.%02d", rom_version/100, rom_version%100);
550 lcd_puts(0, 1, buf);
552 snprintf(buf, 32, "Mask: 0x%04x", bitmask);
553 lcd_puts(0, 2, buf);
555 if (got_id)
556 snprintf(buf, 32, "Flash: M=%02x D=%02x", manu, id);
557 else
558 snprintf(buf, 32, "Flash: M=?? D=??"); /* unknown, sorry */
559 lcd_puts(0, 3, buf);
561 if (has_bootrom)
563 if (rom_crc == 0x56DBA4EE) /* known Version 1 */
564 snprintf(buf, 32, "Boot ROM: V1");
565 else
566 snprintf(buf, 32, "ROMcrc: 0x%08x", rom_crc);
568 else
570 snprintf(buf, 32, "Boot ROM: none");
572 lcd_puts(0, 4, buf);
574 lcd_update();
576 while (!(action_userabort(TIMEOUT_BLOCK)));
578 #elif CONFIG_CPU == MCF5249 || CONFIG_CPU == MCF5250
579 char buf[32];
580 unsigned manu, id; /* flash IDs */
581 int got_id; /* flag if we managed to get the flash IDs */
582 int oldmode; /* saved memory guard mode */
583 int line = 0;
585 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
587 /* get flash ROM type */
588 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
589 if (!got_id)
590 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
592 system_memory_guard(oldmode); /* re-enable memory guard */
594 lcd_setmargins(0, 0);
595 lcd_setfont(FONT_SYSFIXED);
596 lcd_clear_display();
598 lcd_puts(0, line++, "[Hardware info]");
600 if (got_id)
601 snprintf(buf, 32, "Flash: M=%04x D=%04x", manu, id);
602 else
603 snprintf(buf, 32, "Flash: M=???? D=????"); /* unknown, sorry */
604 lcd_puts(0, line++, buf);
606 #ifdef IAUDIO_X5
608 struct ds2411_id id;
610 lcd_puts(0, ++line, "Serial Number:");
612 got_id = ds2411_read_id(&id);
614 if (got_id == DS2411_OK)
616 snprintf(buf, 32, " FC=%02x", (unsigned)id.family_code);
617 lcd_puts(0, ++line, buf);
618 snprintf(buf, 32, " ID=%02X %02X %02X %02X %02X %02X",
619 (unsigned)id.uid[0], (unsigned)id.uid[1], (unsigned)id.uid[2],
620 (unsigned)id.uid[3], (unsigned)id.uid[4], (unsigned)id.uid[5]);
621 lcd_puts(0, ++line, buf);
622 snprintf(buf, 32, " CRC=%02X", (unsigned)id.crc);
624 else
626 snprintf(buf, 32, "READ ERR=%d", got_id);
629 lcd_puts(0, ++line, buf);
631 #endif
633 lcd_update();
635 while (!(action_userabort(TIMEOUT_BLOCK)));
637 #elif defined(CPU_PP502x)
638 int line = 0;
639 char buf[32];
640 char pp_version[] = { (PP_VER2 >> 24) & 0xff, (PP_VER2 >> 16) & 0xff,
641 (PP_VER2 >> 8) & 0xff, (PP_VER2) & 0xff,
642 (PP_VER1 >> 24) & 0xff, (PP_VER1 >> 16) & 0xff,
643 (PP_VER1 >> 8) & 0xff, (PP_VER1) & 0xff, '\0' };
645 lcd_setmargins(0, 0);
646 lcd_setfont(FONT_SYSFIXED);
647 lcd_clear_display();
649 lcd_puts(0, line++, "[Hardware info]");
651 #ifdef IPOD_ARCH
652 snprintf(buf, sizeof(buf), "HW rev: 0x%08lx", IPOD_HW_REVISION);
653 lcd_puts(0, line++, buf);
654 #endif
656 #ifdef IPOD_COLOR
657 extern int lcd_type; /* Defined in lcd-colornano.c */
659 snprintf(buf, sizeof(buf), "LCD type: %d", lcd_type);
660 lcd_puts(0, line++, buf);
661 #endif
663 snprintf(buf, sizeof(buf), "PP version: %s", pp_version);
664 lcd_puts(0, line++, buf);
666 snprintf(buf, sizeof(buf), "Est. clock (kHz): %d", perfcheck());
667 lcd_puts(0, line++, buf);
669 lcd_update();
671 while (!(action_userabort(TIMEOUT_BLOCK)));
673 #elif CONFIG_CPU == PP5002
674 int line = 0;
675 char buf[32];
677 lcd_setmargins(0, 0);
678 lcd_setfont(FONT_SYSFIXED);
679 lcd_clear_display();
681 lcd_puts(0, line++, "[Hardware info]");
683 #ifdef IPOD_ARCH
684 snprintf(buf, sizeof(buf), "HW rev: 0x%08lx", IPOD_HW_REVISION);
685 lcd_puts(0, line++, buf);
686 #endif
688 snprintf(buf, sizeof(buf), "Est. clock (kHz): %d", perfcheck());
689 lcd_puts(0, line++, buf);
691 lcd_update();
693 while (!(action_userabort(TIMEOUT_BLOCK)));
695 #endif /* CONFIG_CPU */
696 return false;
698 #else /* !HAVE_LCD_BITMAP */
699 static bool dbg_hw_info(void)
701 char buf[32];
702 int button;
703 int currval = 0;
704 int rom_version = ROM_VERSION;
705 unsigned manu, id; /* flash IDs */
706 bool got_id; /* flag if we managed to get the flash IDs */
707 unsigned rom_crc = 0xffffffff; /* CRC32 of the boot ROM */
708 bool has_bootrom; /* flag for boot ROM present */
709 int oldmode; /* saved memory guard mode */
711 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
713 /* get flash ROM type */
714 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
715 if (!got_id)
716 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
718 /* check if the boot ROM area is a flash mirror */
719 has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0);
720 if (has_bootrom) /* if ROM and Flash different */
722 /* calculate CRC16 checksum of boot ROM */
723 rom_crc = crc_32((unsigned char*)0x0000, 64*1024, 0xffffffff);
726 system_memory_guard(oldmode); /* re-enable memory guard */
728 lcd_clear_display();
730 lcd_puts(0, 0, "[HW Info]");
731 while(1)
733 switch(currval)
735 case 0:
736 snprintf(buf, 32, "ROM: %d.%02d",
737 rom_version/100, rom_version%100);
738 break;
739 case 1:
740 if (got_id)
741 snprintf(buf, 32, "Flash:%02x,%02x", manu, id);
742 else
743 snprintf(buf, 32, "Flash:??,??"); /* unknown, sorry */
744 break;
745 case 2:
746 if (has_bootrom)
748 if (rom_crc == 0x56DBA4EE) /* known Version 1 */
749 snprintf(buf, 32, "BootROM: V1");
750 else if (rom_crc == 0x358099E8)
751 snprintf(buf, 32, "BootROM: V2");
752 /* alternative boot ROM found in one single player so far */
753 else
754 snprintf(buf, 32, "R: %08x", rom_crc);
756 else
757 snprintf(buf, 32, "BootROM: no");
760 lcd_puts(0, 1, buf);
761 lcd_update();
763 button = get_action(CONTEXT_SETTINGS,TIMEOUT_BLOCK);
765 switch(button)
767 case ACTION_STD_CANCEL:
768 return false;
770 case ACTION_SETTINGS_DEC:
771 currval--;
772 if(currval < 0)
773 currval = 2;
774 break;
776 case ACTION_SETTINGS_INC:
777 currval++;
778 if(currval > 2)
779 currval = 0;
780 break;
783 return false;
785 #endif /* !HAVE_LCD_BITMAP */
786 #endif /* !SIMULATOR */
788 #ifndef SIMULATOR
789 static char* dbg_partitions_getname(int selected_item, void * data, char *buffer)
791 (void)data;
792 int partition = selected_item/2;
793 struct partinfo* p = disk_partinfo(partition);
794 if (selected_item%2)
796 snprintf(buffer, MAX_PATH, " T:%x %ld MB", p->type, p->size / 2048);
798 else
800 snprintf(buffer, MAX_PATH, "P%d: S:%lx", partition, p->start);
802 return buffer;
805 bool dbg_partitions(void)
807 struct action_callback_info info;
808 info.title = "Partition Info";
809 info.count = 4;
810 info.selection_size = 2;
811 info.action_callback = NULL;
812 info.dbg_getname = dbg_partitions_getname;
813 dbg_list(&info);
814 return false;
816 #endif
818 #if defined(CPU_COLDFIRE) && defined(HAVE_SPDIF_OUT)
819 static bool dbg_spdif(void)
821 char buf[128];
822 int line;
823 unsigned int control;
824 int x;
825 char *s;
826 int category;
827 int generation;
828 unsigned int interruptstat;
829 bool valnogood, symbolerr, parityerr;
830 bool done = false;
831 bool spdif_src_on;
832 int spdif_source = spdif_get_output_source(&spdif_src_on);
833 spdif_set_output_source(AUDIO_SRC_SPDIF IF_SPDIF_POWER_(, true));
835 lcd_setmargins(0, 0);
836 lcd_clear_display();
837 lcd_setfont(FONT_SYSFIXED);
839 #ifdef HAVE_SPDIF_POWER
840 spdif_power_enable(true); /* We need SPDIF power for both sending & receiving */
841 #endif
843 while (!done)
845 line = 0;
847 control = EBU1RCVCCHANNEL1;
848 interruptstat = INTERRUPTSTAT;
849 INTERRUPTCLEAR = 0x03c00000;
851 valnogood = (interruptstat & 0x01000000)?true:false;
852 symbolerr = (interruptstat & 0x00800000)?true:false;
853 parityerr = (interruptstat & 0x00400000)?true:false;
855 snprintf(buf, sizeof(buf), "Val: %s Sym: %s Par: %s",
856 valnogood?"--":"OK",
857 symbolerr?"--":"OK",
858 parityerr?"--":"OK");
859 lcd_puts(0, line++, buf);
861 snprintf(buf, sizeof(buf), "Status word: %08x", (int)control);
862 lcd_puts(0, line++, buf);
864 line++;
866 x = control >> 31;
867 snprintf(buf, sizeof(buf), "PRO: %d (%s)",
868 x, x?"Professional":"Consumer");
869 lcd_puts(0, line++, buf);
871 x = (control >> 30) & 1;
872 snprintf(buf, sizeof(buf), "Audio: %d (%s)",
873 x, x?"Non-PCM":"PCM");
874 lcd_puts(0, line++, buf);
876 x = (control >> 29) & 1;
877 snprintf(buf, sizeof(buf), "Copy: %d (%s)",
878 x, x?"Permitted":"Inhibited");
879 lcd_puts(0, line++, buf);
881 x = (control >> 27) & 7;
882 switch(x)
884 case 0:
885 s = "None";
886 break;
887 case 1:
888 s = "50/15us";
889 break;
890 default:
891 s = "Reserved";
892 break;
894 snprintf(buf, sizeof(buf), "Preemphasis: %d (%s)", x, s);
895 lcd_puts(0, line++, buf);
897 x = (control >> 24) & 3;
898 snprintf(buf, sizeof(buf), "Mode: %d", x);
899 lcd_puts(0, line++, buf);
901 category = (control >> 17) & 127;
902 switch(category)
904 case 0x00:
905 s = "General";
906 break;
907 case 0x40:
908 s = "Audio CD";
909 break;
910 default:
911 s = "Unknown";
913 snprintf(buf, sizeof(buf), "Category: 0x%02x (%s)", category, s);
914 lcd_puts(0, line++, buf);
916 x = (control >> 16) & 1;
917 generation = x;
918 if(((category & 0x70) == 0x10) ||
919 ((category & 0x70) == 0x40) ||
920 ((category & 0x78) == 0x38))
922 generation = !generation;
924 snprintf(buf, sizeof(buf), "Generation: %d (%s)",
925 x, generation?"Original":"No ind.");
926 lcd_puts(0, line++, buf);
928 x = (control >> 12) & 15;
929 snprintf(buf, sizeof(buf), "Source: %d", x);
930 lcd_puts(0, line++, buf);
932 x = (control >> 8) & 15;
933 switch(x)
935 case 0:
936 s = "Unspecified";
937 break;
938 case 8:
939 s = "A (Left)";
940 break;
941 case 4:
942 s = "B (Right)";
943 break;
944 default:
945 s = "";
946 break;
948 snprintf(buf, sizeof(buf), "Channel: %d (%s)", x, s);
949 lcd_puts(0, line++, buf);
951 x = (control >> 4) & 15;
952 switch(x)
954 case 0:
955 s = "44.1kHz";
956 break;
957 case 0x4:
958 s = "48kHz";
959 break;
960 case 0xc:
961 s = "32kHz";
962 break;
964 snprintf(buf, sizeof(buf), "Frequency: %d (%s)", x, s);
965 lcd_puts(0, line++, buf);
967 x = (control >> 2) & 3;
968 snprintf(buf, sizeof(buf), "Clock accuracy: %d", x);
969 lcd_puts(0, line++, buf);
970 line++;
972 #ifndef SIMULATOR
973 snprintf(buf, sizeof(buf), "Measured freq: %ldHz",
974 spdif_measure_frequency());
975 lcd_puts(0, line++, buf);
976 #endif
978 lcd_update();
980 if (action_userabort(HZ/10))
981 break;
984 spdif_set_output_source(spdif_source IF_SPDIF_POWER_(, spdif_src_on));
986 #ifdef HAVE_SPDIF_POWER
987 spdif_power_enable(global_settings.spdif_enable);
988 #endif
990 return false;
992 #endif /* CPU_COLDFIRE */
994 #ifndef SIMULATOR
995 #ifdef HAVE_LCD_BITMAP
996 /* button definitions */
997 #if (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
998 (CONFIG_KEYPAD == IRIVER_H300_PAD)
999 # define DEBUG_CANCEL BUTTON_OFF
1001 #elif CONFIG_KEYPAD == RECORDER_PAD
1002 # define DEBUG_CANCEL BUTTON_OFF
1004 #elif CONFIG_KEYPAD == ONDIO_PAD
1005 # define DEBUG_CANCEL BUTTON_MENU
1007 #elif (CONFIG_KEYPAD == IPOD_1G2G_PAD) || \
1008 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
1009 (CONFIG_KEYPAD == IPOD_4G_PAD)
1010 # define DEBUG_CANCEL BUTTON_MENU
1012 #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
1013 # define DEBUG_CANCEL BUTTON_PLAY
1015 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
1016 # define DEBUG_CANCEL BUTTON_REC
1018 #elif CONFIG_KEYPAD == GIGABEAT_PAD
1019 # define DEBUG_CANCEL BUTTON_A
1021 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
1022 # define DEBUG_CANCEL BUTTON_REW
1024 #elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \
1025 (CONFIG_KEYPAD == SANSA_C200_PAD)
1026 # define DEBUG_CANCEL BUTTON_LEFT
1027 #endif /* key definitios */
1029 /* Test code!!! */
1030 bool dbg_ports(void)
1032 #if CONFIG_CPU == SH7034
1033 unsigned short porta;
1034 unsigned short portb;
1035 unsigned char portc;
1036 char buf[32];
1037 int adc_battery_voltage, adc_battery_level;
1039 lcd_setfont(FONT_SYSFIXED);
1040 lcd_setmargins(0, 0);
1041 lcd_clear_display();
1043 while(1)
1045 porta = PADR;
1046 portb = PBDR;
1047 portc = PCDR;
1049 snprintf(buf, 32, "PADR: %04x", porta);
1050 lcd_puts(0, 0, buf);
1051 snprintf(buf, 32, "PBDR: %04x", portb);
1052 lcd_puts(0, 1, buf);
1054 snprintf(buf, 32, "AN0: %03x AN4: %03x", adc_read(0), adc_read(4));
1055 lcd_puts(0, 2, buf);
1056 snprintf(buf, 32, "AN1: %03x AN5: %03x", adc_read(1), adc_read(5));
1057 lcd_puts(0, 3, buf);
1058 snprintf(buf, 32, "AN2: %03x AN6: %03x", adc_read(2), adc_read(6));
1059 lcd_puts(0, 4, buf);
1060 snprintf(buf, 32, "AN3: %03x AN7: %03x", adc_read(3), adc_read(7));
1061 lcd_puts(0, 5, buf);
1063 battery_read_info(&adc_battery_voltage, &adc_battery_level);
1064 snprintf(buf, 32, "Batt: %d.%03dV %d%% ", adc_battery_voltage / 1000,
1065 adc_battery_voltage % 1000, adc_battery_level);
1066 lcd_puts(0, 6, buf);
1068 lcd_update();
1069 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1070 return false;
1072 #elif defined(CPU_COLDFIRE)
1073 unsigned int gpio_out;
1074 unsigned int gpio1_out;
1075 unsigned int gpio_read;
1076 unsigned int gpio1_read;
1077 unsigned int gpio_function;
1078 unsigned int gpio1_function;
1079 unsigned int gpio_enable;
1080 unsigned int gpio1_enable;
1081 int adc_buttons, adc_remote;
1082 int adc_battery_voltage, adc_battery_level;
1083 char buf[128];
1084 int line;
1086 lcd_setmargins(0, 0);
1087 lcd_clear_display();
1088 lcd_setfont(FONT_SYSFIXED);
1090 while(1)
1092 line = 0;
1093 gpio_read = GPIO_READ;
1094 gpio1_read = GPIO1_READ;
1095 gpio_out = GPIO_OUT;
1096 gpio1_out = GPIO1_OUT;
1097 gpio_function = GPIO_FUNCTION;
1098 gpio1_function = GPIO1_FUNCTION;
1099 gpio_enable = GPIO_ENABLE;
1100 gpio1_enable = GPIO1_ENABLE;
1102 snprintf(buf, sizeof(buf), "GPIO_READ: %08x", gpio_read);
1103 lcd_puts(0, line++, buf);
1104 snprintf(buf, sizeof(buf), "GPIO_OUT: %08x", gpio_out);
1105 lcd_puts(0, line++, buf);
1106 snprintf(buf, sizeof(buf), "GPIO_FUNCTION: %08x", gpio_function);
1107 lcd_puts(0, line++, buf);
1108 snprintf(buf, sizeof(buf), "GPIO_ENABLE: %08x", gpio_enable);
1109 lcd_puts(0, line++, buf);
1111 snprintf(buf, sizeof(buf), "GPIO1_READ: %08x", gpio1_read);
1112 lcd_puts(0, line++, buf);
1113 snprintf(buf, sizeof(buf), "GPIO1_OUT: %08x", gpio1_out);
1114 lcd_puts(0, line++, buf);
1115 snprintf(buf, sizeof(buf), "GPIO1_FUNCTION: %08x", gpio1_function);
1116 lcd_puts(0, line++, buf);
1117 snprintf(buf, sizeof(buf), "GPIO1_ENABLE: %08x", gpio1_enable);
1118 lcd_puts(0, line++, buf);
1120 adc_buttons = adc_read(ADC_BUTTONS);
1121 adc_remote = adc_read(ADC_REMOTE);
1122 battery_read_info(&adc_battery_voltage, &adc_battery_level);
1123 #if defined(IAUDIO_X5) || defined(IAUDIO_M5) || defined(IRIVER_H300_SERIES)
1124 snprintf(buf, sizeof(buf), "ADC_BUTTONS (%c): %02x",
1125 button_scan_enabled() ? '+' : '-', adc_buttons);
1126 #else
1127 snprintf(buf, sizeof(buf), "ADC_BUTTONS: %02x", adc_buttons);
1128 #endif
1129 lcd_puts(0, line++, buf);
1130 #if defined(IAUDIO_X5) || defined(IAUDIO_M5)
1131 snprintf(buf, sizeof(buf), "ADC_REMOTE (%c): %02x",
1132 remote_detect() ? '+' : '-', adc_remote);
1133 #else
1134 snprintf(buf, sizeof(buf), "ADC_REMOTE: %02x", adc_remote);
1135 #endif
1136 lcd_puts(0, line++, buf);
1137 #if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES)
1138 snprintf(buf, sizeof(buf), "ADC_REMOTEDETECT: %02x",
1139 adc_read(ADC_REMOTEDETECT));
1140 lcd_puts(0, line++, buf);
1141 #endif
1143 snprintf(buf, 32, "Batt: %d.%03dV %d%% ", adc_battery_voltage / 1000,
1144 adc_battery_voltage % 1000, adc_battery_level);
1145 lcd_puts(0, line++, buf);
1147 #if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES)
1148 snprintf(buf, sizeof(buf), "remotetype: %d", remote_type());
1149 lcd_puts(0, line++, buf);
1150 #endif
1152 lcd_update();
1153 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1154 return false;
1157 #elif defined(CPU_PP502x)
1159 unsigned int gpio_a, gpio_b, gpio_c, gpio_d;
1160 unsigned int gpio_e, gpio_f, gpio_g, gpio_h;
1161 unsigned int gpio_i, gpio_j, gpio_k, gpio_l;
1163 char buf[128];
1164 int line;
1166 lcd_setmargins(0, 0);
1167 lcd_clear_display();
1168 lcd_setfont(FONT_SYSFIXED);
1170 while(1)
1172 gpio_a = GPIOA_INPUT_VAL;
1173 gpio_b = GPIOB_INPUT_VAL;
1174 gpio_c = GPIOC_INPUT_VAL;
1176 gpio_g = GPIOG_INPUT_VAL;
1177 gpio_h = GPIOH_INPUT_VAL;
1178 gpio_i = GPIOI_INPUT_VAL;
1180 line = 0;
1181 snprintf(buf, sizeof(buf), "GPIO_A: %02x GPIO_G: %02x", gpio_a, gpio_g);
1182 lcd_puts(0, line++, buf);
1183 snprintf(buf, sizeof(buf), "GPIO_B: %02x GPIO_H: %02x", gpio_b, gpio_h);
1184 lcd_puts(0, line++, buf);
1185 snprintf(buf, sizeof(buf), "GPIO_C: %02x GPIO_I: %02x", gpio_c, gpio_i);
1186 lcd_puts(0, line++, buf);
1188 gpio_d = GPIOD_INPUT_VAL;
1189 gpio_e = GPIOE_INPUT_VAL;
1190 gpio_f = GPIOF_INPUT_VAL;
1192 gpio_j = GPIOJ_INPUT_VAL;
1193 gpio_k = GPIOK_INPUT_VAL;
1194 gpio_l = GPIOL_INPUT_VAL;
1196 snprintf(buf, sizeof(buf), "GPIO_D: %02x GPIO_J: %02x", gpio_d, gpio_j);
1197 lcd_puts(0, line++, buf);
1198 snprintf(buf, sizeof(buf), "GPIO_E: %02x GPIO_K: %02x", gpio_e, gpio_k);
1199 lcd_puts(0, line++, buf);
1200 snprintf(buf, sizeof(buf), "GPIO_F: %02x GPIO_L: %02x", gpio_f, gpio_l);
1201 lcd_puts(0, line++, buf);
1202 line++;
1204 snprintf(buf, sizeof(buf), "DEV_EN: %08lx", DEV_EN);
1205 lcd_puts(0, line++, buf);
1206 snprintf(buf, sizeof(buf), "CLOCK_SRC: %08lx", CLOCK_SOURCE);
1207 lcd_puts(0, line++, buf);
1208 snprintf(buf, sizeof(buf), "CLCD_CLK_SRC: %08lx", CLCD_CLOCK_SRC);
1209 lcd_puts(0, line++, buf);
1210 snprintf(buf, sizeof(buf), "PLL_CONTROL: %08lx", PLL_CONTROL);
1211 lcd_puts(0, line++, buf);
1212 snprintf(buf, sizeof(buf), "PLL_STATUS: %08lx", PLL_STATUS);
1213 lcd_puts(0, line++, buf);
1214 snprintf(buf, sizeof(buf), "DEV_TIMING1: %08lx", DEV_TIMING1);
1215 lcd_puts(0, line++, buf);
1217 #if defined(IRIVER_H10) || defined(IRIVER_H10_5GB)
1218 line++;
1219 snprintf(buf, sizeof(buf), "BATT: %03x UNK1: %03x", adc_read(ADC_BATTERY),
1220 adc_read(ADC_UNKNOWN_1));
1221 lcd_puts(0, line++, buf);
1222 snprintf(buf, sizeof(buf), "REM: %03x PAD: %03x", adc_read(ADC_REMOTE),
1223 adc_read(ADC_SCROLLPAD));
1224 lcd_puts(0, line++, buf);
1225 #elif defined(SANSA_E200)
1226 line++;
1227 snprintf(buf, sizeof(buf), "ADC_BVDD: %02x", adc_read(ADC_BVDD));
1228 lcd_puts(0, line++, buf);
1229 snprintf(buf, sizeof(buf), "ADC_RTCSUP: %02x", adc_read(ADC_RTCSUP));
1230 lcd_puts(0, line++, buf);
1231 snprintf(buf, sizeof(buf), "ADC_UVDD: %02x", adc_read(ADC_UVDD));
1232 lcd_puts(0, line++, buf);
1233 snprintf(buf, sizeof(buf), "ADC_CHG_IN: %02x", adc_read(ADC_CHG_IN));
1234 lcd_puts(0, line++, buf);
1235 snprintf(buf, sizeof(buf), "ADC_CVDD: %02x", adc_read(ADC_CVDD));
1236 lcd_puts(0, line++, buf);
1237 snprintf(buf, sizeof(buf), "ADC_BATTEMP: %02x", adc_read(ADC_BATTEMP));
1238 lcd_puts(0, line++, buf);
1239 snprintf(buf, sizeof(buf), "ADC_MICSUP1: %02x", adc_read(ADC_MICSUP1));
1240 lcd_puts(0, line++, buf);
1241 snprintf(buf, sizeof(buf), "ADC_MICSUP2: %02x", adc_read(ADC_MICSUP2));
1242 lcd_puts(0, line++, buf);
1243 snprintf(buf, sizeof(buf), "ADC_VBE1: %02x", adc_read(ADC_VBE1));
1244 lcd_puts(0, line++, buf);
1245 snprintf(buf, sizeof(buf), "ADC_VBE2: %02x", adc_read(ADC_VBE2));
1246 lcd_puts(0, line++, buf);
1247 snprintf(buf, sizeof(buf), "ADC_I_MICSUP1: %02x", adc_read(ADC_I_MICSUP1));
1248 lcd_puts(0, line++, buf);
1249 snprintf(buf, sizeof(buf), "ADC_I_MICSUP2: %02x", adc_read(ADC_I_MICSUP2));
1250 lcd_puts(0, line++, buf);
1251 snprintf(buf, sizeof(buf), "ADC_VBAT: %02x", adc_read(ADC_VBAT));
1252 lcd_puts(0, line++, buf);
1253 #endif
1254 lcd_update();
1255 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1256 return false;
1259 #elif CONFIG_CPU == PP5002
1260 unsigned int gpio_a, gpio_b, gpio_c, gpio_d;
1262 char buf[128];
1263 int line;
1265 lcd_setmargins(0, 0);
1266 lcd_clear_display();
1267 lcd_setfont(FONT_SYSFIXED);
1269 while(1)
1271 gpio_a = GPIOA_INPUT_VAL;
1272 gpio_b = GPIOB_INPUT_VAL;
1273 gpio_c = GPIOC_INPUT_VAL;
1274 gpio_d = GPIOD_INPUT_VAL;
1276 line = 0;
1277 snprintf(buf, sizeof(buf), "GPIO_A: %02x GPIO_B: %02x", gpio_a, gpio_b);
1278 lcd_puts(0, line++, buf);
1279 snprintf(buf, sizeof(buf), "GPIO_C: %02x GPIO_D: %02x", gpio_c, gpio_d);
1280 lcd_puts(0, line++, buf);
1282 snprintf(buf, sizeof(buf), "DEV_EN: %08lx", DEV_EN);
1283 lcd_puts(0, line++, buf);
1284 snprintf(buf, sizeof(buf), "CLOCK_ENABLE: %08lx", CLOCK_ENABLE);
1285 lcd_puts(0, line++, buf);
1286 snprintf(buf, sizeof(buf), "CLOCK_SOURCE: %08lx", CLOCK_SOURCE);
1287 lcd_puts(0, line++, buf);
1288 snprintf(buf, sizeof(buf), "PLL_CONTROL: %08lx", PLL_CONTROL);
1289 lcd_puts(0, line++, buf);
1290 snprintf(buf, sizeof(buf), "PLL_DIV: %08lx", PLL_DIV);
1291 lcd_puts(0, line++, buf);
1292 snprintf(buf, sizeof(buf), "PLL_MULT: %08lx", PLL_MULT);
1293 lcd_puts(0, line++, buf);
1294 snprintf(buf, sizeof(buf), "TIMING1_CTL: %08lx", TIMING1_CTL);
1295 lcd_puts(0, line++, buf);
1296 snprintf(buf, sizeof(buf), "TIMING2_CTL: %08lx", TIMING2_CTL);
1297 lcd_puts(0, line++, buf);
1299 lcd_update();
1300 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1301 return false;
1303 #elif CONFIG_CPU == S3C2440
1304 char buf[50];
1305 int line;
1307 lcd_setmargins(0, 0);
1308 lcd_clear_display();
1309 lcd_setfont(FONT_SYSFIXED);
1311 while(1)
1313 line = 0;
1314 snprintf(buf, sizeof(buf), "[Ports and Registers]"); lcd_puts(0, line++, buf);
1316 snprintf(buf, sizeof(buf), "GPACON: %08x GPBCON: %08x", GPACON, GPBCON); lcd_puts(0, line++, buf);
1317 snprintf(buf, sizeof(buf), "GPADAT: %08x GPBDAT: %08x", GPADAT, GPBDAT); lcd_puts(0, line++, buf);
1318 snprintf(buf, sizeof(buf), "GPAUP: %08x GPBUP: %08x", 0, GPBUP); lcd_puts(0, line++, buf);
1319 snprintf(buf, sizeof(buf), "GPCCON: %08x GPDCON: %08x", GPCCON, GPDCON); lcd_puts(0, line++, buf);
1320 snprintf(buf, sizeof(buf), "GPCDAT: %08x GPDDAT: %08x", GPCDAT, GPDDAT); lcd_puts(0, line++, buf);
1321 snprintf(buf, sizeof(buf), "GPCUP: %08x GPDUP: %08x", GPCUP, GPDUP); lcd_puts(0, line++, buf);
1323 snprintf(buf, sizeof(buf), "GPCCON: %08x GPDCON: %08x", GPCCON, GPDCON); lcd_puts(0, line++, buf);
1324 snprintf(buf, sizeof(buf), "GPCDAT: %08x GPDDAT: %08x", GPCDAT, GPDDAT); lcd_puts(0, line++, buf);
1325 snprintf(buf, sizeof(buf), "GPCUP: %08x GPDUP: %08x", GPCUP, GPDUP); lcd_puts(0, line++, buf);
1327 snprintf(buf, sizeof(buf), "GPECON: %08x GPFCON: %08x", GPECON, GPFCON); lcd_puts(0, line++, buf);
1328 snprintf(buf, sizeof(buf), "GPEDAT: %08x GPFDAT: %08x", GPEDAT, GPFDAT); lcd_puts(0, line++, buf);
1329 snprintf(buf, sizeof(buf), "GPEUP: %08x GPFUP: %08x", GPEUP, GPFUP); lcd_puts(0, line++, buf);
1331 snprintf(buf, sizeof(buf), "GPGCON: %08x GPHCON: %08x", GPGCON, GPHCON); lcd_puts(0, line++, buf);
1332 snprintf(buf, sizeof(buf), "GPGDAT: %08x GPHDAT: %08x", GPGDAT, GPHDAT); lcd_puts(0, line++, buf);
1333 snprintf(buf, sizeof(buf), "GPGUP: %08x GPHUP: %08x", GPGUP, GPHUP); lcd_puts(0, line++, buf);
1335 snprintf(buf, sizeof(buf), "GPJCON: %08x", GPJCON); lcd_puts(0, line++, buf);
1336 snprintf(buf, sizeof(buf), "GPJDAT: %08x", GPJDAT); lcd_puts(0, line++, buf);
1337 snprintf(buf, sizeof(buf), "GPJUP: %08x", GPJUP); lcd_puts(0, line++, buf);
1339 line++;
1341 snprintf(buf, sizeof(buf), "SRCPND: %08x INTMOD: %08x", SRCPND, INTMOD); lcd_puts(0, line++, buf);
1342 snprintf(buf, sizeof(buf), "INTMSK: %08x INTPND: %08x", INTMSK, INTPND); lcd_puts(0, line++, buf);
1343 snprintf(buf, sizeof(buf), "CLKCON: %08x CLKSLOW: %08x", CLKCON, CLKSLOW); lcd_puts(0, line++, buf);
1344 snprintf(buf, sizeof(buf), "MPLLCON: %08x UPLLCON: %08x", MPLLCON, UPLLCON); lcd_puts(0, line++, buf);
1345 snprintf(buf, sizeof(buf), "CLKDIVN: %08x", CLKDIVN); lcd_puts(0, line++, buf);
1347 lcd_update();
1348 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1349 return false;
1351 #endif /* CPU */
1352 return false;
1354 #else /* !HAVE_LCD_BITMAP */
1355 bool dbg_ports(void)
1357 unsigned short porta;
1358 unsigned short portb;
1359 unsigned char portc;
1360 char buf[32];
1361 int button;
1362 int adc_battery_voltage;
1363 int currval = 0;
1365 lcd_clear_display();
1367 while(1)
1369 porta = PADR;
1370 portb = PBDR;
1371 portc = PCDR;
1373 switch(currval)
1375 case 0:
1376 snprintf(buf, 32, "PADR: %04x", porta);
1377 break;
1378 case 1:
1379 snprintf(buf, 32, "PBDR: %04x", portb);
1380 break;
1381 case 2:
1382 snprintf(buf, 32, "AN0: %03x", adc_read(0));
1383 break;
1384 case 3:
1385 snprintf(buf, 32, "AN1: %03x", adc_read(1));
1386 break;
1387 case 4:
1388 snprintf(buf, 32, "AN2: %03x", adc_read(2));
1389 break;
1390 case 5:
1391 snprintf(buf, 32, "AN3: %03x", adc_read(3));
1392 break;
1393 case 6:
1394 snprintf(buf, 32, "AN4: %03x", adc_read(4));
1395 break;
1396 case 7:
1397 snprintf(buf, 32, "AN5: %03x", adc_read(5));
1398 break;
1399 case 8:
1400 snprintf(buf, 32, "AN6: %03x", adc_read(6));
1401 break;
1402 case 9:
1403 snprintf(buf, 32, "AN7: %03x", adc_read(7));
1404 break;
1405 break;
1407 lcd_puts(0, 0, buf);
1409 battery_read_info(&adc_battery_voltage, NULL);
1410 snprintf(buf, 32, "Batt: %d.%03dV", adc_battery_voltage / 1000,
1411 adc_battery_voltage % 1000);
1412 lcd_puts(0, 1, buf);
1413 lcd_update();
1415 button = get_action(CONTEXT_SETTINGS,HZ/5);
1417 switch(button)
1419 case ACTION_STD_CANCEL:
1420 return false;
1422 case ACTION_SETTINGS_DEC:
1423 currval--;
1424 if(currval < 0)
1425 currval = 9;
1426 break;
1428 case ACTION_SETTINGS_INC:
1429 currval++;
1430 if(currval > 9)
1431 currval = 0;
1432 break;
1435 return false;
1437 #endif /* !HAVE_LCD_BITMAP */
1438 #endif /* !SIMULATOR */
1440 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
1441 static bool dbg_cpufreq(void)
1443 char buf[128];
1444 int line;
1445 int button;
1447 #ifdef HAVE_LCD_BITMAP
1448 lcd_setmargins(0, 0);
1449 lcd_setfont(FONT_SYSFIXED);
1450 #endif
1451 lcd_clear_display();
1453 while(1)
1455 line = 0;
1457 snprintf(buf, sizeof(buf), "Frequency: %ld", FREQ);
1458 lcd_puts(0, line++, buf);
1460 snprintf(buf, sizeof(buf), "boost_counter: %d", get_cpu_boost_counter());
1461 lcd_puts(0, line++, buf);
1463 lcd_update();
1464 button = get_action(CONTEXT_STD,HZ/10);
1466 switch(button)
1468 case ACTION_STD_PREV:
1469 cpu_boost(true);
1470 break;
1472 case ACTION_STD_NEXT:
1473 cpu_boost(false);
1474 break;
1476 case ACTION_STD_OK:
1477 while (get_cpu_boost_counter() > 0)
1478 cpu_boost(false);
1479 set_cpu_frequency(CPUFREQ_DEFAULT);
1480 break;
1482 case ACTION_STD_CANCEL:
1483 return false;
1487 return false;
1489 #endif /* HAVE_ADJUSTABLE_CPU_FREQ */
1491 #ifndef SIMULATOR
1492 #ifdef HAVE_LCD_BITMAP
1494 * view_battery() shows a automatically scaled graph of the battery voltage
1495 * over time. Usable for estimating battery life / charging rate.
1496 * The power_history array is updated in power_thread of powermgmt.c.
1499 #define BAT_LAST_VAL MIN(LCD_WIDTH, POWER_HISTORY_LEN)
1500 #define BAT_YSPACE (LCD_HEIGHT - 20)
1502 static bool view_battery(void)
1504 int view = 0;
1505 int i, x, y;
1506 unsigned short maxv, minv;
1507 char buf[32];
1509 lcd_setmargins(0, 0);
1510 lcd_setfont(FONT_SYSFIXED);
1512 while(1)
1514 lcd_clear_display();
1515 switch (view) {
1516 case 0: /* voltage history graph */
1517 /* Find maximum and minimum voltage for scaling */
1518 minv = power_history[0];
1519 maxv = minv + 1;
1520 for (i = 1; i < BAT_LAST_VAL && power_history[i]; i++) {
1521 if (power_history[i] > maxv)
1522 maxv = power_history[i];
1523 if (power_history[i] < minv)
1524 minv = power_history[i];
1527 snprintf(buf, 30, "Battery %d.%03d", power_history[0] / 1000,
1528 power_history[0] % 1000);
1529 lcd_puts(0, 0, buf);
1530 snprintf(buf, 30, "scale %d.%03d-%d.%03dV",
1531 minv / 1000, minv % 1000, maxv / 1000, maxv % 1000);
1532 lcd_puts(0, 1, buf);
1534 x = 0;
1535 for (i = BAT_LAST_VAL - 1; i >= 0; i--) {
1536 y = (power_history[i] - minv) * BAT_YSPACE / (maxv - minv);
1537 lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
1538 lcd_vline(x, LCD_HEIGHT-1, 20);
1539 lcd_set_drawmode(DRMODE_SOLID);
1540 lcd_vline(x, LCD_HEIGHT-1,
1541 MIN(MAX(LCD_HEIGHT-1 - y, 20), LCD_HEIGHT-1));
1542 x++;
1545 break;
1547 case 1: /* status: */
1548 lcd_puts(0, 0, "Power status:");
1550 battery_read_info(&y, NULL);
1551 snprintf(buf, 30, "Battery: %d.%03d V", y / 1000, y % 1000);
1552 lcd_puts(0, 1, buf);
1553 #ifdef ADC_EXT_POWER
1554 y = (adc_read(ADC_EXT_POWER) * EXT_SCALE_FACTOR) / 1000;
1555 snprintf(buf, 30, "External: %d.%03d V", y / 1000, y % 1000);
1556 lcd_puts(0, 2, buf);
1557 #endif
1558 #if CONFIG_CHARGING
1559 #if CONFIG_CHARGING == CHARGING_CONTROL
1560 snprintf(buf, 30, "Chgr: %s %s",
1561 charger_inserted() ? "present" : "absent",
1562 charger_enabled ? "on" : "off");
1563 lcd_puts(0, 3, buf);
1564 snprintf(buf, 30, "short delta: %d", short_delta);
1565 lcd_puts(0, 5, buf);
1566 snprintf(buf, 30, "long delta: %d", long_delta);
1567 lcd_puts(0, 6, buf);
1568 lcd_puts(0, 7, power_message);
1569 snprintf(buf, 30, "USB Inserted: %s",
1570 usb_inserted() ? "yes" : "no");
1571 lcd_puts(0, 8, buf);
1572 #if defined IRIVER_H300_SERIES
1573 snprintf(buf, 30, "USB Charging Enabled: %s",
1574 usb_charging_enabled() ? "yes" : "no");
1575 lcd_puts(0, 9, buf);
1576 #endif
1577 #else /* CONFIG_CHARGING != CHARGING_CONTROL */
1578 #if defined IPOD_NANO || defined IPOD_VIDEO
1579 int usb_pwr = (GPIOL_INPUT_VAL & 0x10)?true:false;
1580 int ext_pwr = (GPIOL_INPUT_VAL & 0x08)?false:true;
1581 int dock = (GPIOA_INPUT_VAL & 0x10)?true:false;
1582 int charging = (GPIOB_INPUT_VAL & 0x01)?false:true;
1583 int headphone= (GPIOA_INPUT_VAL & 0x80)?true:false;
1585 snprintf(buf, 30, "USB pwr: %s",
1586 usb_pwr ? "present" : "absent");
1587 lcd_puts(0, 3, buf);
1588 snprintf(buf, 30, "EXT pwr: %s",
1589 ext_pwr ? "present" : "absent");
1590 lcd_puts(0, 4, buf);
1591 snprintf(buf, 30, "Battery: %s",
1592 charging ? "charging" : (usb_pwr||ext_pwr) ? "charged" : "discharging");
1593 lcd_puts(0, 5, buf);
1594 snprintf(buf, 30, "Dock mode: %s",
1595 dock ? "enabled" : "disabled");
1596 lcd_puts(0, 6, buf);
1597 snprintf(buf, 30, "Headphone: %s",
1598 headphone ? "connected" : "disconnected");
1599 lcd_puts(0, 7, buf);
1600 #else
1601 snprintf(buf, 30, "Charger: %s",
1602 charger_inserted() ? "present" : "absent");
1603 lcd_puts(0, 3, buf);
1604 #endif
1605 #endif /* CONFIG_CHARGING != CHARGING_CONTROL */
1606 #endif /* CONFIG_CHARGING */
1607 break;
1609 case 2: /* voltage deltas: */
1610 lcd_puts(0, 0, "Voltage deltas:");
1612 for (i = 0; i <= 6; i++) {
1613 y = power_history[i] - power_history[i+1];
1614 snprintf(buf, 30, "-%d min: %s%d.%03d V", i,
1615 (y < 0) ? "-" : "", ((y < 0) ? y * -1 : y) / 1000,
1616 ((y < 0) ? y * -1 : y ) % 1000);
1617 lcd_puts(0, i+1, buf);
1619 break;
1621 case 3: /* remaining time estimation: */
1623 #if CONFIG_CHARGING == CHARGING_CONTROL
1624 snprintf(buf, 30, "charge_state: %d", charge_state);
1625 lcd_puts(0, 0, buf);
1627 snprintf(buf, 30, "Cycle time: %d m", powermgmt_last_cycle_startstop_min);
1628 lcd_puts(0, 1, buf);
1630 snprintf(buf, 30, "Lvl@cyc st: %d%%", powermgmt_last_cycle_level);
1631 lcd_puts(0, 2, buf);
1633 snprintf(buf, 30, "P=%2d I=%2d", pid_p, pid_i);
1634 lcd_puts(0, 3, buf);
1636 snprintf(buf, 30, "Trickle sec: %d/60", trickle_sec);
1637 lcd_puts(0, 4, buf);
1638 #endif /* CONFIG_CHARGING == CHARGING_CONTROL */
1640 snprintf(buf, 30, "Last PwrHist: %d.%03dV",
1641 power_history[0] / 1000,
1642 power_history[0] % 1000);
1643 lcd_puts(0, 5, buf);
1645 snprintf(buf, 30, "battery level: %d%%", battery_level());
1646 lcd_puts(0, 6, buf);
1648 snprintf(buf, 30, "Est. remain: %d m", battery_time());
1649 lcd_puts(0, 7, buf);
1650 break;
1653 lcd_update();
1655 switch(get_action(CONTEXT_SETTINGS,HZ/2))
1657 case ACTION_SETTINGS_DEC:
1658 if (view)
1659 view--;
1660 break;
1662 case ACTION_SETTINGS_INC:
1663 if (view < 3)
1664 view++;
1665 break;
1667 case ACTION_STD_CANCEL:
1668 return false;
1671 return false;
1674 #endif /* HAVE_LCD_BITMAP */
1675 #endif
1677 #ifndef SIMULATOR
1678 #if defined(HAVE_MMC) || defined(HAVE_HOTSWAP)
1679 #if defined(HAVE_MMC)
1680 #define CARDTYPE "MMC"
1681 #else
1682 #define CARDTYPE "microSD"
1683 #endif
1684 static int cardinfo_callback(int btn, struct action_callback_info *info)
1686 tCardInfo *card;
1687 unsigned char card_name[7];
1688 unsigned char pbuf[32];
1689 static const unsigned char i_vmin[] = { 0, 1, 5, 10, 25, 35, 60, 100 };
1690 static const unsigned char i_vmax[] = { 1, 5, 10, 25, 35, 45, 80, 200 };
1691 static const unsigned char *kbit_units[] = { "kBit/s", "MBit/s", "GBit/s" };
1692 static const unsigned char *nsec_units[] = { "ns", "µs", "ms" };
1693 static const char *spec_vers[] = { "1.0-1.2", "1.4", "2.0-2.2",
1694 "3.1-3.31", "4.0" };
1695 if ((btn == ACTION_STD_OK) || (btn == SYS_FS_CHANGED) || (btn == ACTION_REDRAW))
1697 if (btn == ACTION_STD_OK)
1698 info->cbdata ^= 0x1; /* change cards */
1700 dbg_listmessage_setlines(0);
1702 card = card_get_info(info->cbdata);
1704 if (card->initialized > 0)
1706 card_name[6] = '\0';
1707 strncpy(card_name, ((unsigned char*)card->cid) + 3, 6);
1708 dbg_listmessage_addline(
1709 "%s Rev %d.%d", card_name,
1710 (int) card_extract_bits(card->cid, 72, 4),
1711 (int) card_extract_bits(card->cid, 76, 4));
1712 dbg_listmessage_addline(
1713 "Prod: %d/%d",
1714 (int) card_extract_bits(card->cid, 112, 4),
1715 (int) card_extract_bits(card->cid, 116, 4) + 1997);
1716 dbg_listmessage_addline(
1717 "Ser#: 0x%08lx",
1718 card_extract_bits(card->cid, 80, 32));
1719 dbg_listmessage_addline(
1720 "M=%02x, O=%04x",
1721 (int) card_extract_bits(card->cid, 0, 8),
1722 (int) card_extract_bits(card->cid, 8, 16));
1723 int temp = card_extract_bits(card->csd, 2, 4);
1724 dbg_listmessage_addline(
1725 CARDTYPE " v%s", temp < 5 ?
1726 spec_vers[temp] : "?.?");
1727 dbg_listmessage_addline(
1728 "Blocks: 0x%06lx", card->numblocks);
1729 dbg_listmessage_addline(
1730 "Blksz.: %d P:%c%c", card->blocksize,
1731 card_extract_bits(card->csd, 48, 1) ? 'R' : '-',
1732 card_extract_bits(card->csd, 106, 1) ? 'W' : '-');
1733 output_dyn_value(pbuf, sizeof pbuf, card->speed / 1000,
1734 kbit_units, false);
1735 dbg_listmessage_addline(
1736 "Speed: %s", pbuf);
1737 output_dyn_value(pbuf, sizeof pbuf, card->tsac,
1738 nsec_units, false);
1739 dbg_listmessage_addline(
1740 "Tsac: %s", pbuf);
1741 dbg_listmessage_addline(
1742 "Nsac: %d clk", card->nsac);
1743 dbg_listmessage_addline(
1744 "R2W: *%d", card->r2w_factor);
1745 dbg_listmessage_addline(
1746 "IRmax: %d..%d mA",
1747 i_vmin[card_extract_bits(card->csd, 66, 3)],
1748 i_vmax[card_extract_bits(card->csd, 69, 3)]);
1749 dbg_listmessage_addline(
1750 "IWmax: %d..%d mA",
1751 i_vmin[card_extract_bits(card->csd, 72, 3)],
1752 i_vmax[card_extract_bits(card->csd, 75, 3)]);
1754 else if (card->initialized == 0)
1756 dbg_listmessage_addline("Not Found!");
1758 #ifndef HAVE_MMC
1759 else /* card->initialized < 0 */
1761 dbg_listmessage_addline("Init Error! (%d)", card->initialized);
1763 #endif
1764 snprintf(info->title, 16, "[" CARDTYPE " %d]", (int)info->cbdata);
1765 gui_synclist_set_nb_items(info->lists, dbg_listmessage_getlines());
1766 gui_synclist_select_item(info->lists, 0);
1767 btn = ACTION_REDRAW;
1769 return btn;
1771 static bool dbg_disk_info(void)
1773 char listtitle[16];
1774 struct action_callback_info info;
1775 info.title = listtitle;
1776 info.count = 1;
1777 info.selection_size = 1;
1778 info.action_callback = cardinfo_callback;
1779 info.dbg_getname = dbg_listmessage_getname;
1780 info.cbdata = 0;
1781 dbg_list(&info);
1782 return false;
1784 #else /* !defined(HAVE_MMC) && !defined(HAVE_HOTSWAP) */
1785 static int disk_callback(int btn, struct action_callback_info *info)
1787 int i;
1788 char buf[128];
1789 unsigned short* identify_info = ata_get_identify();
1790 bool timing_info_present = false;
1791 (void)btn;
1793 dbg_listmessage_setlines(0);
1795 for (i=0; i < 20; i++)
1796 ((unsigned short*)buf)[i]=htobe16(identify_info[i+27]);
1797 buf[40]=0;
1798 /* kill trailing space */
1799 for (i=39; i && buf[i]==' '; i--)
1800 buf[i] = 0;
1801 dbg_listmessage_addline(
1802 "Model: %s", buf);
1803 for (i=0; i < 4; i++)
1804 ((unsigned short*)buf)[i]=htobe16(identify_info[i+23]);
1805 buf[8]=0;
1806 dbg_listmessage_addline(
1807 "Firmware: %s", buf);
1808 snprintf(buf, sizeof buf, "%ld MB",
1809 ((unsigned long)identify_info[61] << 16 |
1810 (unsigned long)identify_info[60]) / 2048 );
1811 dbg_listmessage_addline(
1812 "Size: %s", buf);
1813 unsigned long free;
1814 fat_size( IF_MV2(0,) NULL, &free );
1815 dbg_listmessage_addline(
1816 "Free: %ld MB", free / 1024);
1817 dbg_listmessage_addline(
1818 "Spinup time: %d ms", ata_spinup_time * (1000/HZ));
1819 i = identify_info[83] & (1<<3);
1820 dbg_listmessage_addline(
1821 "Power mgmt: %s", i ? "enabled" : "unsupported");
1822 i = identify_info[83] & (1<<9);
1823 dbg_listmessage_addline(
1824 "Noise mgmt: %s", i ? "enabled" : "unsupported");
1825 i = identify_info[82] & (1<<6);
1826 dbg_listmessage_addline(
1827 "Read-ahead: %s", i ? "enabled" : "unsupported");
1828 timing_info_present = identify_info[53] & (1<<1);
1829 if(timing_info_present) {
1830 char pio3[2], pio4[2];pio3[1] = 0;
1831 pio4[1] = 0;
1832 pio3[0] = (identify_info[64] & (1<<0)) ? '3' : 0;
1833 pio4[0] = (identify_info[64] & (1<<1)) ? '4' : 0;
1834 dbg_listmessage_addline(
1835 "PIO modes: 0 1 2 %s %s", pio3, pio4);
1837 else {
1838 dbg_listmessage_addline(
1839 "No PIO mode info");
1841 timing_info_present = identify_info[53] & (1<<1);
1842 if(timing_info_present) {
1843 dbg_listmessage_addline(
1844 "Cycle times %dns/%dns",
1845 identify_info[67],
1846 identify_info[68] );
1847 } else {
1848 dbg_listmessage_addline(
1849 "No timing info");
1851 timing_info_present = identify_info[53] & (1<<1);
1852 if(timing_info_present) {
1853 i = identify_info[49] & (1<<11);
1854 dbg_listmessage_addline(
1855 "IORDY support: %s", i ? "yes" : "no");
1856 i = identify_info[49] & (1<<10);
1857 dbg_listmessage_addline(
1858 "IORDY disable: %s", i ? "yes" : "no");
1859 } else {
1860 dbg_listmessage_addline(
1861 "No timing info");
1863 dbg_listmessage_addline(
1864 "Cluster size: %d bytes", fat_get_cluster_size(IF_MV(0)));
1865 gui_synclist_set_nb_items(info->lists, dbg_listmessage_getlines());
1866 return btn;
1868 static bool dbg_disk_info(void)
1870 struct action_callback_info info;
1871 info.title = "Disk Info";
1872 info.count = 1;
1873 info.selection_size = 1;
1874 info.action_callback = disk_callback;
1875 info.dbg_getname = dbg_listmessage_getname;
1876 dbg_list(&info);
1877 return false;
1879 #endif /* !defined(HAVE_MMC) && !defined(HAVE_HOTSWAP) */
1880 #endif /* !SIMULATOR */
1882 #ifdef HAVE_DIRCACHE
1883 static int dircache_callback(int btn, struct action_callback_info *info)
1885 (void)btn; (void)info;
1886 dbg_listmessage_setlines(0);
1887 dbg_listmessage_addline("Cache initialized: %s",
1888 dircache_is_enabled() ? "Yes" : "No");
1889 dbg_listmessage_addline("Cache size: %d B",
1890 dircache_get_cache_size());
1891 dbg_listmessage_addline("Last size: %d B",
1892 global_status.dircache_size);
1893 dbg_listmessage_addline("Limit: %d B",
1894 DIRCACHE_LIMIT);
1895 dbg_listmessage_addline("Reserve: %d/%d B",
1896 dircache_get_reserve_used(), DIRCACHE_RESERVE);
1897 dbg_listmessage_addline("Scanning took: %d s",
1898 dircache_get_build_ticks() / HZ);
1899 dbg_listmessage_addline("Entry count: %d",
1900 dircache_get_entry_count());
1901 return btn;
1904 static bool dbg_dircache_info(void)
1906 struct action_callback_info info;
1907 info.title = "Dircache Info";
1908 info.count = 7;
1909 info.selection_size = 1;
1910 info.action_callback = dircache_callback;
1911 info.dbg_getname = dbg_listmessage_getname;
1912 dbg_list(&info);
1913 return false;
1916 #endif /* HAVE_DIRCACHE */
1918 #ifdef HAVE_TAGCACHE
1919 static int database_callback(int btn, struct action_callback_info *info)
1921 (void)btn; (void)info;
1922 struct tagcache_stat *stat = tagcache_get_stat();
1923 dbg_listmessage_setlines(0);
1924 dbg_listmessage_addline("Initialized: %s",
1925 stat->initialized ? "Yes" : "No");
1926 dbg_listmessage_addline("DB Ready: %s",
1927 stat->ready ? "Yes" : "No");
1928 dbg_listmessage_addline("RAM Cache: %s",
1929 stat->ramcache ? "Yes" : "No");
1930 dbg_listmessage_addline("RAM: %d/%d B",
1931 stat->ramcache_used, stat->ramcache_allocated);
1932 dbg_listmessage_addline("Progress: %d%% (%d entries)",
1933 stat->progress, stat->processed_entries);
1934 dbg_listmessage_addline("Commit step: %d",
1935 stat->commit_step);
1936 dbg_listmessage_addline("Commit delayed: %s",
1937 stat->commit_delayed ? "Yes" : "No");
1938 return btn;
1940 static bool dbg_tagcache_info(void)
1942 struct action_callback_info info;
1943 info.title = "Database Info";
1944 info.count = 7;
1945 info.selection_size = 1;
1946 info.action_callback = database_callback;
1947 info.dbg_getname = dbg_listmessage_getname;
1948 dbg_list(&info);
1949 return false;
1951 #endif
1953 #if CONFIG_CPU == SH7034
1954 static bool dbg_save_roms(void)
1956 int fd;
1957 int oldmode = system_memory_guard(MEMGUARD_NONE);
1959 fd = creat("/internal_rom_0000-FFFF.bin");
1960 if(fd >= 0)
1962 write(fd, (void *)0, 0x10000);
1963 close(fd);
1966 fd = creat("/internal_rom_2000000-203FFFF.bin");
1967 if(fd >= 0)
1969 write(fd, (void *)0x2000000, 0x40000);
1970 close(fd);
1973 system_memory_guard(oldmode);
1974 return false;
1976 #elif defined CPU_COLDFIRE
1977 static bool dbg_save_roms(void)
1979 int fd;
1980 int oldmode = system_memory_guard(MEMGUARD_NONE);
1982 #if defined(IRIVER_H100_SERIES)
1983 fd = creat("/internal_rom_000000-1FFFFF.bin");
1984 #elif defined(IRIVER_H300_SERIES)
1985 fd = creat("/internal_rom_000000-3FFFFF.bin");
1986 #elif defined(IAUDIO_X5) || defined(IAUDIO_M5)
1987 fd = creat("/internal_rom_000000-3FFFFF.bin");
1988 #endif
1989 if(fd >= 0)
1991 write(fd, (void *)0, FLASH_SIZE);
1992 close(fd);
1994 system_memory_guard(oldmode);
1996 #ifdef HAVE_EEPROM
1997 fd = creat("/internal_eeprom.bin");
1998 if (fd >= 0)
2000 int old_irq_level;
2001 char buf[EEPROM_SIZE];
2002 int err;
2004 old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL);
2006 err = eeprom_24cxx_read(0, buf, sizeof buf);
2007 if (err)
2008 gui_syncsplash(HZ*3, "Eeprom read failure (%d)",err);
2009 else
2011 write(fd, buf, sizeof buf);
2014 set_irq_level(old_irq_level);
2016 close(fd);
2018 #endif
2020 return false;
2022 #elif defined(CPU_PP) && !(defined(SANSA_E200) || defined(SANSA_C200))
2023 static bool dbg_save_roms(void)
2025 int fd;
2027 fd = creat("/internal_rom_000000-0FFFFF.bin");
2028 if(fd >= 0)
2030 write(fd, (void *)0x20000000, FLASH_SIZE);
2031 close(fd);
2034 return false;
2036 #endif /* CPU */
2038 #ifndef SIMULATOR
2039 #if CONFIG_TUNER
2040 static int radio_callback(int btn, struct action_callback_info *info)
2042 dbg_listmessage_setlines(1);
2044 #if (CONFIG_TUNER & LV24020LP)
2045 dbg_listmessage_addline("CTRL_STAT: %02X", lv24020lp_get(LV24020LP_CTRL_STAT) );
2046 dbg_listmessage_addline("RADIO_STAT: %02X", lv24020lp_get(LV24020LP_REG_STAT) );
2047 dbg_listmessage_addline("MSS_FM: %d kHz", lv24020lp_get(LV24020LP_MSS_FM) );
2048 dbg_listmessage_addline("MSS_IF: %d Hz", lv24020lp_get(LV24020LP_MSS_IF) );
2049 dbg_listmessage_addline("MSS_SD: %d Hz", lv24020lp_get(LV24020LP_MSS_SD) );
2050 dbg_listmessage_addline("if_set: %d Hz", lv24020lp_get(LV24020LP_IF_SET) );
2051 dbg_listmessage_addline("sd_set: %d Hz", lv24020lp_get(LV24020LP_SD_SET) );
2052 #endif
2053 #if (CONFIG_TUNER & S1A0903X01)
2054 dbg_listmessage_addline("Samsung regs: %08X", s1a0903x01_get(RADIO_ALL));
2055 /* This one doesn't return dynamic data atm */
2056 #endif
2057 #if (CONFIG_TUNER & TEA5767)
2058 struct tea5767_dbg_info nfo;
2059 tea5767_dbg_info(&nfo);
2060 dbg_listmessage_addline("Philips regs:");
2061 dbg_listmessage_addline(
2062 " Read: %02X %02X %02X %02X %02X",
2063 (unsigned)nfo.read_regs[0], (unsigned)nfo.read_regs[1],
2064 (unsigned)nfo.read_regs[2], (unsigned)nfo.read_regs[3],
2065 (unsigned)nfo.read_regs[4]);
2066 dbg_listmessage_addline(
2067 " Write: %02X %02X %02X %02X %02X",
2068 (unsigned)nfo.write_regs[0], (unsigned)nfo.write_regs[1],
2069 (unsigned)nfo.write_regs[2], (unsigned)nfo.write_regs[3],
2070 (unsigned)nfo.write_regs[4]);
2071 #endif
2073 if (btn != ACTION_STD_CANCEL)
2074 btn = ACTION_REDRAW;
2076 gui_synclist_set_nb_items(info->lists, dbg_listmessage_getlines());
2077 return btn;
2079 static bool dbg_fm_radio(void)
2081 struct action_callback_info info;
2083 info.title = "FM Radio";
2084 info.count = 1;
2085 info.selection_size = 1;
2086 info.cbdata = radio_hardware_present();
2087 info.action_callback = info.cbdata ? radio_callback : NULL;
2088 info.dbg_getname = dbg_listmessage_getname;
2090 dbg_listmessage_setlines(0);
2091 dbg_listmessage_addline("HW detected: %s", info.cbdata ? "yes" : "no");
2093 dbg_list(&info);
2094 return false;
2096 #endif /* CONFIG_TUNER */
2097 #endif /* !SIMULATOR */
2099 #ifdef HAVE_LCD_BITMAP
2100 extern bool do_screendump_instead_of_usb;
2102 static bool dbg_screendump(void)
2104 do_screendump_instead_of_usb = !do_screendump_instead_of_usb;
2105 gui_syncsplash(HZ, "Screendump %s",
2106 do_screendump_instead_of_usb?"enabled":"disabled");
2107 return false;
2109 #endif /* HAVE_LCD_BITMAP */
2111 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
2112 static bool dbg_set_memory_guard(void)
2114 static const struct opt_items names[MAXMEMGUARD] = {
2115 { "None", -1 },
2116 { "Flash ROM writes", -1 },
2117 { "Zero area (all)", -1 }
2119 int mode = system_memory_guard(MEMGUARD_KEEP);
2121 set_option( "Catch mem accesses", &mode, INT, names, MAXMEMGUARD, NULL);
2122 system_memory_guard(mode);
2124 return false;
2126 #endif /* CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) */
2128 #if defined(TOSHIBA_GIGABEAT_F) && !defined(SIMULATOR)
2130 extern volatile bool lcd_poweroff;
2132 static bool dbg_lcd_power_off(void)
2134 lcd_setmargins(0, 0);
2136 while(1)
2138 int button;
2140 lcd_clear_display();
2141 lcd_puts(0, 0, "LCD Power Off");
2142 if(lcd_poweroff)
2143 lcd_puts(1, 1, "Yes");
2144 else
2145 lcd_puts(1, 1, "No");
2147 lcd_update();
2149 button = get_action(CONTEXT_STD,HZ/5);
2150 switch(button)
2152 case ACTION_STD_PREV:
2153 case ACTION_STD_NEXT:
2154 lcd_poweroff = !lcd_poweroff;
2155 break;
2156 case ACTION_STD_OK:
2157 case ACTION_STD_CANCEL:
2158 return false;
2159 default:
2160 sleep(HZ/10);
2161 break;
2164 return false;
2166 #endif
2168 #if defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS)
2169 static bool dbg_write_eeprom(void)
2171 int fd;
2172 int rc;
2173 int old_irq_level;
2174 char buf[EEPROM_SIZE];
2175 int err;
2177 fd = open("/internal_eeprom.bin", O_RDONLY);
2179 if (fd >= 0)
2181 rc = read(fd, buf, EEPROM_SIZE);
2183 if(rc == EEPROM_SIZE)
2185 old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL);
2187 err = eeprom_24cxx_write(0, buf, sizeof buf);
2188 if (err)
2189 gui_syncsplash(HZ*3, "Eeprom write failure (%d)",err);
2190 else
2191 gui_syncsplash(HZ*3, "Eeprom written successfully");
2193 set_irq_level(old_irq_level);
2195 else
2197 gui_syncsplash(HZ*3, "File read error (%d)",rc);
2199 close(fd);
2201 else
2203 gui_syncsplash(HZ*3, "Failed to open 'internal_eeprom.bin'");
2206 return false;
2208 #endif /* defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS) */
2209 #ifdef CPU_BOOST_LOGGING
2210 static bool cpu_boost_log(void)
2212 int i = 0,j=0;
2213 int count = cpu_boost_log_getcount();
2214 int lines = LCD_HEIGHT/SYSFONT_HEIGHT;
2215 char *str;
2216 bool done;
2217 lcd_setmargins(0, 0);
2218 lcd_setfont(FONT_SYSFIXED);
2219 str = cpu_boost_log_getlog_first();
2220 while (i < count)
2222 lcd_clear_display();
2223 for(j=0; j<lines; j++,i++)
2225 if (!str)
2226 str = cpu_boost_log_getlog_next();
2227 if (str)
2229 lcd_puts(0, j,str);
2231 str = NULL;
2233 lcd_update();
2234 done = false;
2235 while (!done)
2237 switch(get_action(CONTEXT_STD,TIMEOUT_BLOCK))
2239 case ACTION_STD_OK:
2240 case ACTION_STD_PREV:
2241 case ACTION_STD_NEXT:
2242 done = true;
2243 break;
2244 case ACTION_STD_CANCEL:
2245 i = count;
2246 done = true;
2247 break;
2251 get_action(CONTEXT_STD,TIMEOUT_BLOCK);
2252 lcd_setfont(FONT_UI);
2253 return false;
2255 #endif
2259 /****** The menu *********/
2260 struct the_menu_item {
2261 unsigned char *desc; /* string or ID */
2262 bool (*function) (void); /* return true if USB was connected */
2264 static const struct the_menu_item menuitems[] = {
2265 #if defined(TOSHIBA_GIGABEAT_F) && !defined(SIMULATOR)
2266 { "LCD Power Off", dbg_lcd_power_off },
2267 #endif
2268 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || \
2269 (defined(CPU_PP) && !(defined(SANSA_E200) || defined(SANSA_C200)))
2270 { "Dump ROM contents", dbg_save_roms },
2271 #endif
2272 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || defined(CPU_PP) || CONFIG_CPU == S3C2440
2273 { "View I/O ports", dbg_ports },
2274 #endif
2275 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
2276 { "CPU frequency", dbg_cpufreq },
2277 #endif
2278 #if defined(IRIVER_H100_SERIES) && !defined(SIMULATOR)
2279 { "S/PDIF analyzer", dbg_spdif },
2280 #endif
2281 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
2282 { "Catch mem accesses", dbg_set_memory_guard },
2283 #endif
2284 { "View OS stacks", dbg_os },
2285 #ifdef HAVE_LCD_BITMAP
2286 #ifndef SIMULATOR
2287 { "View battery", view_battery },
2288 #endif
2289 { "Screendump", dbg_screendump },
2290 #endif
2291 #ifndef SIMULATOR
2292 { "View HW info", dbg_hw_info },
2293 #endif
2294 #ifndef SIMULATOR
2295 { "View partitions", dbg_partitions },
2296 #endif
2297 #ifndef SIMULATOR
2298 { "View disk info", dbg_disk_info },
2299 #endif
2300 #ifdef HAVE_DIRCACHE
2301 { "View dircache info", dbg_dircache_info },
2302 #endif
2303 #ifdef HAVE_TAGCACHE
2304 { "View database info", dbg_tagcache_info },
2305 #endif
2306 #ifdef HAVE_LCD_BITMAP
2307 #if CONFIG_CODEC == SWCODEC || !defined(SIMULATOR)
2308 { "View audio thread", dbg_audio_thread },
2309 #endif
2310 #ifdef PM_DEBUG
2311 { "pm histogram", peak_meter_histogram},
2312 #endif /* PM_DEBUG */
2313 #endif /* HAVE_LCD_BITMAP */
2314 #ifndef SIMULATOR
2315 #if CONFIG_TUNER
2316 { "FM Radio", dbg_fm_radio },
2317 #endif
2318 #endif
2319 #if defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS)
2320 { "Write back EEPROM", dbg_write_eeprom },
2321 #endif
2322 #ifdef ROCKBOX_HAS_LOGF
2323 {"logf", logfdisplay },
2324 {"logfdump", logfdump },
2325 #endif
2326 #ifdef CPU_BOOST_LOGGING
2327 {"cpu_boost log",cpu_boost_log},
2328 #endif
2330 static int menu_action_callback(int btn, struct action_callback_info *info)
2332 if (btn == ACTION_STD_OK)
2334 menuitems[gui_synclist_get_sel_pos(info->lists)].function();
2335 gui_synclist_draw(info->lists);
2337 return btn;
2339 static char* dbg_menu_getname(int item, void * data, char *buffer)
2341 (void)data; (void)buffer;
2342 return menuitems[item].desc;
2344 bool debug_menu(void)
2346 struct action_callback_info info;
2347 info.title = "Debug Menu";
2348 info.count = ARRAYLEN(menuitems);
2349 info.selection_size = 1;
2350 info.action_callback = menu_action_callback;
2351 info.dbg_getname = dbg_menu_getname;
2352 dbg_list(&info);
2353 return false;