Make the audio thread debug screen leavable on H10 (and potentially other targets...
[kugel-rb.git] / apps / debug_menu.c
blob64d22b41bd9b9e852c98a12ee769a9ea8daa269d
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);
155 action_signalscreenchange();
157 if (info->action_callback)
158 info->action_callback(ACTION_REDRAW, info);
160 gui_synclist_draw(&lists);
162 while(1)
164 gui_syncstatusbar_draw(&statusbars, true);
165 action = get_action(CONTEXT_STD, HZ/5);
166 if (gui_synclist_do_button(&lists, action, LIST_WRAP_UNLESS_HELD))
167 continue;
168 if (info->action_callback)
169 action = info->action_callback(action, info);
170 if (action == ACTION_STD_CANCEL)
171 break;
172 else if (action == ACTION_REDRAW)
173 gui_synclist_draw(&lists);
174 else if(default_event_handler(action) == SYS_USB_CONNECTED)
175 return true;
177 action_signalscreenchange();
178 return false;
180 /*---------------------------------------------------*/
181 /* SPECIAL DEBUG STUFF */
182 /*---------------------------------------------------*/
183 extern struct thread_entry threads[MAXTHREADS];
186 #ifndef SIMULATOR
187 static char thread_status_char(int status)
189 switch (status)
191 case STATE_RUNNING : return 'R';
192 case STATE_BLOCKED : return 'B';
193 case STATE_SLEEPING : return 'S';
194 case STATE_BLOCKED_W_TMO: return 'T';
197 return '?';
199 #if NUM_CORES > 1
200 #define IF_COP2(...) __VA_ARGS__
201 #else
202 #define IF_COP2(...)
203 #endif
204 static char* threads_getname(int selected_item, void * data, char *buffer)
206 (void)data;
207 struct thread_entry *thread = NULL;
208 int status, usage;
209 thread = &threads[selected_item];
211 if (thread->name == NULL)
213 snprintf(buffer, MAX_PATH, "%2d: ---", selected_item);
214 return buffer;
217 usage = thread_stack_usage(thread);
218 status = thread_get_status(thread);
219 #ifdef HAVE_PRIORITY_SCHEDULING
220 snprintf(buffer, MAX_PATH, "%2d: " IF_COP2("(%d) ") "%c%c %d %2d%% %s",
221 selected_item,
222 IF_COP2(thread->core,)
223 (status == STATE_RUNNING) ? '*' : ' ',
224 thread_status_char(status),
225 thread->priority,
226 usage, thread->name);
227 #else
228 snprintf(buffer, MAX_PATH, "%2d: " IF_COP2("(%d) ") "%c%c %2d%% %s",
229 selected_item,
230 IF_COP2(thread->core,)
231 (status == STATE_RUNNING) ? '*' : ' ',
232 thread_status_char(status),
233 usage, thread->name);
234 #endif
235 return buffer;
237 static int dbg_threads_action_callback(int action, struct action_callback_info *info)
239 #ifdef ROCKBOX_HAS_LOGF
240 if (action == ACTION_STD_OK)
242 struct thread_entry *thread = &threads[gui_synclist_get_sel_pos(info->lists)];
243 if (thread->name != NULL)
244 remove_thread(thread);
246 #endif
247 gui_synclist_draw(info->lists);
248 return action;
250 /* Test code!!! */
251 static bool dbg_os(void)
253 struct action_callback_info info;
254 info.title = IF_COP2("Core and ") "Stack usage:";
255 info.count = MAXTHREADS;
256 info.selection_size = 1;
257 info.action_callback = dbg_threads_action_callback;
258 info.dbg_getname = threads_getname;
259 return dbg_list(&info);
261 #endif /* !SIMULATOR */
263 #ifdef HAVE_LCD_BITMAP
264 #if CONFIG_CODEC != SWCODEC
265 #ifndef SIMULATOR
266 static bool dbg_audio_thread(void)
268 char buf[32];
269 struct audio_debug d;
271 lcd_setmargins(0, 0);
272 lcd_setfont(FONT_SYSFIXED);
274 while(1)
276 if (action_userabort(HZ/5))
277 return false;
279 audio_get_debugdata(&d);
281 lcd_clear_display();
283 snprintf(buf, sizeof(buf), "read: %x", d.audiobuf_read);
284 lcd_puts(0, 0, buf);
285 snprintf(buf, sizeof(buf), "write: %x", d.audiobuf_write);
286 lcd_puts(0, 1, buf);
287 snprintf(buf, sizeof(buf), "swap: %x", d.audiobuf_swapwrite);
288 lcd_puts(0, 2, buf);
289 snprintf(buf, sizeof(buf), "playing: %d", d.playing);
290 lcd_puts(0, 3, buf);
291 snprintf(buf, sizeof(buf), "playable: %x", d.playable_space);
292 lcd_puts(0, 4, buf);
293 snprintf(buf, sizeof(buf), "unswapped: %x", d.unswapped_space);
294 lcd_puts(0, 5, buf);
296 /* Playable space left */
297 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, 6*8, 112, 4, d.audiobuflen, 0,
298 d.playable_space, HORIZONTAL);
300 /* Show the watermark limit */
301 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, 6*8+4, 112, 4, d.audiobuflen, 0,
302 d.low_watermark_level, HORIZONTAL);
304 snprintf(buf, sizeof(buf), "wm: %x - %x",
305 d.low_watermark_level, d.lowest_watermark_level);
306 lcd_puts(0, 7, buf);
308 lcd_update();
310 return false;
312 #endif /* !SIMULATOR */
313 #else /* CONFIG_CODEC == SWCODEC */
314 extern size_t filebuflen;
315 /* This is a size_t, but call it a long so it puts a - when it's bad. */
317 static unsigned int ticks, boost_ticks;
319 static void dbg_audio_task(void)
321 #ifndef SIMULATOR
322 if(FREQ > CPUFREQ_NORMAL)
323 boost_ticks++;
324 #endif
326 ticks++;
329 static bool dbg_audio_thread(void)
331 char buf[32];
332 int button;
333 int line;
334 bool done = false;
335 size_t bufused;
336 size_t bufsize = pcmbuf_get_bufsize();
337 int pcmbufdescs = pcmbuf_descs();
339 ticks = boost_ticks = 0;
341 tick_add_task(dbg_audio_task);
343 lcd_setmargins(0, 0);
344 lcd_setfont(FONT_SYSFIXED);
345 while(!done)
347 button = get_action(CONTEXT_STD,HZ/5);
348 switch(button)
350 case ACTION_STD_NEXT:
351 audio_next();
352 break;
353 case ACTION_STD_PREV:
354 audio_prev();
355 break;
356 case ACTION_STD_CANCEL:
357 done = true;
358 break;
360 line = 0;
361 lcd_clear_display();
363 bufused = bufsize - pcmbuf_free();
365 snprintf(buf, sizeof(buf), "pcm: %7ld/%7ld", (long) bufused, (long) bufsize);
366 lcd_puts(0, line++, buf);
368 /* Playable space left */
369 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6, bufsize, 0, bufused, HORIZONTAL);
370 line++;
372 snprintf(buf, sizeof(buf), "codec: %8ld/%8ld", audio_filebufused(), (long) filebuflen);
373 lcd_puts(0, line++, buf);
375 /* Playable space left */
376 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6, filebuflen, 0,
377 audio_filebufused(), HORIZONTAL);
378 line++;
380 snprintf(buf, sizeof(buf), "track count: %2d", audio_track_count());
381 lcd_puts(0, line++, buf);
383 #ifndef SIMULATOR
384 snprintf(buf, sizeof(buf), "cpu freq: %3dMHz",
385 (int)((FREQ + 500000) / 1000000));
386 lcd_puts(0, line++, buf);
387 #endif
389 if (ticks > 0)
391 snprintf(buf, sizeof(buf), "boost ratio: %3d%%",
392 boost_ticks * 100 / ticks);
393 lcd_puts(0, line++, buf);
396 snprintf(buf, sizeof(buf), "pcmbufdesc: %2d/%2d",
397 pcmbuf_used_descs(), pcmbufdescs);
398 lcd_puts(0, line++, buf);
400 lcd_update();
403 tick_remove_task(dbg_audio_task);
405 action_signalscreenchange();
406 return false;
408 #endif /* CONFIG_CODEC */
409 #endif /* HAVE_LCD_BITMAP */
412 #if (CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE))
413 /* Tool function to read the flash manufacturer and type, if available.
414 Only chips which could be reprogrammed in system will return values.
415 (The mode switch addresses vary between flash manufacturers, hence addr1/2) */
416 /* In IRAM to avoid problems when running directly from Flash */
417 static bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
418 unsigned addr1, unsigned addr2)
419 ICODE_ATTR __attribute__((noinline));
420 static bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
421 unsigned addr1, unsigned addr2)
424 unsigned not_manu, not_id; /* read values before switching to ID mode */
425 unsigned manu, id; /* read values when in ID mode */
427 #if CONFIG_CPU == SH7034
428 volatile unsigned char* flash = (unsigned char*)0x2000000; /* flash mapping */
429 #elif defined(CPU_COLDFIRE)
430 volatile unsigned short* flash = (unsigned short*)0; /* flash mapping */
431 #endif
432 int old_level; /* saved interrupt level */
434 not_manu = flash[0]; /* read the normal content */
435 not_id = flash[1]; /* should be 'A' (0x41) and 'R' (0x52) from the "ARCH" marker */
437 /* disable interrupts, prevent any stray flash access */
438 old_level = set_irq_level(HIGHEST_IRQ_LEVEL);
440 flash[addr1] = 0xAA; /* enter command mode */
441 flash[addr2] = 0x55;
442 flash[addr1] = 0x90; /* ID command */
443 /* Atmel wants 20ms pause here */
444 /* sleep(HZ/50); no sleeping possible while interrupts are disabled */
446 manu = flash[0]; /* read the IDs */
447 id = flash[1];
449 flash[0] = 0xF0; /* reset flash (back to normal read mode) */
450 /* Atmel wants 20ms pause here */
451 /* sleep(HZ/50); no sleeping possible while interrupts are disabled */
453 set_irq_level(old_level); /* enable interrupts again */
455 /* I assume success if the obtained values are different from
456 the normal flash content. This is not perfectly bulletproof, they
457 could theoretically be the same by chance, causing us to fail. */
458 if (not_manu != manu || not_id != id) /* a value has changed */
460 *p_manufacturer = manu; /* return the results */
461 *p_device = id;
462 return true; /* success */
464 return false; /* fail */
466 #endif /* (CONFIG_CPU == SH7034 || CPU_COLDFIRE) */
468 #ifndef SIMULATOR
469 #ifdef CPU_PP
470 static int perfcheck(void)
472 int result;
474 asm (
475 "mrs r2, CPSR \n"
476 "orr r0, r2, #0xc0 \n" /* disable IRQ and FIQ */
477 "msr CPSR_c, r0 \n"
478 "mov %[res], #0 \n"
479 "ldr r0, [%[timr]] \n"
480 "add r0, r0, %[tmo] \n"
481 "1: \n"
482 "add %[res], %[res], #1 \n"
483 "ldr r1, [%[timr]] \n"
484 "cmp r1, r0 \n"
485 "bmi 1b \n"
486 "msr CPSR_c, r2 \n" /* reset IRQ and FIQ state */
488 [res]"=&r"(result)
490 [timr]"r"(&USEC_TIMER),
491 [tmo]"r"(
492 #if CONFIG_CPU == PP5002
493 16000
494 #else /* PP5020/5022/5024 */
495 10226
496 #endif
499 "r0", "r1", "r2"
501 return result;
503 #endif
505 #ifdef HAVE_LCD_BITMAP
506 static bool dbg_hw_info(void)
508 #if CONFIG_CPU == SH7034
509 char buf[32];
510 int bitmask = HW_MASK;
511 int rom_version = ROM_VERSION;
512 unsigned manu, id; /* flash IDs */
513 bool got_id; /* flag if we managed to get the flash IDs */
514 unsigned rom_crc = 0xffffffff; /* CRC32 of the boot ROM */
515 bool has_bootrom; /* flag for boot ROM present */
516 int oldmode; /* saved memory guard mode */
518 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
520 /* get flash ROM type */
521 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
522 if (!got_id)
523 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
525 /* check if the boot ROM area is a flash mirror */
526 has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0);
527 if (has_bootrom) /* if ROM and Flash different */
529 /* calculate CRC16 checksum of boot ROM */
530 rom_crc = crc_32((unsigned char*)0x0000, 64*1024, 0xffffffff);
533 system_memory_guard(oldmode); /* re-enable memory guard */
535 lcd_setmargins(0, 0);
536 lcd_setfont(FONT_SYSFIXED);
537 lcd_clear_display();
539 lcd_puts(0, 0, "[Hardware info]");
541 snprintf(buf, 32, "ROM: %d.%02d", rom_version/100, rom_version%100);
542 lcd_puts(0, 1, buf);
544 snprintf(buf, 32, "Mask: 0x%04x", bitmask);
545 lcd_puts(0, 2, buf);
547 if (got_id)
548 snprintf(buf, 32, "Flash: M=%02x D=%02x", manu, id);
549 else
550 snprintf(buf, 32, "Flash: M=?? D=??"); /* unknown, sorry */
551 lcd_puts(0, 3, buf);
553 if (has_bootrom)
555 if (rom_crc == 0x56DBA4EE) /* known Version 1 */
556 snprintf(buf, 32, "Boot ROM: V1");
557 else
558 snprintf(buf, 32, "ROMcrc: 0x%08x", rom_crc);
560 else
562 snprintf(buf, 32, "Boot ROM: none");
564 lcd_puts(0, 4, buf);
566 lcd_update();
568 while(1)
570 if (action_userabort(TIMEOUT_BLOCK))
571 return false;
573 #elif CONFIG_CPU == MCF5249 || CONFIG_CPU == MCF5250
574 char buf[32];
575 unsigned manu, id; /* flash IDs */
576 int got_id; /* flag if we managed to get the flash IDs */
577 int oldmode; /* saved memory guard mode */
578 int line = 0;
580 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
582 /* get flash ROM type */
583 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
584 if (!got_id)
585 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
587 system_memory_guard(oldmode); /* re-enable memory guard */
589 lcd_setmargins(0, 0);
590 lcd_setfont(FONT_SYSFIXED);
591 lcd_clear_display();
593 lcd_puts(0, line++, "[Hardware info]");
595 if (got_id)
596 snprintf(buf, 32, "Flash: M=%04x D=%04x", manu, id);
597 else
598 snprintf(buf, 32, "Flash: M=???? D=????"); /* unknown, sorry */
599 lcd_puts(0, line++, buf);
601 #ifdef IAUDIO_X5
603 struct ds2411_id id;
605 lcd_puts(0, ++line, "Serial Number:");
607 got_id = ds2411_read_id(&id);
609 if (got_id == DS2411_OK)
611 snprintf(buf, 32, " FC=%02x", (unsigned)id.family_code);
612 lcd_puts(0, ++line, buf);
613 snprintf(buf, 32, " ID=%02X %02X %02X %02X %02X %02X",
614 (unsigned)id.uid[0], (unsigned)id.uid[1], (unsigned)id.uid[2],
615 (unsigned)id.uid[3], (unsigned)id.uid[4], (unsigned)id.uid[5]);
616 lcd_puts(0, ++line, buf);
617 snprintf(buf, 32, " CRC=%02X", (unsigned)id.crc);
619 else
621 snprintf(buf, 32, "READ ERR=%d", got_id);
624 lcd_puts(0, ++line, buf);
626 #endif
628 lcd_update();
630 while(1)
632 if (action_userabort(TIMEOUT_BLOCK))
633 return false;
635 #elif defined(CPU_PP502x)
636 char buf[32];
637 char pp_version[] = { (PP_VER2 >> 24) & 0xff, (PP_VER2 >> 16) & 0xff,
638 (PP_VER2 >> 8) & 0xff, (PP_VER2) & 0xff,
639 (PP_VER1 >> 24) & 0xff, (PP_VER1 >> 16) & 0xff,
640 (PP_VER1 >> 8) & 0xff, (PP_VER1) & 0xff, '\0' };
642 lcd_setmargins(0, 0);
643 lcd_setfont(FONT_SYSFIXED);
644 lcd_clear_display();
646 lcd_puts(0, 0, "[Hardware info]");
648 snprintf(buf, sizeof(buf), "HW rev: 0x%08x", ipod_hw_rev);
649 lcd_puts(0, 1, buf);
651 snprintf(buf, sizeof(buf), "PP version: %s", pp_version);
652 lcd_puts(0, 2, buf);
654 snprintf(buf, sizeof(buf), "Est. clock (kHz): %d", perfcheck());
655 lcd_puts(0, 3, buf);
657 lcd_update();
659 while(1)
661 if (action_userabort(TIMEOUT_BLOCK))
662 return false;
664 #endif /* CONFIG_CPU */
665 return false;
667 #else /* !HAVE_LCD_BITMAP */
668 static bool dbg_hw_info(void)
670 char buf[32];
671 int button;
672 int currval = 0;
673 int rom_version = ROM_VERSION;
674 unsigned manu, id; /* flash IDs */
675 bool got_id; /* flag if we managed to get the flash IDs */
676 unsigned rom_crc = 0xffffffff; /* CRC32 of the boot ROM */
677 bool has_bootrom; /* flag for boot ROM present */
678 int oldmode; /* saved memory guard mode */
680 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
682 /* get flash ROM type */
683 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
684 if (!got_id)
685 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
687 /* check if the boot ROM area is a flash mirror */
688 has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0);
689 if (has_bootrom) /* if ROM and Flash different */
691 /* calculate CRC16 checksum of boot ROM */
692 rom_crc = crc_32((unsigned char*)0x0000, 64*1024, 0xffffffff);
695 system_memory_guard(oldmode); /* re-enable memory guard */
697 lcd_clear_display();
699 lcd_puts(0, 0, "[HW Info]");
700 while(1)
702 switch(currval)
704 case 0:
705 snprintf(buf, 32, "ROM: %d.%02d",
706 rom_version/100, rom_version%100);
707 break;
708 case 1:
709 if (got_id)
710 snprintf(buf, 32, "Flash:%02x,%02x", manu, id);
711 else
712 snprintf(buf, 32, "Flash:??,??"); /* unknown, sorry */
713 break;
714 case 2:
715 if (has_bootrom)
717 if (rom_crc == 0x56DBA4EE) /* known Version 1 */
718 snprintf(buf, 32, "BootROM: V1");
719 else if (rom_crc == 0x358099E8)
720 snprintf(buf, 32, "BootROM: V2");
721 /* alternative boot ROM found in one single player so far */
722 else
723 snprintf(buf, 32, "R: %08x", rom_crc);
725 else
726 snprintf(buf, 32, "BootROM: no");
729 lcd_puts(0, 1, buf);
730 lcd_update();
732 button = get_action(CONTEXT_SETTINGS,TIMEOUT_BLOCK);
734 switch(button)
736 case ACTION_STD_CANCEL:
737 action_signalscreenchange();
738 return false;
740 case ACTION_SETTINGS_DEC:
741 currval--;
742 if(currval < 0)
743 currval = 2;
744 break;
746 case ACTION_SETTINGS_INC:
747 currval++;
748 if(currval > 2)
749 currval = 0;
750 break;
753 return false;
755 #endif /* !HAVE_LCD_BITMAP */
756 #endif /* !SIMULATOR */
758 #ifndef SIMULATOR
759 static char* dbg_partitions_getname(int selected_item, void * data, char *buffer)
761 (void)data;
762 int partition = selected_item/2;
763 struct partinfo* p = disk_partinfo(partition);
764 if (selected_item%2)
766 snprintf(buffer, MAX_PATH, " T:%x %ld MB", p->type, p->size / 2048);
768 else
770 snprintf(buffer, MAX_PATH, "P%d: S:%lx", partition, p->start);
772 return buffer;
775 bool dbg_partitions(void)
777 struct action_callback_info info;
778 info.title = "Partition Info";
779 info.count = 4;
780 info.selection_size = 2;
781 info.action_callback = NULL;
782 info.dbg_getname = dbg_partitions_getname;
783 dbg_list(&info);
784 return false;
786 #endif
788 #if defined(CPU_COLDFIRE) && defined(HAVE_SPDIF_OUT)
789 static bool dbg_spdif(void)
791 char buf[128];
792 int line;
793 unsigned int control;
794 int x;
795 char *s;
796 int category;
797 int generation;
798 unsigned int interruptstat;
799 bool valnogood, symbolerr, parityerr;
800 bool done = false;
801 bool spdif_src_on;
802 int spdif_source = spdif_get_output_source(&spdif_src_on);
803 spdif_set_output_source(AUDIO_SRC_SPDIF IF_SPDIF_POWER_(, true));
805 lcd_setmargins(0, 0);
806 lcd_clear_display();
807 lcd_setfont(FONT_SYSFIXED);
809 #ifdef HAVE_SPDIF_POWER
810 spdif_power_enable(true); /* We need SPDIF power for both sending & receiving */
811 #endif
813 while (!done)
815 line = 0;
817 control = EBU1RCVCCHANNEL1;
818 interruptstat = INTERRUPTSTAT;
819 INTERRUPTCLEAR = 0x03c00000;
821 valnogood = (interruptstat & 0x01000000)?true:false;
822 symbolerr = (interruptstat & 0x00800000)?true:false;
823 parityerr = (interruptstat & 0x00400000)?true:false;
825 snprintf(buf, sizeof(buf), "Val: %s Sym: %s Par: %s",
826 valnogood?"--":"OK",
827 symbolerr?"--":"OK",
828 parityerr?"--":"OK");
829 lcd_puts(0, line++, buf);
831 snprintf(buf, sizeof(buf), "Status word: %08x", (int)control);
832 lcd_puts(0, line++, buf);
834 line++;
836 x = control >> 31;
837 snprintf(buf, sizeof(buf), "PRO: %d (%s)",
838 x, x?"Professional":"Consumer");
839 lcd_puts(0, line++, buf);
841 x = (control >> 30) & 1;
842 snprintf(buf, sizeof(buf), "Audio: %d (%s)",
843 x, x?"Non-PCM":"PCM");
844 lcd_puts(0, line++, buf);
846 x = (control >> 29) & 1;
847 snprintf(buf, sizeof(buf), "Copy: %d (%s)",
848 x, x?"Permitted":"Inhibited");
849 lcd_puts(0, line++, buf);
851 x = (control >> 27) & 7;
852 switch(x)
854 case 0:
855 s = "None";
856 break;
857 case 1:
858 s = "50/15us";
859 break;
860 default:
861 s = "Reserved";
862 break;
864 snprintf(buf, sizeof(buf), "Preemphasis: %d (%s)", x, s);
865 lcd_puts(0, line++, buf);
867 x = (control >> 24) & 3;
868 snprintf(buf, sizeof(buf), "Mode: %d", x);
869 lcd_puts(0, line++, buf);
871 category = (control >> 17) & 127;
872 switch(category)
874 case 0x00:
875 s = "General";
876 break;
877 case 0x40:
878 s = "Audio CD";
879 break;
880 default:
881 s = "Unknown";
883 snprintf(buf, sizeof(buf), "Category: 0x%02x (%s)", category, s);
884 lcd_puts(0, line++, buf);
886 x = (control >> 16) & 1;
887 generation = x;
888 if(((category & 0x70) == 0x10) ||
889 ((category & 0x70) == 0x40) ||
890 ((category & 0x78) == 0x38))
892 generation = !generation;
894 snprintf(buf, sizeof(buf), "Generation: %d (%s)",
895 x, generation?"Original":"No ind.");
896 lcd_puts(0, line++, buf);
898 x = (control >> 12) & 15;
899 snprintf(buf, sizeof(buf), "Source: %d", x);
900 lcd_puts(0, line++, buf);
902 x = (control >> 8) & 15;
903 switch(x)
905 case 0:
906 s = "Unspecified";
907 break;
908 case 8:
909 s = "A (Left)";
910 break;
911 case 4:
912 s = "B (Right)";
913 break;
914 default:
915 s = "";
916 break;
918 snprintf(buf, sizeof(buf), "Channel: %d (%s)", x, s);
919 lcd_puts(0, line++, buf);
921 x = (control >> 4) & 15;
922 switch(x)
924 case 0:
925 s = "44.1kHz";
926 break;
927 case 0x4:
928 s = "48kHz";
929 break;
930 case 0xc:
931 s = "32kHz";
932 break;
934 snprintf(buf, sizeof(buf), "Frequency: %d (%s)", x, s);
935 lcd_puts(0, line++, buf);
937 x = (control >> 2) & 3;
938 snprintf(buf, sizeof(buf), "Clock accuracy: %d", x);
939 lcd_puts(0, line++, buf);
940 line++;
942 #ifndef SIMULATOR
943 snprintf(buf, sizeof(buf), "Measured freq: %ldHz",
944 spdif_measure_frequency());
945 lcd_puts(0, line++, buf);
946 #endif
948 lcd_update();
950 if (action_userabort(HZ/10))
951 break;
954 spdif_set_output_source(spdif_source IF_SPDIF_POWER_(, spdif_src_on));
956 #ifdef HAVE_SPDIF_POWER
957 spdif_power_enable(global_settings.spdif_enable);
958 #endif
960 return false;
962 #endif /* CPU_COLDFIRE */
964 #ifndef SIMULATOR
965 #ifdef HAVE_LCD_BITMAP
966 /* button definitions */
967 #if (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
968 (CONFIG_KEYPAD == IRIVER_H300_PAD)
969 # define DEBUG_CANCEL BUTTON_OFF
971 #elif CONFIG_KEYPAD == RECORDER_PAD
972 # define DEBUG_CANCEL BUTTON_OFF
974 #elif CONFIG_KEYPAD == ONDIO_PAD
975 # define DEBUG_CANCEL BUTTON_MENU
977 #elif (CONFIG_KEYPAD == IPOD_3G_PAD) || \
978 (CONFIG_KEYPAD == IPOD_4G_PAD)
979 # define DEBUG_CANCEL BUTTON_MENU
981 #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
982 # define DEBUG_CANCEL BUTTON_PLAY
984 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
985 # define DEBUG_CANCEL BUTTON_REC
987 #elif CONFIG_KEYPAD == GIGABEAT_PAD
988 # define DEBUG_CANCEL BUTTON_A
990 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
991 # define DEBUG_CANCEL BUTTON_REW
993 #elif CONFIG_KEYPAD == SANSA_E200_PAD
994 # define DEBUG_CANCEL BUTTON_LEFT
995 #endif /* key definitios */
997 /* Test code!!! */
998 bool dbg_ports(void)
1000 #if CONFIG_CPU == SH7034
1001 unsigned short porta;
1002 unsigned short portb;
1003 unsigned char portc;
1004 char buf[32];
1005 int adc_battery_voltage, adc_battery_level;
1007 lcd_setfont(FONT_SYSFIXED);
1008 lcd_setmargins(0, 0);
1009 lcd_clear_display();
1011 while(1)
1013 porta = PADR;
1014 portb = PBDR;
1015 portc = PCDR;
1017 snprintf(buf, 32, "PADR: %04x", porta);
1018 lcd_puts(0, 0, buf);
1019 snprintf(buf, 32, "PBDR: %04x", portb);
1020 lcd_puts(0, 1, buf);
1022 snprintf(buf, 32, "AN0: %03x AN4: %03x", adc_read(0), adc_read(4));
1023 lcd_puts(0, 2, buf);
1024 snprintf(buf, 32, "AN1: %03x AN5: %03x", adc_read(1), adc_read(5));
1025 lcd_puts(0, 3, buf);
1026 snprintf(buf, 32, "AN2: %03x AN6: %03x", adc_read(2), adc_read(6));
1027 lcd_puts(0, 4, buf);
1028 snprintf(buf, 32, "AN3: %03x AN7: %03x", adc_read(3), adc_read(7));
1029 lcd_puts(0, 5, buf);
1031 battery_read_info(NULL, &adc_battery_voltage,
1032 &adc_battery_level);
1033 snprintf(buf, 32, "Batt: %d.%02dV %d%% ", adc_battery_voltage / 100,
1034 adc_battery_voltage % 100, adc_battery_level);
1035 lcd_puts(0, 6, buf);
1037 lcd_update();
1038 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1039 return false;
1041 #elif defined(CPU_COLDFIRE)
1042 unsigned int gpio_out;
1043 unsigned int gpio1_out;
1044 unsigned int gpio_read;
1045 unsigned int gpio1_read;
1046 unsigned int gpio_function;
1047 unsigned int gpio1_function;
1048 unsigned int gpio_enable;
1049 unsigned int gpio1_enable;
1050 int adc_buttons, adc_remote;
1051 int adc_battery, adc_battery_voltage, adc_battery_level;
1052 char buf[128];
1053 int line;
1055 lcd_setmargins(0, 0);
1056 lcd_clear_display();
1057 lcd_setfont(FONT_SYSFIXED);
1059 while(1)
1061 line = 0;
1062 gpio_read = GPIO_READ;
1063 gpio1_read = GPIO1_READ;
1064 gpio_out = GPIO_OUT;
1065 gpio1_out = GPIO1_OUT;
1066 gpio_function = GPIO_FUNCTION;
1067 gpio1_function = GPIO1_FUNCTION;
1068 gpio_enable = GPIO_ENABLE;
1069 gpio1_enable = GPIO1_ENABLE;
1071 snprintf(buf, sizeof(buf), "GPIO_READ: %08x", gpio_read);
1072 lcd_puts(0, line++, buf);
1073 snprintf(buf, sizeof(buf), "GPIO_OUT: %08x", gpio_out);
1074 lcd_puts(0, line++, buf);
1075 snprintf(buf, sizeof(buf), "GPIO_FUNCTION: %08x", gpio_function);
1076 lcd_puts(0, line++, buf);
1077 snprintf(buf, sizeof(buf), "GPIO_ENABLE: %08x", gpio_enable);
1078 lcd_puts(0, line++, buf);
1080 snprintf(buf, sizeof(buf), "GPIO1_READ: %08x", gpio1_read);
1081 lcd_puts(0, line++, buf);
1082 snprintf(buf, sizeof(buf), "GPIO1_OUT: %08x", gpio1_out);
1083 lcd_puts(0, line++, buf);
1084 snprintf(buf, sizeof(buf), "GPIO1_FUNCTION: %08x", gpio1_function);
1085 lcd_puts(0, line++, buf);
1086 snprintf(buf, sizeof(buf), "GPIO1_ENABLE: %08x", gpio1_enable);
1087 lcd_puts(0, line++, buf);
1089 adc_buttons = adc_read(ADC_BUTTONS);
1090 adc_remote = adc_read(ADC_REMOTE);
1091 battery_read_info(&adc_battery, &adc_battery_voltage,
1092 &adc_battery_level);
1093 #if defined(IAUDIO_X5) || defined(IAUDIO_M5) || defined(IRIVER_H300_SERIES)
1094 snprintf(buf, sizeof(buf), "ADC_BUTTONS (%c): %02x",
1095 button_scan_enabled() ? '+' : '-', adc_buttons);
1096 #else
1097 snprintf(buf, sizeof(buf), "ADC_BUTTONS: %02x", adc_buttons);
1098 #endif
1099 lcd_puts(0, line++, buf);
1100 #if defined(IAUDIO_X5) || defined(IAUDIO_M5)
1101 snprintf(buf, sizeof(buf), "ADC_REMOTE (%c): %02x",
1102 remote_detect() ? '+' : '-', adc_remote);
1103 #else
1104 snprintf(buf, sizeof(buf), "ADC_REMOTE: %02x", adc_remote);
1105 #endif
1107 lcd_puts(0, line++, buf);
1108 snprintf(buf, sizeof(buf), "ADC_BATTERY: %02x", adc_battery);
1109 lcd_puts(0, line++, buf);
1110 #if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES)
1111 snprintf(buf, sizeof(buf), "ADC_REMOTEDETECT: %02x",
1112 adc_read(ADC_REMOTEDETECT));
1113 lcd_puts(0, line++, buf);
1114 #endif
1116 snprintf(buf, 32, "Batt: %d.%02dV %d%% ", adc_battery_voltage / 100,
1117 adc_battery_voltage % 100, adc_battery_level);
1118 lcd_puts(0, line++, buf);
1120 #if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES)
1121 snprintf(buf, sizeof(buf), "remotetype: %d", remote_type());
1122 lcd_puts(0, line++, buf);
1123 #endif
1125 lcd_update();
1126 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1127 return false;
1130 #elif defined(CPU_PP502x)
1132 unsigned int gpio_a, gpio_b, gpio_c, gpio_d;
1133 unsigned int gpio_e, gpio_f, gpio_g, gpio_h;
1134 unsigned int gpio_i, gpio_j, gpio_k, gpio_l;
1136 char buf[128];
1137 int line;
1139 lcd_setmargins(0, 0);
1140 lcd_clear_display();
1141 lcd_setfont(FONT_SYSFIXED);
1143 while(1)
1145 gpio_a = GPIOA_INPUT_VAL;
1146 gpio_b = GPIOB_INPUT_VAL;
1147 gpio_c = GPIOC_INPUT_VAL;
1149 gpio_g = GPIOG_INPUT_VAL;
1150 gpio_h = GPIOH_INPUT_VAL;
1151 gpio_i = GPIOI_INPUT_VAL;
1153 line = 0;
1154 snprintf(buf, sizeof(buf), "GPIO_A: %02x GPIO_G: %02x", gpio_a, gpio_g);
1155 lcd_puts(0, line++, buf);
1156 snprintf(buf, sizeof(buf), "GPIO_B: %02x GPIO_H: %02x", gpio_b, gpio_h);
1157 lcd_puts(0, line++, buf);
1158 snprintf(buf, sizeof(buf), "GPIO_C: %02x GPIO_I: %02x", gpio_c, gpio_i);
1159 lcd_puts(0, line++, buf);
1161 gpio_d = GPIOD_INPUT_VAL;
1162 gpio_e = GPIOE_INPUT_VAL;
1163 gpio_f = GPIOF_INPUT_VAL;
1165 gpio_j = GPIOJ_INPUT_VAL;
1166 gpio_k = GPIOK_INPUT_VAL;
1167 gpio_l = GPIOL_INPUT_VAL;
1169 snprintf(buf, sizeof(buf), "GPIO_D: %02x GPIO_J: %02x", gpio_d, gpio_j);
1170 lcd_puts(0, line++, buf);
1171 snprintf(buf, sizeof(buf), "GPIO_E: %02x GPIO_K: %02x", gpio_e, gpio_k);
1172 lcd_puts(0, line++, buf);
1173 snprintf(buf, sizeof(buf), "GPIO_F: %02x GPIO_L: %02x", gpio_f, gpio_l);
1174 lcd_puts(0, line++, buf);
1175 line++;
1177 snprintf(buf, sizeof(buf), "CLOCK_SRC: %08lx", inl(0x60006020));
1178 lcd_puts(0, line++, buf);
1179 snprintf(buf, sizeof(buf), "CLOCK_0x2C: %08lx", inl(0x6000602c));
1180 lcd_puts(0, line++, buf);
1181 snprintf(buf, sizeof(buf), "CLOCK_0xA0: %08lx", inl(0x600060a0));
1182 lcd_puts(0, line++, buf);
1183 snprintf(buf, sizeof(buf), "PLL_CONTROL: %08lx", inl(0x60006034));
1184 lcd_puts(0, line++, buf);
1185 snprintf(buf, sizeof(buf), "PLL_STATUS: %08lx", inl(0x6000603c));
1186 lcd_puts(0, line++, buf);
1187 snprintf(buf, sizeof(buf), "DEV_0x34: %08lx", inl(0x70000034));
1188 lcd_puts(0, line++, buf);
1190 #if defined(IRIVER_H10) || defined(IRIVER_H10_5GB)
1191 line++;
1192 snprintf(buf, sizeof(buf), "ADC_BATTERY: %02x", adc_read(ADC_BATTERY));
1193 lcd_puts(0, line++, buf);
1194 snprintf(buf, sizeof(buf), "ADC_UNKNOWN_1: %02x", adc_read(ADC_UNKNOWN_1));
1195 lcd_puts(0, line++, buf);
1196 snprintf(buf, sizeof(buf), "ADC_REMOTE: %02x", adc_read(ADC_REMOTE));
1197 lcd_puts(0, line++, buf);
1198 snprintf(buf, sizeof(buf), "ADC_SCROLLPAD: %02x", adc_read(ADC_SCROLLPAD));
1199 lcd_puts(0, line++, buf);
1200 #elif defined(SANSA_E200)
1201 line++;
1202 snprintf(buf, sizeof(buf), "ADC_BVDD: %02x", adc_read(ADC_BVDD));
1203 lcd_puts(0, line++, buf);
1204 snprintf(buf, sizeof(buf), "ADC_RTCSUP: %02x", adc_read(ADC_RTCSUP));
1205 lcd_puts(0, line++, buf);
1206 snprintf(buf, sizeof(buf), "ADC_UVDD: %02x", adc_read(ADC_UVDD));
1207 lcd_puts(0, line++, buf);
1208 snprintf(buf, sizeof(buf), "ADC_CHG_IN: %02x", adc_read(ADC_CHG_IN));
1209 lcd_puts(0, line++, buf);
1210 snprintf(buf, sizeof(buf), "ADC_CVDD: %02x", adc_read(ADC_CVDD));
1211 lcd_puts(0, line++, buf);
1212 snprintf(buf, sizeof(buf), "ADC_BATTEMP: %02x", adc_read(ADC_BATTEMP));
1213 lcd_puts(0, line++, buf);
1214 snprintf(buf, sizeof(buf), "ADC_MICSUP1: %02x", adc_read(ADC_MICSUP1));
1215 lcd_puts(0, line++, buf);
1216 snprintf(buf, sizeof(buf), "ADC_MICSUP2: %02x", adc_read(ADC_MICSUP2));
1217 lcd_puts(0, line++, buf);
1218 snprintf(buf, sizeof(buf), "ADC_VBE1: %02x", adc_read(ADC_VBE1));
1219 lcd_puts(0, line++, buf);
1220 snprintf(buf, sizeof(buf), "ADC_VBE2: %02x", adc_read(ADC_VBE2));
1221 lcd_puts(0, line++, buf);
1222 snprintf(buf, sizeof(buf), "ADC_I_MICSUP1: %02x", adc_read(ADC_I_MICSUP1));
1223 lcd_puts(0, line++, buf);
1224 snprintf(buf, sizeof(buf), "ADC_I_MICSUP2: %02x", adc_read(ADC_I_MICSUP2));
1225 lcd_puts(0, line++, buf);
1226 snprintf(buf, sizeof(buf), "ADC_VBAT: %02x", adc_read(ADC_VBAT));
1227 lcd_puts(0, line++, buf);
1228 #endif
1229 lcd_update();
1230 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1231 return false;
1234 #elif CONFIG_CPU == PP5002
1235 unsigned int gpio_a, gpio_b, gpio_c, gpio_d;
1237 char buf[128];
1238 int line;
1240 lcd_setmargins(0, 0);
1241 lcd_clear_display();
1242 lcd_setfont(FONT_SYSFIXED);
1244 while(1)
1246 gpio_a = GPIOA_INPUT_VAL;
1247 gpio_b = GPIOB_INPUT_VAL;
1248 gpio_c = GPIOC_INPUT_VAL;
1249 gpio_d = GPIOD_INPUT_VAL;
1251 line = 0;
1252 snprintf(buf, sizeof(buf), "GPIO_A: %02x GPIO_B: %02x", gpio_a, gpio_b);
1253 lcd_puts(0, line++, buf);
1254 snprintf(buf, sizeof(buf), "GPIO_C: %02x GPIO_D: %02x", gpio_c, gpio_d);
1255 lcd_puts(0, line++, buf);
1257 snprintf(buf, sizeof(buf), "CLOCK_ENABLE: %08lx", CLOCK_ENABLE);
1258 lcd_puts(0, line++, buf);
1259 snprintf(buf, sizeof(buf), "CLOCK_SOURCE: %08lx", CLOCK_SOURCE);
1260 lcd_puts(0, line++, buf);
1261 snprintf(buf, sizeof(buf), "CLOCK_DIV: %08lx", CLOCK_DIV);
1262 lcd_puts(0, line++, buf);
1263 snprintf(buf, sizeof(buf), "PLL_DIV: %08lx", PLL_DIV);
1264 lcd_puts(0, line++, buf);
1265 snprintf(buf, sizeof(buf), "PLL_MULT: %08lx", PLL_MULT);
1266 lcd_puts(0, line++, buf);
1267 snprintf(buf, sizeof(buf), "TIMING1_CTL: %08lx", TIMING1_CTL);
1268 lcd_puts(0, line++, buf);
1269 snprintf(buf, sizeof(buf), "TIMING2_CTL: %08lx", TIMING2_CTL);
1270 lcd_puts(0, line++, buf);
1271 snprintf(buf, sizeof(buf), "Est. clock (kHz): %d", perfcheck());
1272 lcd_puts(0, line++, buf);
1274 lcd_update();
1275 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1276 return false;
1278 #elif CONFIG_CPU == S3C2440
1279 char buf[50];
1280 int line;
1282 lcd_setmargins(0, 0);
1283 lcd_clear_display();
1284 lcd_setfont(FONT_SYSFIXED);
1286 while(1)
1288 line = 0;
1289 snprintf(buf, sizeof(buf), "[Ports and Registers]"); lcd_puts(0, line++, buf);
1291 snprintf(buf, sizeof(buf), "GPACON: %08x GPBCON: %08x", GPACON, GPBCON); lcd_puts(0, line++, buf);
1292 snprintf(buf, sizeof(buf), "GPADAT: %08x GPBDAT: %08x", GPADAT, GPBDAT); lcd_puts(0, line++, buf);
1293 snprintf(buf, sizeof(buf), "GPAUP: %08x GPBUP: %08x", 0, GPBUP); lcd_puts(0, line++, buf);
1294 snprintf(buf, sizeof(buf), "GPCCON: %08x GPDCON: %08x", GPCCON, GPDCON); lcd_puts(0, line++, buf);
1295 snprintf(buf, sizeof(buf), "GPCDAT: %08x GPDDAT: %08x", GPCDAT, GPDDAT); lcd_puts(0, line++, buf);
1296 snprintf(buf, sizeof(buf), "GPCUP: %08x GPDUP: %08x", GPCUP, GPDUP); lcd_puts(0, line++, buf);
1298 snprintf(buf, sizeof(buf), "GPCCON: %08x GPDCON: %08x", GPCCON, GPDCON); lcd_puts(0, line++, buf);
1299 snprintf(buf, sizeof(buf), "GPCDAT: %08x GPDDAT: %08x", GPCDAT, GPDDAT); lcd_puts(0, line++, buf);
1300 snprintf(buf, sizeof(buf), "GPCUP: %08x GPDUP: %08x", GPCUP, GPDUP); lcd_puts(0, line++, buf);
1302 snprintf(buf, sizeof(buf), "GPECON: %08x GPFCON: %08x", GPECON, GPFCON); lcd_puts(0, line++, buf);
1303 snprintf(buf, sizeof(buf), "GPEDAT: %08x GPFDAT: %08x", GPEDAT, GPFDAT); lcd_puts(0, line++, buf);
1304 snprintf(buf, sizeof(buf), "GPEUP: %08x GPFUP: %08x", GPEUP, GPFUP); lcd_puts(0, line++, buf);
1306 snprintf(buf, sizeof(buf), "GPGCON: %08x GPHCON: %08x", GPGCON, GPHCON); lcd_puts(0, line++, buf);
1307 snprintf(buf, sizeof(buf), "GPGDAT: %08x GPHDAT: %08x", GPGDAT, GPHDAT); lcd_puts(0, line++, buf);
1308 snprintf(buf, sizeof(buf), "GPGUP: %08x GPHUP: %08x", GPGUP, GPHUP); lcd_puts(0, line++, buf);
1310 snprintf(buf, sizeof(buf), "GPJCON: %08x", GPJCON); lcd_puts(0, line++, buf);
1311 snprintf(buf, sizeof(buf), "GPJDAT: %08x", GPJDAT); lcd_puts(0, line++, buf);
1312 snprintf(buf, sizeof(buf), "GPJUP: %08x", GPJUP); lcd_puts(0, line++, buf);
1314 line++;
1316 snprintf(buf, sizeof(buf), "SRCPND: %08x INTMOD: %08x", SRCPND, INTMOD); lcd_puts(0, line++, buf);
1317 snprintf(buf, sizeof(buf), "INTMSK: %08x INTPND: %08x", INTMSK, INTPND); lcd_puts(0, line++, buf);
1318 snprintf(buf, sizeof(buf), "CLKCON: %08x CLKSLOW: %08x", CLKCON, CLKSLOW); lcd_puts(0, line++, buf);
1319 snprintf(buf, sizeof(buf), "MPLLCON: %08x UPLLCON: %08x", MPLLCON, UPLLCON); lcd_puts(0, line++, buf);
1320 snprintf(buf, sizeof(buf), "CLKDIVN: %08x", CLKDIVN); lcd_puts(0, line++, buf);
1322 lcd_update();
1323 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1324 return false;
1326 #endif /* CPU */
1327 return false;
1329 #else /* !HAVE_LCD_BITMAP */
1330 bool dbg_ports(void)
1332 unsigned short porta;
1333 unsigned short portb;
1334 unsigned char portc;
1335 char buf[32];
1336 int button;
1337 int adc_battery_voltage;
1338 int currval = 0;
1340 lcd_clear_display();
1342 while(1)
1344 porta = PADR;
1345 portb = PBDR;
1346 portc = PCDR;
1348 switch(currval)
1350 case 0:
1351 snprintf(buf, 32, "PADR: %04x", porta);
1352 break;
1353 case 1:
1354 snprintf(buf, 32, "PBDR: %04x", portb);
1355 break;
1356 case 2:
1357 snprintf(buf, 32, "AN0: %03x", adc_read(0));
1358 break;
1359 case 3:
1360 snprintf(buf, 32, "AN1: %03x", adc_read(1));
1361 break;
1362 case 4:
1363 snprintf(buf, 32, "AN2: %03x", adc_read(2));
1364 break;
1365 case 5:
1366 snprintf(buf, 32, "AN3: %03x", adc_read(3));
1367 break;
1368 case 6:
1369 snprintf(buf, 32, "AN4: %03x", adc_read(4));
1370 break;
1371 case 7:
1372 snprintf(buf, 32, "AN5: %03x", adc_read(5));
1373 break;
1374 case 8:
1375 snprintf(buf, 32, "AN6: %03x", adc_read(6));
1376 break;
1377 case 9:
1378 snprintf(buf, 32, "AN7: %03x", adc_read(7));
1379 break;
1380 break;
1382 lcd_puts(0, 0, buf);
1384 battery_read_info(NULL, &adc_battery_voltage, NULL);
1385 snprintf(buf, 32, "Batt: %d.%02dV", adc_battery_voltage / 100,
1386 adc_battery_voltage % 100);
1387 lcd_puts(0, 1, buf);
1388 lcd_update();
1390 button = get_action(CONTEXT_SETTINGS,HZ/5);
1392 switch(button)
1394 case ACTION_STD_CANCEL:
1395 action_signalscreenchange();
1396 return false;
1398 case ACTION_SETTINGS_DEC:
1399 currval--;
1400 if(currval < 0)
1401 currval = 9;
1402 break;
1404 case ACTION_SETTINGS_INC:
1405 currval++;
1406 if(currval > 9)
1407 currval = 0;
1408 break;
1411 return false;
1413 #endif /* !HAVE_LCD_BITMAP */
1414 #endif /* !SIMULATOR */
1416 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
1417 static bool dbg_cpufreq(void)
1419 char buf[128];
1420 int line;
1421 int button;
1423 #ifdef HAVE_LCD_BITMAP
1424 lcd_setmargins(0, 0);
1425 lcd_setfont(FONT_SYSFIXED);
1426 #endif
1427 lcd_clear_display();
1429 while(1)
1431 line = 0;
1433 snprintf(buf, sizeof(buf), "Frequency: %ld", FREQ);
1434 lcd_puts(0, line++, buf);
1436 snprintf(buf, sizeof(buf), "boost_counter: %d", get_cpu_boost_counter());
1437 lcd_puts(0, line++, buf);
1439 lcd_update();
1440 button = get_action(CONTEXT_STD,HZ/10);
1442 switch(button)
1444 case ACTION_STD_PREV:
1445 cpu_boost(true);
1446 break;
1448 case ACTION_STD_NEXT:
1449 cpu_boost(false);
1450 break;
1452 case ACTION_STD_OK:
1453 while (get_cpu_boost_counter() > 0)
1454 cpu_boost(false);
1455 set_cpu_frequency(CPUFREQ_DEFAULT);
1456 break;
1458 case ACTION_STD_CANCEL:
1459 action_signalscreenchange();
1460 return false;
1464 return false;
1466 #endif /* HAVE_ADJUSTABLE_CPU_FREQ */
1468 #ifndef SIMULATOR
1469 #ifdef HAVE_LCD_BITMAP
1471 * view_battery() shows a automatically scaled graph of the battery voltage
1472 * over time. Usable for estimating battery life / charging rate.
1473 * The power_history array is updated in power_thread of powermgmt.c.
1476 #define BAT_LAST_VAL MIN(LCD_WIDTH, POWER_HISTORY_LEN)
1477 #define BAT_YSPACE (LCD_HEIGHT - 20)
1479 static bool view_battery(void)
1481 int view = 0;
1482 int i, x, y;
1483 unsigned short maxv, minv;
1484 char buf[32];
1486 lcd_setmargins(0, 0);
1487 lcd_setfont(FONT_SYSFIXED);
1489 while(1)
1491 lcd_clear_display();
1492 switch (view) {
1493 case 0: /* voltage history graph */
1494 /* Find maximum and minimum voltage for scaling */
1495 maxv = 0;
1496 minv = 65535;
1497 for (i = 0; i < BAT_LAST_VAL; i++) {
1498 if (power_history[i] > maxv)
1499 maxv = power_history[i];
1500 if (power_history[i] && (power_history[i] < minv))
1502 minv = power_history[i];
1506 if ((minv < 1) || (minv >= 65535))
1507 minv = 1;
1508 if (maxv < 2)
1509 maxv = 2;
1510 if (minv == maxv)
1511 maxv < 65535 ? maxv++ : minv--;
1513 snprintf(buf, 30, "Battery %d.%02d", power_history[0] / 100,
1514 power_history[0] % 100);
1515 lcd_puts(0, 0, buf);
1516 snprintf(buf, 30, "scale %d.%02d-%d.%02d V",
1517 minv / 100, minv % 100, maxv / 100, maxv % 100);
1518 lcd_puts(0, 1, buf);
1520 x = 0;
1521 for (i = BAT_LAST_VAL - 1; i >= 0; i--) {
1522 y = (power_history[i] - minv) * BAT_YSPACE / (maxv - minv);
1523 lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
1524 lcd_vline(x, LCD_HEIGHT-1, 20);
1525 lcd_set_drawmode(DRMODE_SOLID);
1526 lcd_vline(x, LCD_HEIGHT-1,
1527 MIN(MAX(LCD_HEIGHT-1 - y, 20), LCD_HEIGHT-1));
1528 x++;
1531 break;
1533 case 1: /* status: */
1534 lcd_puts(0, 0, "Power status:");
1536 battery_read_info(NULL, &y, NULL);
1537 snprintf(buf, 30, "Battery: %d.%02d V", y / 100, y % 100);
1538 lcd_puts(0, 1, buf);
1539 #ifdef ADC_EXT_POWER
1540 y = (adc_read(ADC_EXT_POWER) * EXT_SCALE_FACTOR) / 10000;
1541 snprintf(buf, 30, "External: %d.%02d V", y / 100, y % 100);
1542 lcd_puts(0, 2, buf);
1543 #endif
1544 #if CONFIG_CHARGING
1545 #if CONFIG_CHARGING == CHARGING_CONTROL
1546 snprintf(buf, 30, "Chgr: %s %s",
1547 charger_inserted() ? "present" : "absent",
1548 charger_enabled ? "on" : "off");
1549 lcd_puts(0, 3, buf);
1550 snprintf(buf, 30, "short delta: %d", short_delta);
1551 lcd_puts(0, 5, buf);
1552 snprintf(buf, 30, "long delta: %d", long_delta);
1553 lcd_puts(0, 6, buf);
1554 lcd_puts(0, 7, power_message);
1555 snprintf(buf, 30, "USB Inserted: %s",
1556 usb_inserted() ? "yes" : "no");
1557 lcd_puts(0, 8, buf);
1558 #if defined IRIVER_H300_SERIES
1559 snprintf(buf, 30, "USB Charging Enabled: %s",
1560 usb_charging_enabled() ? "yes" : "no");
1561 lcd_puts(0, 9, buf);
1562 #endif
1563 #else /* CONFIG_CHARGING != CHARGING_CONTROL */
1564 #if defined IPOD_NANO || defined IPOD_VIDEO
1565 int usb_pwr = (GPIOL_INPUT_VAL & 0x10)?true:false;
1566 int ext_pwr = (GPIOL_INPUT_VAL & 0x08)?false:true;
1567 int dock = (GPIOA_INPUT_VAL & 0x10)?true:false;
1568 int charging = (GPIOB_INPUT_VAL & 0x01)?false:true;
1569 int headphone= (GPIOA_INPUT_VAL & 0x80)?true:false;
1571 snprintf(buf, 30, "USB pwr: %s",
1572 usb_pwr ? "present" : "absent");
1573 lcd_puts(0, 3, buf);
1574 snprintf(buf, 30, "EXT pwr: %s",
1575 ext_pwr ? "present" : "absent");
1576 lcd_puts(0, 4, buf);
1577 snprintf(buf, 30, "Battery: %s",
1578 charging ? "charging" : (usb_pwr||ext_pwr) ? "charged" : "discharging");
1579 lcd_puts(0, 5, buf);
1580 snprintf(buf, 30, "Dock mode: %s",
1581 dock ? "enabled" : "disabled");
1582 lcd_puts(0, 6, buf);
1583 snprintf(buf, 30, "Headphone: %s",
1584 headphone ? "connected" : "disconnected");
1585 lcd_puts(0, 7, buf);
1586 #else
1587 snprintf(buf, 30, "Charger: %s",
1588 charger_inserted() ? "present" : "absent");
1589 lcd_puts(0, 3, buf);
1590 #endif
1591 #endif /* CONFIG_CHARGING != CHARGING_CONTROL */
1592 #endif /* CONFIG_CHARGING */
1593 break;
1595 case 2: /* voltage deltas: */
1596 lcd_puts(0, 0, "Voltage deltas:");
1598 for (i = 0; i <= 6; i++) {
1599 y = power_history[i] - power_history[i+i];
1600 snprintf(buf, 30, "-%d min: %s%d.%02d V", i,
1601 (y < 0) ? "-" : "", ((y < 0) ? y * -1 : y) / 100,
1602 ((y < 0) ? y * -1 : y ) % 100);
1603 lcd_puts(0, i+1, buf);
1605 break;
1607 case 3: /* remaining time estimation: */
1609 #if CONFIG_CHARGING == CHARGING_CONTROL
1610 snprintf(buf, 30, "charge_state: %d", charge_state);
1611 lcd_puts(0, 0, buf);
1613 snprintf(buf, 30, "Cycle time: %d m", powermgmt_last_cycle_startstop_min);
1614 lcd_puts(0, 1, buf);
1616 snprintf(buf, 30, "Lvl@cyc st: %d%%", powermgmt_last_cycle_level);
1617 lcd_puts(0, 2, buf);
1619 snprintf(buf, 30, "P=%2d I=%2d", pid_p, pid_i);
1620 lcd_puts(0, 3, buf);
1622 snprintf(buf, 30, "Trickle sec: %d/60", trickle_sec);
1623 lcd_puts(0, 4, buf);
1624 #endif /* CONFIG_CHARGING == CHARGING_CONTROL */
1626 snprintf(buf, 30, "Last PwrHist: %d.%02d V",
1627 power_history[0] / 100,
1628 power_history[0] % 100);
1629 lcd_puts(0, 5, buf);
1631 snprintf(buf, 30, "battery level: %d%%", battery_level());
1632 lcd_puts(0, 6, buf);
1634 snprintf(buf, 30, "Est. remain: %d m", battery_time());
1635 lcd_puts(0, 7, buf);
1636 break;
1639 lcd_update();
1641 switch(get_action(CONTEXT_SETTINGS,HZ/2))
1643 case ACTION_SETTINGS_DEC:
1644 if (view)
1645 view--;
1646 break;
1648 case ACTION_SETTINGS_INC:
1649 if (view < 3)
1650 view++;
1651 break;
1653 case ACTION_STD_CANCEL:
1654 action_signalscreenchange();
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)
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
1743 dbg_listmessage_addline("Not Found!");
1745 snprintf(info->title, 16, "[" CARDTYPE " %d]", (int)info->cbdata);
1746 gui_synclist_set_nb_items(info->lists, dbg_listmessage_getlines());
1747 gui_synclist_select_item(info->lists, 0);
1748 btn = ACTION_REDRAW;
1750 return btn;
1752 static bool dbg_disk_info(void)
1754 char listtitle[16];
1755 struct action_callback_info info;
1756 info.title = listtitle;
1757 info.count = 1;
1758 info.selection_size = 1;
1759 info.action_callback = cardinfo_callback;
1760 info.dbg_getname = dbg_listmessage_getname;
1761 info.cbdata = 0;
1762 dbg_list(&info);
1763 return false;
1765 #else /* !defined(HAVE_MMC) && !defined(HAVE_HOTSWAP) */
1766 static int disk_callback(int btn, struct action_callback_info *info)
1768 int i;
1769 char buf[128];
1770 unsigned short* identify_info = ata_get_identify();
1771 bool timing_info_present = false;
1772 (void)btn;
1774 dbg_listmessage_setlines(0);
1776 for (i=0; i < 20; i++)
1777 ((unsigned short*)buf)[i]=htobe16(identify_info[i+27]);
1778 buf[40]=0;
1779 /* kill trailing space */
1780 for (i=39; i && buf[i]==' '; i--)
1781 buf[i] = 0;
1782 dbg_listmessage_addline(
1783 "Model: %s", buf);
1784 for (i=0; i < 4; i++)
1785 ((unsigned short*)buf)[i]=htobe16(identify_info[i+23]);
1786 buf[8]=0;
1787 dbg_listmessage_addline(
1788 "Firmware: %s", buf);
1789 snprintf(buf, sizeof buf, "%ld MB",
1790 ((unsigned long)identify_info[61] << 16 |
1791 (unsigned long)identify_info[60]) / 2048 );
1792 dbg_listmessage_addline(
1793 "Size: %s", buf);
1794 unsigned long free;
1795 fat_size( IF_MV2(0,) NULL, &free );
1796 dbg_listmessage_addline(
1797 "Free: %ld MB", free / 1024);
1798 dbg_listmessage_addline(
1799 "Spinup time: %d ms", ata_spinup_time * (1000/HZ));
1800 i = identify_info[83] & (1<<3);
1801 dbg_listmessage_addline(
1802 "Power mgmt: %s", i ? "enabled" : "unsupported");
1803 i = identify_info[83] & (1<<9);
1804 dbg_listmessage_addline(
1805 "Noise mgmt: %s", i ? "enabled" : "unsupported");
1806 i = identify_info[82] & (1<<6);
1807 dbg_listmessage_addline(
1808 "Read-ahead: %s", i ? "enabled" : "unsupported");
1809 timing_info_present = identify_info[53] & (1<<1);
1810 if(timing_info_present) {
1811 char pio3[2], pio4[2];pio3[1] = 0;
1812 pio4[1] = 0;
1813 pio3[0] = (identify_info[64] & (1<<0)) ? '3' : 0;
1814 pio4[0] = (identify_info[64] & (1<<1)) ? '4' : 0;
1815 dbg_listmessage_addline(
1816 "PIO modes: 0 1 2 %s %s", pio3, pio4);
1818 else {
1819 dbg_listmessage_addline(
1820 "No PIO mode info");
1822 timing_info_present = identify_info[53] & (1<<1);
1823 if(timing_info_present) {
1824 dbg_listmessage_addline(
1825 "Cycle times %dns/%dns",
1826 identify_info[67],
1827 identify_info[68] );
1828 } else {
1829 dbg_listmessage_addline(
1830 "No timing info");
1832 timing_info_present = identify_info[53] & (1<<1);
1833 if(timing_info_present) {
1834 i = identify_info[49] & (1<<11);
1835 dbg_listmessage_addline(
1836 "IORDY support: %s", i ? "yes" : "no");
1837 i = identify_info[49] & (1<<10);
1838 dbg_listmessage_addline(
1839 "IORDY disable: %s", i ? "yes" : "no");
1840 } else {
1841 dbg_listmessage_addline(
1842 "No timing info");
1844 dbg_listmessage_addline(
1845 "Cluster size: %d bytes", fat_get_cluster_size(IF_MV(0)));
1846 gui_synclist_set_nb_items(info->lists, dbg_listmessage_getlines());
1847 return btn;
1849 static bool dbg_disk_info(void)
1851 struct action_callback_info info;
1852 info.title = "Disk Info";
1853 info.count = 1;
1854 info.selection_size = 1;
1855 info.action_callback = disk_callback;
1856 info.dbg_getname = dbg_listmessage_getname;
1857 dbg_list(&info);
1858 return false;
1860 #endif /* !defined(HAVE_MMC) && !defined(HAVE_HOTSWAP) */
1861 #endif /* !SIMULATOR */
1863 #ifdef HAVE_DIRCACHE
1864 static int dircache_callback(int btn, struct action_callback_info *info)
1866 (void)btn; (void)info;
1867 dbg_listmessage_setlines(0);
1868 dbg_listmessage_addline("Cache initialized: %s",
1869 dircache_is_enabled() ? "Yes" : "No");
1870 dbg_listmessage_addline("Cache size: %d B",
1871 dircache_get_cache_size());
1872 dbg_listmessage_addline("Last size: %d B",
1873 global_status.dircache_size);
1874 dbg_listmessage_addline("Limit: %d B",
1875 DIRCACHE_LIMIT);
1876 dbg_listmessage_addline("Reserve: %d/%d B",
1877 dircache_get_reserve_used(), DIRCACHE_RESERVE);
1878 dbg_listmessage_addline("Scanning took: %d s",
1879 dircache_get_build_ticks() / HZ);
1880 dbg_listmessage_addline("Entry count: %d",
1881 dircache_get_entry_count());
1882 return btn;
1885 static bool dbg_dircache_info(void)
1887 struct action_callback_info info;
1888 info.title = "Dircache Info";
1889 info.count = 7;
1890 info.selection_size = 1;
1891 info.action_callback = dircache_callback;
1892 info.dbg_getname = dbg_listmessage_getname;
1893 dbg_list(&info);
1894 return false;
1897 #endif /* HAVE_DIRCACHE */
1899 #ifdef HAVE_TAGCACHE
1900 static int database_callback(int btn, struct action_callback_info *info)
1902 (void)btn; (void)info;
1903 struct tagcache_stat *stat = tagcache_get_stat();
1904 dbg_listmessage_setlines(0);
1905 dbg_listmessage_addline("Initialized: %s",
1906 stat->initialized ? "Yes" : "No");
1907 dbg_listmessage_addline("DB Ready: %s",
1908 stat->ready ? "Yes" : "No");
1909 dbg_listmessage_addline("RAM Cache: %s",
1910 stat->ramcache ? "Yes" : "No");
1911 dbg_listmessage_addline("RAM: %d/%d B",
1912 stat->ramcache_used, stat->ramcache_allocated);
1913 dbg_listmessage_addline("Progress: %d%% (%d entries)",
1914 stat->progress, stat->processed_entries);
1915 dbg_listmessage_addline("Commit step: %d",
1916 stat->commit_step);
1917 dbg_listmessage_addline("Commit delayed: %s",
1918 stat->commit_delayed ? "Yes" : "No");
1919 return btn;
1921 static bool dbg_tagcache_info(void)
1923 struct action_callback_info info;
1924 info.title = "Database Info";
1925 info.count = 7;
1926 info.selection_size = 1;
1927 info.action_callback = database_callback;
1928 info.dbg_getname = dbg_listmessage_getname;
1929 dbg_list(&info);
1930 return false;
1932 #endif
1934 #if CONFIG_CPU == SH7034
1935 static bool dbg_save_roms(void)
1937 int fd;
1938 int oldmode = system_memory_guard(MEMGUARD_NONE);
1940 fd = creat("/internal_rom_0000-FFFF.bin");
1941 if(fd >= 0)
1943 write(fd, (void *)0, 0x10000);
1944 close(fd);
1947 fd = creat("/internal_rom_2000000-203FFFF.bin");
1948 if(fd >= 0)
1950 write(fd, (void *)0x2000000, 0x40000);
1951 close(fd);
1954 system_memory_guard(oldmode);
1955 return false;
1957 #elif defined CPU_COLDFIRE
1958 static bool dbg_save_roms(void)
1960 int fd;
1961 int oldmode = system_memory_guard(MEMGUARD_NONE);
1963 #if defined(IRIVER_H100_SERIES)
1964 fd = creat("/internal_rom_000000-1FFFFF.bin");
1965 #elif defined(IRIVER_H300_SERIES)
1966 fd = creat("/internal_rom_000000-3FFFFF.bin");
1967 #elif defined(IAUDIO_X5) || defined(IAUDIO_M5)
1968 fd = creat("/internal_rom_000000-3FFFFF.bin");
1969 #endif
1970 if(fd >= 0)
1972 write(fd, (void *)0, FLASH_SIZE);
1973 close(fd);
1975 system_memory_guard(oldmode);
1977 #ifdef HAVE_EEPROM
1978 fd = creat("/internal_eeprom.bin");
1979 if (fd >= 0)
1981 int old_irq_level;
1982 char buf[EEPROM_SIZE];
1983 int err;
1985 old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL);
1987 err = eeprom_24cxx_read(0, buf, sizeof buf);
1988 if (err)
1989 gui_syncsplash(HZ*3, "Eeprom read failure (%d)",err);
1990 else
1992 write(fd, buf, sizeof buf);
1995 set_irq_level(old_irq_level);
1997 close(fd);
1999 #endif
2001 return false;
2003 #elif defined(CPU_PP) && !defined(SANSA_E200)
2004 static bool dbg_save_roms(void)
2006 int fd;
2008 fd = creat("/internal_rom_000000-0FFFFF.bin");
2009 if(fd >= 0)
2011 write(fd, (void *)0x20000000, FLASH_SIZE);
2012 close(fd);
2015 return false;
2017 #endif /* CPU */
2019 #ifndef SIMULATOR
2020 #if CONFIG_TUNER
2021 static int radio_callback(int btn, struct action_callback_info *info)
2023 dbg_listmessage_setlines(1);
2025 #if (CONFIG_TUNER & LV24020LP)
2026 dbg_listmessage_addline("CTRL_STAT: %02X", lv24020lp_get(LV24020LP_CTRL_STAT) );
2027 dbg_listmessage_addline("RADIO_STAT: %02X", lv24020lp_get(LV24020LP_REG_STAT) );
2028 dbg_listmessage_addline("MSS_FM: %d kHz", lv24020lp_get(LV24020LP_MSS_FM) );
2029 dbg_listmessage_addline("MSS_IF: %d Hz", lv24020lp_get(LV24020LP_MSS_IF) );
2030 dbg_listmessage_addline("MSS_SD: %d Hz", lv24020lp_get(LV24020LP_MSS_SD) );
2031 dbg_listmessage_addline("if_set: %d Hz", lv24020lp_get(LV24020LP_IF_SET) );
2032 dbg_listmessage_addline("sd_set: %d Hz", lv24020lp_get(LV24020LP_SD_SET) );
2033 #endif
2034 #if (CONFIG_TUNER & S1A0903X01)
2035 dbg_listmessage_addline("Samsung regs: %08X", s1a0903x01_get(RADIO_ALL));
2036 /* This one doesn't return dynamic data atm */
2037 #endif
2038 #if (CONFIG_TUNER & TEA5767)
2039 struct tea5767_dbg_info nfo;
2040 tea5767_dbg_info(&nfo);
2041 dbg_listmessage_addline("Philips regs:");
2042 dbg_listmessage_addline(
2043 " Read: %02X %02X %02X %02X %02X",
2044 (unsigned)nfo.read_regs[0], (unsigned)nfo.read_regs[1],
2045 (unsigned)nfo.read_regs[2], (unsigned)nfo.read_regs[3],
2046 (unsigned)nfo.read_regs[4]);
2047 dbg_listmessage_addline(
2048 " Write: %02X %02X %02X %02X %02X",
2049 (unsigned)nfo.write_regs[0], (unsigned)nfo.write_regs[1],
2050 (unsigned)nfo.write_regs[2], (unsigned)nfo.write_regs[3],
2051 (unsigned)nfo.write_regs[4]);
2052 #endif
2054 if (btn != ACTION_STD_CANCEL)
2055 btn = ACTION_REDRAW;
2057 gui_synclist_set_nb_items(info->lists, dbg_listmessage_getlines());
2058 return btn;
2060 static bool dbg_fm_radio(void)
2062 struct action_callback_info info;
2064 info.title = "FM Radio";
2065 info.count = 1;
2066 info.selection_size = 1;
2067 info.cbdata = radio_hardware_present();
2068 info.action_callback = info.cbdata ? radio_callback : NULL;
2069 info.dbg_getname = dbg_listmessage_getname;
2071 dbg_listmessage_setlines(0);
2072 dbg_listmessage_addline("HW detected: %s", info.cbdata ? "yes" : "no");
2074 dbg_list(&info);
2075 return false;
2077 #endif /* CONFIG_TUNER */
2078 #endif /* !SIMULATOR */
2080 #ifdef HAVE_LCD_BITMAP
2081 extern bool do_screendump_instead_of_usb;
2083 static bool dbg_screendump(void)
2085 do_screendump_instead_of_usb = !do_screendump_instead_of_usb;
2086 gui_syncsplash(HZ, "Screendump %s",
2087 do_screendump_instead_of_usb?"enabled":"disabled");
2088 return false;
2090 #endif /* HAVE_LCD_BITMAP */
2092 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
2093 static bool dbg_set_memory_guard(void)
2095 static const struct opt_items names[MAXMEMGUARD] = {
2096 { "None", -1 },
2097 { "Flash ROM writes", -1 },
2098 { "Zero area (all)", -1 }
2100 int mode = system_memory_guard(MEMGUARD_KEEP);
2102 set_option( "Catch mem accesses", &mode, INT, names, MAXMEMGUARD, NULL);
2103 system_memory_guard(mode);
2105 return false;
2107 #endif /* CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) */
2109 #if defined(TOSHIBA_GIGABEAT_F) && !defined(SIMULATOR)
2111 extern volatile bool lcd_poweroff;
2113 static bool dbg_lcd_power_off(void)
2115 lcd_setmargins(0, 0);
2117 while(1)
2119 int button;
2121 lcd_clear_display();
2122 lcd_puts(0, 0, "LCD Power Off");
2123 if(lcd_poweroff)
2124 lcd_puts(1, 1, "Yes");
2125 else
2126 lcd_puts(1, 1, "No");
2128 lcd_update();
2130 button = get_action(CONTEXT_STD,HZ/5);
2131 switch(button)
2133 case ACTION_STD_PREV:
2134 case ACTION_STD_NEXT:
2135 lcd_poweroff = !lcd_poweroff;
2136 break;
2137 case ACTION_STD_OK:
2138 case ACTION_STD_CANCEL:
2139 action_signalscreenchange();
2140 return false;
2141 default:
2142 sleep(HZ/10);
2143 break;
2146 return false;
2148 #endif
2150 #if defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS)
2151 static bool dbg_write_eeprom(void)
2153 int fd;
2154 int rc;
2155 int old_irq_level;
2156 char buf[EEPROM_SIZE];
2157 int err;
2159 fd = open("/internal_eeprom.bin", O_RDONLY);
2161 if (fd >= 0)
2163 rc = read(fd, buf, EEPROM_SIZE);
2165 if(rc == EEPROM_SIZE)
2167 old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL);
2169 err = eeprom_24cxx_write(0, buf, sizeof buf);
2170 if (err)
2171 gui_syncsplash(HZ*3, "Eeprom write failure (%d)",err);
2172 else
2173 gui_syncsplash(HZ*3, "Eeprom written successfully");
2175 set_irq_level(old_irq_level);
2177 else
2179 gui_syncsplash(HZ*3, "File read error (%d)",rc);
2181 close(fd);
2183 else
2185 gui_syncsplash(HZ*3, "Failed to open 'internal_eeprom.bin'");
2188 return false;
2190 #endif /* defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS) */
2191 #ifdef CPU_BOOST_LOGGING
2192 static bool cpu_boost_log(void)
2194 int i = 0,j=0;
2195 int count = cpu_boost_log_getcount();
2196 int lines = LCD_HEIGHT/SYSFONT_HEIGHT;
2197 char *str;
2198 bool done;
2199 lcd_setmargins(0, 0);
2200 lcd_setfont(FONT_SYSFIXED);
2201 str = cpu_boost_log_getlog_first();
2202 while (i < count)
2204 lcd_clear_display();
2205 for(j=0; j<lines; j++,i++)
2207 if (!str)
2208 str = cpu_boost_log_getlog_next();
2209 if (str)
2211 lcd_puts(0, j,str);
2213 str = NULL;
2215 lcd_update();
2216 done = false;
2217 action_signalscreenchange();
2218 while (!done)
2220 switch(get_action(CONTEXT_STD,TIMEOUT_BLOCK))
2222 case ACTION_STD_OK:
2223 case ACTION_STD_PREV:
2224 case ACTION_STD_NEXT:
2225 done = true;
2226 break;
2227 case ACTION_STD_CANCEL:
2228 i = count;
2229 done = true;
2230 break;
2234 get_action(CONTEXT_STD,TIMEOUT_BLOCK);
2235 lcd_setfont(FONT_UI);
2236 action_signalscreenchange();
2237 return false;
2239 #endif
2243 /****** The menu *********/
2244 struct the_menu_item {
2245 unsigned char *desc; /* string or ID */
2246 bool (*function) (void); /* return true if USB was connected */
2248 static const struct the_menu_item menuitems[] = {
2249 #if defined(TOSHIBA_GIGABEAT_F) && !defined(SIMULATOR)
2250 { "LCD Power Off", dbg_lcd_power_off },
2251 #endif
2252 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || \
2253 (defined(CPU_PP) && !defined(SANSA_E200))
2254 { "Dump ROM contents", dbg_save_roms },
2255 #endif
2256 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || defined(CPU_PP) || CONFIG_CPU == S3C2440
2257 { "View I/O ports", dbg_ports },
2258 #endif
2259 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
2260 { "CPU frequency", dbg_cpufreq },
2261 #endif
2262 #if defined(IRIVER_H100_SERIES) && !defined(SIMULATOR)
2263 { "S/PDIF analyzer", dbg_spdif },
2264 #endif
2265 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
2266 { "Catch mem accesses", dbg_set_memory_guard },
2267 #endif
2268 #ifndef SIMULATOR
2269 { "View OS stacks", dbg_os },
2270 #endif
2271 #ifdef HAVE_LCD_BITMAP
2272 #ifndef SIMULATOR
2273 { "View battery", view_battery },
2274 #endif
2275 { "Screendump", dbg_screendump },
2276 #endif
2277 #ifndef SIMULATOR
2278 { "View HW info", dbg_hw_info },
2279 #endif
2280 #ifndef SIMULATOR
2281 { "View partitions", dbg_partitions },
2282 #endif
2283 #ifndef SIMULATOR
2284 { "View disk info", dbg_disk_info },
2285 #endif
2286 #ifdef HAVE_DIRCACHE
2287 { "View dircache info", dbg_dircache_info },
2288 #endif
2289 #ifdef HAVE_TAGCACHE
2290 { "View database info", dbg_tagcache_info },
2291 #endif
2292 #ifdef HAVE_LCD_BITMAP
2293 #if CONFIG_CODEC == SWCODEC || !defined(SIMULATOR)
2294 { "View audio thread", dbg_audio_thread },
2295 #endif
2296 #ifdef PM_DEBUG
2297 { "pm histogram", peak_meter_histogram},
2298 #endif /* PM_DEBUG */
2299 #endif /* HAVE_LCD_BITMAP */
2300 #ifndef SIMULATOR
2301 #if CONFIG_TUNER
2302 { "FM Radio", dbg_fm_radio },
2303 #endif
2304 #endif
2305 #if defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS)
2306 { "Write back EEPROM", dbg_write_eeprom },
2307 #endif
2308 #ifdef ROCKBOX_HAS_LOGF
2309 {"logf", logfdisplay },
2310 {"logfdump", logfdump },
2311 #endif
2312 #ifdef CPU_BOOST_LOGGING
2313 {"cpu_boost log",cpu_boost_log},
2314 #endif
2316 static int menu_action_callback(int btn, struct action_callback_info *info)
2318 if (btn == ACTION_STD_OK)
2320 menuitems[gui_synclist_get_sel_pos(info->lists)].function();
2321 gui_synclist_draw(info->lists);
2323 return btn;
2325 static char* dbg_menu_getname(int item, void * data, char *buffer)
2327 (void)data; (void)buffer;
2328 return menuitems[item].desc;
2330 bool debug_menu(void)
2332 struct action_callback_info info;
2333 info.title = "Debug Menu";
2334 info.count = ARRAYLEN(menuitems);
2335 info.selection_size = 1;
2336 info.action_callback = menu_action_callback;
2337 info.dbg_getname = dbg_menu_getname;
2338 dbg_list(&info);
2339 return false;