make usb_serial work again. Also know as "make sure arrays are allocated at their...
[kugel-rb.git] / apps / debug_menu.c
blobf93755a293e521e6f56a151c1b61a1fa04b9d023
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) && defined(ROCKBOX_HAS_LOGF)
106 #include "usb_core.h"
107 #endif
109 /*---------------------------------------------------*/
110 /* SPECIAL DEBUG STUFF */
111 /*---------------------------------------------------*/
112 extern struct thread_entry threads[MAXTHREADS];
114 static char thread_status_char(unsigned status)
116 static const char thread_status_chars[THREAD_NUM_STATES+1] =
118 [0 ... THREAD_NUM_STATES] = '?',
119 [STATE_RUNNING] = 'R',
120 [STATE_BLOCKED] = 'B',
121 [STATE_SLEEPING] = 'S',
122 [STATE_BLOCKED_W_TMO] = 'T',
123 [STATE_FROZEN] = 'F',
124 [STATE_KILLED] = 'K',
127 #if NUM_CORES > 1
128 if (status == STATE_BUSY) /* Not a state index */
129 return '.';
130 #endif
132 if (status > THREAD_NUM_STATES)
133 status = THREAD_NUM_STATES;
135 return thread_status_chars[status];
138 static char* threads_getname(int selected_item, void * data, char *buffer)
140 (void)data;
141 struct thread_entry *thread;
142 char name[32];
144 #if NUM_CORES > 1
145 if (selected_item < (int)NUM_CORES)
147 snprintf(buffer, MAX_PATH, "Idle (%d): %2d%%", selected_item,
148 idle_stack_usage(selected_item));
149 return buffer;
152 selected_item -= NUM_CORES;
153 #endif
155 thread = &threads[selected_item];
157 if (thread->state == STATE_KILLED)
159 snprintf(buffer, MAX_PATH, "%2d: ---", selected_item);
160 return buffer;
163 thread_get_name(name, 32, thread);
165 snprintf(buffer, MAX_PATH,
166 "%2d: " IF_COP("(%d) ") "%c%c " IF_PRIO("%d ") "%2d%% %s",
167 selected_item,
168 IF_COP(thread->core,)
169 #ifdef HAVE_SCHEDULER_BOOSTCTRL
170 (thread->boosted) ? '+' :
171 #endif
172 ((thread->state == STATE_RUNNING) ? '*' : ' '),
173 thread_status_char(thread->state),
174 IF_PRIO(thread->priority,)
175 thread_stack_usage(thread), name);
177 return buffer;
179 static int dbg_threads_action_callback(int action, struct gui_synclist *lists)
181 (void)lists;
182 #ifdef ROCKBOX_HAS_LOGF
183 if (action == ACTION_STD_OK)
185 int selpos = gui_synclist_get_sel_pos(lists);
186 #if NUM_CORES > 1
187 if (selpos >= NUM_CORES)
188 remove_thread(&threads[selpos - NUM_CORES]);
189 #else
190 remove_thread(&threads[selpos]);
191 #endif
192 return ACTION_REDRAW;
194 #endif /* ROCKBOX_HAS_LOGF */
195 if (action == ACTION_NONE)
196 action = ACTION_REDRAW;
197 return action;
199 /* Test code!!! */
200 static bool dbg_os(void)
202 struct simplelist_info info;
203 simplelist_info_init(&info, IF_COP("Core and ") "Stack usage:",
204 #if NUM_CORES == 1
205 MAXTHREADS,
206 #else
207 MAXTHREADS+NUM_CORES,
208 #endif
209 NULL);
210 #ifndef ROCKBOX_HAS_LOGF
211 info.hide_selection = true;
212 #endif
213 info.action_callback = dbg_threads_action_callback;
214 info.get_name = threads_getname;
215 return simplelist_show_list(&info);
218 #ifdef HAVE_LCD_BITMAP
219 #if CONFIG_CODEC != SWCODEC
220 #ifndef SIMULATOR
221 static bool dbg_audio_thread(void)
223 char buf[32];
224 struct audio_debug d;
226 lcd_setmargins(0, 0);
227 lcd_setfont(FONT_SYSFIXED);
229 while(1)
231 if (action_userabort(HZ/5))
232 return false;
234 audio_get_debugdata(&d);
236 lcd_clear_display();
238 snprintf(buf, sizeof(buf), "read: %x", d.audiobuf_read);
239 lcd_puts(0, 0, buf);
240 snprintf(buf, sizeof(buf), "write: %x", d.audiobuf_write);
241 lcd_puts(0, 1, buf);
242 snprintf(buf, sizeof(buf), "swap: %x", d.audiobuf_swapwrite);
243 lcd_puts(0, 2, buf);
244 snprintf(buf, sizeof(buf), "playing: %d", d.playing);
245 lcd_puts(0, 3, buf);
246 snprintf(buf, sizeof(buf), "playable: %x", d.playable_space);
247 lcd_puts(0, 4, buf);
248 snprintf(buf, sizeof(buf), "unswapped: %x", d.unswapped_space);
249 lcd_puts(0, 5, buf);
251 /* Playable space left */
252 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, 6*8, 112, 4, d.audiobuflen, 0,
253 d.playable_space, HORIZONTAL);
255 /* Show the watermark limit */
256 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, 6*8+4, 112, 4, d.audiobuflen, 0,
257 d.low_watermark_level, HORIZONTAL);
259 snprintf(buf, sizeof(buf), "wm: %x - %x",
260 d.low_watermark_level, d.lowest_watermark_level);
261 lcd_puts(0, 7, buf);
263 lcd_update();
265 return false;
267 #endif /* !SIMULATOR */
268 #else /* CONFIG_CODEC == SWCODEC */
269 extern size_t filebuflen;
270 /* This is a size_t, but call it a long so it puts a - when it's bad. */
272 static unsigned int ticks, boost_ticks;
274 static void dbg_audio_task(void)
276 #ifndef SIMULATOR
277 if(FREQ > CPUFREQ_NORMAL)
278 boost_ticks++;
279 #endif
281 ticks++;
284 static bool dbg_buffering_thread(void)
286 char buf[32];
287 int button;
288 int line;
289 bool done = false;
290 size_t bufused;
291 size_t bufsize = pcmbuf_get_bufsize();
292 int pcmbufdescs = pcmbuf_descs();
293 struct buffering_debug d;
295 ticks = boost_ticks = 0;
297 tick_add_task(dbg_audio_task);
299 lcd_setmargins(0, 0);
300 lcd_setfont(FONT_SYSFIXED);
301 while(!done)
303 button = get_action(CONTEXT_STD,HZ/5);
304 switch(button)
306 case ACTION_STD_NEXT:
307 audio_next();
308 break;
309 case ACTION_STD_PREV:
310 audio_prev();
311 break;
312 case ACTION_STD_CANCEL:
313 done = true;
314 break;
317 buffering_get_debugdata(&d);
319 line = 0;
320 lcd_clear_display();
322 bufused = bufsize - pcmbuf_free();
324 snprintf(buf, sizeof(buf), "pcm: %7ld/%7ld", (long) bufused, (long) bufsize);
325 lcd_puts(0, line++, buf);
327 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6,
328 bufsize, 0, bufused, HORIZONTAL);
329 line++;
331 snprintf(buf, sizeof(buf), "alloc: %8ld/%8ld", audio_filebufused(),
332 (long) filebuflen);
333 lcd_puts(0, line++, buf);
335 #if LCD_HEIGHT > 80
336 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6,
337 filebuflen, 0, audio_filebufused(), HORIZONTAL);
338 line++;
340 snprintf(buf, sizeof(buf), "real: %8ld/%8ld", (long)d.buffered_data,
341 (long)filebuflen);
342 lcd_puts(0, line++, buf);
344 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6,
345 filebuflen, 0, (long)d.buffered_data, HORIZONTAL);
346 line++;
347 #endif
349 snprintf(buf, sizeof(buf), "usefl: %8ld/%8ld", (long)(d.useful_data),
350 (long)filebuflen);
351 lcd_puts(0, line++, buf);
353 #if LCD_HEIGHT > 80
354 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6,
355 filebuflen, 0, d.useful_data, HORIZONTAL);
356 line++;
357 #endif
359 snprintf(buf, sizeof(buf), "data_rem: %ld", (long)d.data_rem);
360 lcd_puts(0, line++, buf);
362 snprintf(buf, sizeof(buf), "track count: %2d", audio_track_count());
363 lcd_puts(0, line++, buf);
365 snprintf(buf, sizeof(buf), "handle count: %d", (int)d.num_handles);
366 lcd_puts(0, line++, buf);
368 #ifndef SIMULATOR
369 snprintf(buf, sizeof(buf), "cpu freq: %3dMHz",
370 (int)((FREQ + 500000) / 1000000));
371 lcd_puts(0, line++, buf);
372 #endif
374 if (ticks > 0)
376 snprintf(buf, sizeof(buf), "boost ratio: %3d%%",
377 boost_ticks * 100 / ticks);
378 lcd_puts(0, line++, buf);
381 snprintf(buf, sizeof(buf), "pcmbufdesc: %2d/%2d",
382 pcmbuf_used_descs(), pcmbufdescs);
383 lcd_puts(0, line++, buf);
385 lcd_update();
388 tick_remove_task(dbg_audio_task);
390 return false;
392 #endif /* CONFIG_CODEC */
393 #endif /* HAVE_LCD_BITMAP */
396 #if (CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE))
397 /* Tool function to read the flash manufacturer and type, if available.
398 Only chips which could be reprogrammed in system will return values.
399 (The mode switch addresses vary between flash manufacturers, hence addr1/2) */
400 /* In IRAM to avoid problems when running directly from Flash */
401 static bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
402 unsigned addr1, unsigned addr2)
403 ICODE_ATTR __attribute__((noinline));
404 static bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
405 unsigned addr1, unsigned addr2)
408 unsigned not_manu, not_id; /* read values before switching to ID mode */
409 unsigned manu, id; /* read values when in ID mode */
411 #if CONFIG_CPU == SH7034
412 volatile unsigned char* flash = (unsigned char*)0x2000000; /* flash mapping */
413 #elif defined(CPU_COLDFIRE)
414 volatile unsigned short* flash = (unsigned short*)0; /* flash mapping */
415 #endif
416 int old_level; /* saved interrupt level */
418 not_manu = flash[0]; /* read the normal content */
419 not_id = flash[1]; /* should be 'A' (0x41) and 'R' (0x52) from the "ARCH" marker */
421 /* disable interrupts, prevent any stray flash access */
422 old_level = set_irq_level(HIGHEST_IRQ_LEVEL);
424 flash[addr1] = 0xAA; /* enter command mode */
425 flash[addr2] = 0x55;
426 flash[addr1] = 0x90; /* ID command */
427 /* Atmel wants 20ms pause here */
428 /* sleep(HZ/50); no sleeping possible while interrupts are disabled */
430 manu = flash[0]; /* read the IDs */
431 id = flash[1];
433 flash[0] = 0xF0; /* reset flash (back to normal read mode) */
434 /* Atmel wants 20ms pause here */
435 /* sleep(HZ/50); no sleeping possible while interrupts are disabled */
437 set_irq_level(old_level); /* enable interrupts again */
439 /* I assume success if the obtained values are different from
440 the normal flash content. This is not perfectly bulletproof, they
441 could theoretically be the same by chance, causing us to fail. */
442 if (not_manu != manu || not_id != id) /* a value has changed */
444 *p_manufacturer = manu; /* return the results */
445 *p_device = id;
446 return true; /* success */
448 return false; /* fail */
450 #endif /* (CONFIG_CPU == SH7034 || CPU_COLDFIRE) */
452 #ifndef SIMULATOR
453 #ifdef CPU_PP
454 static int perfcheck(void)
456 int result;
458 asm (
459 "mrs r2, CPSR \n"
460 "orr r0, r2, #0xc0 \n" /* disable IRQ and FIQ */
461 "msr CPSR_c, r0 \n"
462 "mov %[res], #0 \n"
463 "ldr r0, [%[timr]] \n"
464 "add r0, r0, %[tmo] \n"
465 "1: \n"
466 "add %[res], %[res], #1 \n"
467 "ldr r1, [%[timr]] \n"
468 "cmp r1, r0 \n"
469 "bmi 1b \n"
470 "msr CPSR_c, r2 \n" /* reset IRQ and FIQ state */
472 [res]"=&r"(result)
474 [timr]"r"(&USEC_TIMER),
475 [tmo]"r"(
476 #if CONFIG_CPU == PP5002
477 16000
478 #else /* PP5020/5022/5024 */
479 10226
480 #endif
483 "r0", "r1", "r2"
485 return result;
487 #endif
489 #ifdef HAVE_LCD_BITMAP
490 static bool dbg_hw_info(void)
492 #if CONFIG_CPU == SH7034
493 char buf[32];
494 int bitmask = HW_MASK;
495 int rom_version = ROM_VERSION;
496 unsigned manu, id; /* flash IDs */
497 bool got_id; /* flag if we managed to get the flash IDs */
498 unsigned rom_crc = 0xffffffff; /* CRC32 of the boot ROM */
499 bool has_bootrom; /* flag for boot ROM present */
500 int oldmode; /* saved memory guard mode */
502 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
504 /* get flash ROM type */
505 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
506 if (!got_id)
507 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
509 /* check if the boot ROM area is a flash mirror */
510 has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0);
511 if (has_bootrom) /* if ROM and Flash different */
513 /* calculate CRC16 checksum of boot ROM */
514 rom_crc = crc_32((unsigned char*)0x0000, 64*1024, 0xffffffff);
517 system_memory_guard(oldmode); /* re-enable memory guard */
519 lcd_setmargins(0, 0);
520 lcd_setfont(FONT_SYSFIXED);
521 lcd_clear_display();
523 lcd_puts(0, 0, "[Hardware info]");
525 snprintf(buf, 32, "ROM: %d.%02d", rom_version/100, rom_version%100);
526 lcd_puts(0, 1, buf);
528 snprintf(buf, 32, "Mask: 0x%04x", bitmask);
529 lcd_puts(0, 2, buf);
531 if (got_id)
532 snprintf(buf, 32, "Flash: M=%02x D=%02x", manu, id);
533 else
534 snprintf(buf, 32, "Flash: M=?? D=??"); /* unknown, sorry */
535 lcd_puts(0, 3, buf);
537 if (has_bootrom)
539 if (rom_crc == 0x56DBA4EE) /* known Version 1 */
540 snprintf(buf, 32, "Boot ROM: V1");
541 else
542 snprintf(buf, 32, "ROMcrc: 0x%08x", rom_crc);
544 else
546 snprintf(buf, 32, "Boot ROM: none");
548 lcd_puts(0, 4, buf);
550 lcd_update();
552 while (!(action_userabort(TIMEOUT_BLOCK)));
554 #elif CONFIG_CPU == MCF5249 || CONFIG_CPU == MCF5250
555 char buf[32];
556 unsigned manu, id; /* flash IDs */
557 int got_id; /* flag if we managed to get the flash IDs */
558 int oldmode; /* saved memory guard mode */
559 int line = 0;
561 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
563 /* get flash ROM type */
564 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
565 if (!got_id)
566 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
568 system_memory_guard(oldmode); /* re-enable memory guard */
570 lcd_setmargins(0, 0);
571 lcd_setfont(FONT_SYSFIXED);
572 lcd_clear_display();
574 lcd_puts(0, line++, "[Hardware info]");
576 if (got_id)
577 snprintf(buf, 32, "Flash: M=%04x D=%04x", manu, id);
578 else
579 snprintf(buf, 32, "Flash: M=???? D=????"); /* unknown, sorry */
580 lcd_puts(0, line++, buf);
582 #ifdef IAUDIO_X5
584 struct ds2411_id id;
586 lcd_puts(0, ++line, "Serial Number:");
588 got_id = ds2411_read_id(&id);
590 if (got_id == DS2411_OK)
592 snprintf(buf, 32, " FC=%02x", (unsigned)id.family_code);
593 lcd_puts(0, ++line, buf);
594 snprintf(buf, 32, " ID=%02X %02X %02X %02X %02X %02X",
595 (unsigned)id.uid[0], (unsigned)id.uid[1], (unsigned)id.uid[2],
596 (unsigned)id.uid[3], (unsigned)id.uid[4], (unsigned)id.uid[5]);
597 lcd_puts(0, ++line, buf);
598 snprintf(buf, 32, " CRC=%02X", (unsigned)id.crc);
600 else
602 snprintf(buf, 32, "READ ERR=%d", got_id);
605 lcd_puts(0, ++line, buf);
607 #endif
609 lcd_update();
611 while (!(action_userabort(TIMEOUT_BLOCK)));
613 #elif defined(CPU_PP502x)
614 int line = 0;
615 char buf[32];
616 char pp_version[] = { (PP_VER2 >> 24) & 0xff, (PP_VER2 >> 16) & 0xff,
617 (PP_VER2 >> 8) & 0xff, (PP_VER2) & 0xff,
618 (PP_VER1 >> 24) & 0xff, (PP_VER1 >> 16) & 0xff,
619 (PP_VER1 >> 8) & 0xff, (PP_VER1) & 0xff, '\0' };
621 lcd_setmargins(0, 0);
622 lcd_setfont(FONT_SYSFIXED);
623 lcd_clear_display();
625 lcd_puts(0, line++, "[Hardware info]");
627 #ifdef IPOD_ARCH
628 snprintf(buf, sizeof(buf), "HW rev: 0x%08lx", IPOD_HW_REVISION);
629 lcd_puts(0, line++, buf);
630 #endif
632 #ifdef IPOD_COLOR
633 extern int lcd_type; /* Defined in lcd-colornano.c */
635 snprintf(buf, sizeof(buf), "LCD type: %d", lcd_type);
636 lcd_puts(0, line++, buf);
637 #endif
639 snprintf(buf, sizeof(buf), "PP version: %s", pp_version);
640 lcd_puts(0, line++, buf);
642 snprintf(buf, sizeof(buf), "Est. clock (kHz): %d", perfcheck());
643 lcd_puts(0, line++, buf);
645 lcd_update();
647 while (!(action_userabort(TIMEOUT_BLOCK)));
649 #elif CONFIG_CPU == PP5002
650 int line = 0;
651 char buf[32];
652 char pp_version[] = { (PP_VER4 >> 8) & 0xff, PP_VER4 & 0xff,
653 (PP_VER3 >> 8) & 0xff, PP_VER3 & 0xff,
654 (PP_VER2 >> 8) & 0xff, PP_VER2 & 0xff,
655 (PP_VER1 >> 8) & 0xff, PP_VER1 & 0xff, '\0' };
658 lcd_setmargins(0, 0);
659 lcd_setfont(FONT_SYSFIXED);
660 lcd_clear_display();
662 lcd_puts(0, line++, "[Hardware info]");
664 #ifdef IPOD_ARCH
665 snprintf(buf, sizeof(buf), "HW rev: 0x%08lx", IPOD_HW_REVISION);
666 lcd_puts(0, line++, buf);
667 #endif
669 snprintf(buf, sizeof(buf), "PP version: %s", pp_version);
670 lcd_puts(0, line++, buf);
672 snprintf(buf, sizeof(buf), "Est. clock (kHz): %d", perfcheck());
673 lcd_puts(0, line++, buf);
675 lcd_update();
677 while (!(action_userabort(TIMEOUT_BLOCK)));
678 #else
679 /* Define this function in your target tree */
680 return __dbg_hw_info();
681 #endif /* CONFIG_CPU */
682 return false;
684 #else /* !HAVE_LCD_BITMAP */
685 static bool dbg_hw_info(void)
687 char buf[32];
688 int button;
689 int currval = 0;
690 int rom_version = ROM_VERSION;
691 unsigned manu, id; /* flash IDs */
692 bool got_id; /* flag if we managed to get the flash IDs */
693 unsigned rom_crc = 0xffffffff; /* CRC32 of the boot ROM */
694 bool has_bootrom; /* flag for boot ROM present */
695 int oldmode; /* saved memory guard mode */
697 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
699 /* get flash ROM type */
700 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
701 if (!got_id)
702 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
704 /* check if the boot ROM area is a flash mirror */
705 has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0);
706 if (has_bootrom) /* if ROM and Flash different */
708 /* calculate CRC16 checksum of boot ROM */
709 rom_crc = crc_32((unsigned char*)0x0000, 64*1024, 0xffffffff);
712 system_memory_guard(oldmode); /* re-enable memory guard */
714 lcd_clear_display();
716 lcd_puts(0, 0, "[HW Info]");
717 while(1)
719 switch(currval)
721 case 0:
722 snprintf(buf, 32, "ROM: %d.%02d",
723 rom_version/100, rom_version%100);
724 break;
725 case 1:
726 if (got_id)
727 snprintf(buf, 32, "Flash:%02x,%02x", manu, id);
728 else
729 snprintf(buf, 32, "Flash:??,??"); /* unknown, sorry */
730 break;
731 case 2:
732 if (has_bootrom)
734 if (rom_crc == 0x56DBA4EE) /* known Version 1 */
735 snprintf(buf, 32, "BootROM: V1");
736 else if (rom_crc == 0x358099E8)
737 snprintf(buf, 32, "BootROM: V2");
738 /* alternative boot ROM found in one single player so far */
739 else
740 snprintf(buf, 32, "R: %08x", rom_crc);
742 else
743 snprintf(buf, 32, "BootROM: no");
746 lcd_puts(0, 1, buf);
747 lcd_update();
749 button = get_action(CONTEXT_SETTINGS,TIMEOUT_BLOCK);
751 switch(button)
753 case ACTION_STD_CANCEL:
754 return false;
756 case ACTION_SETTINGS_DEC:
757 currval--;
758 if(currval < 0)
759 currval = 2;
760 break;
762 case ACTION_SETTINGS_INC:
763 currval++;
764 if(currval > 2)
765 currval = 0;
766 break;
769 return false;
771 #endif /* !HAVE_LCD_BITMAP */
772 #endif /* !SIMULATOR */
774 #ifndef SIMULATOR
775 static char* dbg_partitions_getname(int selected_item, void * data, char *buffer)
777 (void)data;
778 int partition = selected_item/2;
779 struct partinfo* p = disk_partinfo(partition);
780 if (selected_item%2)
782 snprintf(buffer, MAX_PATH, " T:%x %ld MB", p->type, p->size / 2048);
784 else
786 snprintf(buffer, MAX_PATH, "P%d: S:%lx", partition, p->start);
788 return buffer;
791 bool dbg_partitions(void)
793 struct simplelist_info info;
794 simplelist_info_init(&info, "Partition Info", 4, NULL);
795 info.selection_size = 2;
796 info.hide_selection = true;
797 info.get_name = dbg_partitions_getname;
798 return simplelist_show_list(&info);
800 #endif
802 #if defined(CPU_COLDFIRE) && defined(HAVE_SPDIF_OUT)
803 static bool dbg_spdif(void)
805 char buf[128];
806 int line;
807 unsigned int control;
808 int x;
809 char *s;
810 int category;
811 int generation;
812 unsigned int interruptstat;
813 bool valnogood, symbolerr, parityerr;
814 bool done = false;
815 bool spdif_src_on;
816 int spdif_source = spdif_get_output_source(&spdif_src_on);
817 spdif_set_output_source(AUDIO_SRC_SPDIF IF_SPDIF_POWER_(, true));
819 lcd_setmargins(0, 0);
820 lcd_clear_display();
821 lcd_setfont(FONT_SYSFIXED);
823 #ifdef HAVE_SPDIF_POWER
824 spdif_power_enable(true); /* We need SPDIF power for both sending & receiving */
825 #endif
827 while (!done)
829 line = 0;
831 control = EBU1RCVCCHANNEL1;
832 interruptstat = INTERRUPTSTAT;
833 INTERRUPTCLEAR = 0x03c00000;
835 valnogood = (interruptstat & 0x01000000)?true:false;
836 symbolerr = (interruptstat & 0x00800000)?true:false;
837 parityerr = (interruptstat & 0x00400000)?true:false;
839 snprintf(buf, sizeof(buf), "Val: %s Sym: %s Par: %s",
840 valnogood?"--":"OK",
841 symbolerr?"--":"OK",
842 parityerr?"--":"OK");
843 lcd_puts(0, line++, buf);
845 snprintf(buf, sizeof(buf), "Status word: %08x", (int)control);
846 lcd_puts(0, line++, buf);
848 line++;
850 x = control >> 31;
851 snprintf(buf, sizeof(buf), "PRO: %d (%s)",
852 x, x?"Professional":"Consumer");
853 lcd_puts(0, line++, buf);
855 x = (control >> 30) & 1;
856 snprintf(buf, sizeof(buf), "Audio: %d (%s)",
857 x, x?"Non-PCM":"PCM");
858 lcd_puts(0, line++, buf);
860 x = (control >> 29) & 1;
861 snprintf(buf, sizeof(buf), "Copy: %d (%s)",
862 x, x?"Permitted":"Inhibited");
863 lcd_puts(0, line++, buf);
865 x = (control >> 27) & 7;
866 switch(x)
868 case 0:
869 s = "None";
870 break;
871 case 1:
872 s = "50/15us";
873 break;
874 default:
875 s = "Reserved";
876 break;
878 snprintf(buf, sizeof(buf), "Preemphasis: %d (%s)", x, s);
879 lcd_puts(0, line++, buf);
881 x = (control >> 24) & 3;
882 snprintf(buf, sizeof(buf), "Mode: %d", x);
883 lcd_puts(0, line++, buf);
885 category = (control >> 17) & 127;
886 switch(category)
888 case 0x00:
889 s = "General";
890 break;
891 case 0x40:
892 s = "Audio CD";
893 break;
894 default:
895 s = "Unknown";
897 snprintf(buf, sizeof(buf), "Category: 0x%02x (%s)", category, s);
898 lcd_puts(0, line++, buf);
900 x = (control >> 16) & 1;
901 generation = x;
902 if(((category & 0x70) == 0x10) ||
903 ((category & 0x70) == 0x40) ||
904 ((category & 0x78) == 0x38))
906 generation = !generation;
908 snprintf(buf, sizeof(buf), "Generation: %d (%s)",
909 x, generation?"Original":"No ind.");
910 lcd_puts(0, line++, buf);
912 x = (control >> 12) & 15;
913 snprintf(buf, sizeof(buf), "Source: %d", x);
914 lcd_puts(0, line++, buf);
916 x = (control >> 8) & 15;
917 switch(x)
919 case 0:
920 s = "Unspecified";
921 break;
922 case 8:
923 s = "A (Left)";
924 break;
925 case 4:
926 s = "B (Right)";
927 break;
928 default:
929 s = "";
930 break;
932 snprintf(buf, sizeof(buf), "Channel: %d (%s)", x, s);
933 lcd_puts(0, line++, buf);
935 x = (control >> 4) & 15;
936 switch(x)
938 case 0:
939 s = "44.1kHz";
940 break;
941 case 0x4:
942 s = "48kHz";
943 break;
944 case 0xc:
945 s = "32kHz";
946 break;
948 snprintf(buf, sizeof(buf), "Frequency: %d (%s)", x, s);
949 lcd_puts(0, line++, buf);
951 x = (control >> 2) & 3;
952 snprintf(buf, sizeof(buf), "Clock accuracy: %d", x);
953 lcd_puts(0, line++, buf);
954 line++;
956 #ifndef SIMULATOR
957 snprintf(buf, sizeof(buf), "Measured freq: %ldHz",
958 spdif_measure_frequency());
959 lcd_puts(0, line++, buf);
960 #endif
962 lcd_update();
964 if (action_userabort(HZ/10))
965 break;
968 spdif_set_output_source(spdif_source IF_SPDIF_POWER_(, spdif_src_on));
970 #ifdef HAVE_SPDIF_POWER
971 spdif_power_enable(global_settings.spdif_enable);
972 #endif
974 return false;
976 #endif /* CPU_COLDFIRE */
978 #ifndef SIMULATOR
979 #ifdef HAVE_LCD_BITMAP
980 /* button definitions */
981 #if (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
982 (CONFIG_KEYPAD == IRIVER_H300_PAD)
983 # define DEBUG_CANCEL BUTTON_OFF
985 #elif CONFIG_KEYPAD == RECORDER_PAD
986 # define DEBUG_CANCEL BUTTON_OFF
988 #elif CONFIG_KEYPAD == ONDIO_PAD
989 # define DEBUG_CANCEL BUTTON_MENU
991 #elif (CONFIG_KEYPAD == IPOD_1G2G_PAD) || \
992 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
993 (CONFIG_KEYPAD == IPOD_4G_PAD)
994 # define DEBUG_CANCEL BUTTON_MENU
996 #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
997 # define DEBUG_CANCEL BUTTON_PLAY
999 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
1000 # define DEBUG_CANCEL BUTTON_REC
1002 #elif (CONFIG_KEYPAD == IRIVER_H10_PAD)
1003 # define DEBUG_CANCEL BUTTON_REW
1005 #elif (CONFIG_KEYPAD == MROBE100_PAD)
1006 # define DEBUG_CANCEL BUTTON_MENU
1008 #elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \
1009 (CONFIG_KEYPAD == SANSA_C200_PAD)
1010 # define DEBUG_CANCEL BUTTON_LEFT
1011 #endif /* key definitions */
1013 /* Test code!!! */
1014 bool dbg_ports(void)
1016 #if CONFIG_CPU == SH7034
1017 char buf[32];
1018 int adc_battery_voltage, adc_battery_level;
1020 lcd_setfont(FONT_SYSFIXED);
1021 lcd_setmargins(0, 0);
1022 lcd_clear_display();
1024 while(1)
1026 snprintf(buf, 32, "PADR: %04x", (unsigned short)PADR);
1027 lcd_puts(0, 0, buf);
1028 snprintf(buf, 32, "PBDR: %04x", (unsigned short)PBDR);
1029 lcd_puts(0, 1, buf);
1031 snprintf(buf, 32, "AN0: %03x AN4: %03x", adc_read(0), adc_read(4));
1032 lcd_puts(0, 2, buf);
1033 snprintf(buf, 32, "AN1: %03x AN5: %03x", adc_read(1), adc_read(5));
1034 lcd_puts(0, 3, buf);
1035 snprintf(buf, 32, "AN2: %03x AN6: %03x", adc_read(2), adc_read(6));
1036 lcd_puts(0, 4, buf);
1037 snprintf(buf, 32, "AN3: %03x AN7: %03x", adc_read(3), adc_read(7));
1038 lcd_puts(0, 5, buf);
1040 battery_read_info(&adc_battery_voltage, &adc_battery_level);
1041 snprintf(buf, 32, "Batt: %d.%03dV %d%% ", adc_battery_voltage / 1000,
1042 adc_battery_voltage % 1000, adc_battery_level);
1043 lcd_puts(0, 6, buf);
1045 lcd_update();
1046 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1047 return false;
1049 #elif defined(CPU_COLDFIRE)
1050 unsigned int gpio_out;
1051 unsigned int gpio1_out;
1052 unsigned int gpio_read;
1053 unsigned int gpio1_read;
1054 unsigned int gpio_function;
1055 unsigned int gpio1_function;
1056 unsigned int gpio_enable;
1057 unsigned int gpio1_enable;
1058 int adc_buttons, adc_remote;
1059 int adc_battery_voltage, adc_battery_level;
1060 char buf[128];
1061 int line;
1063 lcd_setmargins(0, 0);
1064 lcd_clear_display();
1065 lcd_setfont(FONT_SYSFIXED);
1067 while(1)
1069 line = 0;
1070 gpio_read = GPIO_READ;
1071 gpio1_read = GPIO1_READ;
1072 gpio_out = GPIO_OUT;
1073 gpio1_out = GPIO1_OUT;
1074 gpio_function = GPIO_FUNCTION;
1075 gpio1_function = GPIO1_FUNCTION;
1076 gpio_enable = GPIO_ENABLE;
1077 gpio1_enable = GPIO1_ENABLE;
1079 snprintf(buf, sizeof(buf), "GPIO_READ: %08x", gpio_read);
1080 lcd_puts(0, line++, buf);
1081 snprintf(buf, sizeof(buf), "GPIO_OUT: %08x", gpio_out);
1082 lcd_puts(0, line++, buf);
1083 snprintf(buf, sizeof(buf), "GPIO_FUNCTION: %08x", gpio_function);
1084 lcd_puts(0, line++, buf);
1085 snprintf(buf, sizeof(buf), "GPIO_ENABLE: %08x", gpio_enable);
1086 lcd_puts(0, line++, buf);
1088 snprintf(buf, sizeof(buf), "GPIO1_READ: %08x", gpio1_read);
1089 lcd_puts(0, line++, buf);
1090 snprintf(buf, sizeof(buf), "GPIO1_OUT: %08x", gpio1_out);
1091 lcd_puts(0, line++, buf);
1092 snprintf(buf, sizeof(buf), "GPIO1_FUNCTION: %08x", gpio1_function);
1093 lcd_puts(0, line++, buf);
1094 snprintf(buf, sizeof(buf), "GPIO1_ENABLE: %08x", gpio1_enable);
1095 lcd_puts(0, line++, buf);
1097 adc_buttons = adc_read(ADC_BUTTONS);
1098 adc_remote = adc_read(ADC_REMOTE);
1099 battery_read_info(&adc_battery_voltage, &adc_battery_level);
1100 #if defined(IAUDIO_X5) || defined(IAUDIO_M5) || defined(IRIVER_H300_SERIES)
1101 snprintf(buf, sizeof(buf), "ADC_BUTTONS (%c): %02x",
1102 button_scan_enabled() ? '+' : '-', adc_buttons);
1103 #else
1104 snprintf(buf, sizeof(buf), "ADC_BUTTONS: %02x", adc_buttons);
1105 #endif
1106 lcd_puts(0, line++, buf);
1107 #if defined(IAUDIO_X5) || defined(IAUDIO_M5)
1108 snprintf(buf, sizeof(buf), "ADC_REMOTE (%c): %02x",
1109 remote_detect() ? '+' : '-', adc_remote);
1110 #else
1111 snprintf(buf, sizeof(buf), "ADC_REMOTE: %02x", adc_remote);
1112 #endif
1113 lcd_puts(0, line++, buf);
1114 #if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES)
1115 snprintf(buf, sizeof(buf), "ADC_REMOTEDETECT: %02x",
1116 adc_read(ADC_REMOTEDETECT));
1117 lcd_puts(0, line++, buf);
1118 #endif
1120 snprintf(buf, 32, "Batt: %d.%03dV %d%% ", adc_battery_voltage / 1000,
1121 adc_battery_voltage % 1000, adc_battery_level);
1122 lcd_puts(0, line++, buf);
1124 #if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES)
1125 snprintf(buf, sizeof(buf), "remotetype: %d", remote_type());
1126 lcd_puts(0, line++, buf);
1127 #endif
1129 lcd_update();
1130 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1131 return false;
1134 #elif defined(CPU_PP502x)
1136 char buf[128];
1137 int line;
1139 lcd_setmargins(0, 0);
1140 lcd_clear_display();
1141 lcd_setfont(FONT_SYSFIXED);
1143 while(1)
1145 line = 0;
1146 lcd_puts(0, line++, "GPIO STATES:");
1147 snprintf(buf, sizeof(buf), "A: %02x E: %02x I: %02x",
1148 (unsigned int)GPIOA_INPUT_VAL,
1149 (unsigned int)GPIOE_INPUT_VAL,
1150 (unsigned int)GPIOI_INPUT_VAL);
1151 lcd_puts(0, line++, buf);
1152 snprintf(buf, sizeof(buf), "B: %02x F: %02x J: %02x",
1153 (unsigned int)GPIOB_INPUT_VAL,
1154 (unsigned int)GPIOF_INPUT_VAL,
1155 (unsigned int)GPIOJ_INPUT_VAL);
1156 lcd_puts(0, line++, buf);
1157 snprintf(buf, sizeof(buf), "C: %02x G: %02x K: %02x",
1158 (unsigned int)GPIOC_INPUT_VAL,
1159 (unsigned int)GPIOG_INPUT_VAL,
1160 (unsigned int)GPIOK_INPUT_VAL);
1161 lcd_puts(0, line++, buf);
1162 snprintf(buf, sizeof(buf), "D: %02x H: %02x L: %02x",
1163 (unsigned int)GPIOD_INPUT_VAL,
1164 (unsigned int)GPIOH_INPUT_VAL,
1165 (unsigned int)GPIOL_INPUT_VAL);
1166 lcd_puts(0, line++, buf);
1167 line++;
1168 snprintf(buf, sizeof(buf), "GPO32_VAL: %08lx", GPO32_VAL);
1169 lcd_puts(0, line++, buf);
1170 snprintf(buf, sizeof(buf), "GPO32_EN: %08lx", GPO32_ENABLE);
1171 lcd_puts(0, line++, buf);
1172 snprintf(buf, sizeof(buf), "DEV_EN: %08lx", DEV_EN);
1173 lcd_puts(0, line++, buf);
1174 snprintf(buf, sizeof(buf), "DEV_EN2: %08lx", DEV_EN2);
1175 lcd_puts(0, line++, buf);
1176 snprintf(buf, sizeof(buf), "DEV_EN3: %08lx", inl(0x60006044));
1177 lcd_puts(0, line++, buf); /* to be verified */
1178 snprintf(buf, sizeof(buf), "DEV_INIT1: %08lx", DEV_INIT1);
1179 lcd_puts(0, line++, buf);
1180 snprintf(buf, sizeof(buf), "DEV_INIT2: %08lx", DEV_INIT2);
1181 lcd_puts(0, line++, buf);
1183 #if defined(IRIVER_H10) || defined(IRIVER_H10_5GB)
1184 line++;
1185 snprintf(buf, sizeof(buf), "BATT: %03x UNK1: %03x",
1186 adc_read(ADC_BATTERY), adc_read(ADC_UNKNOWN_1));
1187 lcd_puts(0, line++, buf);
1188 snprintf(buf, sizeof(buf), "REM: %03x PAD: %03x",
1189 adc_read(ADC_REMOTE), adc_read(ADC_SCROLLPAD));
1190 lcd_puts(0, line++, buf);
1191 #elif defined(SANSA_E200)
1192 snprintf(buf, sizeof(buf), "ADC_BVDD: %4d", adc_read(ADC_BVDD));
1193 lcd_puts(0, line++, buf);
1194 snprintf(buf, sizeof(buf), "ADC_RTCSUP: %4d", adc_read(ADC_RTCSUP));
1195 lcd_puts(0, line++, buf);
1196 snprintf(buf, sizeof(buf), "ADC_UVDD: %4d", adc_read(ADC_UVDD));
1197 lcd_puts(0, line++, buf);
1198 snprintf(buf, sizeof(buf), "ADC_CHG_IN: %4d", adc_read(ADC_CHG_IN));
1199 lcd_puts(0, line++, buf);
1200 snprintf(buf, sizeof(buf), "ADC_CVDD: %4d", adc_read(ADC_CVDD));
1201 lcd_puts(0, line++, buf);
1202 snprintf(buf, sizeof(buf), "ADC_BATTEMP: %4d", adc_read(ADC_BATTEMP));
1203 lcd_puts(0, line++, buf);
1204 snprintf(buf, sizeof(buf), "ADC_MICSUP1: %4d", adc_read(ADC_MICSUP1));
1205 lcd_puts(0, line++, buf);
1206 snprintf(buf, sizeof(buf), "ADC_MICSUP2: %4d", adc_read(ADC_MICSUP2));
1207 lcd_puts(0, line++, buf);
1208 snprintf(buf, sizeof(buf), "ADC_VBE1: %4d", adc_read(ADC_VBE1));
1209 lcd_puts(0, line++, buf);
1210 snprintf(buf, sizeof(buf), "ADC_VBE2: %4d", adc_read(ADC_VBE2));
1211 lcd_puts(0, line++, buf);
1212 snprintf(buf, sizeof(buf), "ADC_I_MICSUP1:%4d", adc_read(ADC_I_MICSUP1));
1213 lcd_puts(0, line++, buf);
1214 snprintf(buf, sizeof(buf), "ADC_I_MICSUP2:%4d", adc_read(ADC_I_MICSUP2));
1215 lcd_puts(0, line++, buf);
1216 snprintf(buf, sizeof(buf), "ADC_VBAT: %4d", adc_read(ADC_VBAT));
1217 lcd_puts(0, line++, buf);
1218 snprintf(buf, sizeof(buf), "CHARGER: %02X/%02X", i2c_readbyte(AS3514_I2C_ADDR, CHRGR), i2c_readbyte(AS3514_I2C_ADDR, IRQ_ENRD0));
1219 lcd_puts(0, line++, buf);
1220 #endif
1221 lcd_update();
1222 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1223 return false;
1226 #elif CONFIG_CPU == PP5002
1227 char buf[128];
1228 int line;
1230 lcd_setmargins(0, 0);
1231 lcd_clear_display();
1232 lcd_setfont(FONT_SYSFIXED);
1234 while(1)
1236 line = 0;
1237 snprintf(buf, sizeof(buf), "GPIO_A: %02x GPIO_B: %02x",
1238 (unsigned int)GPIOA_INPUT_VAL, (unsigned int)GPIOB_INPUT_VAL);
1239 lcd_puts(0, line++, buf);
1240 snprintf(buf, sizeof(buf), "GPIO_C: %02x GPIO_D: %02x",
1241 (unsigned int)GPIOC_INPUT_VAL, (unsigned int)GPIOD_INPUT_VAL);
1242 lcd_puts(0, line++, buf);
1244 snprintf(buf, sizeof(buf), "DEV_EN: %08lx", DEV_EN);
1245 lcd_puts(0, line++, buf);
1246 snprintf(buf, sizeof(buf), "CLOCK_ENABLE: %08lx", CLOCK_ENABLE);
1247 lcd_puts(0, line++, buf);
1248 snprintf(buf, sizeof(buf), "CLOCK_SOURCE: %08lx", CLOCK_SOURCE);
1249 lcd_puts(0, line++, buf);
1250 snprintf(buf, sizeof(buf), "PLL_CONTROL: %08lx", PLL_CONTROL);
1251 lcd_puts(0, line++, buf);
1252 snprintf(buf, sizeof(buf), "PLL_DIV: %08lx", PLL_DIV);
1253 lcd_puts(0, line++, buf);
1254 snprintf(buf, sizeof(buf), "PLL_MULT: %08lx", PLL_MULT);
1255 lcd_puts(0, line++, buf);
1256 snprintf(buf, sizeof(buf), "TIMING1_CTL: %08lx", TIMING1_CTL);
1257 lcd_puts(0, line++, buf);
1258 snprintf(buf, sizeof(buf), "TIMING2_CTL: %08lx", TIMING2_CTL);
1259 lcd_puts(0, line++, buf);
1261 lcd_update();
1262 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1263 return false;
1265 #else
1266 return __dbg_ports();
1267 #endif /* CPU */
1268 return false;
1270 #else /* !HAVE_LCD_BITMAP */
1271 bool dbg_ports(void)
1273 char buf[32];
1274 int button;
1275 int adc_battery_voltage;
1276 int currval = 0;
1278 lcd_clear_display();
1280 while(1)
1282 switch(currval)
1284 case 0:
1285 snprintf(buf, 32, "PADR: %04x", (unsigned short)PADR);
1286 break;
1287 case 1:
1288 snprintf(buf, 32, "PBDR: %04x", (unsigned short)PBDR);
1289 break;
1290 case 2:
1291 snprintf(buf, 32, "AN0: %03x", adc_read(0));
1292 break;
1293 case 3:
1294 snprintf(buf, 32, "AN1: %03x", adc_read(1));
1295 break;
1296 case 4:
1297 snprintf(buf, 32, "AN2: %03x", adc_read(2));
1298 break;
1299 case 5:
1300 snprintf(buf, 32, "AN3: %03x", adc_read(3));
1301 break;
1302 case 6:
1303 snprintf(buf, 32, "AN4: %03x", adc_read(4));
1304 break;
1305 case 7:
1306 snprintf(buf, 32, "AN5: %03x", adc_read(5));
1307 break;
1308 case 8:
1309 snprintf(buf, 32, "AN6: %03x", adc_read(6));
1310 break;
1311 case 9:
1312 snprintf(buf, 32, "AN7: %03x", adc_read(7));
1313 break;
1314 break;
1316 lcd_puts(0, 0, buf);
1318 battery_read_info(&adc_battery_voltage, NULL);
1319 snprintf(buf, 32, "Batt: %d.%03dV", adc_battery_voltage / 1000,
1320 adc_battery_voltage % 1000);
1321 lcd_puts(0, 1, buf);
1322 lcd_update();
1324 button = get_action(CONTEXT_SETTINGS,HZ/5);
1326 switch(button)
1328 case ACTION_STD_CANCEL:
1329 return false;
1331 case ACTION_SETTINGS_DEC:
1332 currval--;
1333 if(currval < 0)
1334 currval = 9;
1335 break;
1337 case ACTION_SETTINGS_INC:
1338 currval++;
1339 if(currval > 9)
1340 currval = 0;
1341 break;
1344 return false;
1346 #endif /* !HAVE_LCD_BITMAP */
1347 #endif /* !SIMULATOR */
1349 #if (CONFIG_RTC == RTC_PCF50605) && !defined(SIMULATOR)
1350 static bool dbg_pcf(void)
1352 char buf[128];
1353 int line;
1355 #ifdef HAVE_LCD_BITMAP
1356 lcd_setmargins(0, 0);
1357 lcd_setfont(FONT_SYSFIXED);
1358 #endif
1359 lcd_clear_display();
1361 while(1)
1363 line = 0;
1365 snprintf(buf, sizeof(buf), "DCDC1: %02x", pcf50605_read(0x1b));
1366 lcd_puts(0, line++, buf);
1367 snprintf(buf, sizeof(buf), "DCDC2: %02x", pcf50605_read(0x1c));
1368 lcd_puts(0, line++, buf);
1369 snprintf(buf, sizeof(buf), "DCDC3: %02x", pcf50605_read(0x1d));
1370 lcd_puts(0, line++, buf);
1371 snprintf(buf, sizeof(buf), "DCDC4: %02x", pcf50605_read(0x1e));
1372 lcd_puts(0, line++, buf);
1373 snprintf(buf, sizeof(buf), "DCDEC1: %02x", pcf50605_read(0x1f));
1374 lcd_puts(0, line++, buf);
1375 snprintf(buf, sizeof(buf), "DCDEC2: %02x", pcf50605_read(0x20));
1376 lcd_puts(0, line++, buf);
1377 snprintf(buf, sizeof(buf), "DCUDC1: %02x", pcf50605_read(0x21));
1378 lcd_puts(0, line++, buf);
1379 snprintf(buf, sizeof(buf), "DCUDC2: %02x", pcf50605_read(0x22));
1380 lcd_puts(0, line++, buf);
1381 snprintf(buf, sizeof(buf), "IOREGC: %02x", pcf50605_read(0x23));
1382 lcd_puts(0, line++, buf);
1383 snprintf(buf, sizeof(buf), "D1REGC: %02x", pcf50605_read(0x24));
1384 lcd_puts(0, line++, buf);
1385 snprintf(buf, sizeof(buf), "D2REGC: %02x", pcf50605_read(0x25));
1386 lcd_puts(0, line++, buf);
1387 snprintf(buf, sizeof(buf), "D3REGC: %02x", pcf50605_read(0x26));
1388 lcd_puts(0, line++, buf);
1389 snprintf(buf, sizeof(buf), "LPREG1: %02x", pcf50605_read(0x27));
1390 lcd_puts(0, line++, buf);
1392 lcd_update();
1393 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1395 return false;
1399 return false;
1401 #endif
1403 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
1404 static bool dbg_cpufreq(void)
1406 char buf[128];
1407 int line;
1408 int button;
1410 #ifdef HAVE_LCD_BITMAP
1411 lcd_setmargins(0, 0);
1412 lcd_setfont(FONT_SYSFIXED);
1413 #endif
1414 lcd_clear_display();
1416 while(1)
1418 line = 0;
1420 snprintf(buf, sizeof(buf), "Frequency: %ld", FREQ);
1421 lcd_puts(0, line++, buf);
1423 snprintf(buf, sizeof(buf), "boost_counter: %d", get_cpu_boost_counter());
1424 lcd_puts(0, line++, buf);
1426 lcd_update();
1427 button = get_action(CONTEXT_STD,HZ/10);
1429 switch(button)
1431 case ACTION_STD_PREV:
1432 cpu_boost(true);
1433 break;
1435 case ACTION_STD_NEXT:
1436 cpu_boost(false);
1437 break;
1439 case ACTION_STD_OK:
1440 while (get_cpu_boost_counter() > 0)
1441 cpu_boost(false);
1442 set_cpu_frequency(CPUFREQ_DEFAULT);
1443 break;
1445 case ACTION_STD_CANCEL:
1446 return false;
1450 return false;
1452 #endif /* HAVE_ADJUSTABLE_CPU_FREQ */
1454 #if defined(HAVE_TSC2100) && !defined(SIMULATOR)
1455 #include "tsc2100.h"
1456 char *itob(int n, int len)
1458 static char binary[64];
1459 int i,j;
1460 for (i=1, j=0;i<=len;i++)
1462 binary[j++] = n&(1<<(len-i))?'1':'0';
1463 if (i%4 == 0)
1464 binary[j++] = ' ';
1466 binary[j] = '\0';
1467 return binary;
1469 static char* tsc2100_debug_getname(int selected_item, void * data, char *buffer)
1471 int *page = (int*)data;
1472 bool reserved = false;
1473 switch (*page)
1475 case 0:
1476 if ((selected_item > 0x0a) ||
1477 (selected_item == 0x04) ||
1478 (selected_item == 0x08))
1479 reserved = true;
1480 break;
1481 case 1:
1482 if ((selected_item > 0x05) ||
1483 (selected_item == 0x02))
1484 reserved = true;
1485 break;
1486 case 2:
1487 if (selected_item > 0x1e)
1488 reserved = true;
1489 break;
1491 if (reserved)
1492 snprintf(buffer, MAX_PATH, "%02x: RESERVED", selected_item);
1493 else
1494 snprintf(buffer, MAX_PATH, "%02x: %s", selected_item,
1495 itob(tsc2100_readreg(*page, selected_item)&0xffff,16));
1496 return buffer;
1498 static int tsc2100debug_action_callback(int action, struct gui_synclist *lists)
1500 int *page = (int*)lists->data;
1501 if (action == ACTION_STD_OK)
1503 *page = (*page+1)%3;
1504 snprintf(lists->title, 32,
1505 "tsc2100 registers - Page %d", *page);
1506 return ACTION_REDRAW;
1508 return action;
1510 bool tsc2100_debug(void)
1512 int page = 0;
1513 char title[32] = "tsc2100 registers - Page 0";
1514 struct simplelist_info info;
1515 simplelist_info_init(&info, title, 32, &page);
1516 info.timeout = HZ/100;
1517 info.get_name = tsc2100_debug_getname;
1518 info.action_callback= tsc2100debug_action_callback;
1519 return simplelist_show_list(&info);
1521 #endif
1522 #ifndef SIMULATOR
1523 #ifdef HAVE_LCD_BITMAP
1525 * view_battery() shows a automatically scaled graph of the battery voltage
1526 * over time. Usable for estimating battery life / charging rate.
1527 * The power_history array is updated in power_thread of powermgmt.c.
1530 #define BAT_LAST_VAL MIN(LCD_WIDTH, POWER_HISTORY_LEN)
1531 #define BAT_YSPACE (LCD_HEIGHT - 20)
1533 static bool view_battery(void)
1535 int view = 0;
1536 int i, x, y;
1537 unsigned short maxv, minv;
1538 char buf[32];
1540 lcd_setmargins(0, 0);
1541 lcd_setfont(FONT_SYSFIXED);
1543 while(1)
1545 lcd_clear_display();
1546 switch (view) {
1547 case 0: /* voltage history graph */
1548 /* Find maximum and minimum voltage for scaling */
1549 minv = power_history[0];
1550 maxv = minv + 1;
1551 for (i = 1; i < BAT_LAST_VAL && power_history[i]; i++) {
1552 if (power_history[i] > maxv)
1553 maxv = power_history[i];
1554 if (power_history[i] < minv)
1555 minv = power_history[i];
1558 snprintf(buf, 30, "Battery %d.%03d", power_history[0] / 1000,
1559 power_history[0] % 1000);
1560 lcd_puts(0, 0, buf);
1561 snprintf(buf, 30, "scale %d.%03d-%d.%03dV",
1562 minv / 1000, minv % 1000, maxv / 1000, maxv % 1000);
1563 lcd_puts(0, 1, buf);
1565 x = 0;
1566 for (i = BAT_LAST_VAL - 1; i >= 0; i--) {
1567 y = (power_history[i] - minv) * BAT_YSPACE / (maxv - minv);
1568 lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
1569 lcd_vline(x, LCD_HEIGHT-1, 20);
1570 lcd_set_drawmode(DRMODE_SOLID);
1571 lcd_vline(x, LCD_HEIGHT-1,
1572 MIN(MAX(LCD_HEIGHT-1 - y, 20), LCD_HEIGHT-1));
1573 x++;
1576 break;
1578 case 1: /* status: */
1579 lcd_puts(0, 0, "Power status:");
1581 battery_read_info(&y, NULL);
1582 snprintf(buf, 30, "Battery: %d.%03d V", y / 1000, y % 1000);
1583 lcd_puts(0, 1, buf);
1584 #ifdef ADC_EXT_POWER
1585 y = (adc_read(ADC_EXT_POWER) * EXT_SCALE_FACTOR) / 1000;
1586 snprintf(buf, 30, "External: %d.%03d V", y / 1000, y % 1000);
1587 lcd_puts(0, 2, buf);
1588 #endif
1589 #if CONFIG_CHARGING
1590 #if CONFIG_CHARGING == CHARGING_CONTROL
1591 snprintf(buf, 30, "Chgr: %s %s",
1592 charger_inserted() ? "present" : "absent",
1593 charger_enabled ? "on" : "off");
1594 lcd_puts(0, 3, buf);
1595 snprintf(buf, 30, "short delta: %d", short_delta);
1596 lcd_puts(0, 5, buf);
1597 snprintf(buf, 30, "long delta: %d", long_delta);
1598 lcd_puts(0, 6, buf);
1599 lcd_puts(0, 7, power_message);
1600 snprintf(buf, 30, "USB Inserted: %s",
1601 usb_inserted() ? "yes" : "no");
1602 lcd_puts(0, 8, buf);
1603 #if defined IRIVER_H300_SERIES
1604 snprintf(buf, 30, "USB Charging Enabled: %s",
1605 usb_charging_enabled() ? "yes" : "no");
1606 lcd_puts(0, 9, buf);
1607 #endif
1608 #else /* CONFIG_CHARGING != CHARGING_CONTROL */
1609 #if defined IPOD_NANO || defined IPOD_VIDEO
1610 int usb_pwr = (GPIOL_INPUT_VAL & 0x10)?true:false;
1611 int ext_pwr = (GPIOL_INPUT_VAL & 0x08)?false:true;
1612 int dock = (GPIOA_INPUT_VAL & 0x10)?true:false;
1613 int charging = (GPIOB_INPUT_VAL & 0x01)?false:true;
1614 int headphone= (GPIOA_INPUT_VAL & 0x80)?true:false;
1616 snprintf(buf, 30, "USB pwr: %s",
1617 usb_pwr ? "present" : "absent");
1618 lcd_puts(0, 3, buf);
1619 snprintf(buf, 30, "EXT pwr: %s",
1620 ext_pwr ? "present" : "absent");
1621 lcd_puts(0, 4, buf);
1622 snprintf(buf, 30, "Battery: %s",
1623 charging ? "charging" : (usb_pwr||ext_pwr) ? "charged" : "discharging");
1624 lcd_puts(0, 5, buf);
1625 snprintf(buf, 30, "Dock mode: %s",
1626 dock ? "enabled" : "disabled");
1627 lcd_puts(0, 6, buf);
1628 snprintf(buf, 30, "Headphone: %s",
1629 headphone ? "connected" : "disconnected");
1630 lcd_puts(0, 7, buf);
1631 #else
1632 snprintf(buf, 30, "Charger: %s",
1633 charger_inserted() ? "present" : "absent");
1634 lcd_puts(0, 3, buf);
1635 #endif
1636 #endif /* CONFIG_CHARGING != CHARGING_CONTROL */
1637 #endif /* CONFIG_CHARGING */
1638 break;
1640 case 2: /* voltage deltas: */
1641 lcd_puts(0, 0, "Voltage deltas:");
1643 for (i = 0; i <= 6; i++) {
1644 y = power_history[i] - power_history[i+1];
1645 snprintf(buf, 30, "-%d min: %s%d.%03d V", i,
1646 (y < 0) ? "-" : "", ((y < 0) ? y * -1 : y) / 1000,
1647 ((y < 0) ? y * -1 : y ) % 1000);
1648 lcd_puts(0, i+1, buf);
1650 break;
1652 case 3: /* remaining time estimation: */
1654 #if CONFIG_CHARGING == CHARGING_CONTROL
1655 snprintf(buf, 30, "charge_state: %d", charge_state);
1656 lcd_puts(0, 0, buf);
1658 snprintf(buf, 30, "Cycle time: %d m", powermgmt_last_cycle_startstop_min);
1659 lcd_puts(0, 1, buf);
1661 snprintf(buf, 30, "Lvl@cyc st: %d%%", powermgmt_last_cycle_level);
1662 lcd_puts(0, 2, buf);
1664 snprintf(buf, 30, "P=%2d I=%2d", pid_p, pid_i);
1665 lcd_puts(0, 3, buf);
1667 snprintf(buf, 30, "Trickle sec: %d/60", trickle_sec);
1668 lcd_puts(0, 4, buf);
1669 #endif /* CONFIG_CHARGING == CHARGING_CONTROL */
1671 snprintf(buf, 30, "Last PwrHist: %d.%03dV",
1672 power_history[0] / 1000,
1673 power_history[0] % 1000);
1674 lcd_puts(0, 5, buf);
1676 snprintf(buf, 30, "battery level: %d%%", battery_level());
1677 lcd_puts(0, 6, buf);
1679 snprintf(buf, 30, "Est. remain: %d m", battery_time());
1680 lcd_puts(0, 7, buf);
1681 break;
1684 lcd_update();
1686 switch(get_action(CONTEXT_SETTINGS,HZ/2))
1688 case ACTION_SETTINGS_DEC:
1689 if (view)
1690 view--;
1691 break;
1693 case ACTION_SETTINGS_INC:
1694 if (view < 3)
1695 view++;
1696 break;
1698 case ACTION_STD_CANCEL:
1699 return false;
1702 return false;
1705 #endif /* HAVE_LCD_BITMAP */
1706 #endif
1708 #ifndef SIMULATOR
1709 #if defined(HAVE_MMC) || defined(HAVE_HOTSWAP)
1710 #if defined(HAVE_MMC)
1711 #define CARDTYPE "MMC"
1712 #else
1713 #define CARDTYPE "microSD"
1714 #endif
1715 static int disk_callback(int btn, struct gui_synclist *lists)
1717 tCardInfo *card;
1718 int *cardnum = (int*)lists->data;
1719 unsigned char card_name[7];
1720 unsigned char pbuf[32];
1721 char *title = lists->title;
1722 static const unsigned char i_vmin[] = { 0, 1, 5, 10, 25, 35, 60, 100 };
1723 static const unsigned char i_vmax[] = { 1, 5, 10, 25, 35, 45, 80, 200 };
1724 static const unsigned char *kbit_units[] = { "kBit/s", "MBit/s", "GBit/s" };
1725 static const unsigned char *nsec_units[] = { "ns", "�s", "ms" };
1726 static const char *spec_vers[] = { "1.0-1.2", "1.4", "2.0-2.2",
1727 "3.1-3.31", "4.0" };
1728 if ((btn == ACTION_STD_OK) || (btn == SYS_FS_CHANGED) || (btn == ACTION_REDRAW))
1730 if (btn == ACTION_STD_OK)
1732 *cardnum ^= 0x1; /* change cards */
1735 simplelist_set_line_count(0);
1737 card = card_get_info(*cardnum);
1739 if (card->initialized > 0)
1741 card_name[6] = '\0';
1742 strncpy(card_name, ((unsigned char*)card->cid) + 3, 6);
1743 simplelist_addline(SIMPLELIST_ADD_LINE,
1744 "%s Rev %d.%d", card_name,
1745 (int) card_extract_bits(card->cid, 72, 4),
1746 (int) card_extract_bits(card->cid, 76, 4));
1747 simplelist_addline(SIMPLELIST_ADD_LINE,
1748 "Prod: %d/%d",
1749 (int) card_extract_bits(card->cid, 112, 4),
1750 (int) card_extract_bits(card->cid, 116, 4) + 1997);
1751 simplelist_addline(SIMPLELIST_ADD_LINE,
1752 "Ser#: 0x%08lx",
1753 card_extract_bits(card->cid, 80, 32));
1754 simplelist_addline(SIMPLELIST_ADD_LINE,
1755 "M=%02x, O=%04x",
1756 (int) card_extract_bits(card->cid, 0, 8),
1757 (int) card_extract_bits(card->cid, 8, 16));
1758 int temp = card_extract_bits(card->csd, 2, 4);
1759 simplelist_addline(SIMPLELIST_ADD_LINE,
1760 CARDTYPE " v%s", temp < 5 ?
1761 spec_vers[temp] : "?.?");
1762 simplelist_addline(SIMPLELIST_ADD_LINE,
1763 "Blocks: 0x%06lx", card->numblocks);
1764 simplelist_addline(SIMPLELIST_ADD_LINE,
1765 "Blksz.: %d P:%c%c", card->blocksize,
1766 card_extract_bits(card->csd, 48, 1) ? 'R' : '-',
1767 card_extract_bits(card->csd, 106, 1) ? 'W' : '-');
1768 output_dyn_value(pbuf, sizeof pbuf, card->speed / 1000,
1769 kbit_units, false);
1770 simplelist_addline(SIMPLELIST_ADD_LINE,
1771 "Speed: %s", pbuf);
1772 output_dyn_value(pbuf, sizeof pbuf, card->tsac,
1773 nsec_units, false);
1774 simplelist_addline(SIMPLELIST_ADD_LINE,
1775 "Tsac: %s", pbuf);
1776 simplelist_addline(SIMPLELIST_ADD_LINE,
1777 "Nsac: %d clk", card->nsac);
1778 simplelist_addline(SIMPLELIST_ADD_LINE,
1779 "R2W: *%d", card->r2w_factor);
1780 simplelist_addline(SIMPLELIST_ADD_LINE,
1781 "IRmax: %d..%d mA",
1782 i_vmin[card_extract_bits(card->csd, 66, 3)],
1783 i_vmax[card_extract_bits(card->csd, 69, 3)]);
1784 simplelist_addline(SIMPLELIST_ADD_LINE,
1785 "IWmax: %d..%d mA",
1786 i_vmin[card_extract_bits(card->csd, 72, 3)],
1787 i_vmax[card_extract_bits(card->csd, 75, 3)]);
1789 else if (card->initialized == 0)
1791 simplelist_addline(SIMPLELIST_ADD_LINE, "Not Found!");
1793 #ifndef HAVE_MMC
1794 else /* card->initialized < 0 */
1796 simplelist_addline(SIMPLELIST_ADD_LINE, "Init Error! (%d)", card->initialized);
1798 #endif
1799 snprintf(title, 16, "[" CARDTYPE " %d]", *cardnum);
1800 gui_synclist_set_title(lists, title, Icon_NOICON);
1801 gui_synclist_set_nb_items(lists, simplelist_get_line_count());
1802 gui_synclist_select_item(lists, 0);
1803 btn = ACTION_REDRAW;
1805 return btn;
1807 #else /* !defined(HAVE_MMC) && !defined(HAVE_HOTSWAP) */
1808 static int disk_callback(int btn, struct gui_synclist *lists)
1810 (void)lists;
1811 int i;
1812 char buf[128];
1813 unsigned short* identify_info = ata_get_identify();
1814 bool timing_info_present = false;
1815 (void)btn;
1817 simplelist_set_line_count(0);
1819 for (i=0; i < 20; i++)
1820 ((unsigned short*)buf)[i]=htobe16(identify_info[i+27]);
1821 buf[40]=0;
1822 /* kill trailing space */
1823 for (i=39; i && buf[i]==' '; i--)
1824 buf[i] = 0;
1825 simplelist_addline(SIMPLELIST_ADD_LINE, "Model: %s", buf);
1826 for (i=0; i < 4; i++)
1827 ((unsigned short*)buf)[i]=htobe16(identify_info[i+23]);
1828 buf[8]=0;
1829 simplelist_addline(SIMPLELIST_ADD_LINE,
1830 "Firmware: %s", buf);
1831 snprintf(buf, sizeof buf, "%ld MB",
1832 ((unsigned long)identify_info[61] << 16 |
1833 (unsigned long)identify_info[60]) / 2048 );
1834 simplelist_addline(SIMPLELIST_ADD_LINE,
1835 "Size: %s", buf);
1836 unsigned long free;
1837 fat_size( IF_MV2(0,) NULL, &free );
1838 simplelist_addline(SIMPLELIST_ADD_LINE,
1839 "Free: %ld MB", free / 1024);
1840 simplelist_addline(SIMPLELIST_ADD_LINE,
1841 "Spinup time: %d ms", ata_spinup_time * (1000/HZ));
1842 i = identify_info[83] & (1<<3);
1843 simplelist_addline(SIMPLELIST_ADD_LINE,
1844 "Power mgmt: %s", i ? "enabled" : "unsupported");
1845 i = identify_info[83] & (1<<9);
1846 simplelist_addline(SIMPLELIST_ADD_LINE,
1847 "Noise mgmt: %s", i ? "enabled" : "unsupported");
1848 i = identify_info[82] & (1<<6);
1849 simplelist_addline(SIMPLELIST_ADD_LINE,
1850 "Read-ahead: %s", i ? "enabled" : "unsupported");
1851 timing_info_present = identify_info[53] & (1<<1);
1852 if(timing_info_present) {
1853 char pio3[2], pio4[2];pio3[1] = 0;
1854 pio4[1] = 0;
1855 pio3[0] = (identify_info[64] & (1<<0)) ? '3' : 0;
1856 pio4[0] = (identify_info[64] & (1<<1)) ? '4' : 0;
1857 simplelist_addline(SIMPLELIST_ADD_LINE,
1858 "PIO modes: 0 1 2 %s %s", pio3, pio4);
1860 else {
1861 simplelist_addline(SIMPLELIST_ADD_LINE,
1862 "No PIO mode info");
1864 timing_info_present = identify_info[53] & (1<<1);
1865 if(timing_info_present) {
1866 simplelist_addline(SIMPLELIST_ADD_LINE,
1867 "Cycle times %dns/%dns",
1868 identify_info[67],
1869 identify_info[68] );
1870 } else {
1871 simplelist_addline(SIMPLELIST_ADD_LINE,
1872 "No timing info");
1874 timing_info_present = identify_info[53] & (1<<1);
1875 if(timing_info_present) {
1876 i = identify_info[49] & (1<<11);
1877 simplelist_addline(SIMPLELIST_ADD_LINE,
1878 "IORDY support: %s", i ? "yes" : "no");
1879 i = identify_info[49] & (1<<10);
1880 simplelist_addline(SIMPLELIST_ADD_LINE,
1881 "IORDY disable: %s", i ? "yes" : "no");
1882 } else {
1883 simplelist_addline(SIMPLELIST_ADD_LINE,
1884 "No timing info");
1886 simplelist_addline(SIMPLELIST_ADD_LINE,
1887 "Cluster size: %d bytes", fat_get_cluster_size(IF_MV(0)));
1888 return btn;
1891 static bool dbg_identify_info(void)
1893 int fd = creat("/identify_info.bin");
1894 if(fd >= 0)
1896 #ifdef ROCKBOX_LITTLE_ENDIAN
1897 ecwrite(fd, ata_get_identify(), SECTOR_SIZE/2, "s", true);
1898 #else
1899 write(fd, ata_get_identify(), SECTOR_SIZE);
1900 #endif
1901 close(fd);
1903 return false;
1905 #endif /* !defined(HAVE_MMC) && !defined(HAVE_HOTSWAP) */
1906 static bool dbg_disk_info(void)
1908 struct simplelist_info info;
1909 simplelist_info_init(&info, "Disk Info", 1, NULL);
1910 #if defined(HAVE_MMC) || defined(HAVE_HOTSWAP)
1911 char title[16];
1912 int card = 0;
1913 info.callback_data = (void*)&card;
1914 info.title = title;
1915 #endif
1916 info.action_callback = disk_callback;
1917 info.hide_selection = true;
1918 return simplelist_show_list(&info);
1920 #endif /* !SIMULATOR */
1922 #ifdef HAVE_DIRCACHE
1923 static int dircache_callback(int btn, struct gui_synclist *lists)
1925 (void)btn; (void)lists;
1926 simplelist_set_line_count(0);
1927 simplelist_addline(SIMPLELIST_ADD_LINE, "Cache initialized: %s",
1928 dircache_is_enabled() ? "Yes" : "No");
1929 simplelist_addline(SIMPLELIST_ADD_LINE, "Cache size: %d B",
1930 dircache_get_cache_size());
1931 simplelist_addline(SIMPLELIST_ADD_LINE, "Last size: %d B",
1932 global_status.dircache_size);
1933 simplelist_addline(SIMPLELIST_ADD_LINE, "Limit: %d B",
1934 DIRCACHE_LIMIT);
1935 simplelist_addline(SIMPLELIST_ADD_LINE, "Reserve: %d/%d B",
1936 dircache_get_reserve_used(), DIRCACHE_RESERVE);
1937 simplelist_addline(SIMPLELIST_ADD_LINE, "Scanning took: %d s",
1938 dircache_get_build_ticks() / HZ);
1939 simplelist_addline(SIMPLELIST_ADD_LINE, "Entry count: %d",
1940 dircache_get_entry_count());
1941 return btn;
1944 static bool dbg_dircache_info(void)
1946 struct simplelist_info info;
1947 simplelist_info_init(&info, "Dircache Info", 7, NULL);
1948 info.action_callback = dircache_callback;
1949 info.hide_selection = true;
1950 return simplelist_show_list(&info);
1953 #endif /* HAVE_DIRCACHE */
1955 #ifdef HAVE_TAGCACHE
1956 static int database_callback(int btn, struct gui_synclist *lists)
1958 (void)lists;
1959 struct tagcache_stat *stat = tagcache_get_stat();
1960 static bool synced = false;
1962 simplelist_set_line_count(0);
1964 simplelist_addline(SIMPLELIST_ADD_LINE, "Initialized: %s",
1965 stat->initialized ? "Yes" : "No");
1966 simplelist_addline(SIMPLELIST_ADD_LINE, "DB Ready: %s",
1967 stat->ready ? "Yes" : "No");
1968 simplelist_addline(SIMPLELIST_ADD_LINE, "RAM Cache: %s",
1969 stat->ramcache ? "Yes" : "No");
1970 simplelist_addline(SIMPLELIST_ADD_LINE, "RAM: %d/%d B",
1971 stat->ramcache_used, stat->ramcache_allocated);
1972 simplelist_addline(SIMPLELIST_ADD_LINE, "Progress: %d%% (%d entries)",
1973 stat->progress, stat->processed_entries);
1974 simplelist_addline(SIMPLELIST_ADD_LINE, "Curfile: %s",
1975 stat->curentry ? stat->curentry : "---");
1976 simplelist_addline(SIMPLELIST_ADD_LINE, "Commit step: %d",
1977 stat->commit_step);
1978 simplelist_addline(SIMPLELIST_ADD_LINE, "Commit delayed: %s",
1979 stat->commit_delayed ? "Yes" : "No");
1981 simplelist_addline(SIMPLELIST_ADD_LINE, "Queue length: %d",
1982 stat->queue_length);
1984 if (synced)
1986 synced = false;
1987 tagcache_screensync_event();
1990 if (!btn && stat->curentry)
1992 synced = true;
1993 return ACTION_REDRAW;
1996 if (btn == ACTION_STD_CANCEL)
1997 tagcache_screensync_enable(false);
1999 return btn;
2001 static bool dbg_tagcache_info(void)
2003 struct simplelist_info info;
2004 simplelist_info_init(&info, "Database Info", 8, NULL);
2005 info.action_callback = database_callback;
2006 info.hide_selection = true;
2008 /* Don't do nonblock here, must give enough processing time
2009 for tagcache thread. */
2010 /* info.timeout = TIMEOUT_NOBLOCK; */
2011 info.timeout = 1;
2012 tagcache_screensync_enable(true);
2013 return simplelist_show_list(&info);
2015 #endif
2017 #if CONFIG_CPU == SH7034
2018 static bool dbg_save_roms(void)
2020 int fd;
2021 int oldmode = system_memory_guard(MEMGUARD_NONE);
2023 fd = creat("/internal_rom_0000-FFFF.bin");
2024 if(fd >= 0)
2026 write(fd, (void *)0, 0x10000);
2027 close(fd);
2030 fd = creat("/internal_rom_2000000-203FFFF.bin");
2031 if(fd >= 0)
2033 write(fd, (void *)0x2000000, 0x40000);
2034 close(fd);
2037 system_memory_guard(oldmode);
2038 return false;
2040 #elif defined CPU_COLDFIRE
2041 static bool dbg_save_roms(void)
2043 int fd;
2044 int oldmode = system_memory_guard(MEMGUARD_NONE);
2046 #if defined(IRIVER_H100_SERIES)
2047 fd = creat("/internal_rom_000000-1FFFFF.bin");
2048 #elif defined(IRIVER_H300_SERIES)
2049 fd = creat("/internal_rom_000000-3FFFFF.bin");
2050 #elif defined(IAUDIO_X5) || defined(IAUDIO_M5)
2051 fd = creat("/internal_rom_000000-3FFFFF.bin");
2052 #endif
2053 if(fd >= 0)
2055 write(fd, (void *)0, FLASH_SIZE);
2056 close(fd);
2058 system_memory_guard(oldmode);
2060 #ifdef HAVE_EEPROM
2061 fd = creat("/internal_eeprom.bin");
2062 if (fd >= 0)
2064 int old_irq_level;
2065 char buf[EEPROM_SIZE];
2066 int err;
2068 old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL);
2070 err = eeprom_24cxx_read(0, buf, sizeof buf);
2071 if (err)
2072 gui_syncsplash(HZ*3, "Eeprom read failure (%d)",err);
2073 else
2075 write(fd, buf, sizeof buf);
2078 set_irq_level(old_irq_level);
2080 close(fd);
2082 #endif
2084 return false;
2086 #elif defined(CPU_PP) && !(defined(SANSA_E200) || defined(SANSA_C200))
2087 static bool dbg_save_roms(void)
2089 int fd;
2091 fd = creat("/internal_rom_000000-0FFFFF.bin");
2092 if(fd >= 0)
2094 write(fd, (void *)0x20000000, FLASH_SIZE);
2095 close(fd);
2098 return false;
2100 #endif /* CPU */
2102 #ifndef SIMULATOR
2103 #if CONFIG_TUNER
2104 static int radio_callback(int btn, struct gui_synclist *lists)
2106 (void)lists;
2107 if (btn == ACTION_STD_CANCEL)
2108 return btn;
2109 simplelist_set_line_count(1);
2111 #if (CONFIG_TUNER & LV24020LP)
2112 simplelist_addline(SIMPLELIST_ADD_LINE,
2113 "CTRL_STAT: %02X", lv24020lp_get(LV24020LP_CTRL_STAT) );
2114 simplelist_addline(SIMPLELIST_ADD_LINE,
2115 "RADIO_STAT: %02X", lv24020lp_get(LV24020LP_REG_STAT) );
2116 simplelist_addline(SIMPLELIST_ADD_LINE,
2117 "MSS_FM: %d kHz", lv24020lp_get(LV24020LP_MSS_FM) );
2118 simplelist_addline(SIMPLELIST_ADD_LINE,
2119 "MSS_IF: %d Hz", lv24020lp_get(LV24020LP_MSS_IF) );
2120 simplelist_addline(SIMPLELIST_ADD_LINE,
2121 "MSS_SD: %d Hz", lv24020lp_get(LV24020LP_MSS_SD) );
2122 simplelist_addline(SIMPLELIST_ADD_LINE,
2123 "if_set: %d Hz", lv24020lp_get(LV24020LP_IF_SET) );
2124 simplelist_addline(SIMPLELIST_ADD_LINE,
2125 "sd_set: %d Hz", lv24020lp_get(LV24020LP_SD_SET) );
2126 #endif
2127 #if (CONFIG_TUNER & S1A0903X01)
2128 simplelist_addline(SIMPLELIST_ADD_LINE,
2129 "Samsung regs: %08X", s1a0903x01_get(RADIO_ALL));
2130 /* This one doesn't return dynamic data atm */
2131 #endif
2132 #if (CONFIG_TUNER & TEA5767)
2133 struct tea5767_dbg_info nfo;
2134 tea5767_dbg_info(&nfo);
2135 simplelist_addline(SIMPLELIST_ADD_LINE, "Philips regs:");
2136 simplelist_addline(SIMPLELIST_ADD_LINE,
2137 " Read: %02X %02X %02X %02X %02X",
2138 (unsigned)nfo.read_regs[0], (unsigned)nfo.read_regs[1],
2139 (unsigned)nfo.read_regs[2], (unsigned)nfo.read_regs[3],
2140 (unsigned)nfo.read_regs[4]);
2141 simplelist_addline(SIMPLELIST_ADD_LINE,
2142 " Write: %02X %02X %02X %02X %02X",
2143 (unsigned)nfo.write_regs[0], (unsigned)nfo.write_regs[1],
2144 (unsigned)nfo.write_regs[2], (unsigned)nfo.write_regs[3],
2145 (unsigned)nfo.write_regs[4]);
2146 #endif
2147 return ACTION_REDRAW;
2149 static bool dbg_fm_radio(void)
2151 struct simplelist_info info;
2152 simplelist_info_init(&info, "FM Radio", 1, NULL);
2153 simplelist_set_line_count(0);
2154 simplelist_addline(SIMPLELIST_ADD_LINE, "HW detected: %s",
2155 radio_hardware_present() ? "yes" : "no");
2157 info.action_callback = radio_hardware_present()?radio_callback : NULL;
2158 info.hide_selection = true;
2159 return simplelist_show_list(&info);
2161 #endif /* CONFIG_TUNER */
2162 #endif /* !SIMULATOR */
2164 #ifdef HAVE_LCD_BITMAP
2165 extern bool do_screendump_instead_of_usb;
2167 static bool dbg_screendump(void)
2169 do_screendump_instead_of_usb = !do_screendump_instead_of_usb;
2170 gui_syncsplash(HZ, "Screendump %s",
2171 do_screendump_instead_of_usb?"enabled":"disabled");
2172 return false;
2174 #endif /* HAVE_LCD_BITMAP */
2176 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
2177 static bool dbg_set_memory_guard(void)
2179 static const struct opt_items names[MAXMEMGUARD] = {
2180 { "None", -1 },
2181 { "Flash ROM writes", -1 },
2182 { "Zero area (all)", -1 }
2184 int mode = system_memory_guard(MEMGUARD_KEEP);
2186 set_option( "Catch mem accesses", &mode, INT, names, MAXMEMGUARD, NULL);
2187 system_memory_guard(mode);
2189 return false;
2191 #endif /* CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) */
2193 #if defined(TOSHIBA_GIGABEAT_F) && !defined(SIMULATOR)
2195 extern volatile bool lcd_poweroff;
2197 static bool dbg_lcd_power_off(void)
2199 lcd_setmargins(0, 0);
2201 while(1)
2203 int button;
2205 lcd_clear_display();
2206 lcd_puts(0, 0, "LCD Power Off");
2207 if(lcd_poweroff)
2208 lcd_puts(1, 1, "Yes");
2209 else
2210 lcd_puts(1, 1, "No");
2212 lcd_update();
2214 button = get_action(CONTEXT_STD,HZ/5);
2215 switch(button)
2217 case ACTION_STD_PREV:
2218 case ACTION_STD_NEXT:
2219 lcd_poweroff = !lcd_poweroff;
2220 break;
2221 case ACTION_STD_OK:
2222 case ACTION_STD_CANCEL:
2223 return false;
2224 default:
2225 sleep(HZ/10);
2226 break;
2229 return false;
2231 #endif
2233 #if defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS)
2234 static bool dbg_write_eeprom(void)
2236 int fd;
2237 int rc;
2238 int old_irq_level;
2239 char buf[EEPROM_SIZE];
2240 int err;
2242 fd = open("/internal_eeprom.bin", O_RDONLY);
2244 if (fd >= 0)
2246 rc = read(fd, buf, EEPROM_SIZE);
2248 if(rc == EEPROM_SIZE)
2250 old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL);
2252 err = eeprom_24cxx_write(0, buf, sizeof buf);
2253 if (err)
2254 gui_syncsplash(HZ*3, "Eeprom write failure (%d)",err);
2255 else
2256 gui_syncsplash(HZ*3, "Eeprom written successfully");
2258 set_irq_level(old_irq_level);
2260 else
2262 gui_syncsplash(HZ*3, "File read error (%d)",rc);
2264 close(fd);
2266 else
2268 gui_syncsplash(HZ*3, "Failed to open 'internal_eeprom.bin'");
2271 return false;
2273 #endif /* defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS) */
2274 #ifdef CPU_BOOST_LOGGING
2275 static bool cpu_boost_log(void)
2277 int i = 0,j=0;
2278 int count = cpu_boost_log_getcount();
2279 int lines = LCD_HEIGHT/SYSFONT_HEIGHT;
2280 char *str;
2281 bool done;
2282 lcd_setmargins(0, 0);
2283 lcd_setfont(FONT_SYSFIXED);
2284 str = cpu_boost_log_getlog_first();
2285 while (i < count)
2287 lcd_clear_display();
2288 for(j=0; j<lines; j++,i++)
2290 if (!str)
2291 str = cpu_boost_log_getlog_next();
2292 if (str)
2294 lcd_puts(0, j,str);
2296 str = NULL;
2298 lcd_update();
2299 done = false;
2300 while (!done)
2302 switch(get_action(CONTEXT_STD,TIMEOUT_BLOCK))
2304 case ACTION_STD_OK:
2305 case ACTION_STD_PREV:
2306 case ACTION_STD_NEXT:
2307 done = true;
2308 break;
2309 case ACTION_STD_CANCEL:
2310 i = count;
2311 done = true;
2312 break;
2316 get_action(CONTEXT_STD,TIMEOUT_BLOCK);
2317 lcd_setfont(FONT_UI);
2318 return false;
2320 #endif
2322 #if (defined(HAVE_SCROLLWHEEL) && (CONFIG_KEYPAD==IPOD_4G_PAD) && !defined(SIMULATOR))
2323 extern bool wheel_is_touched;
2324 extern int old_wheel_value;
2325 extern int new_wheel_value;
2326 extern int wheel_delta;
2327 extern unsigned int accumulated_wheel_delta;
2328 extern unsigned int wheel_velocity;
2330 static bool dbg_scrollwheel(void)
2332 char buf[64];
2333 unsigned int speed;
2335 lcd_setmargins(0, 0);
2336 lcd_setfont(FONT_SYSFIXED);
2338 while (1)
2340 if (action_userabort(HZ/10))
2341 return false;
2343 lcd_clear_display();
2345 /* show internal variables of scrollwheel driver */
2346 snprintf(buf, sizeof(buf), "wheel touched: %s", (wheel_is_touched) ? "true" : "false");
2347 lcd_puts(0, 0, buf);
2348 snprintf(buf, sizeof(buf), "new position: %2d", new_wheel_value);
2349 lcd_puts(0, 1, buf);
2350 snprintf(buf, sizeof(buf), "old position: %2d", old_wheel_value);
2351 lcd_puts(0, 2, buf);
2352 snprintf(buf, sizeof(buf), "wheel delta: %2d", wheel_delta);
2353 lcd_puts(0, 3, buf);
2354 snprintf(buf, sizeof(buf), "accumulated delta: %2d", accumulated_wheel_delta);
2355 lcd_puts(0, 4, buf);
2356 snprintf(buf, sizeof(buf), "velo [deg/s]: %4d", (int)wheel_velocity);
2357 lcd_puts(0, 5, buf);
2359 /* show effective accelerated scrollspeed */
2360 speed = button_apply_acceleration( (1<<31)|(1<<24)|wheel_velocity);
2361 snprintf(buf, sizeof(buf), "accel. speed: %4d", speed);
2362 lcd_puts(0, 6, buf);
2364 lcd_update();
2366 return false;
2368 #endif
2370 #if defined(HAVE_USBSTACK) && defined(ROCKBOX_HAS_LOGF) && defined(USB_SERIAL)
2371 static bool logf_usb_serial(void)
2373 bool serial_enabled = !usb_core_driver_enabled(USB_DRIVER_SERIAL);
2374 usb_core_enable_driver(USB_DRIVER_SERIAL,serial_enabled);
2375 gui_syncsplash(HZ, "USB logf %s",
2376 serial_enabled?"enabled":"disabled");
2377 return false;
2379 #endif
2382 /****** The menu *********/
2383 struct the_menu_item {
2384 unsigned char *desc; /* string or ID */
2385 bool (*function) (void); /* return true if USB was connected */
2387 static const struct the_menu_item menuitems[] = {
2388 #if defined(TOSHIBA_GIGABEAT_F) && !defined(SIMULATOR)
2389 { "LCD Power Off", dbg_lcd_power_off },
2390 #endif
2391 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || \
2392 (defined(CPU_PP) && !(defined(SANSA_E200) || defined(SANSA_C200)))
2393 { "Dump ROM contents", dbg_save_roms },
2394 #endif
2395 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || defined(CPU_PP) || CONFIG_CPU == S3C2440
2396 { "View I/O ports", dbg_ports },
2397 #endif
2398 #if (CONFIG_RTC == RTC_PCF50605) && !defined(SIMULATOR)
2399 { "View PCF registers", dbg_pcf },
2400 #endif
2401 #if defined(HAVE_TSC2100) && !defined(SIMULATOR)
2402 { "TSC2100 debug", tsc2100_debug },
2403 #endif
2404 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
2405 { "CPU frequency", dbg_cpufreq },
2406 #endif
2407 #if defined(IRIVER_H100_SERIES) && !defined(SIMULATOR)
2408 { "S/PDIF analyzer", dbg_spdif },
2409 #endif
2410 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
2411 { "Catch mem accesses", dbg_set_memory_guard },
2412 #endif
2413 { "View OS stacks", dbg_os },
2414 #ifdef HAVE_LCD_BITMAP
2415 #ifndef SIMULATOR
2416 { "View battery", view_battery },
2417 #endif
2418 { "Screendump", dbg_screendump },
2419 #endif
2420 #ifndef SIMULATOR
2421 { "View HW info", dbg_hw_info },
2422 #endif
2423 #ifndef SIMULATOR
2424 { "View partitions", dbg_partitions },
2425 #endif
2426 #ifndef SIMULATOR
2427 { "View disk info", dbg_disk_info },
2428 #if !defined(HAVE_MMC) && !defined(HAVE_HOTSWAP)
2429 { "Dump ATA identify info", dbg_identify_info},
2430 #endif
2431 #endif
2432 #ifdef HAVE_DIRCACHE
2433 { "View dircache info", dbg_dircache_info },
2434 #endif
2435 #ifdef HAVE_TAGCACHE
2436 { "View database info", dbg_tagcache_info },
2437 #endif
2438 #ifdef HAVE_LCD_BITMAP
2439 #if CONFIG_CODEC == SWCODEC
2440 { "View buffering thread", dbg_buffering_thread },
2441 #elif !defined(SIMULATOR)
2442 { "View audio thread", dbg_audio_thread },
2443 #endif
2444 #ifdef PM_DEBUG
2445 { "pm histogram", peak_meter_histogram},
2446 #endif /* PM_DEBUG */
2447 #endif /* HAVE_LCD_BITMAP */
2448 #ifndef SIMULATOR
2449 #if CONFIG_TUNER
2450 { "FM Radio", dbg_fm_radio },
2451 #endif
2452 #endif
2453 #if defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS)
2454 { "Write back EEPROM", dbg_write_eeprom },
2455 #endif
2456 #ifdef ROCKBOX_HAS_LOGF
2457 {"logf", logfdisplay },
2458 {"logfdump", logfdump },
2459 #endif
2460 #if defined(HAVE_USBSTACK) && defined(ROCKBOX_HAS_LOGF) && defined(USB_SERIAL)
2461 {"logf over usb",logf_usb_serial },
2462 #endif
2463 #ifdef CPU_BOOST_LOGGING
2464 {"cpu_boost log",cpu_boost_log},
2465 #endif
2466 #if (defined(HAVE_SCROLLWHEEL) && (CONFIG_KEYPAD==IPOD_4G_PAD) && !defined(SIMULATOR))
2467 {"Debug scrollwheel", dbg_scrollwheel},
2468 #endif
2470 static int menu_action_callback(int btn, struct gui_synclist *lists)
2472 if (btn == ACTION_STD_OK)
2474 menuitems[gui_synclist_get_sel_pos(lists)].function();
2475 btn = ACTION_REDRAW;
2477 return btn;
2479 static char* dbg_menu_getname(int item, void * data, char *buffer)
2481 (void)data; (void)buffer;
2482 return menuitems[item].desc;
2484 bool debug_menu(void)
2486 struct simplelist_info info;
2488 simplelist_info_init(&info, "Debug Menu", ARRAYLEN(menuitems), NULL);
2489 info.action_callback = menu_action_callback;
2490 info.get_name = dbg_menu_getname;
2492 return simplelist_show_list(&info);