Manual: make sure that there won't be any additional spaces in the \opt{}. This shoul...
[Rockbox.git] / apps / debug_menu.c
blobd865f12e65b28aa52fd921f3968c3a9ad88225f2
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 "structec.h"
30 #include "action.h"
31 #include "debug.h"
32 #include "thread.h"
33 #include "powermgmt.h"
34 #include "system.h"
35 #include "font.h"
36 #include "audio.h"
37 #include "mp3_playback.h"
38 #include "settings.h"
39 #include "list.h"
40 #include "statusbar.h"
41 #include "dir.h"
42 #include "panic.h"
43 #include "screens.h"
44 #include "misc.h"
45 #include "splash.h"
46 #include "dircache.h"
47 #ifdef HAVE_TAGCACHE
48 #include "tagcache.h"
49 #endif
50 #include "lcd-remote.h"
51 #include "crc32.h"
52 #include "logf.h"
53 #ifndef SIMULATOR
54 #include "disk.h"
55 #include "adc.h"
56 #include "power.h"
57 #include "usb.h"
58 #include "rtc.h"
59 #include "ata.h"
60 #include "fat.h"
61 #include "mas.h"
62 #include "eeprom_24cxx.h"
63 #if defined(HAVE_MMC) || defined(HAVE_HOTSWAP)
64 #include "ata_mmc.h"
65 #endif
66 #if CONFIG_TUNER
67 #include "tuner.h"
68 #include "radio.h"
69 #endif
70 #endif
72 #ifdef HAVE_LCD_BITMAP
73 #include "scrollbar.h"
74 #include "peakmeter.h"
75 #endif
76 #include "logfdisp.h"
77 #if CONFIG_CODEC == SWCODEC
78 #include "pcmbuf.h"
79 #include "buffering.h"
80 #if defined(HAVE_SPDIF_OUT) || defined(HAVE_SPDIF_IN)
81 #include "spdif.h"
82 #endif
83 #endif
84 #ifdef IRIVER_H300_SERIES
85 #include "pcf50606.h" /* for pcf50606_read */
86 #endif
87 #ifdef IAUDIO_X5
88 #include "ds2411.h"
89 #endif
90 #include "hwcompat.h"
91 #include "button.h"
92 #if CONFIG_RTC == RTC_PCF50605
93 #include "pcf50605.h"
94 #endif
96 #if CONFIG_CPU == DM320 || CONFIG_CPU == S3C2440 || CONFIG_CPU == TCC7801
97 #include "debug-target.h"
98 #endif
100 #if defined(SANSA_E200)
101 #include "i2c-pp.h"
102 #include "as3514.h"
103 #endif
105 #if defined(HAVE_USBSTACK)
106 #include "usb_core.h"
107 #endif
108 #ifdef USB_STORAGE
109 #include "../firmware/usbstack/usb_storage.h"
110 #endif
112 /*---------------------------------------------------*/
113 /* SPECIAL DEBUG STUFF */
114 /*---------------------------------------------------*/
115 extern struct thread_entry threads[MAXTHREADS];
117 static char thread_status_char(unsigned status)
119 static const char thread_status_chars[THREAD_NUM_STATES+1] =
121 [0 ... THREAD_NUM_STATES] = '?',
122 [STATE_RUNNING] = 'R',
123 [STATE_BLOCKED] = 'B',
124 [STATE_SLEEPING] = 'S',
125 [STATE_BLOCKED_W_TMO] = 'T',
126 [STATE_FROZEN] = 'F',
127 [STATE_KILLED] = 'K',
130 #if NUM_CORES > 1
131 if (status == STATE_BUSY) /* Not a state index */
132 return '.';
133 #endif
135 if (status > THREAD_NUM_STATES)
136 status = THREAD_NUM_STATES;
138 return thread_status_chars[status];
141 static char* threads_getname(int selected_item, void * data, char *buffer)
143 (void)data;
144 struct thread_entry *thread;
145 char name[32];
147 #if NUM_CORES > 1
148 if (selected_item < (int)NUM_CORES)
150 snprintf(buffer, MAX_PATH, "Idle (%d): %2d%%", selected_item,
151 idle_stack_usage(selected_item));
152 return buffer;
155 selected_item -= NUM_CORES;
156 #endif
158 thread = &threads[selected_item];
160 if (thread->state == STATE_KILLED)
162 snprintf(buffer, MAX_PATH, "%2d: ---", selected_item);
163 return buffer;
166 thread_get_name(name, 32, thread);
168 snprintf(buffer, MAX_PATH,
169 "%2d: " IF_COP("(%d) ") "%c%c " IF_PRIO("%d ") "%2d%% %s",
170 selected_item,
171 IF_COP(thread->core,)
172 #ifdef HAVE_SCHEDULER_BOOSTCTRL
173 (thread->boosted) ? '+' :
174 #endif
175 ((thread->state == STATE_RUNNING) ? '*' : ' '),
176 thread_status_char(thread->state),
177 IF_PRIO(thread->priority,)
178 thread_stack_usage(thread), name);
180 return buffer;
182 static int dbg_threads_action_callback(int action, struct gui_synclist *lists)
184 (void)lists;
185 #ifdef ROCKBOX_HAS_LOGF
186 if (action == ACTION_STD_OK)
188 int selpos = gui_synclist_get_sel_pos(lists);
189 #if NUM_CORES > 1
190 if (selpos >= NUM_CORES)
191 remove_thread(&threads[selpos - NUM_CORES]);
192 #else
193 remove_thread(&threads[selpos]);
194 #endif
195 return ACTION_REDRAW;
197 #endif /* ROCKBOX_HAS_LOGF */
198 if (action == ACTION_NONE)
199 action = ACTION_REDRAW;
200 return action;
202 /* Test code!!! */
203 static bool dbg_os(void)
205 struct simplelist_info info;
206 simplelist_info_init(&info, IF_COP("Core and ") "Stack usage:",
207 #if NUM_CORES == 1
208 MAXTHREADS,
209 #else
210 MAXTHREADS+NUM_CORES,
211 #endif
212 NULL);
213 #ifndef ROCKBOX_HAS_LOGF
214 info.hide_selection = true;
215 #endif
216 info.action_callback = dbg_threads_action_callback;
217 info.get_name = threads_getname;
218 return simplelist_show_list(&info);
221 #ifdef HAVE_LCD_BITMAP
222 #if CONFIG_CODEC != SWCODEC
223 #ifndef SIMULATOR
224 static bool dbg_audio_thread(void)
226 char buf[32];
227 struct audio_debug d;
229 lcd_setmargins(0, 0);
230 lcd_setfont(FONT_SYSFIXED);
232 while(1)
234 if (action_userabort(HZ/5))
235 return false;
237 audio_get_debugdata(&d);
239 lcd_clear_display();
241 snprintf(buf, sizeof(buf), "read: %x", d.audiobuf_read);
242 lcd_puts(0, 0, buf);
243 snprintf(buf, sizeof(buf), "write: %x", d.audiobuf_write);
244 lcd_puts(0, 1, buf);
245 snprintf(buf, sizeof(buf), "swap: %x", d.audiobuf_swapwrite);
246 lcd_puts(0, 2, buf);
247 snprintf(buf, sizeof(buf), "playing: %d", d.playing);
248 lcd_puts(0, 3, buf);
249 snprintf(buf, sizeof(buf), "playable: %x", d.playable_space);
250 lcd_puts(0, 4, buf);
251 snprintf(buf, sizeof(buf), "unswapped: %x", d.unswapped_space);
252 lcd_puts(0, 5, buf);
254 /* Playable space left */
255 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, 6*8, 112, 4, d.audiobuflen, 0,
256 d.playable_space, HORIZONTAL);
258 /* Show the watermark limit */
259 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, 6*8+4, 112, 4, d.audiobuflen, 0,
260 d.low_watermark_level, HORIZONTAL);
262 snprintf(buf, sizeof(buf), "wm: %x - %x",
263 d.low_watermark_level, d.lowest_watermark_level);
264 lcd_puts(0, 7, buf);
266 lcd_update();
268 return false;
270 #endif /* !SIMULATOR */
271 #else /* CONFIG_CODEC == SWCODEC */
272 extern size_t filebuflen;
273 /* This is a size_t, but call it a long so it puts a - when it's bad. */
275 static unsigned int ticks, boost_ticks;
277 static void dbg_audio_task(void)
279 #ifndef SIMULATOR
280 if(FREQ > CPUFREQ_NORMAL)
281 boost_ticks++;
282 #endif
284 ticks++;
287 static bool dbg_buffering_thread(void)
289 char buf[32];
290 int button;
291 int line;
292 bool done = false;
293 size_t bufused;
294 size_t bufsize = pcmbuf_get_bufsize();
295 int pcmbufdescs = pcmbuf_descs();
296 struct buffering_debug d;
298 ticks = boost_ticks = 0;
300 tick_add_task(dbg_audio_task);
302 lcd_setmargins(0, 0);
303 lcd_setfont(FONT_SYSFIXED);
304 while(!done)
306 button = get_action(CONTEXT_STD,HZ/5);
307 switch(button)
309 case ACTION_STD_NEXT:
310 audio_next();
311 break;
312 case ACTION_STD_PREV:
313 audio_prev();
314 break;
315 case ACTION_STD_CANCEL:
316 done = true;
317 break;
320 buffering_get_debugdata(&d);
322 line = 0;
323 lcd_clear_display();
325 bufused = bufsize - pcmbuf_free();
327 snprintf(buf, sizeof(buf), "pcm: %7ld/%7ld", (long) bufused, (long) bufsize);
328 lcd_puts(0, line++, buf);
330 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6,
331 bufsize, 0, bufused, HORIZONTAL);
332 line++;
334 snprintf(buf, sizeof(buf), "alloc: %8ld/%8ld", audio_filebufused(),
335 (long) filebuflen);
336 lcd_puts(0, line++, buf);
338 #if LCD_HEIGHT > 80
339 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6,
340 filebuflen, 0, audio_filebufused(), HORIZONTAL);
341 line++;
343 snprintf(buf, sizeof(buf), "real: %8ld/%8ld", (long)d.buffered_data,
344 (long)filebuflen);
345 lcd_puts(0, line++, buf);
347 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6,
348 filebuflen, 0, (long)d.buffered_data, HORIZONTAL);
349 line++;
350 #endif
352 snprintf(buf, sizeof(buf), "usefl: %8ld/%8ld", (long)(d.useful_data),
353 (long)filebuflen);
354 lcd_puts(0, line++, buf);
356 #if LCD_HEIGHT > 80
357 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6,
358 filebuflen, 0, d.useful_data, HORIZONTAL);
359 line++;
360 #endif
362 snprintf(buf, sizeof(buf), "data_rem: %ld", (long)d.data_rem);
363 lcd_puts(0, line++, buf);
365 snprintf(buf, sizeof(buf), "track count: %2d", audio_track_count());
366 lcd_puts(0, line++, buf);
368 snprintf(buf, sizeof(buf), "handle count: %d", (int)d.num_handles);
369 lcd_puts(0, line++, buf);
371 #ifndef SIMULATOR
372 snprintf(buf, sizeof(buf), "cpu freq: %3dMHz",
373 (int)((FREQ + 500000) / 1000000));
374 lcd_puts(0, line++, buf);
375 #endif
377 if (ticks > 0)
379 snprintf(buf, sizeof(buf), "boost ratio: %3d%%",
380 boost_ticks * 100 / ticks);
381 lcd_puts(0, line++, buf);
384 snprintf(buf, sizeof(buf), "pcmbufdesc: %2d/%2d",
385 pcmbuf_used_descs(), pcmbufdescs);
386 lcd_puts(0, line++, buf);
388 lcd_update();
391 tick_remove_task(dbg_audio_task);
393 return false;
395 #endif /* CONFIG_CODEC */
396 #endif /* HAVE_LCD_BITMAP */
399 #if (CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE))
400 /* Tool function to read the flash manufacturer and type, if available.
401 Only chips which could be reprogrammed in system will return values.
402 (The mode switch addresses vary between flash manufacturers, hence addr1/2) */
403 /* In IRAM to avoid problems when running directly from Flash */
404 static bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
405 unsigned addr1, unsigned addr2)
406 ICODE_ATTR __attribute__((noinline));
407 static bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
408 unsigned addr1, unsigned addr2)
411 unsigned not_manu, not_id; /* read values before switching to ID mode */
412 unsigned manu, id; /* read values when in ID mode */
414 #if CONFIG_CPU == SH7034
415 volatile unsigned char* flash = (unsigned char*)0x2000000; /* flash mapping */
416 #elif defined(CPU_COLDFIRE)
417 volatile unsigned short* flash = (unsigned short*)0; /* flash mapping */
418 #endif
419 int old_level; /* saved interrupt level */
421 not_manu = flash[0]; /* read the normal content */
422 not_id = flash[1]; /* should be 'A' (0x41) and 'R' (0x52) from the "ARCH" marker */
424 /* disable interrupts, prevent any stray flash access */
425 old_level = set_irq_level(HIGHEST_IRQ_LEVEL);
427 flash[addr1] = 0xAA; /* enter command mode */
428 flash[addr2] = 0x55;
429 flash[addr1] = 0x90; /* ID command */
430 /* Atmel wants 20ms pause here */
431 /* sleep(HZ/50); no sleeping possible while interrupts are disabled */
433 manu = flash[0]; /* read the IDs */
434 id = flash[1];
436 flash[0] = 0xF0; /* reset flash (back to normal read mode) */
437 /* Atmel wants 20ms pause here */
438 /* sleep(HZ/50); no sleeping possible while interrupts are disabled */
440 set_irq_level(old_level); /* enable interrupts again */
442 /* I assume success if the obtained values are different from
443 the normal flash content. This is not perfectly bulletproof, they
444 could theoretically be the same by chance, causing us to fail. */
445 if (not_manu != manu || not_id != id) /* a value has changed */
447 *p_manufacturer = manu; /* return the results */
448 *p_device = id;
449 return true; /* success */
451 return false; /* fail */
453 #endif /* (CONFIG_CPU == SH7034 || CPU_COLDFIRE) */
455 #ifndef SIMULATOR
456 #ifdef CPU_PP
457 static int perfcheck(void)
459 int result;
461 asm (
462 "mrs r2, CPSR \n"
463 "orr r0, r2, #0xc0 \n" /* disable IRQ and FIQ */
464 "msr CPSR_c, r0 \n"
465 "mov %[res], #0 \n"
466 "ldr r0, [%[timr]] \n"
467 "add r0, r0, %[tmo] \n"
468 "1: \n"
469 "add %[res], %[res], #1 \n"
470 "ldr r1, [%[timr]] \n"
471 "cmp r1, r0 \n"
472 "bmi 1b \n"
473 "msr CPSR_c, r2 \n" /* reset IRQ and FIQ state */
475 [res]"=&r"(result)
477 [timr]"r"(&USEC_TIMER),
478 [tmo]"r"(
479 #if CONFIG_CPU == PP5002
480 16000
481 #else /* PP5020/5022/5024 */
482 10226
483 #endif
486 "r0", "r1", "r2"
488 return result;
490 #endif
492 #ifdef HAVE_LCD_BITMAP
493 static bool dbg_hw_info(void)
495 #if CONFIG_CPU == SH7034
496 char buf[32];
497 int bitmask = HW_MASK;
498 int rom_version = ROM_VERSION;
499 unsigned manu, id; /* flash IDs */
500 bool got_id; /* flag if we managed to get the flash IDs */
501 unsigned rom_crc = 0xffffffff; /* CRC32 of the boot ROM */
502 bool has_bootrom; /* flag for boot ROM present */
503 int oldmode; /* saved memory guard mode */
505 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
507 /* get flash ROM type */
508 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
509 if (!got_id)
510 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
512 /* check if the boot ROM area is a flash mirror */
513 has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0);
514 if (has_bootrom) /* if ROM and Flash different */
516 /* calculate CRC16 checksum of boot ROM */
517 rom_crc = crc_32((unsigned char*)0x0000, 64*1024, 0xffffffff);
520 system_memory_guard(oldmode); /* re-enable memory guard */
522 lcd_setmargins(0, 0);
523 lcd_setfont(FONT_SYSFIXED);
524 lcd_clear_display();
526 lcd_puts(0, 0, "[Hardware info]");
528 snprintf(buf, 32, "ROM: %d.%02d", rom_version/100, rom_version%100);
529 lcd_puts(0, 1, buf);
531 snprintf(buf, 32, "Mask: 0x%04x", bitmask);
532 lcd_puts(0, 2, buf);
534 if (got_id)
535 snprintf(buf, 32, "Flash: M=%02x D=%02x", manu, id);
536 else
537 snprintf(buf, 32, "Flash: M=?? D=??"); /* unknown, sorry */
538 lcd_puts(0, 3, buf);
540 if (has_bootrom)
542 if (rom_crc == 0x56DBA4EE) /* known Version 1 */
543 snprintf(buf, 32, "Boot ROM: V1");
544 else
545 snprintf(buf, 32, "ROMcrc: 0x%08x", rom_crc);
547 else
549 snprintf(buf, 32, "Boot ROM: none");
551 lcd_puts(0, 4, buf);
553 lcd_update();
555 while (!(action_userabort(TIMEOUT_BLOCK)));
557 #elif CONFIG_CPU == MCF5249 || CONFIG_CPU == MCF5250
558 char buf[32];
559 unsigned manu, id; /* flash IDs */
560 int got_id; /* flag if we managed to get the flash IDs */
561 int oldmode; /* saved memory guard mode */
562 int line = 0;
564 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
566 /* get flash ROM type */
567 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
568 if (!got_id)
569 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
571 system_memory_guard(oldmode); /* re-enable memory guard */
573 lcd_setmargins(0, 0);
574 lcd_setfont(FONT_SYSFIXED);
575 lcd_clear_display();
577 lcd_puts(0, line++, "[Hardware info]");
579 if (got_id)
580 snprintf(buf, 32, "Flash: M=%04x D=%04x", manu, id);
581 else
582 snprintf(buf, 32, "Flash: M=???? D=????"); /* unknown, sorry */
583 lcd_puts(0, line++, buf);
585 #ifdef IAUDIO_X5
587 struct ds2411_id id;
589 lcd_puts(0, ++line, "Serial Number:");
591 got_id = ds2411_read_id(&id);
593 if (got_id == DS2411_OK)
595 snprintf(buf, 32, " FC=%02x", (unsigned)id.family_code);
596 lcd_puts(0, ++line, buf);
597 snprintf(buf, 32, " ID=%02X %02X %02X %02X %02X %02X",
598 (unsigned)id.uid[0], (unsigned)id.uid[1], (unsigned)id.uid[2],
599 (unsigned)id.uid[3], (unsigned)id.uid[4], (unsigned)id.uid[5]);
600 lcd_puts(0, ++line, buf);
601 snprintf(buf, 32, " CRC=%02X", (unsigned)id.crc);
603 else
605 snprintf(buf, 32, "READ ERR=%d", got_id);
608 lcd_puts(0, ++line, buf);
610 #endif
612 lcd_update();
614 while (!(action_userabort(TIMEOUT_BLOCK)));
616 #elif defined(CPU_PP502x)
617 int line = 0;
618 char buf[32];
619 char pp_version[] = { (PP_VER2 >> 24) & 0xff, (PP_VER2 >> 16) & 0xff,
620 (PP_VER2 >> 8) & 0xff, (PP_VER2) & 0xff,
621 (PP_VER1 >> 24) & 0xff, (PP_VER1 >> 16) & 0xff,
622 (PP_VER1 >> 8) & 0xff, (PP_VER1) & 0xff, '\0' };
624 lcd_setmargins(0, 0);
625 lcd_setfont(FONT_SYSFIXED);
626 lcd_clear_display();
628 lcd_puts(0, line++, "[Hardware info]");
630 #ifdef IPOD_ARCH
631 snprintf(buf, sizeof(buf), "HW rev: 0x%08lx", IPOD_HW_REVISION);
632 lcd_puts(0, line++, buf);
633 #endif
635 #ifdef IPOD_COLOR
636 extern int lcd_type; /* Defined in lcd-colornano.c */
638 snprintf(buf, sizeof(buf), "LCD type: %d", lcd_type);
639 lcd_puts(0, line++, buf);
640 #endif
642 snprintf(buf, sizeof(buf), "PP version: %s", pp_version);
643 lcd_puts(0, line++, buf);
645 snprintf(buf, sizeof(buf), "Est. clock (kHz): %d", perfcheck());
646 lcd_puts(0, line++, buf);
648 lcd_update();
650 while (!(action_userabort(TIMEOUT_BLOCK)));
652 #elif CONFIG_CPU == PP5002
653 int line = 0;
654 char buf[32];
655 char pp_version[] = { (PP_VER4 >> 8) & 0xff, PP_VER4 & 0xff,
656 (PP_VER3 >> 8) & 0xff, PP_VER3 & 0xff,
657 (PP_VER2 >> 8) & 0xff, PP_VER2 & 0xff,
658 (PP_VER1 >> 8) & 0xff, PP_VER1 & 0xff, '\0' };
661 lcd_setmargins(0, 0);
662 lcd_setfont(FONT_SYSFIXED);
663 lcd_clear_display();
665 lcd_puts(0, line++, "[Hardware info]");
667 #ifdef IPOD_ARCH
668 snprintf(buf, sizeof(buf), "HW rev: 0x%08lx", IPOD_HW_REVISION);
669 lcd_puts(0, line++, buf);
670 #endif
672 snprintf(buf, sizeof(buf), "PP version: %s", pp_version);
673 lcd_puts(0, line++, buf);
675 snprintf(buf, sizeof(buf), "Est. clock (kHz): %d", perfcheck());
676 lcd_puts(0, line++, buf);
678 lcd_update();
680 while (!(action_userabort(TIMEOUT_BLOCK)));
681 #else
682 /* Define this function in your target tree */
683 return __dbg_hw_info();
684 #endif /* CONFIG_CPU */
685 return false;
687 #else /* !HAVE_LCD_BITMAP */
688 static bool dbg_hw_info(void)
690 char buf[32];
691 int button;
692 int currval = 0;
693 int rom_version = ROM_VERSION;
694 unsigned manu, id; /* flash IDs */
695 bool got_id; /* flag if we managed to get the flash IDs */
696 unsigned rom_crc = 0xffffffff; /* CRC32 of the boot ROM */
697 bool has_bootrom; /* flag for boot ROM present */
698 int oldmode; /* saved memory guard mode */
700 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
702 /* get flash ROM type */
703 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
704 if (!got_id)
705 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
707 /* check if the boot ROM area is a flash mirror */
708 has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0);
709 if (has_bootrom) /* if ROM and Flash different */
711 /* calculate CRC16 checksum of boot ROM */
712 rom_crc = crc_32((unsigned char*)0x0000, 64*1024, 0xffffffff);
715 system_memory_guard(oldmode); /* re-enable memory guard */
717 lcd_clear_display();
719 lcd_puts(0, 0, "[HW Info]");
720 while(1)
722 switch(currval)
724 case 0:
725 snprintf(buf, 32, "ROM: %d.%02d",
726 rom_version/100, rom_version%100);
727 break;
728 case 1:
729 if (got_id)
730 snprintf(buf, 32, "Flash:%02x,%02x", manu, id);
731 else
732 snprintf(buf, 32, "Flash:??,??"); /* unknown, sorry */
733 break;
734 case 2:
735 if (has_bootrom)
737 if (rom_crc == 0x56DBA4EE) /* known Version 1 */
738 snprintf(buf, 32, "BootROM: V1");
739 else if (rom_crc == 0x358099E8)
740 snprintf(buf, 32, "BootROM: V2");
741 /* alternative boot ROM found in one single player so far */
742 else
743 snprintf(buf, 32, "R: %08x", rom_crc);
745 else
746 snprintf(buf, 32, "BootROM: no");
749 lcd_puts(0, 1, buf);
750 lcd_update();
752 button = get_action(CONTEXT_SETTINGS,TIMEOUT_BLOCK);
754 switch(button)
756 case ACTION_STD_CANCEL:
757 return false;
759 case ACTION_SETTINGS_DEC:
760 currval--;
761 if(currval < 0)
762 currval = 2;
763 break;
765 case ACTION_SETTINGS_INC:
766 currval++;
767 if(currval > 2)
768 currval = 0;
769 break;
772 return false;
774 #endif /* !HAVE_LCD_BITMAP */
775 #endif /* !SIMULATOR */
777 #ifndef SIMULATOR
778 static char* dbg_partitions_getname(int selected_item, void * data, char *buffer)
780 (void)data;
781 int partition = selected_item/2;
782 struct partinfo* p = disk_partinfo(partition);
783 if (selected_item%2)
785 snprintf(buffer, MAX_PATH, " T:%x %ld MB", p->type, p->size / 2048);
787 else
789 snprintf(buffer, MAX_PATH, "P%d: S:%lx", partition, p->start);
791 return buffer;
794 bool dbg_partitions(void)
796 struct simplelist_info info;
797 simplelist_info_init(&info, "Partition Info", 4, NULL);
798 info.selection_size = 2;
799 info.hide_selection = true;
800 info.get_name = dbg_partitions_getname;
801 return simplelist_show_list(&info);
803 #endif
805 #if defined(CPU_COLDFIRE) && defined(HAVE_SPDIF_OUT)
806 static bool dbg_spdif(void)
808 char buf[128];
809 int line;
810 unsigned int control;
811 int x;
812 char *s;
813 int category;
814 int generation;
815 unsigned int interruptstat;
816 bool valnogood, symbolerr, parityerr;
817 bool done = false;
818 bool spdif_src_on;
819 int spdif_source = spdif_get_output_source(&spdif_src_on);
820 spdif_set_output_source(AUDIO_SRC_SPDIF IF_SPDIF_POWER_(, true));
822 lcd_setmargins(0, 0);
823 lcd_clear_display();
824 lcd_setfont(FONT_SYSFIXED);
826 #ifdef HAVE_SPDIF_POWER
827 spdif_power_enable(true); /* We need SPDIF power for both sending & receiving */
828 #endif
830 while (!done)
832 line = 0;
834 control = EBU1RCVCCHANNEL1;
835 interruptstat = INTERRUPTSTAT;
836 INTERRUPTCLEAR = 0x03c00000;
838 valnogood = (interruptstat & 0x01000000)?true:false;
839 symbolerr = (interruptstat & 0x00800000)?true:false;
840 parityerr = (interruptstat & 0x00400000)?true:false;
842 snprintf(buf, sizeof(buf), "Val: %s Sym: %s Par: %s",
843 valnogood?"--":"OK",
844 symbolerr?"--":"OK",
845 parityerr?"--":"OK");
846 lcd_puts(0, line++, buf);
848 snprintf(buf, sizeof(buf), "Status word: %08x", (int)control);
849 lcd_puts(0, line++, buf);
851 line++;
853 x = control >> 31;
854 snprintf(buf, sizeof(buf), "PRO: %d (%s)",
855 x, x?"Professional":"Consumer");
856 lcd_puts(0, line++, buf);
858 x = (control >> 30) & 1;
859 snprintf(buf, sizeof(buf), "Audio: %d (%s)",
860 x, x?"Non-PCM":"PCM");
861 lcd_puts(0, line++, buf);
863 x = (control >> 29) & 1;
864 snprintf(buf, sizeof(buf), "Copy: %d (%s)",
865 x, x?"Permitted":"Inhibited");
866 lcd_puts(0, line++, buf);
868 x = (control >> 27) & 7;
869 switch(x)
871 case 0:
872 s = "None";
873 break;
874 case 1:
875 s = "50/15us";
876 break;
877 default:
878 s = "Reserved";
879 break;
881 snprintf(buf, sizeof(buf), "Preemphasis: %d (%s)", x, s);
882 lcd_puts(0, line++, buf);
884 x = (control >> 24) & 3;
885 snprintf(buf, sizeof(buf), "Mode: %d", x);
886 lcd_puts(0, line++, buf);
888 category = (control >> 17) & 127;
889 switch(category)
891 case 0x00:
892 s = "General";
893 break;
894 case 0x40:
895 s = "Audio CD";
896 break;
897 default:
898 s = "Unknown";
900 snprintf(buf, sizeof(buf), "Category: 0x%02x (%s)", category, s);
901 lcd_puts(0, line++, buf);
903 x = (control >> 16) & 1;
904 generation = x;
905 if(((category & 0x70) == 0x10) ||
906 ((category & 0x70) == 0x40) ||
907 ((category & 0x78) == 0x38))
909 generation = !generation;
911 snprintf(buf, sizeof(buf), "Generation: %d (%s)",
912 x, generation?"Original":"No ind.");
913 lcd_puts(0, line++, buf);
915 x = (control >> 12) & 15;
916 snprintf(buf, sizeof(buf), "Source: %d", x);
917 lcd_puts(0, line++, buf);
919 x = (control >> 8) & 15;
920 switch(x)
922 case 0:
923 s = "Unspecified";
924 break;
925 case 8:
926 s = "A (Left)";
927 break;
928 case 4:
929 s = "B (Right)";
930 break;
931 default:
932 s = "";
933 break;
935 snprintf(buf, sizeof(buf), "Channel: %d (%s)", x, s);
936 lcd_puts(0, line++, buf);
938 x = (control >> 4) & 15;
939 switch(x)
941 case 0:
942 s = "44.1kHz";
943 break;
944 case 0x4:
945 s = "48kHz";
946 break;
947 case 0xc:
948 s = "32kHz";
949 break;
951 snprintf(buf, sizeof(buf), "Frequency: %d (%s)", x, s);
952 lcd_puts(0, line++, buf);
954 x = (control >> 2) & 3;
955 snprintf(buf, sizeof(buf), "Clock accuracy: %d", x);
956 lcd_puts(0, line++, buf);
957 line++;
959 #ifndef SIMULATOR
960 snprintf(buf, sizeof(buf), "Measured freq: %ldHz",
961 spdif_measure_frequency());
962 lcd_puts(0, line++, buf);
963 #endif
965 lcd_update();
967 if (action_userabort(HZ/10))
968 break;
971 spdif_set_output_source(spdif_source IF_SPDIF_POWER_(, spdif_src_on));
973 #ifdef HAVE_SPDIF_POWER
974 spdif_power_enable(global_settings.spdif_enable);
975 #endif
977 return false;
979 #endif /* CPU_COLDFIRE */
981 #ifndef SIMULATOR
982 #ifdef HAVE_LCD_BITMAP
983 /* button definitions */
984 #if (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
985 (CONFIG_KEYPAD == IRIVER_H300_PAD)
986 # define DEBUG_CANCEL BUTTON_OFF
988 #elif CONFIG_KEYPAD == RECORDER_PAD
989 # define DEBUG_CANCEL BUTTON_OFF
991 #elif CONFIG_KEYPAD == ONDIO_PAD
992 # define DEBUG_CANCEL BUTTON_MENU
994 #elif (CONFIG_KEYPAD == IPOD_1G2G_PAD) || \
995 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
996 (CONFIG_KEYPAD == IPOD_4G_PAD)
997 # define DEBUG_CANCEL BUTTON_MENU
999 #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
1000 # define DEBUG_CANCEL BUTTON_PLAY
1002 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
1003 # define DEBUG_CANCEL BUTTON_REC
1005 #elif (CONFIG_KEYPAD == IAUDIO_M3_PAD)
1006 # define DEBUG_CANCEL BUTTON_RC_REC
1008 #elif (CONFIG_KEYPAD == IRIVER_H10_PAD)
1009 # define DEBUG_CANCEL BUTTON_REW
1011 #elif (CONFIG_KEYPAD == MROBE100_PAD)
1012 # define DEBUG_CANCEL BUTTON_MENU
1014 #elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \
1015 (CONFIG_KEYPAD == SANSA_C200_PAD)
1016 # define DEBUG_CANCEL BUTTON_LEFT
1017 #endif /* key definitions */
1019 /* Test code!!! */
1020 bool dbg_ports(void)
1022 #if CONFIG_CPU == SH7034
1023 char buf[32];
1024 int adc_battery_voltage, adc_battery_level;
1026 lcd_setfont(FONT_SYSFIXED);
1027 lcd_setmargins(0, 0);
1028 lcd_clear_display();
1030 while(1)
1032 snprintf(buf, 32, "PADR: %04x", (unsigned short)PADR);
1033 lcd_puts(0, 0, buf);
1034 snprintf(buf, 32, "PBDR: %04x", (unsigned short)PBDR);
1035 lcd_puts(0, 1, buf);
1037 snprintf(buf, 32, "AN0: %03x AN4: %03x", adc_read(0), adc_read(4));
1038 lcd_puts(0, 2, buf);
1039 snprintf(buf, 32, "AN1: %03x AN5: %03x", adc_read(1), adc_read(5));
1040 lcd_puts(0, 3, buf);
1041 snprintf(buf, 32, "AN2: %03x AN6: %03x", adc_read(2), adc_read(6));
1042 lcd_puts(0, 4, buf);
1043 snprintf(buf, 32, "AN3: %03x AN7: %03x", adc_read(3), adc_read(7));
1044 lcd_puts(0, 5, buf);
1046 battery_read_info(&adc_battery_voltage, &adc_battery_level);
1047 snprintf(buf, 32, "Batt: %d.%03dV %d%% ", adc_battery_voltage / 1000,
1048 adc_battery_voltage % 1000, adc_battery_level);
1049 lcd_puts(0, 6, buf);
1051 lcd_update();
1052 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1053 return false;
1055 #elif defined(CPU_COLDFIRE)
1056 unsigned int gpio_out;
1057 unsigned int gpio1_out;
1058 unsigned int gpio_read;
1059 unsigned int gpio1_read;
1060 unsigned int gpio_function;
1061 unsigned int gpio1_function;
1062 unsigned int gpio_enable;
1063 unsigned int gpio1_enable;
1064 int adc_buttons, adc_remote;
1065 int adc_battery_voltage, adc_battery_level;
1066 char buf[128];
1067 int line;
1069 lcd_setmargins(0, 0);
1070 lcd_clear_display();
1071 lcd_setfont(FONT_SYSFIXED);
1073 while(1)
1075 line = 0;
1076 gpio_read = GPIO_READ;
1077 gpio1_read = GPIO1_READ;
1078 gpio_out = GPIO_OUT;
1079 gpio1_out = GPIO1_OUT;
1080 gpio_function = GPIO_FUNCTION;
1081 gpio1_function = GPIO1_FUNCTION;
1082 gpio_enable = GPIO_ENABLE;
1083 gpio1_enable = GPIO1_ENABLE;
1085 snprintf(buf, sizeof(buf), "GPIO_READ: %08x", gpio_read);
1086 lcd_puts(0, line++, buf);
1087 snprintf(buf, sizeof(buf), "GPIO_OUT: %08x", gpio_out);
1088 lcd_puts(0, line++, buf);
1089 snprintf(buf, sizeof(buf), "GPIO_FUNC: %08x", gpio_function);
1090 lcd_puts(0, line++, buf);
1091 snprintf(buf, sizeof(buf), "GPIO_ENA: %08x", gpio_enable);
1092 lcd_puts(0, line++, buf);
1094 snprintf(buf, sizeof(buf), "GPIO1_READ: %08x", gpio1_read);
1095 lcd_puts(0, line++, buf);
1096 snprintf(buf, sizeof(buf), "GPIO1_OUT: %08x", gpio1_out);
1097 lcd_puts(0, line++, buf);
1098 snprintf(buf, sizeof(buf), "GPIO1_FUNC: %08x", gpio1_function);
1099 lcd_puts(0, line++, buf);
1100 snprintf(buf, sizeof(buf), "GPIO1_ENA: %08x", gpio1_enable);
1101 lcd_puts(0, line++, buf);
1103 adc_buttons = adc_read(ADC_BUTTONS);
1104 adc_remote = adc_read(ADC_REMOTE);
1105 battery_read_info(&adc_battery_voltage, &adc_battery_level);
1106 #if defined(IAUDIO_X5) || defined(IAUDIO_M5) || defined(IRIVER_H300_SERIES)
1107 snprintf(buf, sizeof(buf), "ADC_BUTTONS (%c): %02x",
1108 button_scan_enabled() ? '+' : '-', adc_buttons);
1109 #else
1110 snprintf(buf, sizeof(buf), "ADC_BUTTONS: %02x", adc_buttons);
1111 #endif
1112 lcd_puts(0, line++, buf);
1113 #if defined(IAUDIO_X5) || defined(IAUDIO_M5)
1114 snprintf(buf, sizeof(buf), "ADC_REMOTE (%c): %02x",
1115 remote_detect() ? '+' : '-', adc_remote);
1116 #else
1117 snprintf(buf, sizeof(buf), "ADC_REMOTE: %02x", adc_remote);
1118 #endif
1119 lcd_puts(0, line++, buf);
1120 #if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES)
1121 snprintf(buf, sizeof(buf), "ADC_REMOTEDETECT: %02x",
1122 adc_read(ADC_REMOTEDETECT));
1123 lcd_puts(0, line++, buf);
1124 #endif
1126 snprintf(buf, 32, "Batt: %d.%03dV %d%% ", adc_battery_voltage / 1000,
1127 adc_battery_voltage % 1000, adc_battery_level);
1128 lcd_puts(0, line++, buf);
1130 #if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES)
1131 snprintf(buf, sizeof(buf), "remotetype: %d", remote_type());
1132 lcd_puts(0, line++, buf);
1133 #endif
1135 lcd_update();
1136 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1137 return false;
1140 #elif defined(CPU_PP502x)
1142 char buf[128];
1143 int line;
1145 lcd_setmargins(0, 0);
1146 lcd_clear_display();
1147 lcd_setfont(FONT_SYSFIXED);
1149 while(1)
1151 line = 0;
1152 lcd_puts(0, line++, "GPIO STATES:");
1153 snprintf(buf, sizeof(buf), "A: %02x E: %02x I: %02x",
1154 (unsigned int)GPIOA_INPUT_VAL,
1155 (unsigned int)GPIOE_INPUT_VAL,
1156 (unsigned int)GPIOI_INPUT_VAL);
1157 lcd_puts(0, line++, buf);
1158 snprintf(buf, sizeof(buf), "B: %02x F: %02x J: %02x",
1159 (unsigned int)GPIOB_INPUT_VAL,
1160 (unsigned int)GPIOF_INPUT_VAL,
1161 (unsigned int)GPIOJ_INPUT_VAL);
1162 lcd_puts(0, line++, buf);
1163 snprintf(buf, sizeof(buf), "C: %02x G: %02x K: %02x",
1164 (unsigned int)GPIOC_INPUT_VAL,
1165 (unsigned int)GPIOG_INPUT_VAL,
1166 (unsigned int)GPIOK_INPUT_VAL);
1167 lcd_puts(0, line++, buf);
1168 snprintf(buf, sizeof(buf), "D: %02x H: %02x L: %02x",
1169 (unsigned int)GPIOD_INPUT_VAL,
1170 (unsigned int)GPIOH_INPUT_VAL,
1171 (unsigned int)GPIOL_INPUT_VAL);
1172 lcd_puts(0, line++, buf);
1173 line++;
1174 snprintf(buf, sizeof(buf), "GPO32_VAL: %08lx", GPO32_VAL);
1175 lcd_puts(0, line++, buf);
1176 snprintf(buf, sizeof(buf), "GPO32_EN: %08lx", GPO32_ENABLE);
1177 lcd_puts(0, line++, buf);
1178 snprintf(buf, sizeof(buf), "DEV_EN: %08lx", DEV_EN);
1179 lcd_puts(0, line++, buf);
1180 snprintf(buf, sizeof(buf), "DEV_EN2: %08lx", DEV_EN2);
1181 lcd_puts(0, line++, buf);
1182 snprintf(buf, sizeof(buf), "DEV_EN3: %08lx", inl(0x60006044));
1183 lcd_puts(0, line++, buf); /* to be verified */
1184 snprintf(buf, sizeof(buf), "DEV_INIT1: %08lx", DEV_INIT1);
1185 lcd_puts(0, line++, buf);
1186 snprintf(buf, sizeof(buf), "DEV_INIT2: %08lx", DEV_INIT2);
1187 lcd_puts(0, line++, buf);
1189 #if defined(IRIVER_H10) || defined(IRIVER_H10_5GB)
1190 line++;
1191 snprintf(buf, sizeof(buf), "BATT: %03x UNK1: %03x",
1192 adc_read(ADC_BATTERY), adc_read(ADC_UNKNOWN_1));
1193 lcd_puts(0, line++, buf);
1194 snprintf(buf, sizeof(buf), "REM: %03x PAD: %03x",
1195 adc_read(ADC_REMOTE), adc_read(ADC_SCROLLPAD));
1196 lcd_puts(0, line++, buf);
1197 #elif defined(SANSA_E200)
1198 snprintf(buf, sizeof(buf), "ADC_BVDD: %4d", adc_read(ADC_BVDD));
1199 lcd_puts(0, line++, buf);
1200 snprintf(buf, sizeof(buf), "ADC_RTCSUP: %4d", adc_read(ADC_RTCSUP));
1201 lcd_puts(0, line++, buf);
1202 snprintf(buf, sizeof(buf), "ADC_UVDD: %4d", adc_read(ADC_UVDD));
1203 lcd_puts(0, line++, buf);
1204 snprintf(buf, sizeof(buf), "ADC_CHG_IN: %4d", adc_read(ADC_CHG_IN));
1205 lcd_puts(0, line++, buf);
1206 snprintf(buf, sizeof(buf), "ADC_CVDD: %4d", adc_read(ADC_CVDD));
1207 lcd_puts(0, line++, buf);
1208 snprintf(buf, sizeof(buf), "ADC_BATTEMP: %4d", adc_read(ADC_BATTEMP));
1209 lcd_puts(0, line++, buf);
1210 snprintf(buf, sizeof(buf), "ADC_MICSUP1: %4d", adc_read(ADC_MICSUP1));
1211 lcd_puts(0, line++, buf);
1212 snprintf(buf, sizeof(buf), "ADC_MICSUP2: %4d", adc_read(ADC_MICSUP2));
1213 lcd_puts(0, line++, buf);
1214 snprintf(buf, sizeof(buf), "ADC_VBE1: %4d", adc_read(ADC_VBE1));
1215 lcd_puts(0, line++, buf);
1216 snprintf(buf, sizeof(buf), "ADC_VBE2: %4d", adc_read(ADC_VBE2));
1217 lcd_puts(0, line++, buf);
1218 snprintf(buf, sizeof(buf), "ADC_I_MICSUP1:%4d", adc_read(ADC_I_MICSUP1));
1219 lcd_puts(0, line++, buf);
1220 snprintf(buf, sizeof(buf), "ADC_I_MICSUP2:%4d", adc_read(ADC_I_MICSUP2));
1221 lcd_puts(0, line++, buf);
1222 snprintf(buf, sizeof(buf), "ADC_VBAT: %4d", adc_read(ADC_VBAT));
1223 lcd_puts(0, line++, buf);
1224 snprintf(buf, sizeof(buf), "CHARGER: %02X/%02X", i2c_readbyte(AS3514_I2C_ADDR, CHRGR), i2c_readbyte(AS3514_I2C_ADDR, IRQ_ENRD0));
1225 lcd_puts(0, line++, buf);
1226 #endif
1227 lcd_update();
1228 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1229 return false;
1232 #elif CONFIG_CPU == PP5002
1233 char buf[128];
1234 int line;
1236 lcd_setmargins(0, 0);
1237 lcd_clear_display();
1238 lcd_setfont(FONT_SYSFIXED);
1240 while(1)
1242 line = 0;
1243 snprintf(buf, sizeof(buf), "GPIO_A: %02x GPIO_B: %02x",
1244 (unsigned int)GPIOA_INPUT_VAL, (unsigned int)GPIOB_INPUT_VAL);
1245 lcd_puts(0, line++, buf);
1246 snprintf(buf, sizeof(buf), "GPIO_C: %02x GPIO_D: %02x",
1247 (unsigned int)GPIOC_INPUT_VAL, (unsigned int)GPIOD_INPUT_VAL);
1248 lcd_puts(0, line++, buf);
1250 snprintf(buf, sizeof(buf), "DEV_EN: %08lx", DEV_EN);
1251 lcd_puts(0, line++, buf);
1252 snprintf(buf, sizeof(buf), "CLOCK_ENABLE: %08lx", CLOCK_ENABLE);
1253 lcd_puts(0, line++, buf);
1254 snprintf(buf, sizeof(buf), "CLOCK_SOURCE: %08lx", CLOCK_SOURCE);
1255 lcd_puts(0, line++, buf);
1256 snprintf(buf, sizeof(buf), "PLL_CONTROL: %08lx", PLL_CONTROL);
1257 lcd_puts(0, line++, buf);
1258 snprintf(buf, sizeof(buf), "PLL_DIV: %08lx", PLL_DIV);
1259 lcd_puts(0, line++, buf);
1260 snprintf(buf, sizeof(buf), "PLL_MULT: %08lx", PLL_MULT);
1261 lcd_puts(0, line++, buf);
1262 snprintf(buf, sizeof(buf), "TIMING1_CTL: %08lx", TIMING1_CTL);
1263 lcd_puts(0, line++, buf);
1264 snprintf(buf, sizeof(buf), "TIMING2_CTL: %08lx", TIMING2_CTL);
1265 lcd_puts(0, line++, buf);
1267 lcd_update();
1268 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1269 return false;
1271 #else
1272 return __dbg_ports();
1273 #endif /* CPU */
1274 return false;
1276 #else /* !HAVE_LCD_BITMAP */
1277 bool dbg_ports(void)
1279 char buf[32];
1280 int button;
1281 int adc_battery_voltage;
1282 int currval = 0;
1284 lcd_clear_display();
1286 while(1)
1288 switch(currval)
1290 case 0:
1291 snprintf(buf, 32, "PADR: %04x", (unsigned short)PADR);
1292 break;
1293 case 1:
1294 snprintf(buf, 32, "PBDR: %04x", (unsigned short)PBDR);
1295 break;
1296 case 2:
1297 snprintf(buf, 32, "AN0: %03x", adc_read(0));
1298 break;
1299 case 3:
1300 snprintf(buf, 32, "AN1: %03x", adc_read(1));
1301 break;
1302 case 4:
1303 snprintf(buf, 32, "AN2: %03x", adc_read(2));
1304 break;
1305 case 5:
1306 snprintf(buf, 32, "AN3: %03x", adc_read(3));
1307 break;
1308 case 6:
1309 snprintf(buf, 32, "AN4: %03x", adc_read(4));
1310 break;
1311 case 7:
1312 snprintf(buf, 32, "AN5: %03x", adc_read(5));
1313 break;
1314 case 8:
1315 snprintf(buf, 32, "AN6: %03x", adc_read(6));
1316 break;
1317 case 9:
1318 snprintf(buf, 32, "AN7: %03x", adc_read(7));
1319 break;
1320 break;
1322 lcd_puts(0, 0, buf);
1324 battery_read_info(&adc_battery_voltage, NULL);
1325 snprintf(buf, 32, "Batt: %d.%03dV", adc_battery_voltage / 1000,
1326 adc_battery_voltage % 1000);
1327 lcd_puts(0, 1, buf);
1328 lcd_update();
1330 button = get_action(CONTEXT_SETTINGS,HZ/5);
1332 switch(button)
1334 case ACTION_STD_CANCEL:
1335 return false;
1337 case ACTION_SETTINGS_DEC:
1338 currval--;
1339 if(currval < 0)
1340 currval = 9;
1341 break;
1343 case ACTION_SETTINGS_INC:
1344 currval++;
1345 if(currval > 9)
1346 currval = 0;
1347 break;
1350 return false;
1352 #endif /* !HAVE_LCD_BITMAP */
1353 #endif /* !SIMULATOR */
1355 #if (CONFIG_RTC == RTC_PCF50605) && !defined(SIMULATOR)
1356 static bool dbg_pcf(void)
1358 char buf[128];
1359 int line;
1361 #ifdef HAVE_LCD_BITMAP
1362 lcd_setmargins(0, 0);
1363 lcd_setfont(FONT_SYSFIXED);
1364 #endif
1365 lcd_clear_display();
1367 while(1)
1369 line = 0;
1371 snprintf(buf, sizeof(buf), "DCDC1: %02x", pcf50605_read(0x1b));
1372 lcd_puts(0, line++, buf);
1373 snprintf(buf, sizeof(buf), "DCDC2: %02x", pcf50605_read(0x1c));
1374 lcd_puts(0, line++, buf);
1375 snprintf(buf, sizeof(buf), "DCDC3: %02x", pcf50605_read(0x1d));
1376 lcd_puts(0, line++, buf);
1377 snprintf(buf, sizeof(buf), "DCDC4: %02x", pcf50605_read(0x1e));
1378 lcd_puts(0, line++, buf);
1379 snprintf(buf, sizeof(buf), "DCDEC1: %02x", pcf50605_read(0x1f));
1380 lcd_puts(0, line++, buf);
1381 snprintf(buf, sizeof(buf), "DCDEC2: %02x", pcf50605_read(0x20));
1382 lcd_puts(0, line++, buf);
1383 snprintf(buf, sizeof(buf), "DCUDC1: %02x", pcf50605_read(0x21));
1384 lcd_puts(0, line++, buf);
1385 snprintf(buf, sizeof(buf), "DCUDC2: %02x", pcf50605_read(0x22));
1386 lcd_puts(0, line++, buf);
1387 snprintf(buf, sizeof(buf), "IOREGC: %02x", pcf50605_read(0x23));
1388 lcd_puts(0, line++, buf);
1389 snprintf(buf, sizeof(buf), "D1REGC: %02x", pcf50605_read(0x24));
1390 lcd_puts(0, line++, buf);
1391 snprintf(buf, sizeof(buf), "D2REGC: %02x", pcf50605_read(0x25));
1392 lcd_puts(0, line++, buf);
1393 snprintf(buf, sizeof(buf), "D3REGC: %02x", pcf50605_read(0x26));
1394 lcd_puts(0, line++, buf);
1395 snprintf(buf, sizeof(buf), "LPREG1: %02x", pcf50605_read(0x27));
1396 lcd_puts(0, line++, buf);
1398 lcd_update();
1399 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1401 return false;
1405 return false;
1407 #endif
1409 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
1410 static bool dbg_cpufreq(void)
1412 char buf[128];
1413 int line;
1414 int button;
1416 #ifdef HAVE_LCD_BITMAP
1417 lcd_setmargins(0, 0);
1418 lcd_setfont(FONT_SYSFIXED);
1419 #endif
1420 lcd_clear_display();
1422 while(1)
1424 line = 0;
1426 snprintf(buf, sizeof(buf), "Frequency: %ld", FREQ);
1427 lcd_puts(0, line++, buf);
1429 snprintf(buf, sizeof(buf), "boost_counter: %d", get_cpu_boost_counter());
1430 lcd_puts(0, line++, buf);
1432 lcd_update();
1433 button = get_action(CONTEXT_STD,HZ/10);
1435 switch(button)
1437 case ACTION_STD_PREV:
1438 cpu_boost(true);
1439 break;
1441 case ACTION_STD_NEXT:
1442 cpu_boost(false);
1443 break;
1445 case ACTION_STD_OK:
1446 while (get_cpu_boost_counter() > 0)
1447 cpu_boost(false);
1448 set_cpu_frequency(CPUFREQ_DEFAULT);
1449 break;
1451 case ACTION_STD_CANCEL:
1452 return false;
1456 return false;
1458 #endif /* HAVE_ADJUSTABLE_CPU_FREQ */
1460 #if defined(HAVE_TSC2100) && !defined(SIMULATOR)
1461 #include "tsc2100.h"
1462 char *itob(int n, int len)
1464 static char binary[64];
1465 int i,j;
1466 for (i=1, j=0;i<=len;i++)
1468 binary[j++] = n&(1<<(len-i))?'1':'0';
1469 if (i%4 == 0)
1470 binary[j++] = ' ';
1472 binary[j] = '\0';
1473 return binary;
1475 static char* tsc2100_debug_getname(int selected_item, void * data, char *buffer)
1477 int *page = (int*)data;
1478 bool reserved = false;
1479 switch (*page)
1481 case 0:
1482 if ((selected_item > 0x0a) ||
1483 (selected_item == 0x04) ||
1484 (selected_item == 0x08))
1485 reserved = true;
1486 break;
1487 case 1:
1488 if ((selected_item > 0x05) ||
1489 (selected_item == 0x02))
1490 reserved = true;
1491 break;
1492 case 2:
1493 if (selected_item > 0x1e)
1494 reserved = true;
1495 break;
1497 if (reserved)
1498 snprintf(buffer, MAX_PATH, "%02x: RESERVED", selected_item);
1499 else
1500 snprintf(buffer, MAX_PATH, "%02x: %s", selected_item,
1501 itob(tsc2100_readreg(*page, selected_item)&0xffff,16));
1502 return buffer;
1504 static int tsc2100debug_action_callback(int action, struct gui_synclist *lists)
1506 int *page = (int*)lists->data;
1507 if (action == ACTION_STD_OK)
1509 *page = (*page+1)%3;
1510 snprintf(lists->title, 32,
1511 "tsc2100 registers - Page %d", *page);
1512 return ACTION_REDRAW;
1514 return action;
1516 bool tsc2100_debug(void)
1518 int page = 0;
1519 char title[32] = "tsc2100 registers - Page 0";
1520 struct simplelist_info info;
1521 simplelist_info_init(&info, title, 32, &page);
1522 info.timeout = HZ/100;
1523 info.get_name = tsc2100_debug_getname;
1524 info.action_callback= tsc2100debug_action_callback;
1525 return simplelist_show_list(&info);
1527 #endif
1528 #ifndef SIMULATOR
1529 #ifdef HAVE_LCD_BITMAP
1531 * view_battery() shows a automatically scaled graph of the battery voltage
1532 * over time. Usable for estimating battery life / charging rate.
1533 * The power_history array is updated in power_thread of powermgmt.c.
1536 #define BAT_LAST_VAL MIN(LCD_WIDTH, POWER_HISTORY_LEN)
1537 #define BAT_YSPACE (LCD_HEIGHT - 20)
1539 static bool view_battery(void)
1541 int view = 0;
1542 int i, x, y;
1543 unsigned short maxv, minv;
1544 char buf[32];
1546 lcd_setmargins(0, 0);
1547 lcd_setfont(FONT_SYSFIXED);
1549 while(1)
1551 lcd_clear_display();
1552 switch (view) {
1553 case 0: /* voltage history graph */
1554 /* Find maximum and minimum voltage for scaling */
1555 minv = power_history[0];
1556 maxv = minv + 1;
1557 for (i = 1; i < BAT_LAST_VAL && power_history[i]; i++) {
1558 if (power_history[i] > maxv)
1559 maxv = power_history[i];
1560 if (power_history[i] < minv)
1561 minv = power_history[i];
1564 snprintf(buf, 30, "Battery %d.%03d", power_history[0] / 1000,
1565 power_history[0] % 1000);
1566 lcd_puts(0, 0, buf);
1567 snprintf(buf, 30, "scale %d.%03d-%d.%03dV",
1568 minv / 1000, minv % 1000, maxv / 1000, maxv % 1000);
1569 lcd_puts(0, 1, buf);
1571 x = 0;
1572 for (i = BAT_LAST_VAL - 1; i >= 0; i--) {
1573 y = (power_history[i] - minv) * BAT_YSPACE / (maxv - minv);
1574 lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
1575 lcd_vline(x, LCD_HEIGHT-1, 20);
1576 lcd_set_drawmode(DRMODE_SOLID);
1577 lcd_vline(x, LCD_HEIGHT-1,
1578 MIN(MAX(LCD_HEIGHT-1 - y, 20), LCD_HEIGHT-1));
1579 x++;
1582 break;
1584 case 1: /* status: */
1585 lcd_puts(0, 0, "Power status:");
1587 battery_read_info(&y, NULL);
1588 snprintf(buf, 30, "Battery: %d.%03d V", y / 1000, y % 1000);
1589 lcd_puts(0, 1, buf);
1590 #ifdef ADC_EXT_POWER
1591 y = (adc_read(ADC_EXT_POWER) * EXT_SCALE_FACTOR) / 1000;
1592 snprintf(buf, 30, "External: %d.%03d V", y / 1000, y % 1000);
1593 lcd_puts(0, 2, buf);
1594 #endif
1595 #if CONFIG_CHARGING
1596 #if CONFIG_CHARGING == CHARGING_CONTROL
1597 snprintf(buf, 30, "Chgr: %s %s",
1598 charger_inserted() ? "present" : "absent",
1599 charger_enabled ? "on" : "off");
1600 lcd_puts(0, 3, buf);
1601 snprintf(buf, 30, "short delta: %d", short_delta);
1602 lcd_puts(0, 5, buf);
1603 snprintf(buf, 30, "long delta: %d", long_delta);
1604 lcd_puts(0, 6, buf);
1605 lcd_puts(0, 7, power_message);
1606 snprintf(buf, 30, "USB Inserted: %s",
1607 usb_inserted() ? "yes" : "no");
1608 lcd_puts(0, 8, buf);
1609 #if defined IRIVER_H300_SERIES
1610 snprintf(buf, 30, "USB Charging Enabled: %s",
1611 usb_charging_enabled() ? "yes" : "no");
1612 lcd_puts(0, 9, buf);
1613 #endif
1614 #else /* CONFIG_CHARGING != CHARGING_CONTROL */
1615 #if defined IPOD_NANO || defined IPOD_VIDEO
1616 int usb_pwr = (GPIOL_INPUT_VAL & 0x10)?true:false;
1617 int ext_pwr = (GPIOL_INPUT_VAL & 0x08)?false:true;
1618 int dock = (GPIOA_INPUT_VAL & 0x10)?true:false;
1619 int charging = (GPIOB_INPUT_VAL & 0x01)?false:true;
1620 int headphone= (GPIOA_INPUT_VAL & 0x80)?true:false;
1622 snprintf(buf, 30, "USB pwr: %s",
1623 usb_pwr ? "present" : "absent");
1624 lcd_puts(0, 3, buf);
1625 snprintf(buf, 30, "EXT pwr: %s",
1626 ext_pwr ? "present" : "absent");
1627 lcd_puts(0, 4, buf);
1628 snprintf(buf, 30, "Battery: %s",
1629 charging ? "charging" : (usb_pwr||ext_pwr) ? "charged" : "discharging");
1630 lcd_puts(0, 5, buf);
1631 snprintf(buf, 30, "Dock mode: %s",
1632 dock ? "enabled" : "disabled");
1633 lcd_puts(0, 6, buf);
1634 snprintf(buf, 30, "Headphone: %s",
1635 headphone ? "connected" : "disconnected");
1636 lcd_puts(0, 7, buf);
1637 #else
1638 snprintf(buf, 30, "Charger: %s",
1639 charger_inserted() ? "present" : "absent");
1640 lcd_puts(0, 3, buf);
1641 #endif
1642 #endif /* CONFIG_CHARGING != CHARGING_CONTROL */
1643 #endif /* CONFIG_CHARGING */
1644 break;
1646 case 2: /* voltage deltas: */
1647 lcd_puts(0, 0, "Voltage deltas:");
1649 for (i = 0; i <= 6; i++) {
1650 y = power_history[i] - power_history[i+1];
1651 snprintf(buf, 30, "-%d min: %s%d.%03d V", i,
1652 (y < 0) ? "-" : "", ((y < 0) ? y * -1 : y) / 1000,
1653 ((y < 0) ? y * -1 : y ) % 1000);
1654 lcd_puts(0, i+1, buf);
1656 break;
1658 case 3: /* remaining time estimation: */
1660 #if CONFIG_CHARGING == CHARGING_CONTROL
1661 snprintf(buf, 30, "charge_state: %d", charge_state);
1662 lcd_puts(0, 0, buf);
1664 snprintf(buf, 30, "Cycle time: %d m", powermgmt_last_cycle_startstop_min);
1665 lcd_puts(0, 1, buf);
1667 snprintf(buf, 30, "Lvl@cyc st: %d%%", powermgmt_last_cycle_level);
1668 lcd_puts(0, 2, buf);
1670 snprintf(buf, 30, "P=%2d I=%2d", pid_p, pid_i);
1671 lcd_puts(0, 3, buf);
1673 snprintf(buf, 30, "Trickle sec: %d/60", trickle_sec);
1674 lcd_puts(0, 4, buf);
1675 #endif /* CONFIG_CHARGING == CHARGING_CONTROL */
1677 snprintf(buf, 30, "Last PwrHist: %d.%03dV",
1678 power_history[0] / 1000,
1679 power_history[0] % 1000);
1680 lcd_puts(0, 5, buf);
1682 snprintf(buf, 30, "battery level: %d%%", battery_level());
1683 lcd_puts(0, 6, buf);
1685 snprintf(buf, 30, "Est. remain: %d m", battery_time());
1686 lcd_puts(0, 7, buf);
1687 break;
1690 lcd_update();
1692 switch(get_action(CONTEXT_SETTINGS,HZ/2))
1694 case ACTION_SETTINGS_DEC:
1695 if (view)
1696 view--;
1697 break;
1699 case ACTION_SETTINGS_INC:
1700 if (view < 3)
1701 view++;
1702 break;
1704 case ACTION_STD_CANCEL:
1705 return false;
1708 return false;
1711 #endif /* HAVE_LCD_BITMAP */
1712 #endif
1714 #ifndef SIMULATOR
1715 #if defined(HAVE_MMC) || defined(HAVE_HOTSWAP)
1716 #if defined(HAVE_MMC)
1717 #define CARDTYPE "MMC"
1718 #else
1719 #define CARDTYPE "microSD"
1720 #endif
1721 static int disk_callback(int btn, struct gui_synclist *lists)
1723 tCardInfo *card;
1724 int *cardnum = (int*)lists->data;
1725 unsigned char card_name[7];
1726 unsigned char pbuf[32];
1727 char *title = lists->title;
1728 static const unsigned char i_vmin[] = { 0, 1, 5, 10, 25, 35, 60, 100 };
1729 static const unsigned char i_vmax[] = { 1, 5, 10, 25, 35, 45, 80, 200 };
1730 static const unsigned char *kbit_units[] = { "kBit/s", "MBit/s", "GBit/s" };
1731 static const unsigned char *nsec_units[] = { "ns", "�s", "ms" };
1732 static const char *spec_vers[] = { "1.0-1.2", "1.4", "2.0-2.2",
1733 "3.1-3.31", "4.0" };
1734 if ((btn == ACTION_STD_OK) || (btn == SYS_FS_CHANGED) || (btn == ACTION_REDRAW))
1736 if (btn == ACTION_STD_OK)
1738 *cardnum ^= 0x1; /* change cards */
1741 simplelist_set_line_count(0);
1743 card = card_get_info(*cardnum);
1745 if (card->initialized > 0)
1747 card_name[6] = '\0';
1748 strncpy(card_name, ((unsigned char*)card->cid) + 3, 6);
1749 simplelist_addline(SIMPLELIST_ADD_LINE,
1750 "%s Rev %d.%d", card_name,
1751 (int) card_extract_bits(card->cid, 72, 4),
1752 (int) card_extract_bits(card->cid, 76, 4));
1753 simplelist_addline(SIMPLELIST_ADD_LINE,
1754 "Prod: %d/%d",
1755 (int) card_extract_bits(card->cid, 112, 4),
1756 (int) card_extract_bits(card->cid, 116, 4) + 1997);
1757 simplelist_addline(SIMPLELIST_ADD_LINE,
1758 "Ser#: 0x%08lx",
1759 card_extract_bits(card->cid, 80, 32));
1760 simplelist_addline(SIMPLELIST_ADD_LINE,
1761 "M=%02x, O=%04x",
1762 (int) card_extract_bits(card->cid, 0, 8),
1763 (int) card_extract_bits(card->cid, 8, 16));
1764 int temp = card_extract_bits(card->csd, 2, 4);
1765 simplelist_addline(SIMPLELIST_ADD_LINE,
1766 CARDTYPE " v%s", temp < 5 ?
1767 spec_vers[temp] : "?.?");
1768 simplelist_addline(SIMPLELIST_ADD_LINE,
1769 "Blocks: 0x%06lx", card->numblocks);
1770 simplelist_addline(SIMPLELIST_ADD_LINE,
1771 "Blksz.: %d P:%c%c", card->blocksize,
1772 card_extract_bits(card->csd, 48, 1) ? 'R' : '-',
1773 card_extract_bits(card->csd, 106, 1) ? 'W' : '-');
1774 output_dyn_value(pbuf, sizeof pbuf, card->speed / 1000,
1775 kbit_units, false);
1776 simplelist_addline(SIMPLELIST_ADD_LINE,
1777 "Speed: %s", pbuf);
1778 output_dyn_value(pbuf, sizeof pbuf, card->tsac,
1779 nsec_units, false);
1780 simplelist_addline(SIMPLELIST_ADD_LINE,
1781 "Tsac: %s", pbuf);
1782 simplelist_addline(SIMPLELIST_ADD_LINE,
1783 "Nsac: %d clk", card->nsac);
1784 simplelist_addline(SIMPLELIST_ADD_LINE,
1785 "R2W: *%d", card->r2w_factor);
1786 simplelist_addline(SIMPLELIST_ADD_LINE,
1787 "IRmax: %d..%d mA",
1788 i_vmin[card_extract_bits(card->csd, 66, 3)],
1789 i_vmax[card_extract_bits(card->csd, 69, 3)]);
1790 simplelist_addline(SIMPLELIST_ADD_LINE,
1791 "IWmax: %d..%d mA",
1792 i_vmin[card_extract_bits(card->csd, 72, 3)],
1793 i_vmax[card_extract_bits(card->csd, 75, 3)]);
1795 else if (card->initialized == 0)
1797 simplelist_addline(SIMPLELIST_ADD_LINE, "Not Found!");
1799 #ifndef HAVE_MMC
1800 else /* card->initialized < 0 */
1802 simplelist_addline(SIMPLELIST_ADD_LINE, "Init Error! (%d)", card->initialized);
1804 #endif
1805 snprintf(title, 16, "[" CARDTYPE " %d]", *cardnum);
1806 gui_synclist_set_title(lists, title, Icon_NOICON);
1807 gui_synclist_set_nb_items(lists, simplelist_get_line_count());
1808 gui_synclist_select_item(lists, 0);
1809 btn = ACTION_REDRAW;
1811 return btn;
1813 #else /* !defined(HAVE_MMC) && !defined(HAVE_HOTSWAP) */
1814 static int disk_callback(int btn, struct gui_synclist *lists)
1816 (void)lists;
1817 int i;
1818 char buf[128];
1819 unsigned short* identify_info = ata_get_identify();
1820 bool timing_info_present = false;
1821 (void)btn;
1823 simplelist_set_line_count(0);
1825 for (i=0; i < 20; i++)
1826 ((unsigned short*)buf)[i]=htobe16(identify_info[i+27]);
1827 buf[40]=0;
1828 /* kill trailing space */
1829 for (i=39; i && buf[i]==' '; i--)
1830 buf[i] = 0;
1831 simplelist_addline(SIMPLELIST_ADD_LINE, "Model: %s", buf);
1832 for (i=0; i < 4; i++)
1833 ((unsigned short*)buf)[i]=htobe16(identify_info[i+23]);
1834 buf[8]=0;
1835 simplelist_addline(SIMPLELIST_ADD_LINE,
1836 "Firmware: %s", buf);
1837 snprintf(buf, sizeof buf, "%ld MB",
1838 ((unsigned long)identify_info[61] << 16 |
1839 (unsigned long)identify_info[60]) / 2048 );
1840 simplelist_addline(SIMPLELIST_ADD_LINE,
1841 "Size: %s", buf);
1842 unsigned long free;
1843 fat_size( IF_MV2(0,) NULL, &free );
1844 simplelist_addline(SIMPLELIST_ADD_LINE,
1845 "Free: %ld MB", free / 1024);
1846 simplelist_addline(SIMPLELIST_ADD_LINE,
1847 "Spinup time: %d ms", ata_spinup_time * (1000/HZ));
1848 i = identify_info[83] & (1<<3);
1849 simplelist_addline(SIMPLELIST_ADD_LINE,
1850 "Power mgmt: %s", i ? "enabled" : "unsupported");
1851 i = identify_info[83] & (1<<9);
1852 simplelist_addline(SIMPLELIST_ADD_LINE,
1853 "Noise mgmt: %s", i ? "enabled" : "unsupported");
1854 i = identify_info[82] & (1<<6);
1855 simplelist_addline(SIMPLELIST_ADD_LINE,
1856 "Read-ahead: %s", i ? "enabled" : "unsupported");
1857 timing_info_present = identify_info[53] & (1<<1);
1858 if(timing_info_present) {
1859 char pio3[2], pio4[2];pio3[1] = 0;
1860 pio4[1] = 0;
1861 pio3[0] = (identify_info[64] & (1<<0)) ? '3' : 0;
1862 pio4[0] = (identify_info[64] & (1<<1)) ? '4' : 0;
1863 simplelist_addline(SIMPLELIST_ADD_LINE,
1864 "PIO modes: 0 1 2 %s %s", pio3, pio4);
1866 else {
1867 simplelist_addline(SIMPLELIST_ADD_LINE,
1868 "No PIO mode info");
1870 timing_info_present = identify_info[53] & (1<<1);
1871 if(timing_info_present) {
1872 simplelist_addline(SIMPLELIST_ADD_LINE,
1873 "Cycle times %dns/%dns",
1874 identify_info[67],
1875 identify_info[68] );
1876 } else {
1877 simplelist_addline(SIMPLELIST_ADD_LINE,
1878 "No timing info");
1880 timing_info_present = identify_info[53] & (1<<1);
1881 if(timing_info_present) {
1882 i = identify_info[49] & (1<<11);
1883 simplelist_addline(SIMPLELIST_ADD_LINE,
1884 "IORDY support: %s", i ? "yes" : "no");
1885 i = identify_info[49] & (1<<10);
1886 simplelist_addline(SIMPLELIST_ADD_LINE,
1887 "IORDY disable: %s", i ? "yes" : "no");
1888 } else {
1889 simplelist_addline(SIMPLELIST_ADD_LINE,
1890 "No timing info");
1892 simplelist_addline(SIMPLELIST_ADD_LINE,
1893 "Cluster size: %d bytes", fat_get_cluster_size(IF_MV(0)));
1894 return btn;
1897 static bool dbg_identify_info(void)
1899 int fd = creat("/identify_info.bin");
1900 if(fd >= 0)
1902 #ifdef ROCKBOX_LITTLE_ENDIAN
1903 ecwrite(fd, ata_get_identify(), SECTOR_SIZE/2, "s", true);
1904 #else
1905 write(fd, ata_get_identify(), SECTOR_SIZE);
1906 #endif
1907 close(fd);
1909 return false;
1911 #endif /* !defined(HAVE_MMC) && !defined(HAVE_HOTSWAP) */
1912 static bool dbg_disk_info(void)
1914 struct simplelist_info info;
1915 simplelist_info_init(&info, "Disk Info", 1, NULL);
1916 #if defined(HAVE_MMC) || defined(HAVE_HOTSWAP)
1917 char title[16];
1918 int card = 0;
1919 info.callback_data = (void*)&card;
1920 info.title = title;
1921 #endif
1922 info.action_callback = disk_callback;
1923 info.hide_selection = true;
1924 return simplelist_show_list(&info);
1926 #endif /* !SIMULATOR */
1928 #ifdef HAVE_DIRCACHE
1929 static int dircache_callback(int btn, struct gui_synclist *lists)
1931 (void)btn; (void)lists;
1932 simplelist_set_line_count(0);
1933 simplelist_addline(SIMPLELIST_ADD_LINE, "Cache initialized: %s",
1934 dircache_is_enabled() ? "Yes" : "No");
1935 simplelist_addline(SIMPLELIST_ADD_LINE, "Cache size: %d B",
1936 dircache_get_cache_size());
1937 simplelist_addline(SIMPLELIST_ADD_LINE, "Last size: %d B",
1938 global_status.dircache_size);
1939 simplelist_addline(SIMPLELIST_ADD_LINE, "Limit: %d B",
1940 DIRCACHE_LIMIT);
1941 simplelist_addline(SIMPLELIST_ADD_LINE, "Reserve: %d/%d B",
1942 dircache_get_reserve_used(), DIRCACHE_RESERVE);
1943 simplelist_addline(SIMPLELIST_ADD_LINE, "Scanning took: %d s",
1944 dircache_get_build_ticks() / HZ);
1945 simplelist_addline(SIMPLELIST_ADD_LINE, "Entry count: %d",
1946 dircache_get_entry_count());
1947 return btn;
1950 static bool dbg_dircache_info(void)
1952 struct simplelist_info info;
1953 simplelist_info_init(&info, "Dircache Info", 7, NULL);
1954 info.action_callback = dircache_callback;
1955 info.hide_selection = true;
1956 return simplelist_show_list(&info);
1959 #endif /* HAVE_DIRCACHE */
1961 #ifdef HAVE_TAGCACHE
1962 static int database_callback(int btn, struct gui_synclist *lists)
1964 (void)lists;
1965 struct tagcache_stat *stat = tagcache_get_stat();
1966 static bool synced = false;
1968 simplelist_set_line_count(0);
1970 simplelist_addline(SIMPLELIST_ADD_LINE, "Initialized: %s",
1971 stat->initialized ? "Yes" : "No");
1972 simplelist_addline(SIMPLELIST_ADD_LINE, "DB Ready: %s",
1973 stat->ready ? "Yes" : "No");
1974 simplelist_addline(SIMPLELIST_ADD_LINE, "RAM Cache: %s",
1975 stat->ramcache ? "Yes" : "No");
1976 simplelist_addline(SIMPLELIST_ADD_LINE, "RAM: %d/%d B",
1977 stat->ramcache_used, stat->ramcache_allocated);
1978 simplelist_addline(SIMPLELIST_ADD_LINE, "Progress: %d%% (%d entries)",
1979 stat->progress, stat->processed_entries);
1980 simplelist_addline(SIMPLELIST_ADD_LINE, "Curfile: %s",
1981 stat->curentry ? stat->curentry : "---");
1982 simplelist_addline(SIMPLELIST_ADD_LINE, "Commit step: %d",
1983 stat->commit_step);
1984 simplelist_addline(SIMPLELIST_ADD_LINE, "Commit delayed: %s",
1985 stat->commit_delayed ? "Yes" : "No");
1987 simplelist_addline(SIMPLELIST_ADD_LINE, "Queue length: %d",
1988 stat->queue_length);
1990 if (synced)
1992 synced = false;
1993 tagcache_screensync_event();
1996 if (!btn && stat->curentry)
1998 synced = true;
1999 return ACTION_REDRAW;
2002 if (btn == ACTION_STD_CANCEL)
2003 tagcache_screensync_enable(false);
2005 return btn;
2007 static bool dbg_tagcache_info(void)
2009 struct simplelist_info info;
2010 simplelist_info_init(&info, "Database Info", 8, NULL);
2011 info.action_callback = database_callback;
2012 info.hide_selection = true;
2014 /* Don't do nonblock here, must give enough processing time
2015 for tagcache thread. */
2016 /* info.timeout = TIMEOUT_NOBLOCK; */
2017 info.timeout = 1;
2018 tagcache_screensync_enable(true);
2019 return simplelist_show_list(&info);
2021 #endif
2023 #if CONFIG_CPU == SH7034
2024 static bool dbg_save_roms(void)
2026 int fd;
2027 int oldmode = system_memory_guard(MEMGUARD_NONE);
2029 fd = creat("/internal_rom_0000-FFFF.bin");
2030 if(fd >= 0)
2032 write(fd, (void *)0, 0x10000);
2033 close(fd);
2036 fd = creat("/internal_rom_2000000-203FFFF.bin");
2037 if(fd >= 0)
2039 write(fd, (void *)0x2000000, 0x40000);
2040 close(fd);
2043 system_memory_guard(oldmode);
2044 return false;
2046 #elif defined CPU_COLDFIRE
2047 static bool dbg_save_roms(void)
2049 int fd;
2050 int oldmode = system_memory_guard(MEMGUARD_NONE);
2052 #if defined(IRIVER_H100_SERIES)
2053 fd = creat("/internal_rom_000000-1FFFFF.bin");
2054 #elif defined(IRIVER_H300_SERIES)
2055 fd = creat("/internal_rom_000000-3FFFFF.bin");
2056 #elif defined(IAUDIO_X5) || defined(IAUDIO_M5) || defined(IAUDIO_M3)
2057 fd = creat("/internal_rom_000000-3FFFFF.bin");
2058 #endif
2059 if(fd >= 0)
2061 write(fd, (void *)0, FLASH_SIZE);
2062 close(fd);
2064 system_memory_guard(oldmode);
2066 #ifdef HAVE_EEPROM
2067 fd = creat("/internal_eeprom.bin");
2068 if (fd >= 0)
2070 int old_irq_level;
2071 char buf[EEPROM_SIZE];
2072 int err;
2074 old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL);
2076 err = eeprom_24cxx_read(0, buf, sizeof buf);
2077 if (err)
2078 gui_syncsplash(HZ*3, "Eeprom read failure (%d)",err);
2079 else
2081 write(fd, buf, sizeof buf);
2084 set_irq_level(old_irq_level);
2086 close(fd);
2088 #endif
2090 return false;
2092 #elif defined(CPU_PP) && !(defined(SANSA_E200) || defined(SANSA_C200))
2093 static bool dbg_save_roms(void)
2095 int fd;
2097 fd = creat("/internal_rom_000000-0FFFFF.bin");
2098 if(fd >= 0)
2100 write(fd, (void *)0x20000000, FLASH_SIZE);
2101 close(fd);
2104 return false;
2106 #endif /* CPU */
2108 #ifndef SIMULATOR
2109 #if CONFIG_TUNER
2110 static int radio_callback(int btn, struct gui_synclist *lists)
2112 (void)lists;
2113 if (btn == ACTION_STD_CANCEL)
2114 return btn;
2115 simplelist_set_line_count(1);
2117 #if (CONFIG_TUNER & LV24020LP)
2118 simplelist_addline(SIMPLELIST_ADD_LINE,
2119 "CTRL_STAT: %02X", lv24020lp_get(LV24020LP_CTRL_STAT) );
2120 simplelist_addline(SIMPLELIST_ADD_LINE,
2121 "RADIO_STAT: %02X", lv24020lp_get(LV24020LP_REG_STAT) );
2122 simplelist_addline(SIMPLELIST_ADD_LINE,
2123 "MSS_FM: %d kHz", lv24020lp_get(LV24020LP_MSS_FM) );
2124 simplelist_addline(SIMPLELIST_ADD_LINE,
2125 "MSS_IF: %d Hz", lv24020lp_get(LV24020LP_MSS_IF) );
2126 simplelist_addline(SIMPLELIST_ADD_LINE,
2127 "MSS_SD: %d Hz", lv24020lp_get(LV24020LP_MSS_SD) );
2128 simplelist_addline(SIMPLELIST_ADD_LINE,
2129 "if_set: %d Hz", lv24020lp_get(LV24020LP_IF_SET) );
2130 simplelist_addline(SIMPLELIST_ADD_LINE,
2131 "sd_set: %d Hz", lv24020lp_get(LV24020LP_SD_SET) );
2132 #endif
2133 #if (CONFIG_TUNER & S1A0903X01)
2134 simplelist_addline(SIMPLELIST_ADD_LINE,
2135 "Samsung regs: %08X", s1a0903x01_get(RADIO_ALL));
2136 /* This one doesn't return dynamic data atm */
2137 #endif
2138 #if (CONFIG_TUNER & TEA5767)
2139 struct tea5767_dbg_info nfo;
2140 tea5767_dbg_info(&nfo);
2141 simplelist_addline(SIMPLELIST_ADD_LINE, "Philips regs:");
2142 simplelist_addline(SIMPLELIST_ADD_LINE,
2143 " Read: %02X %02X %02X %02X %02X",
2144 (unsigned)nfo.read_regs[0], (unsigned)nfo.read_regs[1],
2145 (unsigned)nfo.read_regs[2], (unsigned)nfo.read_regs[3],
2146 (unsigned)nfo.read_regs[4]);
2147 simplelist_addline(SIMPLELIST_ADD_LINE,
2148 " Write: %02X %02X %02X %02X %02X",
2149 (unsigned)nfo.write_regs[0], (unsigned)nfo.write_regs[1],
2150 (unsigned)nfo.write_regs[2], (unsigned)nfo.write_regs[3],
2151 (unsigned)nfo.write_regs[4]);
2152 #endif
2153 return ACTION_REDRAW;
2155 static bool dbg_fm_radio(void)
2157 struct simplelist_info info;
2158 simplelist_info_init(&info, "FM Radio", 1, NULL);
2159 simplelist_set_line_count(0);
2160 simplelist_addline(SIMPLELIST_ADD_LINE, "HW detected: %s",
2161 radio_hardware_present() ? "yes" : "no");
2163 info.action_callback = radio_hardware_present()?radio_callback : NULL;
2164 info.hide_selection = true;
2165 return simplelist_show_list(&info);
2167 #endif /* CONFIG_TUNER */
2168 #endif /* !SIMULATOR */
2170 #ifdef HAVE_LCD_BITMAP
2171 extern bool do_screendump_instead_of_usb;
2173 static bool dbg_screendump(void)
2175 do_screendump_instead_of_usb = !do_screendump_instead_of_usb;
2176 gui_syncsplash(HZ, "Screendump %s",
2177 do_screendump_instead_of_usb?"enabled":"disabled");
2178 return false;
2180 #endif /* HAVE_LCD_BITMAP */
2182 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
2183 static bool dbg_set_memory_guard(void)
2185 static const struct opt_items names[MAXMEMGUARD] = {
2186 { "None", -1 },
2187 { "Flash ROM writes", -1 },
2188 { "Zero area (all)", -1 }
2190 int mode = system_memory_guard(MEMGUARD_KEEP);
2192 set_option( "Catch mem accesses", &mode, INT, names, MAXMEMGUARD, NULL);
2193 system_memory_guard(mode);
2195 return false;
2197 #endif /* CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) */
2199 #if defined(TOSHIBA_GIGABEAT_F) && !defined(SIMULATOR)
2201 extern volatile bool lcd_poweroff;
2203 static bool dbg_lcd_power_off(void)
2205 lcd_setmargins(0, 0);
2207 while(1)
2209 int button;
2211 lcd_clear_display();
2212 lcd_puts(0, 0, "LCD Power Off");
2213 if(lcd_poweroff)
2214 lcd_puts(1, 1, "Yes");
2215 else
2216 lcd_puts(1, 1, "No");
2218 lcd_update();
2220 button = get_action(CONTEXT_STD,HZ/5);
2221 switch(button)
2223 case ACTION_STD_PREV:
2224 case ACTION_STD_NEXT:
2225 lcd_poweroff = !lcd_poweroff;
2226 break;
2227 case ACTION_STD_OK:
2228 case ACTION_STD_CANCEL:
2229 return false;
2230 default:
2231 sleep(HZ/10);
2232 break;
2235 return false;
2237 #endif
2239 #if defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS)
2240 static bool dbg_write_eeprom(void)
2242 int fd;
2243 int rc;
2244 int old_irq_level;
2245 char buf[EEPROM_SIZE];
2246 int err;
2248 fd = open("/internal_eeprom.bin", O_RDONLY);
2250 if (fd >= 0)
2252 rc = read(fd, buf, EEPROM_SIZE);
2254 if(rc == EEPROM_SIZE)
2256 old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL);
2258 err = eeprom_24cxx_write(0, buf, sizeof buf);
2259 if (err)
2260 gui_syncsplash(HZ*3, "Eeprom write failure (%d)",err);
2261 else
2262 gui_syncsplash(HZ*3, "Eeprom written successfully");
2264 set_irq_level(old_irq_level);
2266 else
2268 gui_syncsplash(HZ*3, "File read error (%d)",rc);
2270 close(fd);
2272 else
2274 gui_syncsplash(HZ*3, "Failed to open 'internal_eeprom.bin'");
2277 return false;
2279 #endif /* defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS) */
2280 #ifdef CPU_BOOST_LOGGING
2281 static bool cpu_boost_log(void)
2283 int i = 0,j=0;
2284 int count = cpu_boost_log_getcount();
2285 int lines = LCD_HEIGHT/SYSFONT_HEIGHT;
2286 char *str;
2287 bool done;
2288 lcd_setmargins(0, 0);
2289 lcd_setfont(FONT_SYSFIXED);
2290 str = cpu_boost_log_getlog_first();
2291 while (i < count)
2293 lcd_clear_display();
2294 for(j=0; j<lines; j++,i++)
2296 if (!str)
2297 str = cpu_boost_log_getlog_next();
2298 if (str)
2300 lcd_puts(0, j,str);
2302 str = NULL;
2304 lcd_update();
2305 done = false;
2306 while (!done)
2308 switch(get_action(CONTEXT_STD,TIMEOUT_BLOCK))
2310 case ACTION_STD_OK:
2311 case ACTION_STD_PREV:
2312 case ACTION_STD_NEXT:
2313 done = true;
2314 break;
2315 case ACTION_STD_CANCEL:
2316 i = count;
2317 done = true;
2318 break;
2322 get_action(CONTEXT_STD,TIMEOUT_BLOCK);
2323 lcd_setfont(FONT_UI);
2324 return false;
2326 #endif
2328 #if (defined(HAVE_SCROLLWHEEL) && (CONFIG_KEYPAD==IPOD_4G_PAD) && !defined(SIMULATOR))
2329 extern bool wheel_is_touched;
2330 extern int old_wheel_value;
2331 extern int new_wheel_value;
2332 extern int wheel_delta;
2333 extern unsigned int accumulated_wheel_delta;
2334 extern unsigned int wheel_velocity;
2336 static bool dbg_scrollwheel(void)
2338 char buf[64];
2339 unsigned int speed;
2341 lcd_setmargins(0, 0);
2342 lcd_setfont(FONT_SYSFIXED);
2344 while (1)
2346 if (action_userabort(HZ/10))
2347 return false;
2349 lcd_clear_display();
2351 /* show internal variables of scrollwheel driver */
2352 snprintf(buf, sizeof(buf), "wheel touched: %s", (wheel_is_touched) ? "true" : "false");
2353 lcd_puts(0, 0, buf);
2354 snprintf(buf, sizeof(buf), "new position: %2d", new_wheel_value);
2355 lcd_puts(0, 1, buf);
2356 snprintf(buf, sizeof(buf), "old position: %2d", old_wheel_value);
2357 lcd_puts(0, 2, buf);
2358 snprintf(buf, sizeof(buf), "wheel delta: %2d", wheel_delta);
2359 lcd_puts(0, 3, buf);
2360 snprintf(buf, sizeof(buf), "accumulated delta: %2d", accumulated_wheel_delta);
2361 lcd_puts(0, 4, buf);
2362 snprintf(buf, sizeof(buf), "velo [deg/s]: %4d", (int)wheel_velocity);
2363 lcd_puts(0, 5, buf);
2365 /* show effective accelerated scrollspeed */
2366 speed = button_apply_acceleration( (1<<31)|(1<<24)|wheel_velocity);
2367 snprintf(buf, sizeof(buf), "accel. speed: %4d", speed);
2368 lcd_puts(0, 6, buf);
2370 lcd_update();
2372 return false;
2374 #endif
2376 #if defined(HAVE_USBSTACK) && defined(ROCKBOX_HAS_LOGF) && defined(USB_SERIAL)
2377 static bool logf_usb_serial(void)
2379 bool serial_enabled = !usb_core_driver_enabled(USB_DRIVER_SERIAL);
2380 usb_core_enable_driver(USB_DRIVER_SERIAL,serial_enabled);
2381 gui_syncsplash(HZ, "USB logf %s",
2382 serial_enabled?"enabled":"disabled");
2383 return false;
2385 #endif
2387 #if defined(HAVE_USBSTACK) && defined(USB_STORAGE)
2388 static bool usb_reconnect(void)
2390 gui_syncsplash(HZ, "Reconnect mass storage");
2391 usb_storage_reconnect();
2392 return false;
2394 #endif
2397 /****** The menu *********/
2398 struct the_menu_item {
2399 unsigned char *desc; /* string or ID */
2400 bool (*function) (void); /* return true if USB was connected */
2402 static const struct the_menu_item menuitems[] = {
2403 #if defined(TOSHIBA_GIGABEAT_F) && !defined(SIMULATOR)
2404 { "LCD Power Off", dbg_lcd_power_off },
2405 #endif
2406 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || \
2407 (defined(CPU_PP) && !(defined(SANSA_E200) || defined(SANSA_C200)))
2408 { "Dump ROM contents", dbg_save_roms },
2409 #endif
2410 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || defined(CPU_PP) || CONFIG_CPU == S3C2440
2411 { "View I/O ports", dbg_ports },
2412 #endif
2413 #if (CONFIG_RTC == RTC_PCF50605) && !defined(SIMULATOR)
2414 { "View PCF registers", dbg_pcf },
2415 #endif
2416 #if defined(HAVE_TSC2100) && !defined(SIMULATOR)
2417 { "TSC2100 debug", tsc2100_debug },
2418 #endif
2419 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
2420 { "CPU frequency", dbg_cpufreq },
2421 #endif
2422 #if defined(IRIVER_H100_SERIES) && !defined(SIMULATOR)
2423 { "S/PDIF analyzer", dbg_spdif },
2424 #endif
2425 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
2426 { "Catch mem accesses", dbg_set_memory_guard },
2427 #endif
2428 { "View OS stacks", dbg_os },
2429 #ifdef HAVE_LCD_BITMAP
2430 #ifndef SIMULATOR
2431 { "View battery", view_battery },
2432 #endif
2433 { "Screendump", dbg_screendump },
2434 #endif
2435 #ifndef SIMULATOR
2436 { "View HW info", dbg_hw_info },
2437 #endif
2438 #ifndef SIMULATOR
2439 { "View partitions", dbg_partitions },
2440 #endif
2441 #ifndef SIMULATOR
2442 { "View disk info", dbg_disk_info },
2443 #if !defined(HAVE_MMC) && !defined(HAVE_HOTSWAP)
2444 { "Dump ATA identify info", dbg_identify_info},
2445 #endif
2446 #endif
2447 #ifdef HAVE_DIRCACHE
2448 { "View dircache info", dbg_dircache_info },
2449 #endif
2450 #ifdef HAVE_TAGCACHE
2451 { "View database info", dbg_tagcache_info },
2452 #endif
2453 #ifdef HAVE_LCD_BITMAP
2454 #if CONFIG_CODEC == SWCODEC
2455 { "View buffering thread", dbg_buffering_thread },
2456 #elif !defined(SIMULATOR)
2457 { "View audio thread", dbg_audio_thread },
2458 #endif
2459 #ifdef PM_DEBUG
2460 { "pm histogram", peak_meter_histogram},
2461 #endif /* PM_DEBUG */
2462 #endif /* HAVE_LCD_BITMAP */
2463 #ifndef SIMULATOR
2464 #if CONFIG_TUNER
2465 { "FM Radio", dbg_fm_radio },
2466 #endif
2467 #endif
2468 #if defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS)
2469 { "Write back EEPROM", dbg_write_eeprom },
2470 #endif
2471 #ifdef ROCKBOX_HAS_LOGF
2472 {"logf", logfdisplay },
2473 {"logfdump", logfdump },
2474 #endif
2475 #if defined(HAVE_USBSTACK) && defined(ROCKBOX_HAS_LOGF) && defined(USB_SERIAL)
2476 {"logf over usb",logf_usb_serial },
2477 #endif
2478 #if defined(HAVE_USBSTACK) && defined(USB_STORAGE)
2479 {"reconnect usb storage",usb_reconnect},
2480 #endif
2481 #ifdef CPU_BOOST_LOGGING
2482 {"cpu_boost log",cpu_boost_log},
2483 #endif
2484 #if (defined(HAVE_SCROLLWHEEL) && (CONFIG_KEYPAD==IPOD_4G_PAD) && !defined(SIMULATOR))
2485 {"Debug scrollwheel", dbg_scrollwheel},
2486 #endif
2488 static int menu_action_callback(int btn, struct gui_synclist *lists)
2490 if (btn == ACTION_STD_OK)
2492 menuitems[gui_synclist_get_sel_pos(lists)].function();
2493 btn = ACTION_REDRAW;
2495 return btn;
2497 static char* dbg_menu_getname(int item, void * data, char *buffer)
2499 (void)data; (void)buffer;
2500 return menuitems[item].desc;
2502 bool debug_menu(void)
2504 struct simplelist_info info;
2506 simplelist_info_init(&info, "Debug Menu", ARRAYLEN(menuitems), NULL);
2507 info.action_callback = menu_action_callback;
2508 info.get_name = dbg_menu_getname;
2510 return simplelist_show_list(&info);