Add the thread state check into test_codec as used in mpegplayer which makes it shoul...
[Rockbox.git] / apps / debug_menu.c
blob0dec961f3fba0872581fa1eac5e0e61cd9548652
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 #define DBGLIST_SHOW_SELECTION 0x1
130 struct action_callback_info
132 char *title;
133 int count;
134 int selection_size;
135 int (*action_callback)(int btn, struct action_callback_info *info);
136 char* (*dbg_getname)(int item, void * data, char *buffer);
137 intptr_t cbdata; /* extra callback data (pointer, int, whatever) */
138 struct gui_synclist *lists; /* passed back to the callback */
141 static char* dbg_menu_getname(int item, void * data, char *buffer);
142 static char* threads_getname(int selected_item, void * data, char *buffer);
143 static bool dbg_list(struct action_callback_info *info)
145 struct gui_synclist lists;
146 int action;
148 info->lists = &lists;
150 gui_synclist_init(&lists, info->dbg_getname, NULL, false,
151 info->selection_size);
152 gui_synclist_set_title(&lists, info->title, NOICON);
153 gui_synclist_set_icon_callback(&lists, NULL);
154 gui_synclist_set_nb_items(&lists, info->count*info->selection_size);
155 gui_synclist_hide_selection_marker(&lists, true);
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 return false;
179 /*---------------------------------------------------*/
180 /* SPECIAL DEBUG STUFF */
181 /*---------------------------------------------------*/
182 extern struct thread_entry threads[MAXTHREADS];
184 static char thread_status_char(unsigned status)
186 static const char thread_status_chars[THREAD_NUM_STATES+1] =
188 [0 ... THREAD_NUM_STATES] = '?',
189 [STATE_RUNNING] = 'R',
190 [STATE_BLOCKED] = 'B',
191 [STATE_SLEEPING] = 'S',
192 [STATE_BLOCKED_W_TMO] = 'T',
193 [STATE_FROZEN] = 'F',
194 [STATE_KILLED] = 'K',
197 #if NUM_CORES > 1
198 if (status == STATE_BUSY) /* Not a state index */
199 return '.';
200 #endif
202 if (status > THREAD_NUM_STATES)
203 status = THREAD_NUM_STATES;
205 return thread_status_chars[status];
208 static char* threads_getname(int selected_item, void * data, char *buffer)
210 (void)data;
211 char name[32];
212 struct thread_entry *thread = NULL;
213 unsigned status;
214 int usage;
216 #if NUM_CORES > 1
217 if (selected_item < (int)NUM_CORES)
219 usage = idle_stack_usage(selected_item);
220 snprintf(buffer, MAX_PATH, "Idle (%d): %2d%%", selected_item, usage);
221 return buffer;
224 selected_item -= NUM_CORES;
225 #endif
227 thread = &threads[selected_item];
228 status = thread_get_status(thread);
230 if (status == STATE_KILLED)
232 snprintf(buffer, MAX_PATH, "%2d: ---", selected_item);
233 return buffer;
236 thread_get_name(name, 32, thread);
237 usage = thread_stack_usage(thread);
239 snprintf(buffer, MAX_PATH,
240 "%2d: " IF_COP("(%d) ") "%c%c " IF_PRIO("%d ") "%2d%% %s",
241 selected_item,
242 IF_COP(thread->core,)
243 (status == STATE_RUNNING) ? '*' : ' ',
244 thread_status_char(status),
245 IF_PRIO(thread->priority,)
246 usage, name);
248 return buffer;
250 static int dbg_threads_action_callback(int action, struct action_callback_info *info)
252 #ifdef ROCKBOX_HAS_LOGF
253 if (action == ACTION_STD_OK)
255 int selpos = gui_synclist_get_sel_pos(info->lists);
256 #if NUM_CORES > 1
257 if (selpos >= NUM_CORES)
258 remove_thread(&threads[selpos - NUM_CORES]);
259 #else
260 remove_thread(&threads[selpos]);
261 #endif
263 gui_synclist_hide_selection_marker(info->lists, false);
264 #endif /* ROCKBOX_HAS_LOGF */
265 gui_synclist_draw(info->lists);
266 return action;
268 /* Test code!!! */
269 static bool dbg_os(void)
271 struct action_callback_info info;
272 info.title = IF_COP("Core and ") "Stack usage:";
273 #if NUM_CORES == 1
274 info.count = MAXTHREADS;
275 #else
276 info.count = MAXTHREADS+NUM_CORES;
277 #endif
278 info.selection_size = 1;
279 info.action_callback = dbg_threads_action_callback;
280 info.dbg_getname = threads_getname;
281 return dbg_list(&info);
284 #ifdef HAVE_LCD_BITMAP
285 #if CONFIG_CODEC != SWCODEC
286 #ifndef SIMULATOR
287 static bool dbg_audio_thread(void)
289 char buf[32];
290 struct audio_debug d;
292 lcd_setmargins(0, 0);
293 lcd_setfont(FONT_SYSFIXED);
295 while(1)
297 if (action_userabort(HZ/5))
298 return false;
300 audio_get_debugdata(&d);
302 lcd_clear_display();
304 snprintf(buf, sizeof(buf), "read: %x", d.audiobuf_read);
305 lcd_puts(0, 0, buf);
306 snprintf(buf, sizeof(buf), "write: %x", d.audiobuf_write);
307 lcd_puts(0, 1, buf);
308 snprintf(buf, sizeof(buf), "swap: %x", d.audiobuf_swapwrite);
309 lcd_puts(0, 2, buf);
310 snprintf(buf, sizeof(buf), "playing: %d", d.playing);
311 lcd_puts(0, 3, buf);
312 snprintf(buf, sizeof(buf), "playable: %x", d.playable_space);
313 lcd_puts(0, 4, buf);
314 snprintf(buf, sizeof(buf), "unswapped: %x", d.unswapped_space);
315 lcd_puts(0, 5, buf);
317 /* Playable space left */
318 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, 6*8, 112, 4, d.audiobuflen, 0,
319 d.playable_space, HORIZONTAL);
321 /* Show the watermark limit */
322 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, 6*8+4, 112, 4, d.audiobuflen, 0,
323 d.low_watermark_level, HORIZONTAL);
325 snprintf(buf, sizeof(buf), "wm: %x - %x",
326 d.low_watermark_level, d.lowest_watermark_level);
327 lcd_puts(0, 7, buf);
329 lcd_update();
331 return false;
333 #endif /* !SIMULATOR */
334 #else /* CONFIG_CODEC == SWCODEC */
335 extern size_t filebuflen;
336 /* This is a size_t, but call it a long so it puts a - when it's bad. */
338 static unsigned int ticks, boost_ticks;
340 static void dbg_audio_task(void)
342 #ifndef SIMULATOR
343 if(FREQ > CPUFREQ_NORMAL)
344 boost_ticks++;
345 #endif
347 ticks++;
350 static bool dbg_audio_thread(void)
352 char buf[32];
353 int button;
354 int line;
355 bool done = false;
356 size_t bufused;
357 size_t bufsize = pcmbuf_get_bufsize();
358 int pcmbufdescs = pcmbuf_descs();
360 ticks = boost_ticks = 0;
362 tick_add_task(dbg_audio_task);
364 lcd_setmargins(0, 0);
365 lcd_setfont(FONT_SYSFIXED);
366 while(!done)
368 button = get_action(CONTEXT_STD,HZ/5);
369 switch(button)
371 case ACTION_STD_NEXT:
372 audio_next();
373 break;
374 case ACTION_STD_PREV:
375 audio_prev();
376 break;
377 case ACTION_STD_CANCEL:
378 done = true;
379 break;
381 line = 0;
382 lcd_clear_display();
384 bufused = bufsize - pcmbuf_free();
386 snprintf(buf, sizeof(buf), "pcm: %7ld/%7ld", (long) bufused, (long) bufsize);
387 lcd_puts(0, line++, buf);
389 /* Playable space left */
390 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6, bufsize, 0, bufused, HORIZONTAL);
391 line++;
393 snprintf(buf, sizeof(buf), "codec: %8ld/%8ld", audio_filebufused(), (long) filebuflen);
394 lcd_puts(0, line++, buf);
396 /* Playable space left */
397 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6, filebuflen, 0,
398 audio_filebufused(), HORIZONTAL);
399 line++;
401 snprintf(buf, sizeof(buf), "track count: %2d", audio_track_count());
402 lcd_puts(0, line++, buf);
404 #ifndef SIMULATOR
405 snprintf(buf, sizeof(buf), "cpu freq: %3dMHz",
406 (int)((FREQ + 500000) / 1000000));
407 lcd_puts(0, line++, buf);
408 #endif
410 if (ticks > 0)
412 snprintf(buf, sizeof(buf), "boost ratio: %3d%%",
413 boost_ticks * 100 / ticks);
414 lcd_puts(0, line++, buf);
417 snprintf(buf, sizeof(buf), "pcmbufdesc: %2d/%2d",
418 pcmbuf_used_descs(), pcmbufdescs);
419 lcd_puts(0, line++, buf);
421 lcd_update();
424 tick_remove_task(dbg_audio_task);
426 return false;
428 #endif /* CONFIG_CODEC */
429 #endif /* HAVE_LCD_BITMAP */
432 #if (CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE))
433 /* Tool function to read the flash manufacturer and type, if available.
434 Only chips which could be reprogrammed in system will return values.
435 (The mode switch addresses vary between flash manufacturers, hence addr1/2) */
436 /* In IRAM to avoid problems when running directly from Flash */
437 static bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
438 unsigned addr1, unsigned addr2)
439 ICODE_ATTR __attribute__((noinline));
440 static bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
441 unsigned addr1, unsigned addr2)
444 unsigned not_manu, not_id; /* read values before switching to ID mode */
445 unsigned manu, id; /* read values when in ID mode */
447 #if CONFIG_CPU == SH7034
448 volatile unsigned char* flash = (unsigned char*)0x2000000; /* flash mapping */
449 #elif defined(CPU_COLDFIRE)
450 volatile unsigned short* flash = (unsigned short*)0; /* flash mapping */
451 #endif
452 int old_level; /* saved interrupt level */
454 not_manu = flash[0]; /* read the normal content */
455 not_id = flash[1]; /* should be 'A' (0x41) and 'R' (0x52) from the "ARCH" marker */
457 /* disable interrupts, prevent any stray flash access */
458 old_level = set_irq_level(HIGHEST_IRQ_LEVEL);
460 flash[addr1] = 0xAA; /* enter command mode */
461 flash[addr2] = 0x55;
462 flash[addr1] = 0x90; /* ID command */
463 /* Atmel wants 20ms pause here */
464 /* sleep(HZ/50); no sleeping possible while interrupts are disabled */
466 manu = flash[0]; /* read the IDs */
467 id = flash[1];
469 flash[0] = 0xF0; /* reset flash (back to normal read mode) */
470 /* Atmel wants 20ms pause here */
471 /* sleep(HZ/50); no sleeping possible while interrupts are disabled */
473 set_irq_level(old_level); /* enable interrupts again */
475 /* I assume success if the obtained values are different from
476 the normal flash content. This is not perfectly bulletproof, they
477 could theoretically be the same by chance, causing us to fail. */
478 if (not_manu != manu || not_id != id) /* a value has changed */
480 *p_manufacturer = manu; /* return the results */
481 *p_device = id;
482 return true; /* success */
484 return false; /* fail */
486 #endif /* (CONFIG_CPU == SH7034 || CPU_COLDFIRE) */
488 #ifndef SIMULATOR
489 #ifdef CPU_PP
490 static int perfcheck(void)
492 int result;
494 asm (
495 "mrs r2, CPSR \n"
496 "orr r0, r2, #0xc0 \n" /* disable IRQ and FIQ */
497 "msr CPSR_c, r0 \n"
498 "mov %[res], #0 \n"
499 "ldr r0, [%[timr]] \n"
500 "add r0, r0, %[tmo] \n"
501 "1: \n"
502 "add %[res], %[res], #1 \n"
503 "ldr r1, [%[timr]] \n"
504 "cmp r1, r0 \n"
505 "bmi 1b \n"
506 "msr CPSR_c, r2 \n" /* reset IRQ and FIQ state */
508 [res]"=&r"(result)
510 [timr]"r"(&USEC_TIMER),
511 [tmo]"r"(
512 #if CONFIG_CPU == PP5002
513 16000
514 #else /* PP5020/5022/5024 */
515 10226
516 #endif
519 "r0", "r1", "r2"
521 return result;
523 #endif
525 #ifdef HAVE_LCD_BITMAP
526 static bool dbg_hw_info(void)
528 #if CONFIG_CPU == SH7034
529 char buf[32];
530 int bitmask = HW_MASK;
531 int rom_version = ROM_VERSION;
532 unsigned manu, id; /* flash IDs */
533 bool got_id; /* flag if we managed to get the flash IDs */
534 unsigned rom_crc = 0xffffffff; /* CRC32 of the boot ROM */
535 bool has_bootrom; /* flag for boot ROM present */
536 int oldmode; /* saved memory guard mode */
538 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
540 /* get flash ROM type */
541 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
542 if (!got_id)
543 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
545 /* check if the boot ROM area is a flash mirror */
546 has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0);
547 if (has_bootrom) /* if ROM and Flash different */
549 /* calculate CRC16 checksum of boot ROM */
550 rom_crc = crc_32((unsigned char*)0x0000, 64*1024, 0xffffffff);
553 system_memory_guard(oldmode); /* re-enable memory guard */
555 lcd_setmargins(0, 0);
556 lcd_setfont(FONT_SYSFIXED);
557 lcd_clear_display();
559 lcd_puts(0, 0, "[Hardware info]");
561 snprintf(buf, 32, "ROM: %d.%02d", rom_version/100, rom_version%100);
562 lcd_puts(0, 1, buf);
564 snprintf(buf, 32, "Mask: 0x%04x", bitmask);
565 lcd_puts(0, 2, buf);
567 if (got_id)
568 snprintf(buf, 32, "Flash: M=%02x D=%02x", manu, id);
569 else
570 snprintf(buf, 32, "Flash: M=?? D=??"); /* unknown, sorry */
571 lcd_puts(0, 3, buf);
573 if (has_bootrom)
575 if (rom_crc == 0x56DBA4EE) /* known Version 1 */
576 snprintf(buf, 32, "Boot ROM: V1");
577 else
578 snprintf(buf, 32, "ROMcrc: 0x%08x", rom_crc);
580 else
582 snprintf(buf, 32, "Boot ROM: none");
584 lcd_puts(0, 4, buf);
586 lcd_update();
588 while (!(action_userabort(TIMEOUT_BLOCK)));
590 #elif CONFIG_CPU == MCF5249 || CONFIG_CPU == MCF5250
591 char buf[32];
592 unsigned manu, id; /* flash IDs */
593 int got_id; /* flag if we managed to get the flash IDs */
594 int oldmode; /* saved memory guard mode */
595 int line = 0;
597 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
599 /* get flash ROM type */
600 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
601 if (!got_id)
602 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
604 system_memory_guard(oldmode); /* re-enable memory guard */
606 lcd_setmargins(0, 0);
607 lcd_setfont(FONT_SYSFIXED);
608 lcd_clear_display();
610 lcd_puts(0, line++, "[Hardware info]");
612 if (got_id)
613 snprintf(buf, 32, "Flash: M=%04x D=%04x", manu, id);
614 else
615 snprintf(buf, 32, "Flash: M=???? D=????"); /* unknown, sorry */
616 lcd_puts(0, line++, buf);
618 #ifdef IAUDIO_X5
620 struct ds2411_id id;
622 lcd_puts(0, ++line, "Serial Number:");
624 got_id = ds2411_read_id(&id);
626 if (got_id == DS2411_OK)
628 snprintf(buf, 32, " FC=%02x", (unsigned)id.family_code);
629 lcd_puts(0, ++line, buf);
630 snprintf(buf, 32, " ID=%02X %02X %02X %02X %02X %02X",
631 (unsigned)id.uid[0], (unsigned)id.uid[1], (unsigned)id.uid[2],
632 (unsigned)id.uid[3], (unsigned)id.uid[4], (unsigned)id.uid[5]);
633 lcd_puts(0, ++line, buf);
634 snprintf(buf, 32, " CRC=%02X", (unsigned)id.crc);
636 else
638 snprintf(buf, 32, "READ ERR=%d", got_id);
641 lcd_puts(0, ++line, buf);
643 #endif
645 lcd_update();
647 while (!(action_userabort(TIMEOUT_BLOCK)));
649 #elif defined(CPU_PP502x)
650 int line = 0;
651 char buf[32];
652 char pp_version[] = { (PP_VER2 >> 24) & 0xff, (PP_VER2 >> 16) & 0xff,
653 (PP_VER2 >> 8) & 0xff, (PP_VER2) & 0xff,
654 (PP_VER1 >> 24) & 0xff, (PP_VER1 >> 16) & 0xff,
655 (PP_VER1 >> 8) & 0xff, (PP_VER1) & 0xff, '\0' };
657 lcd_setmargins(0, 0);
658 lcd_setfont(FONT_SYSFIXED);
659 lcd_clear_display();
661 lcd_puts(0, line++, "[Hardware info]");
663 #ifdef IPOD_ARCH
664 snprintf(buf, sizeof(buf), "HW rev: 0x%08lx", IPOD_HW_REVISION);
665 lcd_puts(0, line++, buf);
666 #endif
668 #ifdef IPOD_COLOR
669 extern int lcd_type; /* Defined in lcd-colornano.c */
671 snprintf(buf, sizeof(buf), "LCD type: %d", lcd_type);
672 lcd_puts(0, line++, buf);
673 #endif
675 snprintf(buf, sizeof(buf), "PP version: %s", pp_version);
676 lcd_puts(0, line++, buf);
678 snprintf(buf, sizeof(buf), "Est. clock (kHz): %d", perfcheck());
679 lcd_puts(0, line++, buf);
681 lcd_update();
683 while (!(action_userabort(TIMEOUT_BLOCK)));
685 #elif CONFIG_CPU == PP5002
686 int line = 0;
687 char buf[32];
689 lcd_setmargins(0, 0);
690 lcd_setfont(FONT_SYSFIXED);
691 lcd_clear_display();
693 lcd_puts(0, line++, "[Hardware info]");
695 #ifdef IPOD_ARCH
696 snprintf(buf, sizeof(buf), "HW rev: 0x%08lx", IPOD_HW_REVISION);
697 lcd_puts(0, line++, buf);
698 #endif
700 snprintf(buf, sizeof(buf), "Est. clock (kHz): %d", perfcheck());
701 lcd_puts(0, line++, buf);
703 lcd_update();
705 while (!(action_userabort(TIMEOUT_BLOCK)));
707 #endif /* CONFIG_CPU */
708 return false;
710 #else /* !HAVE_LCD_BITMAP */
711 static bool dbg_hw_info(void)
713 char buf[32];
714 int button;
715 int currval = 0;
716 int rom_version = ROM_VERSION;
717 unsigned manu, id; /* flash IDs */
718 bool got_id; /* flag if we managed to get the flash IDs */
719 unsigned rom_crc = 0xffffffff; /* CRC32 of the boot ROM */
720 bool has_bootrom; /* flag for boot ROM present */
721 int oldmode; /* saved memory guard mode */
723 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
725 /* get flash ROM type */
726 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
727 if (!got_id)
728 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
730 /* check if the boot ROM area is a flash mirror */
731 has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0);
732 if (has_bootrom) /* if ROM and Flash different */
734 /* calculate CRC16 checksum of boot ROM */
735 rom_crc = crc_32((unsigned char*)0x0000, 64*1024, 0xffffffff);
738 system_memory_guard(oldmode); /* re-enable memory guard */
740 lcd_clear_display();
742 lcd_puts(0, 0, "[HW Info]");
743 while(1)
745 switch(currval)
747 case 0:
748 snprintf(buf, 32, "ROM: %d.%02d",
749 rom_version/100, rom_version%100);
750 break;
751 case 1:
752 if (got_id)
753 snprintf(buf, 32, "Flash:%02x,%02x", manu, id);
754 else
755 snprintf(buf, 32, "Flash:??,??"); /* unknown, sorry */
756 break;
757 case 2:
758 if (has_bootrom)
760 if (rom_crc == 0x56DBA4EE) /* known Version 1 */
761 snprintf(buf, 32, "BootROM: V1");
762 else if (rom_crc == 0x358099E8)
763 snprintf(buf, 32, "BootROM: V2");
764 /* alternative boot ROM found in one single player so far */
765 else
766 snprintf(buf, 32, "R: %08x", rom_crc);
768 else
769 snprintf(buf, 32, "BootROM: no");
772 lcd_puts(0, 1, buf);
773 lcd_update();
775 button = get_action(CONTEXT_SETTINGS,TIMEOUT_BLOCK);
777 switch(button)
779 case ACTION_STD_CANCEL:
780 return false;
782 case ACTION_SETTINGS_DEC:
783 currval--;
784 if(currval < 0)
785 currval = 2;
786 break;
788 case ACTION_SETTINGS_INC:
789 currval++;
790 if(currval > 2)
791 currval = 0;
792 break;
795 return false;
797 #endif /* !HAVE_LCD_BITMAP */
798 #endif /* !SIMULATOR */
800 #ifndef SIMULATOR
801 static char* dbg_partitions_getname(int selected_item, void * data, char *buffer)
803 (void)data;
804 int partition = selected_item/2;
805 struct partinfo* p = disk_partinfo(partition);
806 if (selected_item%2)
808 snprintf(buffer, MAX_PATH, " T:%x %ld MB", p->type, p->size / 2048);
810 else
812 snprintf(buffer, MAX_PATH, "P%d: S:%lx", partition, p->start);
814 return buffer;
817 bool dbg_partitions(void)
819 struct action_callback_info info;
820 info.title = "Partition Info";
821 info.count = 4;
822 info.selection_size = 2;
823 info.action_callback = NULL;
824 info.dbg_getname = dbg_partitions_getname;
825 dbg_list(&info);
826 return false;
828 #endif
830 #if defined(CPU_COLDFIRE) && defined(HAVE_SPDIF_OUT)
831 static bool dbg_spdif(void)
833 char buf[128];
834 int line;
835 unsigned int control;
836 int x;
837 char *s;
838 int category;
839 int generation;
840 unsigned int interruptstat;
841 bool valnogood, symbolerr, parityerr;
842 bool done = false;
843 bool spdif_src_on;
844 int spdif_source = spdif_get_output_source(&spdif_src_on);
845 spdif_set_output_source(AUDIO_SRC_SPDIF IF_SPDIF_POWER_(, true));
847 lcd_setmargins(0, 0);
848 lcd_clear_display();
849 lcd_setfont(FONT_SYSFIXED);
851 #ifdef HAVE_SPDIF_POWER
852 spdif_power_enable(true); /* We need SPDIF power for both sending & receiving */
853 #endif
855 while (!done)
857 line = 0;
859 control = EBU1RCVCCHANNEL1;
860 interruptstat = INTERRUPTSTAT;
861 INTERRUPTCLEAR = 0x03c00000;
863 valnogood = (interruptstat & 0x01000000)?true:false;
864 symbolerr = (interruptstat & 0x00800000)?true:false;
865 parityerr = (interruptstat & 0x00400000)?true:false;
867 snprintf(buf, sizeof(buf), "Val: %s Sym: %s Par: %s",
868 valnogood?"--":"OK",
869 symbolerr?"--":"OK",
870 parityerr?"--":"OK");
871 lcd_puts(0, line++, buf);
873 snprintf(buf, sizeof(buf), "Status word: %08x", (int)control);
874 lcd_puts(0, line++, buf);
876 line++;
878 x = control >> 31;
879 snprintf(buf, sizeof(buf), "PRO: %d (%s)",
880 x, x?"Professional":"Consumer");
881 lcd_puts(0, line++, buf);
883 x = (control >> 30) & 1;
884 snprintf(buf, sizeof(buf), "Audio: %d (%s)",
885 x, x?"Non-PCM":"PCM");
886 lcd_puts(0, line++, buf);
888 x = (control >> 29) & 1;
889 snprintf(buf, sizeof(buf), "Copy: %d (%s)",
890 x, x?"Permitted":"Inhibited");
891 lcd_puts(0, line++, buf);
893 x = (control >> 27) & 7;
894 switch(x)
896 case 0:
897 s = "None";
898 break;
899 case 1:
900 s = "50/15us";
901 break;
902 default:
903 s = "Reserved";
904 break;
906 snprintf(buf, sizeof(buf), "Preemphasis: %d (%s)", x, s);
907 lcd_puts(0, line++, buf);
909 x = (control >> 24) & 3;
910 snprintf(buf, sizeof(buf), "Mode: %d", x);
911 lcd_puts(0, line++, buf);
913 category = (control >> 17) & 127;
914 switch(category)
916 case 0x00:
917 s = "General";
918 break;
919 case 0x40:
920 s = "Audio CD";
921 break;
922 default:
923 s = "Unknown";
925 snprintf(buf, sizeof(buf), "Category: 0x%02x (%s)", category, s);
926 lcd_puts(0, line++, buf);
928 x = (control >> 16) & 1;
929 generation = x;
930 if(((category & 0x70) == 0x10) ||
931 ((category & 0x70) == 0x40) ||
932 ((category & 0x78) == 0x38))
934 generation = !generation;
936 snprintf(buf, sizeof(buf), "Generation: %d (%s)",
937 x, generation?"Original":"No ind.");
938 lcd_puts(0, line++, buf);
940 x = (control >> 12) & 15;
941 snprintf(buf, sizeof(buf), "Source: %d", x);
942 lcd_puts(0, line++, buf);
944 x = (control >> 8) & 15;
945 switch(x)
947 case 0:
948 s = "Unspecified";
949 break;
950 case 8:
951 s = "A (Left)";
952 break;
953 case 4:
954 s = "B (Right)";
955 break;
956 default:
957 s = "";
958 break;
960 snprintf(buf, sizeof(buf), "Channel: %d (%s)", x, s);
961 lcd_puts(0, line++, buf);
963 x = (control >> 4) & 15;
964 switch(x)
966 case 0:
967 s = "44.1kHz";
968 break;
969 case 0x4:
970 s = "48kHz";
971 break;
972 case 0xc:
973 s = "32kHz";
974 break;
976 snprintf(buf, sizeof(buf), "Frequency: %d (%s)", x, s);
977 lcd_puts(0, line++, buf);
979 x = (control >> 2) & 3;
980 snprintf(buf, sizeof(buf), "Clock accuracy: %d", x);
981 lcd_puts(0, line++, buf);
982 line++;
984 #ifndef SIMULATOR
985 snprintf(buf, sizeof(buf), "Measured freq: %ldHz",
986 spdif_measure_frequency());
987 lcd_puts(0, line++, buf);
988 #endif
990 lcd_update();
992 if (action_userabort(HZ/10))
993 break;
996 spdif_set_output_source(spdif_source IF_SPDIF_POWER_(, spdif_src_on));
998 #ifdef HAVE_SPDIF_POWER
999 spdif_power_enable(global_settings.spdif_enable);
1000 #endif
1002 return false;
1004 #endif /* CPU_COLDFIRE */
1006 #ifndef SIMULATOR
1007 #ifdef HAVE_LCD_BITMAP
1008 /* button definitions */
1009 #if (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
1010 (CONFIG_KEYPAD == IRIVER_H300_PAD)
1011 # define DEBUG_CANCEL BUTTON_OFF
1013 #elif CONFIG_KEYPAD == RECORDER_PAD
1014 # define DEBUG_CANCEL BUTTON_OFF
1016 #elif CONFIG_KEYPAD == ONDIO_PAD
1017 # define DEBUG_CANCEL BUTTON_MENU
1019 #elif (CONFIG_KEYPAD == IPOD_1G2G_PAD) || \
1020 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
1021 (CONFIG_KEYPAD == IPOD_4G_PAD)
1022 # define DEBUG_CANCEL BUTTON_MENU
1024 #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
1025 # define DEBUG_CANCEL BUTTON_PLAY
1027 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
1028 # define DEBUG_CANCEL BUTTON_REC
1030 #elif CONFIG_KEYPAD == GIGABEAT_PAD
1031 # define DEBUG_CANCEL BUTTON_A
1033 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
1034 # define DEBUG_CANCEL BUTTON_REW
1036 #elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \
1037 (CONFIG_KEYPAD == SANSA_C200_PAD)
1038 # define DEBUG_CANCEL BUTTON_LEFT
1039 #endif /* key definitios */
1041 /* Test code!!! */
1042 bool dbg_ports(void)
1044 #if CONFIG_CPU == SH7034
1045 unsigned short porta;
1046 unsigned short portb;
1047 unsigned char portc;
1048 char buf[32];
1049 int adc_battery_voltage, adc_battery_level;
1051 lcd_setfont(FONT_SYSFIXED);
1052 lcd_setmargins(0, 0);
1053 lcd_clear_display();
1055 while(1)
1057 porta = PADR;
1058 portb = PBDR;
1059 portc = PCDR;
1061 snprintf(buf, 32, "PADR: %04x", porta);
1062 lcd_puts(0, 0, buf);
1063 snprintf(buf, 32, "PBDR: %04x", portb);
1064 lcd_puts(0, 1, buf);
1066 snprintf(buf, 32, "AN0: %03x AN4: %03x", adc_read(0), adc_read(4));
1067 lcd_puts(0, 2, buf);
1068 snprintf(buf, 32, "AN1: %03x AN5: %03x", adc_read(1), adc_read(5));
1069 lcd_puts(0, 3, buf);
1070 snprintf(buf, 32, "AN2: %03x AN6: %03x", adc_read(2), adc_read(6));
1071 lcd_puts(0, 4, buf);
1072 snprintf(buf, 32, "AN3: %03x AN7: %03x", adc_read(3), adc_read(7));
1073 lcd_puts(0, 5, buf);
1075 battery_read_info(&adc_battery_voltage, &adc_battery_level);
1076 snprintf(buf, 32, "Batt: %d.%03dV %d%% ", adc_battery_voltage / 1000,
1077 adc_battery_voltage % 1000, adc_battery_level);
1078 lcd_puts(0, 6, buf);
1080 lcd_update();
1081 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1082 return false;
1084 #elif defined(CPU_COLDFIRE)
1085 unsigned int gpio_out;
1086 unsigned int gpio1_out;
1087 unsigned int gpio_read;
1088 unsigned int gpio1_read;
1089 unsigned int gpio_function;
1090 unsigned int gpio1_function;
1091 unsigned int gpio_enable;
1092 unsigned int gpio1_enable;
1093 int adc_buttons, adc_remote;
1094 int adc_battery_voltage, adc_battery_level;
1095 char buf[128];
1096 int line;
1098 lcd_setmargins(0, 0);
1099 lcd_clear_display();
1100 lcd_setfont(FONT_SYSFIXED);
1102 while(1)
1104 line = 0;
1105 gpio_read = GPIO_READ;
1106 gpio1_read = GPIO1_READ;
1107 gpio_out = GPIO_OUT;
1108 gpio1_out = GPIO1_OUT;
1109 gpio_function = GPIO_FUNCTION;
1110 gpio1_function = GPIO1_FUNCTION;
1111 gpio_enable = GPIO_ENABLE;
1112 gpio1_enable = GPIO1_ENABLE;
1114 snprintf(buf, sizeof(buf), "GPIO_READ: %08x", gpio_read);
1115 lcd_puts(0, line++, buf);
1116 snprintf(buf, sizeof(buf), "GPIO_OUT: %08x", gpio_out);
1117 lcd_puts(0, line++, buf);
1118 snprintf(buf, sizeof(buf), "GPIO_FUNCTION: %08x", gpio_function);
1119 lcd_puts(0, line++, buf);
1120 snprintf(buf, sizeof(buf), "GPIO_ENABLE: %08x", gpio_enable);
1121 lcd_puts(0, line++, buf);
1123 snprintf(buf, sizeof(buf), "GPIO1_READ: %08x", gpio1_read);
1124 lcd_puts(0, line++, buf);
1125 snprintf(buf, sizeof(buf), "GPIO1_OUT: %08x", gpio1_out);
1126 lcd_puts(0, line++, buf);
1127 snprintf(buf, sizeof(buf), "GPIO1_FUNCTION: %08x", gpio1_function);
1128 lcd_puts(0, line++, buf);
1129 snprintf(buf, sizeof(buf), "GPIO1_ENABLE: %08x", gpio1_enable);
1130 lcd_puts(0, line++, buf);
1132 adc_buttons = adc_read(ADC_BUTTONS);
1133 adc_remote = adc_read(ADC_REMOTE);
1134 battery_read_info(&adc_battery_voltage, &adc_battery_level);
1135 #if defined(IAUDIO_X5) || defined(IAUDIO_M5) || defined(IRIVER_H300_SERIES)
1136 snprintf(buf, sizeof(buf), "ADC_BUTTONS (%c): %02x",
1137 button_scan_enabled() ? '+' : '-', adc_buttons);
1138 #else
1139 snprintf(buf, sizeof(buf), "ADC_BUTTONS: %02x", adc_buttons);
1140 #endif
1141 lcd_puts(0, line++, buf);
1142 #if defined(IAUDIO_X5) || defined(IAUDIO_M5)
1143 snprintf(buf, sizeof(buf), "ADC_REMOTE (%c): %02x",
1144 remote_detect() ? '+' : '-', adc_remote);
1145 #else
1146 snprintf(buf, sizeof(buf), "ADC_REMOTE: %02x", adc_remote);
1147 #endif
1148 lcd_puts(0, line++, buf);
1149 #if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES)
1150 snprintf(buf, sizeof(buf), "ADC_REMOTEDETECT: %02x",
1151 adc_read(ADC_REMOTEDETECT));
1152 lcd_puts(0, line++, buf);
1153 #endif
1155 snprintf(buf, 32, "Batt: %d.%03dV %d%% ", adc_battery_voltage / 1000,
1156 adc_battery_voltage % 1000, adc_battery_level);
1157 lcd_puts(0, line++, buf);
1159 #if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES)
1160 snprintf(buf, sizeof(buf), "remotetype: %d", remote_type());
1161 lcd_puts(0, line++, buf);
1162 #endif
1164 lcd_update();
1165 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1166 return false;
1169 #elif defined(CPU_PP502x)
1171 unsigned int gpio_a, gpio_b, gpio_c, gpio_d;
1172 unsigned int gpio_e, gpio_f, gpio_g, gpio_h;
1173 unsigned int gpio_i, gpio_j, gpio_k, gpio_l;
1175 char buf[128];
1176 int line;
1178 lcd_setmargins(0, 0);
1179 lcd_clear_display();
1180 lcd_setfont(FONT_SYSFIXED);
1182 while(1)
1184 gpio_a = GPIOA_INPUT_VAL;
1185 gpio_b = GPIOB_INPUT_VAL;
1186 gpio_c = GPIOC_INPUT_VAL;
1188 gpio_g = GPIOG_INPUT_VAL;
1189 gpio_h = GPIOH_INPUT_VAL;
1190 gpio_i = GPIOI_INPUT_VAL;
1192 line = 0;
1193 snprintf(buf, sizeof(buf), "GPIO_A: %02x GPIO_G: %02x", gpio_a, gpio_g);
1194 lcd_puts(0, line++, buf);
1195 snprintf(buf, sizeof(buf), "GPIO_B: %02x GPIO_H: %02x", gpio_b, gpio_h);
1196 lcd_puts(0, line++, buf);
1197 snprintf(buf, sizeof(buf), "GPIO_C: %02x GPIO_I: %02x", gpio_c, gpio_i);
1198 lcd_puts(0, line++, buf);
1200 gpio_d = GPIOD_INPUT_VAL;
1201 gpio_e = GPIOE_INPUT_VAL;
1202 gpio_f = GPIOF_INPUT_VAL;
1204 gpio_j = GPIOJ_INPUT_VAL;
1205 gpio_k = GPIOK_INPUT_VAL;
1206 gpio_l = GPIOL_INPUT_VAL;
1208 snprintf(buf, sizeof(buf), "GPIO_D: %02x GPIO_J: %02x", gpio_d, gpio_j);
1209 lcd_puts(0, line++, buf);
1210 snprintf(buf, sizeof(buf), "GPIO_E: %02x GPIO_K: %02x", gpio_e, gpio_k);
1211 lcd_puts(0, line++, buf);
1212 snprintf(buf, sizeof(buf), "GPIO_F: %02x GPIO_L: %02x", gpio_f, gpio_l);
1213 lcd_puts(0, line++, buf);
1214 line++;
1216 snprintf(buf, sizeof(buf), "DEV_EN: %08lx", DEV_EN);
1217 lcd_puts(0, line++, buf);
1218 snprintf(buf, sizeof(buf), "CLOCK_SRC: %08lx", CLOCK_SOURCE);
1219 lcd_puts(0, line++, buf);
1220 snprintf(buf, sizeof(buf), "CLCD_CLK_SRC: %08lx", CLCD_CLOCK_SRC);
1221 lcd_puts(0, line++, buf);
1222 snprintf(buf, sizeof(buf), "PLL_CONTROL: %08lx", PLL_CONTROL);
1223 lcd_puts(0, line++, buf);
1224 snprintf(buf, sizeof(buf), "PLL_STATUS: %08lx", PLL_STATUS);
1225 lcd_puts(0, line++, buf);
1226 snprintf(buf, sizeof(buf), "DEV_TIMING1: %08lx", DEV_TIMING1);
1227 lcd_puts(0, line++, buf);
1229 #if defined(IRIVER_H10) || defined(IRIVER_H10_5GB)
1230 line++;
1231 snprintf(buf, sizeof(buf), "BATT: %03x UNK1: %03x", adc_read(ADC_BATTERY),
1232 adc_read(ADC_UNKNOWN_1));
1233 lcd_puts(0, line++, buf);
1234 snprintf(buf, sizeof(buf), "REM: %03x PAD: %03x", adc_read(ADC_REMOTE),
1235 adc_read(ADC_SCROLLPAD));
1236 lcd_puts(0, line++, buf);
1237 #elif defined(SANSA_E200)
1238 line++;
1239 snprintf(buf, sizeof(buf), "ADC_BVDD: %02x", adc_read(ADC_BVDD));
1240 lcd_puts(0, line++, buf);
1241 snprintf(buf, sizeof(buf), "ADC_RTCSUP: %02x", adc_read(ADC_RTCSUP));
1242 lcd_puts(0, line++, buf);
1243 snprintf(buf, sizeof(buf), "ADC_UVDD: %02x", adc_read(ADC_UVDD));
1244 lcd_puts(0, line++, buf);
1245 snprintf(buf, sizeof(buf), "ADC_CHG_IN: %02x", adc_read(ADC_CHG_IN));
1246 lcd_puts(0, line++, buf);
1247 snprintf(buf, sizeof(buf), "ADC_CVDD: %02x", adc_read(ADC_CVDD));
1248 lcd_puts(0, line++, buf);
1249 snprintf(buf, sizeof(buf), "ADC_BATTEMP: %02x", adc_read(ADC_BATTEMP));
1250 lcd_puts(0, line++, buf);
1251 snprintf(buf, sizeof(buf), "ADC_MICSUP1: %02x", adc_read(ADC_MICSUP1));
1252 lcd_puts(0, line++, buf);
1253 snprintf(buf, sizeof(buf), "ADC_MICSUP2: %02x", adc_read(ADC_MICSUP2));
1254 lcd_puts(0, line++, buf);
1255 snprintf(buf, sizeof(buf), "ADC_VBE1: %02x", adc_read(ADC_VBE1));
1256 lcd_puts(0, line++, buf);
1257 snprintf(buf, sizeof(buf), "ADC_VBE2: %02x", adc_read(ADC_VBE2));
1258 lcd_puts(0, line++, buf);
1259 snprintf(buf, sizeof(buf), "ADC_I_MICSUP1: %02x", adc_read(ADC_I_MICSUP1));
1260 lcd_puts(0, line++, buf);
1261 snprintf(buf, sizeof(buf), "ADC_I_MICSUP2: %02x", adc_read(ADC_I_MICSUP2));
1262 lcd_puts(0, line++, buf);
1263 snprintf(buf, sizeof(buf), "ADC_VBAT: %02x", adc_read(ADC_VBAT));
1264 lcd_puts(0, line++, buf);
1265 #endif
1266 lcd_update();
1267 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1268 return false;
1271 #elif CONFIG_CPU == PP5002
1272 unsigned int gpio_a, gpio_b, gpio_c, gpio_d;
1274 char buf[128];
1275 int line;
1277 lcd_setmargins(0, 0);
1278 lcd_clear_display();
1279 lcd_setfont(FONT_SYSFIXED);
1281 while(1)
1283 gpio_a = GPIOA_INPUT_VAL;
1284 gpio_b = GPIOB_INPUT_VAL;
1285 gpio_c = GPIOC_INPUT_VAL;
1286 gpio_d = GPIOD_INPUT_VAL;
1288 line = 0;
1289 snprintf(buf, sizeof(buf), "GPIO_A: %02x GPIO_B: %02x", gpio_a, gpio_b);
1290 lcd_puts(0, line++, buf);
1291 snprintf(buf, sizeof(buf), "GPIO_C: %02x GPIO_D: %02x", gpio_c, gpio_d);
1292 lcd_puts(0, line++, buf);
1294 snprintf(buf, sizeof(buf), "DEV_EN: %08lx", DEV_EN);
1295 lcd_puts(0, line++, buf);
1296 snprintf(buf, sizeof(buf), "CLOCK_ENABLE: %08lx", CLOCK_ENABLE);
1297 lcd_puts(0, line++, buf);
1298 snprintf(buf, sizeof(buf), "CLOCK_SOURCE: %08lx", CLOCK_SOURCE);
1299 lcd_puts(0, line++, buf);
1300 snprintf(buf, sizeof(buf), "PLL_CONTROL: %08lx", PLL_CONTROL);
1301 lcd_puts(0, line++, buf);
1302 snprintf(buf, sizeof(buf), "PLL_DIV: %08lx", PLL_DIV);
1303 lcd_puts(0, line++, buf);
1304 snprintf(buf, sizeof(buf), "PLL_MULT: %08lx", PLL_MULT);
1305 lcd_puts(0, line++, buf);
1306 snprintf(buf, sizeof(buf), "TIMING1_CTL: %08lx", TIMING1_CTL);
1307 lcd_puts(0, line++, buf);
1308 snprintf(buf, sizeof(buf), "TIMING2_CTL: %08lx", TIMING2_CTL);
1309 lcd_puts(0, line++, buf);
1311 lcd_update();
1312 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1313 return false;
1315 #elif CONFIG_CPU == S3C2440
1316 char buf[50];
1317 int line;
1319 lcd_setmargins(0, 0);
1320 lcd_clear_display();
1321 lcd_setfont(FONT_SYSFIXED);
1323 while(1)
1325 line = 0;
1326 snprintf(buf, sizeof(buf), "[Ports and Registers]"); lcd_puts(0, line++, buf);
1328 snprintf(buf, sizeof(buf), "GPACON: %08x GPBCON: %08x", GPACON, GPBCON); lcd_puts(0, line++, buf);
1329 snprintf(buf, sizeof(buf), "GPADAT: %08x GPBDAT: %08x", GPADAT, GPBDAT); lcd_puts(0, line++, buf);
1330 snprintf(buf, sizeof(buf), "GPAUP: %08x GPBUP: %08x", 0, GPBUP); lcd_puts(0, line++, buf);
1331 snprintf(buf, sizeof(buf), "GPCCON: %08x GPDCON: %08x", GPCCON, GPDCON); lcd_puts(0, line++, buf);
1332 snprintf(buf, sizeof(buf), "GPCDAT: %08x GPDDAT: %08x", GPCDAT, GPDDAT); lcd_puts(0, line++, buf);
1333 snprintf(buf, sizeof(buf), "GPCUP: %08x GPDUP: %08x", GPCUP, GPDUP); lcd_puts(0, line++, buf);
1335 snprintf(buf, sizeof(buf), "GPCCON: %08x GPDCON: %08x", GPCCON, GPDCON); lcd_puts(0, line++, buf);
1336 snprintf(buf, sizeof(buf), "GPCDAT: %08x GPDDAT: %08x", GPCDAT, GPDDAT); lcd_puts(0, line++, buf);
1337 snprintf(buf, sizeof(buf), "GPCUP: %08x GPDUP: %08x", GPCUP, GPDUP); lcd_puts(0, line++, buf);
1339 snprintf(buf, sizeof(buf), "GPECON: %08x GPFCON: %08x", GPECON, GPFCON); lcd_puts(0, line++, buf);
1340 snprintf(buf, sizeof(buf), "GPEDAT: %08x GPFDAT: %08x", GPEDAT, GPFDAT); lcd_puts(0, line++, buf);
1341 snprintf(buf, sizeof(buf), "GPEUP: %08x GPFUP: %08x", GPEUP, GPFUP); lcd_puts(0, line++, buf);
1343 snprintf(buf, sizeof(buf), "GPGCON: %08x GPHCON: %08x", GPGCON, GPHCON); lcd_puts(0, line++, buf);
1344 snprintf(buf, sizeof(buf), "GPGDAT: %08x GPHDAT: %08x", GPGDAT, GPHDAT); lcd_puts(0, line++, buf);
1345 snprintf(buf, sizeof(buf), "GPGUP: %08x GPHUP: %08x", GPGUP, GPHUP); lcd_puts(0, line++, buf);
1347 snprintf(buf, sizeof(buf), "GPJCON: %08x", GPJCON); lcd_puts(0, line++, buf);
1348 snprintf(buf, sizeof(buf), "GPJDAT: %08x", GPJDAT); lcd_puts(0, line++, buf);
1349 snprintf(buf, sizeof(buf), "GPJUP: %08x", GPJUP); lcd_puts(0, line++, buf);
1351 line++;
1353 snprintf(buf, sizeof(buf), "SRCPND: %08x INTMOD: %08x", SRCPND, INTMOD); lcd_puts(0, line++, buf);
1354 snprintf(buf, sizeof(buf), "INTMSK: %08x INTPND: %08x", INTMSK, INTPND); lcd_puts(0, line++, buf);
1355 snprintf(buf, sizeof(buf), "CLKCON: %08x CLKSLOW: %08x", CLKCON, CLKSLOW); lcd_puts(0, line++, buf);
1356 snprintf(buf, sizeof(buf), "MPLLCON: %08x UPLLCON: %08x", MPLLCON, UPLLCON); lcd_puts(0, line++, buf);
1357 snprintf(buf, sizeof(buf), "CLKDIVN: %08x", CLKDIVN); lcd_puts(0, line++, buf);
1359 lcd_update();
1360 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1361 return false;
1363 #endif /* CPU */
1364 return false;
1366 #else /* !HAVE_LCD_BITMAP */
1367 bool dbg_ports(void)
1369 unsigned short porta;
1370 unsigned short portb;
1371 unsigned char portc;
1372 char buf[32];
1373 int button;
1374 int adc_battery_voltage;
1375 int currval = 0;
1377 lcd_clear_display();
1379 while(1)
1381 porta = PADR;
1382 portb = PBDR;
1383 portc = PCDR;
1385 switch(currval)
1387 case 0:
1388 snprintf(buf, 32, "PADR: %04x", porta);
1389 break;
1390 case 1:
1391 snprintf(buf, 32, "PBDR: %04x", portb);
1392 break;
1393 case 2:
1394 snprintf(buf, 32, "AN0: %03x", adc_read(0));
1395 break;
1396 case 3:
1397 snprintf(buf, 32, "AN1: %03x", adc_read(1));
1398 break;
1399 case 4:
1400 snprintf(buf, 32, "AN2: %03x", adc_read(2));
1401 break;
1402 case 5:
1403 snprintf(buf, 32, "AN3: %03x", adc_read(3));
1404 break;
1405 case 6:
1406 snprintf(buf, 32, "AN4: %03x", adc_read(4));
1407 break;
1408 case 7:
1409 snprintf(buf, 32, "AN5: %03x", adc_read(5));
1410 break;
1411 case 8:
1412 snprintf(buf, 32, "AN6: %03x", adc_read(6));
1413 break;
1414 case 9:
1415 snprintf(buf, 32, "AN7: %03x", adc_read(7));
1416 break;
1417 break;
1419 lcd_puts(0, 0, buf);
1421 battery_read_info(&adc_battery_voltage, NULL);
1422 snprintf(buf, 32, "Batt: %d.%03dV", adc_battery_voltage / 1000,
1423 adc_battery_voltage % 1000);
1424 lcd_puts(0, 1, buf);
1425 lcd_update();
1427 button = get_action(CONTEXT_SETTINGS,HZ/5);
1429 switch(button)
1431 case ACTION_STD_CANCEL:
1432 return false;
1434 case ACTION_SETTINGS_DEC:
1435 currval--;
1436 if(currval < 0)
1437 currval = 9;
1438 break;
1440 case ACTION_SETTINGS_INC:
1441 currval++;
1442 if(currval > 9)
1443 currval = 0;
1444 break;
1447 return false;
1449 #endif /* !HAVE_LCD_BITMAP */
1450 #endif /* !SIMULATOR */
1452 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
1453 static bool dbg_cpufreq(void)
1455 char buf[128];
1456 int line;
1457 int button;
1459 #ifdef HAVE_LCD_BITMAP
1460 lcd_setmargins(0, 0);
1461 lcd_setfont(FONT_SYSFIXED);
1462 #endif
1463 lcd_clear_display();
1465 while(1)
1467 line = 0;
1469 snprintf(buf, sizeof(buf), "Frequency: %ld", FREQ);
1470 lcd_puts(0, line++, buf);
1472 snprintf(buf, sizeof(buf), "boost_counter: %d", get_cpu_boost_counter());
1473 lcd_puts(0, line++, buf);
1475 lcd_update();
1476 button = get_action(CONTEXT_STD,HZ/10);
1478 switch(button)
1480 case ACTION_STD_PREV:
1481 cpu_boost(true);
1482 break;
1484 case ACTION_STD_NEXT:
1485 cpu_boost(false);
1486 break;
1488 case ACTION_STD_OK:
1489 while (get_cpu_boost_counter() > 0)
1490 cpu_boost(false);
1491 set_cpu_frequency(CPUFREQ_DEFAULT);
1492 break;
1494 case ACTION_STD_CANCEL:
1495 return false;
1499 return false;
1501 #endif /* HAVE_ADJUSTABLE_CPU_FREQ */
1503 #ifndef SIMULATOR
1504 #ifdef HAVE_LCD_BITMAP
1506 * view_battery() shows a automatically scaled graph of the battery voltage
1507 * over time. Usable for estimating battery life / charging rate.
1508 * The power_history array is updated in power_thread of powermgmt.c.
1511 #define BAT_LAST_VAL MIN(LCD_WIDTH, POWER_HISTORY_LEN)
1512 #define BAT_YSPACE (LCD_HEIGHT - 20)
1514 static bool view_battery(void)
1516 int view = 0;
1517 int i, x, y;
1518 unsigned short maxv, minv;
1519 char buf[32];
1521 lcd_setmargins(0, 0);
1522 lcd_setfont(FONT_SYSFIXED);
1524 while(1)
1526 lcd_clear_display();
1527 switch (view) {
1528 case 0: /* voltage history graph */
1529 /* Find maximum and minimum voltage for scaling */
1530 minv = power_history[0];
1531 maxv = minv + 1;
1532 for (i = 1; i < BAT_LAST_VAL && power_history[i]; i++) {
1533 if (power_history[i] > maxv)
1534 maxv = power_history[i];
1535 if (power_history[i] < minv)
1536 minv = power_history[i];
1539 snprintf(buf, 30, "Battery %d.%03d", power_history[0] / 1000,
1540 power_history[0] % 1000);
1541 lcd_puts(0, 0, buf);
1542 snprintf(buf, 30, "scale %d.%03d-%d.%03dV",
1543 minv / 1000, minv % 1000, maxv / 1000, maxv % 1000);
1544 lcd_puts(0, 1, buf);
1546 x = 0;
1547 for (i = BAT_LAST_VAL - 1; i >= 0; i--) {
1548 y = (power_history[i] - minv) * BAT_YSPACE / (maxv - minv);
1549 lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
1550 lcd_vline(x, LCD_HEIGHT-1, 20);
1551 lcd_set_drawmode(DRMODE_SOLID);
1552 lcd_vline(x, LCD_HEIGHT-1,
1553 MIN(MAX(LCD_HEIGHT-1 - y, 20), LCD_HEIGHT-1));
1554 x++;
1557 break;
1559 case 1: /* status: */
1560 lcd_puts(0, 0, "Power status:");
1562 battery_read_info(&y, NULL);
1563 snprintf(buf, 30, "Battery: %d.%03d V", y / 1000, y % 1000);
1564 lcd_puts(0, 1, buf);
1565 #ifdef ADC_EXT_POWER
1566 y = (adc_read(ADC_EXT_POWER) * EXT_SCALE_FACTOR) / 1000;
1567 snprintf(buf, 30, "External: %d.%03d V", y / 1000, y % 1000);
1568 lcd_puts(0, 2, buf);
1569 #endif
1570 #if CONFIG_CHARGING
1571 #if CONFIG_CHARGING == CHARGING_CONTROL
1572 snprintf(buf, 30, "Chgr: %s %s",
1573 charger_inserted() ? "present" : "absent",
1574 charger_enabled ? "on" : "off");
1575 lcd_puts(0, 3, buf);
1576 snprintf(buf, 30, "short delta: %d", short_delta);
1577 lcd_puts(0, 5, buf);
1578 snprintf(buf, 30, "long delta: %d", long_delta);
1579 lcd_puts(0, 6, buf);
1580 lcd_puts(0, 7, power_message);
1581 snprintf(buf, 30, "USB Inserted: %s",
1582 usb_inserted() ? "yes" : "no");
1583 lcd_puts(0, 8, buf);
1584 #if defined IRIVER_H300_SERIES
1585 snprintf(buf, 30, "USB Charging Enabled: %s",
1586 usb_charging_enabled() ? "yes" : "no");
1587 lcd_puts(0, 9, buf);
1588 #endif
1589 #else /* CONFIG_CHARGING != CHARGING_CONTROL */
1590 #if defined IPOD_NANO || defined IPOD_VIDEO
1591 int usb_pwr = (GPIOL_INPUT_VAL & 0x10)?true:false;
1592 int ext_pwr = (GPIOL_INPUT_VAL & 0x08)?false:true;
1593 int dock = (GPIOA_INPUT_VAL & 0x10)?true:false;
1594 int charging = (GPIOB_INPUT_VAL & 0x01)?false:true;
1595 int headphone= (GPIOA_INPUT_VAL & 0x80)?true:false;
1597 snprintf(buf, 30, "USB pwr: %s",
1598 usb_pwr ? "present" : "absent");
1599 lcd_puts(0, 3, buf);
1600 snprintf(buf, 30, "EXT pwr: %s",
1601 ext_pwr ? "present" : "absent");
1602 lcd_puts(0, 4, buf);
1603 snprintf(buf, 30, "Battery: %s",
1604 charging ? "charging" : (usb_pwr||ext_pwr) ? "charged" : "discharging");
1605 lcd_puts(0, 5, buf);
1606 snprintf(buf, 30, "Dock mode: %s",
1607 dock ? "enabled" : "disabled");
1608 lcd_puts(0, 6, buf);
1609 snprintf(buf, 30, "Headphone: %s",
1610 headphone ? "connected" : "disconnected");
1611 lcd_puts(0, 7, buf);
1612 #else
1613 snprintf(buf, 30, "Charger: %s",
1614 charger_inserted() ? "present" : "absent");
1615 lcd_puts(0, 3, buf);
1616 #endif
1617 #endif /* CONFIG_CHARGING != CHARGING_CONTROL */
1618 #endif /* CONFIG_CHARGING */
1619 break;
1621 case 2: /* voltage deltas: */
1622 lcd_puts(0, 0, "Voltage deltas:");
1624 for (i = 0; i <= 6; i++) {
1625 y = power_history[i] - power_history[i+1];
1626 snprintf(buf, 30, "-%d min: %s%d.%03d V", i,
1627 (y < 0) ? "-" : "", ((y < 0) ? y * -1 : y) / 1000,
1628 ((y < 0) ? y * -1 : y ) % 1000);
1629 lcd_puts(0, i+1, buf);
1631 break;
1633 case 3: /* remaining time estimation: */
1635 #if CONFIG_CHARGING == CHARGING_CONTROL
1636 snprintf(buf, 30, "charge_state: %d", charge_state);
1637 lcd_puts(0, 0, buf);
1639 snprintf(buf, 30, "Cycle time: %d m", powermgmt_last_cycle_startstop_min);
1640 lcd_puts(0, 1, buf);
1642 snprintf(buf, 30, "Lvl@cyc st: %d%%", powermgmt_last_cycle_level);
1643 lcd_puts(0, 2, buf);
1645 snprintf(buf, 30, "P=%2d I=%2d", pid_p, pid_i);
1646 lcd_puts(0, 3, buf);
1648 snprintf(buf, 30, "Trickle sec: %d/60", trickle_sec);
1649 lcd_puts(0, 4, buf);
1650 #endif /* CONFIG_CHARGING == CHARGING_CONTROL */
1652 snprintf(buf, 30, "Last PwrHist: %d.%03dV",
1653 power_history[0] / 1000,
1654 power_history[0] % 1000);
1655 lcd_puts(0, 5, buf);
1657 snprintf(buf, 30, "battery level: %d%%", battery_level());
1658 lcd_puts(0, 6, buf);
1660 snprintf(buf, 30, "Est. remain: %d m", battery_time());
1661 lcd_puts(0, 7, buf);
1662 break;
1665 lcd_update();
1667 switch(get_action(CONTEXT_SETTINGS,HZ/2))
1669 case ACTION_SETTINGS_DEC:
1670 if (view)
1671 view--;
1672 break;
1674 case ACTION_SETTINGS_INC:
1675 if (view < 3)
1676 view++;
1677 break;
1679 case ACTION_STD_CANCEL:
1680 return false;
1683 return false;
1686 #endif /* HAVE_LCD_BITMAP */
1687 #endif
1689 #ifndef SIMULATOR
1690 #if defined(HAVE_MMC) || defined(HAVE_HOTSWAP)
1691 #if defined(HAVE_MMC)
1692 #define CARDTYPE "MMC"
1693 #else
1694 #define CARDTYPE "microSD"
1695 #endif
1696 static int cardinfo_callback(int btn, struct action_callback_info *info)
1698 tCardInfo *card;
1699 unsigned char card_name[7];
1700 unsigned char pbuf[32];
1701 static const unsigned char i_vmin[] = { 0, 1, 5, 10, 25, 35, 60, 100 };
1702 static const unsigned char i_vmax[] = { 1, 5, 10, 25, 35, 45, 80, 200 };
1703 static const unsigned char *kbit_units[] = { "kBit/s", "MBit/s", "GBit/s" };
1704 static const unsigned char *nsec_units[] = { "ns", "µs", "ms" };
1705 static const char *spec_vers[] = { "1.0-1.2", "1.4", "2.0-2.2",
1706 "3.1-3.31", "4.0" };
1707 if ((btn == ACTION_STD_OK) || (btn == SYS_FS_CHANGED) || (btn == ACTION_REDRAW))
1709 if (btn == ACTION_STD_OK)
1710 info->cbdata ^= 0x1; /* change cards */
1712 dbg_listmessage_setlines(0);
1714 card = card_get_info(info->cbdata);
1716 if (card->initialized > 0)
1718 card_name[6] = '\0';
1719 strncpy(card_name, ((unsigned char*)card->cid) + 3, 6);
1720 dbg_listmessage_addline(
1721 "%s Rev %d.%d", card_name,
1722 (int) card_extract_bits(card->cid, 72, 4),
1723 (int) card_extract_bits(card->cid, 76, 4));
1724 dbg_listmessage_addline(
1725 "Prod: %d/%d",
1726 (int) card_extract_bits(card->cid, 112, 4),
1727 (int) card_extract_bits(card->cid, 116, 4) + 1997);
1728 dbg_listmessage_addline(
1729 "Ser#: 0x%08lx",
1730 card_extract_bits(card->cid, 80, 32));
1731 dbg_listmessage_addline(
1732 "M=%02x, O=%04x",
1733 (int) card_extract_bits(card->cid, 0, 8),
1734 (int) card_extract_bits(card->cid, 8, 16));
1735 int temp = card_extract_bits(card->csd, 2, 4);
1736 dbg_listmessage_addline(
1737 CARDTYPE " v%s", temp < 5 ?
1738 spec_vers[temp] : "?.?");
1739 dbg_listmessage_addline(
1740 "Blocks: 0x%06lx", card->numblocks);
1741 dbg_listmessage_addline(
1742 "Blksz.: %d P:%c%c", card->blocksize,
1743 card_extract_bits(card->csd, 48, 1) ? 'R' : '-',
1744 card_extract_bits(card->csd, 106, 1) ? 'W' : '-');
1745 output_dyn_value(pbuf, sizeof pbuf, card->speed / 1000,
1746 kbit_units, false);
1747 dbg_listmessage_addline(
1748 "Speed: %s", pbuf);
1749 output_dyn_value(pbuf, sizeof pbuf, card->tsac,
1750 nsec_units, false);
1751 dbg_listmessage_addline(
1752 "Tsac: %s", pbuf);
1753 dbg_listmessage_addline(
1754 "Nsac: %d clk", card->nsac);
1755 dbg_listmessage_addline(
1756 "R2W: *%d", card->r2w_factor);
1757 dbg_listmessage_addline(
1758 "IRmax: %d..%d mA",
1759 i_vmin[card_extract_bits(card->csd, 66, 3)],
1760 i_vmax[card_extract_bits(card->csd, 69, 3)]);
1761 dbg_listmessage_addline(
1762 "IWmax: %d..%d mA",
1763 i_vmin[card_extract_bits(card->csd, 72, 3)],
1764 i_vmax[card_extract_bits(card->csd, 75, 3)]);
1766 else if (card->initialized == 0)
1768 dbg_listmessage_addline("Not Found!");
1770 #ifndef HAVE_MMC
1771 else /* card->initialized < 0 */
1773 dbg_listmessage_addline("Init Error! (%d)", card->initialized);
1775 #endif
1776 snprintf(info->title, 16, "[" CARDTYPE " %d]", (int)info->cbdata);
1777 gui_synclist_set_nb_items(info->lists, dbg_listmessage_getlines());
1778 gui_synclist_select_item(info->lists, 0);
1779 btn = ACTION_REDRAW;
1781 return btn;
1783 static bool dbg_disk_info(void)
1785 char listtitle[16];
1786 struct action_callback_info info;
1787 info.title = listtitle;
1788 info.count = 1;
1789 info.selection_size = 1;
1790 info.action_callback = cardinfo_callback;
1791 info.dbg_getname = dbg_listmessage_getname;
1792 info.cbdata = 0;
1793 dbg_list(&info);
1794 return false;
1796 #else /* !defined(HAVE_MMC) && !defined(HAVE_HOTSWAP) */
1797 static int disk_callback(int btn, struct action_callback_info *info)
1799 int i;
1800 char buf[128];
1801 unsigned short* identify_info = ata_get_identify();
1802 bool timing_info_present = false;
1803 (void)btn;
1805 dbg_listmessage_setlines(0);
1807 for (i=0; i < 20; i++)
1808 ((unsigned short*)buf)[i]=htobe16(identify_info[i+27]);
1809 buf[40]=0;
1810 /* kill trailing space */
1811 for (i=39; i && buf[i]==' '; i--)
1812 buf[i] = 0;
1813 dbg_listmessage_addline(
1814 "Model: %s", buf);
1815 for (i=0; i < 4; i++)
1816 ((unsigned short*)buf)[i]=htobe16(identify_info[i+23]);
1817 buf[8]=0;
1818 dbg_listmessage_addline(
1819 "Firmware: %s", buf);
1820 snprintf(buf, sizeof buf, "%ld MB",
1821 ((unsigned long)identify_info[61] << 16 |
1822 (unsigned long)identify_info[60]) / 2048 );
1823 dbg_listmessage_addline(
1824 "Size: %s", buf);
1825 unsigned long free;
1826 fat_size( IF_MV2(0,) NULL, &free );
1827 dbg_listmessage_addline(
1828 "Free: %ld MB", free / 1024);
1829 dbg_listmessage_addline(
1830 "Spinup time: %d ms", ata_spinup_time * (1000/HZ));
1831 i = identify_info[83] & (1<<3);
1832 dbg_listmessage_addline(
1833 "Power mgmt: %s", i ? "enabled" : "unsupported");
1834 i = identify_info[83] & (1<<9);
1835 dbg_listmessage_addline(
1836 "Noise mgmt: %s", i ? "enabled" : "unsupported");
1837 i = identify_info[82] & (1<<6);
1838 dbg_listmessage_addline(
1839 "Read-ahead: %s", i ? "enabled" : "unsupported");
1840 timing_info_present = identify_info[53] & (1<<1);
1841 if(timing_info_present) {
1842 char pio3[2], pio4[2];pio3[1] = 0;
1843 pio4[1] = 0;
1844 pio3[0] = (identify_info[64] & (1<<0)) ? '3' : 0;
1845 pio4[0] = (identify_info[64] & (1<<1)) ? '4' : 0;
1846 dbg_listmessage_addline(
1847 "PIO modes: 0 1 2 %s %s", pio3, pio4);
1849 else {
1850 dbg_listmessage_addline(
1851 "No PIO mode info");
1853 timing_info_present = identify_info[53] & (1<<1);
1854 if(timing_info_present) {
1855 dbg_listmessage_addline(
1856 "Cycle times %dns/%dns",
1857 identify_info[67],
1858 identify_info[68] );
1859 } else {
1860 dbg_listmessage_addline(
1861 "No timing info");
1863 timing_info_present = identify_info[53] & (1<<1);
1864 if(timing_info_present) {
1865 i = identify_info[49] & (1<<11);
1866 dbg_listmessage_addline(
1867 "IORDY support: %s", i ? "yes" : "no");
1868 i = identify_info[49] & (1<<10);
1869 dbg_listmessage_addline(
1870 "IORDY disable: %s", i ? "yes" : "no");
1871 } else {
1872 dbg_listmessage_addline(
1873 "No timing info");
1875 dbg_listmessage_addline(
1876 "Cluster size: %d bytes", fat_get_cluster_size(IF_MV(0)));
1877 gui_synclist_set_nb_items(info->lists, dbg_listmessage_getlines());
1878 return btn;
1880 static bool dbg_disk_info(void)
1882 struct action_callback_info info;
1883 info.title = "Disk Info";
1884 info.count = 1;
1885 info.selection_size = 1;
1886 info.action_callback = disk_callback;
1887 info.dbg_getname = dbg_listmessage_getname;
1888 dbg_list(&info);
1889 return false;
1891 #endif /* !defined(HAVE_MMC) && !defined(HAVE_HOTSWAP) */
1892 #endif /* !SIMULATOR */
1894 #ifdef HAVE_DIRCACHE
1895 static int dircache_callback(int btn, struct action_callback_info *info)
1897 (void)btn; (void)info;
1898 dbg_listmessage_setlines(0);
1899 dbg_listmessage_addline("Cache initialized: %s",
1900 dircache_is_enabled() ? "Yes" : "No");
1901 dbg_listmessage_addline("Cache size: %d B",
1902 dircache_get_cache_size());
1903 dbg_listmessage_addline("Last size: %d B",
1904 global_status.dircache_size);
1905 dbg_listmessage_addline("Limit: %d B",
1906 DIRCACHE_LIMIT);
1907 dbg_listmessage_addline("Reserve: %d/%d B",
1908 dircache_get_reserve_used(), DIRCACHE_RESERVE);
1909 dbg_listmessage_addline("Scanning took: %d s",
1910 dircache_get_build_ticks() / HZ);
1911 dbg_listmessage_addline("Entry count: %d",
1912 dircache_get_entry_count());
1913 return btn;
1916 static bool dbg_dircache_info(void)
1918 struct action_callback_info info;
1919 info.title = "Dircache Info";
1920 info.count = 7;
1921 info.selection_size = 1;
1922 info.action_callback = dircache_callback;
1923 info.dbg_getname = dbg_listmessage_getname;
1924 dbg_list(&info);
1925 return false;
1928 #endif /* HAVE_DIRCACHE */
1930 #ifdef HAVE_TAGCACHE
1931 static int database_callback(int btn, struct action_callback_info *info)
1933 (void)btn; (void)info;
1934 struct tagcache_stat *stat = tagcache_get_stat();
1935 dbg_listmessage_setlines(0);
1936 dbg_listmessage_addline("Initialized: %s",
1937 stat->initialized ? "Yes" : "No");
1938 dbg_listmessage_addline("DB Ready: %s",
1939 stat->ready ? "Yes" : "No");
1940 dbg_listmessage_addline("RAM Cache: %s",
1941 stat->ramcache ? "Yes" : "No");
1942 dbg_listmessage_addline("RAM: %d/%d B",
1943 stat->ramcache_used, stat->ramcache_allocated);
1944 dbg_listmessage_addline("Progress: %d%% (%d entries)",
1945 stat->progress, stat->processed_entries);
1946 dbg_listmessage_addline("Commit step: %d",
1947 stat->commit_step);
1948 dbg_listmessage_addline("Commit delayed: %s",
1949 stat->commit_delayed ? "Yes" : "No");
1950 return btn;
1952 static bool dbg_tagcache_info(void)
1954 struct action_callback_info info;
1955 info.title = "Database Info";
1956 info.count = 7;
1957 info.selection_size = 1;
1958 info.action_callback = database_callback;
1959 info.dbg_getname = dbg_listmessage_getname;
1960 dbg_list(&info);
1961 return false;
1963 #endif
1965 #if CONFIG_CPU == SH7034
1966 static bool dbg_save_roms(void)
1968 int fd;
1969 int oldmode = system_memory_guard(MEMGUARD_NONE);
1971 fd = creat("/internal_rom_0000-FFFF.bin");
1972 if(fd >= 0)
1974 write(fd, (void *)0, 0x10000);
1975 close(fd);
1978 fd = creat("/internal_rom_2000000-203FFFF.bin");
1979 if(fd >= 0)
1981 write(fd, (void *)0x2000000, 0x40000);
1982 close(fd);
1985 system_memory_guard(oldmode);
1986 return false;
1988 #elif defined CPU_COLDFIRE
1989 static bool dbg_save_roms(void)
1991 int fd;
1992 int oldmode = system_memory_guard(MEMGUARD_NONE);
1994 #if defined(IRIVER_H100_SERIES)
1995 fd = creat("/internal_rom_000000-1FFFFF.bin");
1996 #elif defined(IRIVER_H300_SERIES)
1997 fd = creat("/internal_rom_000000-3FFFFF.bin");
1998 #elif defined(IAUDIO_X5) || defined(IAUDIO_M5)
1999 fd = creat("/internal_rom_000000-3FFFFF.bin");
2000 #endif
2001 if(fd >= 0)
2003 write(fd, (void *)0, FLASH_SIZE);
2004 close(fd);
2006 system_memory_guard(oldmode);
2008 #ifdef HAVE_EEPROM
2009 fd = creat("/internal_eeprom.bin");
2010 if (fd >= 0)
2012 int old_irq_level;
2013 char buf[EEPROM_SIZE];
2014 int err;
2016 old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL);
2018 err = eeprom_24cxx_read(0, buf, sizeof buf);
2019 if (err)
2020 gui_syncsplash(HZ*3, "Eeprom read failure (%d)",err);
2021 else
2023 write(fd, buf, sizeof buf);
2026 set_irq_level(old_irq_level);
2028 close(fd);
2030 #endif
2032 return false;
2034 #elif defined(CPU_PP) && !(defined(SANSA_E200) || defined(SANSA_C200))
2035 static bool dbg_save_roms(void)
2037 int fd;
2039 fd = creat("/internal_rom_000000-0FFFFF.bin");
2040 if(fd >= 0)
2042 write(fd, (void *)0x20000000, FLASH_SIZE);
2043 close(fd);
2046 return false;
2048 #endif /* CPU */
2050 #ifndef SIMULATOR
2051 #if CONFIG_TUNER
2052 static int radio_callback(int btn, struct action_callback_info *info)
2054 dbg_listmessage_setlines(1);
2056 #if (CONFIG_TUNER & LV24020LP)
2057 dbg_listmessage_addline("CTRL_STAT: %02X", lv24020lp_get(LV24020LP_CTRL_STAT) );
2058 dbg_listmessage_addline("RADIO_STAT: %02X", lv24020lp_get(LV24020LP_REG_STAT) );
2059 dbg_listmessage_addline("MSS_FM: %d kHz", lv24020lp_get(LV24020LP_MSS_FM) );
2060 dbg_listmessage_addline("MSS_IF: %d Hz", lv24020lp_get(LV24020LP_MSS_IF) );
2061 dbg_listmessage_addline("MSS_SD: %d Hz", lv24020lp_get(LV24020LP_MSS_SD) );
2062 dbg_listmessage_addline("if_set: %d Hz", lv24020lp_get(LV24020LP_IF_SET) );
2063 dbg_listmessage_addline("sd_set: %d Hz", lv24020lp_get(LV24020LP_SD_SET) );
2064 #endif
2065 #if (CONFIG_TUNER & S1A0903X01)
2066 dbg_listmessage_addline("Samsung regs: %08X", s1a0903x01_get(RADIO_ALL));
2067 /* This one doesn't return dynamic data atm */
2068 #endif
2069 #if (CONFIG_TUNER & TEA5767)
2070 struct tea5767_dbg_info nfo;
2071 tea5767_dbg_info(&nfo);
2072 dbg_listmessage_addline("Philips regs:");
2073 dbg_listmessage_addline(
2074 " Read: %02X %02X %02X %02X %02X",
2075 (unsigned)nfo.read_regs[0], (unsigned)nfo.read_regs[1],
2076 (unsigned)nfo.read_regs[2], (unsigned)nfo.read_regs[3],
2077 (unsigned)nfo.read_regs[4]);
2078 dbg_listmessage_addline(
2079 " Write: %02X %02X %02X %02X %02X",
2080 (unsigned)nfo.write_regs[0], (unsigned)nfo.write_regs[1],
2081 (unsigned)nfo.write_regs[2], (unsigned)nfo.write_regs[3],
2082 (unsigned)nfo.write_regs[4]);
2083 #endif
2085 if (btn != ACTION_STD_CANCEL)
2086 btn = ACTION_REDRAW;
2088 gui_synclist_set_nb_items(info->lists, dbg_listmessage_getlines());
2089 return btn;
2091 static bool dbg_fm_radio(void)
2093 struct action_callback_info info;
2095 info.title = "FM Radio";
2096 info.count = 1;
2097 info.selection_size = 1;
2098 info.cbdata = radio_hardware_present();
2099 info.action_callback = info.cbdata ? radio_callback : NULL;
2100 info.dbg_getname = dbg_listmessage_getname;
2102 dbg_listmessage_setlines(0);
2103 dbg_listmessage_addline("HW detected: %s", info.cbdata ? "yes" : "no");
2105 dbg_list(&info);
2106 return false;
2108 #endif /* CONFIG_TUNER */
2109 #endif /* !SIMULATOR */
2111 #ifdef HAVE_LCD_BITMAP
2112 extern bool do_screendump_instead_of_usb;
2114 static bool dbg_screendump(void)
2116 do_screendump_instead_of_usb = !do_screendump_instead_of_usb;
2117 gui_syncsplash(HZ, "Screendump %s",
2118 do_screendump_instead_of_usb?"enabled":"disabled");
2119 return false;
2121 #endif /* HAVE_LCD_BITMAP */
2123 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
2124 static bool dbg_set_memory_guard(void)
2126 static const struct opt_items names[MAXMEMGUARD] = {
2127 { "None", -1 },
2128 { "Flash ROM writes", -1 },
2129 { "Zero area (all)", -1 }
2131 int mode = system_memory_guard(MEMGUARD_KEEP);
2133 set_option( "Catch mem accesses", &mode, INT, names, MAXMEMGUARD, NULL);
2134 system_memory_guard(mode);
2136 return false;
2138 #endif /* CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) */
2140 #if defined(TOSHIBA_GIGABEAT_F) && !defined(SIMULATOR)
2142 extern volatile bool lcd_poweroff;
2144 static bool dbg_lcd_power_off(void)
2146 lcd_setmargins(0, 0);
2148 while(1)
2150 int button;
2152 lcd_clear_display();
2153 lcd_puts(0, 0, "LCD Power Off");
2154 if(lcd_poweroff)
2155 lcd_puts(1, 1, "Yes");
2156 else
2157 lcd_puts(1, 1, "No");
2159 lcd_update();
2161 button = get_action(CONTEXT_STD,HZ/5);
2162 switch(button)
2164 case ACTION_STD_PREV:
2165 case ACTION_STD_NEXT:
2166 lcd_poweroff = !lcd_poweroff;
2167 break;
2168 case ACTION_STD_OK:
2169 case ACTION_STD_CANCEL:
2170 return false;
2171 default:
2172 sleep(HZ/10);
2173 break;
2176 return false;
2178 #endif
2180 #if defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS)
2181 static bool dbg_write_eeprom(void)
2183 int fd;
2184 int rc;
2185 int old_irq_level;
2186 char buf[EEPROM_SIZE];
2187 int err;
2189 fd = open("/internal_eeprom.bin", O_RDONLY);
2191 if (fd >= 0)
2193 rc = read(fd, buf, EEPROM_SIZE);
2195 if(rc == EEPROM_SIZE)
2197 old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL);
2199 err = eeprom_24cxx_write(0, buf, sizeof buf);
2200 if (err)
2201 gui_syncsplash(HZ*3, "Eeprom write failure (%d)",err);
2202 else
2203 gui_syncsplash(HZ*3, "Eeprom written successfully");
2205 set_irq_level(old_irq_level);
2207 else
2209 gui_syncsplash(HZ*3, "File read error (%d)",rc);
2211 close(fd);
2213 else
2215 gui_syncsplash(HZ*3, "Failed to open 'internal_eeprom.bin'");
2218 return false;
2220 #endif /* defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS) */
2221 #ifdef CPU_BOOST_LOGGING
2222 static bool cpu_boost_log(void)
2224 int i = 0,j=0;
2225 int count = cpu_boost_log_getcount();
2226 int lines = LCD_HEIGHT/SYSFONT_HEIGHT;
2227 char *str;
2228 bool done;
2229 lcd_setmargins(0, 0);
2230 lcd_setfont(FONT_SYSFIXED);
2231 str = cpu_boost_log_getlog_first();
2232 while (i < count)
2234 lcd_clear_display();
2235 for(j=0; j<lines; j++,i++)
2237 if (!str)
2238 str = cpu_boost_log_getlog_next();
2239 if (str)
2241 lcd_puts(0, j,str);
2243 str = NULL;
2245 lcd_update();
2246 done = false;
2247 while (!done)
2249 switch(get_action(CONTEXT_STD,TIMEOUT_BLOCK))
2251 case ACTION_STD_OK:
2252 case ACTION_STD_PREV:
2253 case ACTION_STD_NEXT:
2254 done = true;
2255 break;
2256 case ACTION_STD_CANCEL:
2257 i = count;
2258 done = true;
2259 break;
2263 get_action(CONTEXT_STD,TIMEOUT_BLOCK);
2264 lcd_setfont(FONT_UI);
2265 return false;
2267 #endif
2271 /****** The menu *********/
2272 struct the_menu_item {
2273 unsigned char *desc; /* string or ID */
2274 bool (*function) (void); /* return true if USB was connected */
2276 static const struct the_menu_item menuitems[] = {
2277 #if defined(TOSHIBA_GIGABEAT_F) && !defined(SIMULATOR)
2278 { "LCD Power Off", dbg_lcd_power_off },
2279 #endif
2280 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || \
2281 (defined(CPU_PP) && !(defined(SANSA_E200) || defined(SANSA_C200)))
2282 { "Dump ROM contents", dbg_save_roms },
2283 #endif
2284 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || defined(CPU_PP) || CONFIG_CPU == S3C2440
2285 { "View I/O ports", dbg_ports },
2286 #endif
2287 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
2288 { "CPU frequency", dbg_cpufreq },
2289 #endif
2290 #if defined(IRIVER_H100_SERIES) && !defined(SIMULATOR)
2291 { "S/PDIF analyzer", dbg_spdif },
2292 #endif
2293 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
2294 { "Catch mem accesses", dbg_set_memory_guard },
2295 #endif
2296 { "View OS stacks", dbg_os },
2297 #ifdef HAVE_LCD_BITMAP
2298 #ifndef SIMULATOR
2299 { "View battery", view_battery },
2300 #endif
2301 { "Screendump", dbg_screendump },
2302 #endif
2303 #ifndef SIMULATOR
2304 { "View HW info", dbg_hw_info },
2305 #endif
2306 #ifndef SIMULATOR
2307 { "View partitions", dbg_partitions },
2308 #endif
2309 #ifndef SIMULATOR
2310 { "View disk info", dbg_disk_info },
2311 #endif
2312 #ifdef HAVE_DIRCACHE
2313 { "View dircache info", dbg_dircache_info },
2314 #endif
2315 #ifdef HAVE_TAGCACHE
2316 { "View database info", dbg_tagcache_info },
2317 #endif
2318 #ifdef HAVE_LCD_BITMAP
2319 #if CONFIG_CODEC == SWCODEC || !defined(SIMULATOR)
2320 { "View audio thread", dbg_audio_thread },
2321 #endif
2322 #ifdef PM_DEBUG
2323 { "pm histogram", peak_meter_histogram},
2324 #endif /* PM_DEBUG */
2325 #endif /* HAVE_LCD_BITMAP */
2326 #ifndef SIMULATOR
2327 #if CONFIG_TUNER
2328 { "FM Radio", dbg_fm_radio },
2329 #endif
2330 #endif
2331 #if defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS)
2332 { "Write back EEPROM", dbg_write_eeprom },
2333 #endif
2334 #ifdef ROCKBOX_HAS_LOGF
2335 {"logf", logfdisplay },
2336 {"logfdump", logfdump },
2337 #endif
2338 #ifdef CPU_BOOST_LOGGING
2339 {"cpu_boost log",cpu_boost_log},
2340 #endif
2342 static int menu_action_callback(int btn, struct action_callback_info *info)
2344 gui_synclist_hide_selection_marker(info->lists, false);
2345 if (btn == ACTION_STD_OK)
2347 menuitems[gui_synclist_get_sel_pos(info->lists)].function();
2348 gui_synclist_draw(info->lists);
2350 return btn;
2352 static char* dbg_menu_getname(int item, void * data, char *buffer)
2354 (void)data; (void)buffer;
2355 return menuitems[item].desc;
2357 bool debug_menu(void)
2359 struct action_callback_info info;
2360 info.title = "Debug Menu";
2361 info.count = ARRAYLEN(menuitems);
2362 info.selection_size = 1;
2363 info.action_callback = menu_action_callback;
2364 info.dbg_getname = dbg_menu_getname;
2365 dbg_list(&info);
2366 return false;