Update installation document a bit to catch up with recent changes. Add notes about...
[Rockbox.git] / apps / debug_menu.c
blob5c8a7f965ff3ff95cbf58f1c8522aca42a72f853
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 #include "playback.h"
81 #if defined(HAVE_SPDIF_OUT) || defined(HAVE_SPDIF_IN)
82 #include "spdif.h"
83 #endif
84 #endif
85 #ifdef IRIVER_H300_SERIES
86 #include "pcf50606.h" /* for pcf50606_read */
87 #endif
88 #ifdef IAUDIO_X5
89 #include "ds2411.h"
90 #endif
91 #include "hwcompat.h"
92 #include "button.h"
93 #if CONFIG_RTC == RTC_PCF50605
94 #include "pcf50605.h"
95 #endif
97 #if CONFIG_CPU == DM320 || CONFIG_CPU == S3C2440 || CONFIG_CPU == TCC7801
98 #include "debug-target.h"
99 #endif
101 #if defined(SANSA_E200)
102 #include "i2c-pp.h"
103 #include "as3514.h"
104 #endif
106 #if defined(HAVE_USBSTACK)
107 #include "usb_core.h"
108 #endif
109 #ifdef USB_STORAGE
110 #include "../firmware/usbstack/usb_storage.h"
111 #endif
113 /*---------------------------------------------------*/
114 /* SPECIAL DEBUG STUFF */
115 /*---------------------------------------------------*/
116 extern struct thread_entry threads[MAXTHREADS];
118 static char thread_status_char(unsigned status)
120 static const char thread_status_chars[THREAD_NUM_STATES+1] =
122 [0 ... THREAD_NUM_STATES] = '?',
123 [STATE_RUNNING] = 'R',
124 [STATE_BLOCKED] = 'B',
125 [STATE_SLEEPING] = 'S',
126 [STATE_BLOCKED_W_TMO] = 'T',
127 [STATE_FROZEN] = 'F',
128 [STATE_KILLED] = 'K',
131 if (status > THREAD_NUM_STATES)
132 status = THREAD_NUM_STATES;
134 return thread_status_chars[status];
137 static char* threads_getname(int selected_item, void * data, char *buffer)
139 (void)data;
140 struct thread_entry *thread;
141 char name[32];
143 #if NUM_CORES > 1
144 if (selected_item < (int)NUM_CORES)
146 snprintf(buffer, MAX_PATH, "Idle (%d): %2d%%", selected_item,
147 idle_stack_usage(selected_item));
148 return buffer;
151 selected_item -= NUM_CORES;
152 #endif
154 thread = &threads[selected_item];
156 if (thread->state == STATE_KILLED)
158 snprintf(buffer, MAX_PATH, "%2d: ---", selected_item);
159 return buffer;
162 thread_get_name(name, 32, thread);
164 snprintf(buffer, MAX_PATH,
165 "%2d: " IF_COP("(%d) ") "%c%c " IF_PRIO("%d %d ") "%2d%% %s",
166 selected_item,
167 IF_COP(thread->core,)
168 #ifdef HAVE_SCHEDULER_BOOSTCTRL
169 (thread->cpu_boost) ? '+' :
170 #endif
171 ((thread->state == STATE_RUNNING) ? '*' : ' '),
172 thread_status_char(thread->state),
173 IF_PRIO(thread->base_priority, thread->priority, )
174 thread_stack_usage(thread), name);
176 return buffer;
178 static int dbg_threads_action_callback(int action, struct gui_synclist *lists)
180 (void)lists;
181 #ifdef ROCKBOX_HAS_LOGF
182 if (action == ACTION_STD_OK)
184 int selpos = gui_synclist_get_sel_pos(lists);
185 #if NUM_CORES > 1
186 if (selpos >= NUM_CORES)
187 remove_thread(&threads[selpos - NUM_CORES]);
188 #else
189 remove_thread(&threads[selpos]);
190 #endif
191 return ACTION_REDRAW;
193 #endif /* ROCKBOX_HAS_LOGF */
194 if (action == ACTION_NONE)
195 action = ACTION_REDRAW;
196 return action;
198 /* Test code!!! */
199 static bool dbg_os(void)
201 struct simplelist_info info;
202 simplelist_info_init(&info, IF_COP("Core and ") "Stack usage:",
203 #if NUM_CORES == 1
204 MAXTHREADS,
205 #else
206 MAXTHREADS+NUM_CORES,
207 #endif
208 NULL);
209 #ifndef ROCKBOX_HAS_LOGF
210 info.hide_selection = true;
211 #endif
212 info.action_callback = dbg_threads_action_callback;
213 info.get_name = threads_getname;
214 return simplelist_show_list(&info);
217 #ifdef HAVE_LCD_BITMAP
218 #if CONFIG_CODEC != SWCODEC
219 #ifndef SIMULATOR
220 static bool dbg_audio_thread(void)
222 char buf[32];
223 struct audio_debug d;
225 lcd_setmargins(0, 0);
226 lcd_setfont(FONT_SYSFIXED);
228 while(1)
230 if (action_userabort(HZ/5))
231 return false;
233 audio_get_debugdata(&d);
235 lcd_clear_display();
237 snprintf(buf, sizeof(buf), "read: %x", d.audiobuf_read);
238 lcd_puts(0, 0, buf);
239 snprintf(buf, sizeof(buf), "write: %x", d.audiobuf_write);
240 lcd_puts(0, 1, buf);
241 snprintf(buf, sizeof(buf), "swap: %x", d.audiobuf_swapwrite);
242 lcd_puts(0, 2, buf);
243 snprintf(buf, sizeof(buf), "playing: %d", d.playing);
244 lcd_puts(0, 3, buf);
245 snprintf(buf, sizeof(buf), "playable: %x", d.playable_space);
246 lcd_puts(0, 4, buf);
247 snprintf(buf, sizeof(buf), "unswapped: %x", d.unswapped_space);
248 lcd_puts(0, 5, buf);
250 /* Playable space left */
251 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, 6*8, 112, 4, d.audiobuflen, 0,
252 d.playable_space, HORIZONTAL);
254 /* Show the watermark limit */
255 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, 6*8+4, 112, 4, d.audiobuflen, 0,
256 d.low_watermark_level, HORIZONTAL);
258 snprintf(buf, sizeof(buf), "wm: %x - %x",
259 d.low_watermark_level, d.lowest_watermark_level);
260 lcd_puts(0, 7, buf);
262 lcd_update();
264 return false;
266 #endif /* !SIMULATOR */
267 #else /* CONFIG_CODEC == SWCODEC */
268 extern size_t filebuflen;
269 /* This is a size_t, but call it a long so it puts a - when it's bad. */
271 static unsigned int ticks, boost_ticks;
273 static void dbg_audio_task(void)
275 #ifndef SIMULATOR
276 if(FREQ > CPUFREQ_NORMAL)
277 boost_ticks++;
278 #endif
280 ticks++;
283 static bool dbg_buffering_thread(void)
285 char buf[32];
286 int button;
287 int line;
288 bool done = false;
289 size_t bufused;
290 size_t bufsize = pcmbuf_get_bufsize();
291 int pcmbufdescs = pcmbuf_descs();
292 struct buffering_debug d;
294 ticks = boost_ticks = 0;
296 tick_add_task(dbg_audio_task);
298 lcd_setmargins(0, 0);
299 lcd_setfont(FONT_SYSFIXED);
300 while(!done)
302 button = get_action(CONTEXT_STD,HZ/5);
303 switch(button)
305 case ACTION_STD_NEXT:
306 audio_next();
307 break;
308 case ACTION_STD_PREV:
309 audio_prev();
310 break;
311 case ACTION_STD_CANCEL:
312 done = true;
313 break;
316 buffering_get_debugdata(&d);
318 line = 0;
319 lcd_clear_display();
321 bufused = bufsize - pcmbuf_free();
323 snprintf(buf, sizeof(buf), "pcm: %7ld/%7ld", (long) bufused, (long) bufsize);
324 lcd_puts(0, line++, buf);
326 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6,
327 bufsize, 0, bufused, HORIZONTAL);
328 line++;
330 snprintf(buf, sizeof(buf), "alloc: %8ld/%8ld", audio_filebufused(),
331 (long) filebuflen);
332 lcd_puts(0, line++, buf);
334 #if LCD_HEIGHT > 80
335 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6,
336 filebuflen, 0, audio_filebufused(), HORIZONTAL);
337 line++;
339 snprintf(buf, sizeof(buf), "real: %8ld/%8ld", (long)d.buffered_data,
340 (long)filebuflen);
341 lcd_puts(0, line++, buf);
343 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6,
344 filebuflen, 0, (long)d.buffered_data, HORIZONTAL);
345 line++;
346 #endif
348 snprintf(buf, sizeof(buf), "usefl: %8ld/%8ld", (long)(d.useful_data),
349 (long)filebuflen);
350 lcd_puts(0, line++, buf);
352 #if LCD_HEIGHT > 80
353 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6,
354 filebuflen, 0, d.useful_data, HORIZONTAL);
355 line++;
356 #endif
358 snprintf(buf, sizeof(buf), "data_rem: %ld", (long)d.data_rem);
359 lcd_puts(0, line++, buf);
361 snprintf(buf, sizeof(buf), "track count: %2d", audio_track_count());
362 lcd_puts(0, line++, buf);
364 snprintf(buf, sizeof(buf), "handle count: %d", (int)d.num_handles);
365 lcd_puts(0, line++, buf);
367 #ifndef SIMULATOR
368 snprintf(buf, sizeof(buf), "cpu freq: %3dMHz",
369 (int)((FREQ + 500000) / 1000000));
370 lcd_puts(0, line++, buf);
371 #endif
373 if (ticks > 0)
375 snprintf(buf, sizeof(buf), "boost ratio: %3d%%",
376 boost_ticks * 100 / ticks);
377 lcd_puts(0, line++, buf);
380 snprintf(buf, sizeof(buf), "pcmbufdesc: %2d/%2d",
381 pcmbuf_used_descs(), pcmbufdescs);
382 lcd_puts(0, line++, buf);
384 lcd_update();
387 tick_remove_task(dbg_audio_task);
389 return false;
391 #endif /* CONFIG_CODEC */
392 #endif /* HAVE_LCD_BITMAP */
395 #if (CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE))
396 /* Tool function to read the flash manufacturer and type, if available.
397 Only chips which could be reprogrammed in system will return values.
398 (The mode switch addresses vary between flash manufacturers, hence addr1/2) */
399 /* In IRAM to avoid problems when running directly from Flash */
400 static bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
401 unsigned addr1, unsigned addr2)
402 ICODE_ATTR __attribute__((noinline));
403 static bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
404 unsigned addr1, unsigned addr2)
407 unsigned not_manu, not_id; /* read values before switching to ID mode */
408 unsigned manu, id; /* read values when in ID mode */
410 #if CONFIG_CPU == SH7034
411 volatile unsigned char* flash = (unsigned char*)0x2000000; /* flash mapping */
412 #elif defined(CPU_COLDFIRE)
413 volatile unsigned short* flash = (unsigned short*)0; /* flash mapping */
414 #endif
415 int old_level; /* saved interrupt level */
417 not_manu = flash[0]; /* read the normal content */
418 not_id = flash[1]; /* should be 'A' (0x41) and 'R' (0x52) from the "ARCH" marker */
420 /* disable interrupts, prevent any stray flash access */
421 old_level = disable_irq_save();
423 flash[addr1] = 0xAA; /* enter command mode */
424 flash[addr2] = 0x55;
425 flash[addr1] = 0x90; /* ID command */
426 /* Atmel wants 20ms pause here */
427 /* sleep(HZ/50); no sleeping possible while interrupts are disabled */
429 manu = flash[0]; /* read the IDs */
430 id = flash[1];
432 flash[0] = 0xF0; /* reset flash (back to normal read mode) */
433 /* Atmel wants 20ms pause here */
434 /* sleep(HZ/50); no sleeping possible while interrupts are disabled */
436 restore_irq(old_level); /* enable interrupts again */
438 /* I assume success if the obtained values are different from
439 the normal flash content. This is not perfectly bulletproof, they
440 could theoretically be the same by chance, causing us to fail. */
441 if (not_manu != manu || not_id != id) /* a value has changed */
443 *p_manufacturer = manu; /* return the results */
444 *p_device = id;
445 return true; /* success */
447 return false; /* fail */
449 #endif /* (CONFIG_CPU == SH7034 || CPU_COLDFIRE) */
451 #ifndef SIMULATOR
452 #ifdef CPU_PP
453 static int perfcheck(void)
455 int result;
457 asm (
458 "mrs r2, CPSR \n"
459 "orr r0, r2, #0xc0 \n" /* disable IRQ and FIQ */
460 "msr CPSR_c, r0 \n"
461 "mov %[res], #0 \n"
462 "ldr r0, [%[timr]] \n"
463 "add r0, r0, %[tmo] \n"
464 "1: \n"
465 "add %[res], %[res], #1 \n"
466 "ldr r1, [%[timr]] \n"
467 "cmp r1, r0 \n"
468 "bmi 1b \n"
469 "msr CPSR_c, r2 \n" /* reset IRQ and FIQ state */
471 [res]"=&r"(result)
473 [timr]"r"(&USEC_TIMER),
474 [tmo]"r"(
475 #if CONFIG_CPU == PP5002
476 16000
477 #else /* PP5020/5022/5024 */
478 10226
479 #endif
482 "r0", "r1", "r2"
484 return result;
486 #endif
488 #ifdef HAVE_LCD_BITMAP
489 static bool dbg_hw_info(void)
491 #if CONFIG_CPU == SH7034
492 char buf[32];
493 int bitmask = HW_MASK;
494 int rom_version = ROM_VERSION;
495 unsigned manu, id; /* flash IDs */
496 bool got_id; /* flag if we managed to get the flash IDs */
497 unsigned rom_crc = 0xffffffff; /* CRC32 of the boot ROM */
498 bool has_bootrom; /* flag for boot ROM present */
499 int oldmode; /* saved memory guard mode */
501 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
503 /* get flash ROM type */
504 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
505 if (!got_id)
506 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
508 /* check if the boot ROM area is a flash mirror */
509 has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0);
510 if (has_bootrom) /* if ROM and Flash different */
512 /* calculate CRC16 checksum of boot ROM */
513 rom_crc = crc_32((unsigned char*)0x0000, 64*1024, 0xffffffff);
516 system_memory_guard(oldmode); /* re-enable memory guard */
518 lcd_setmargins(0, 0);
519 lcd_setfont(FONT_SYSFIXED);
520 lcd_clear_display();
522 lcd_puts(0, 0, "[Hardware info]");
524 snprintf(buf, 32, "ROM: %d.%02d", rom_version/100, rom_version%100);
525 lcd_puts(0, 1, buf);
527 snprintf(buf, 32, "Mask: 0x%04x", bitmask);
528 lcd_puts(0, 2, buf);
530 if (got_id)
531 snprintf(buf, 32, "Flash: M=%02x D=%02x", manu, id);
532 else
533 snprintf(buf, 32, "Flash: M=?? D=??"); /* unknown, sorry */
534 lcd_puts(0, 3, buf);
536 if (has_bootrom)
538 if (rom_crc == 0x56DBA4EE) /* known Version 1 */
539 snprintf(buf, 32, "Boot ROM: V1");
540 else
541 snprintf(buf, 32, "ROMcrc: 0x%08x", rom_crc);
543 else
545 snprintf(buf, 32, "Boot ROM: none");
547 lcd_puts(0, 4, buf);
549 lcd_update();
551 while (!(action_userabort(TIMEOUT_BLOCK)));
553 #elif CONFIG_CPU == MCF5249 || CONFIG_CPU == MCF5250
554 char buf[32];
555 unsigned manu, id; /* flash IDs */
556 int got_id; /* flag if we managed to get the flash IDs */
557 int oldmode; /* saved memory guard mode */
558 int line = 0;
560 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
562 /* get flash ROM type */
563 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
564 if (!got_id)
565 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
567 system_memory_guard(oldmode); /* re-enable memory guard */
569 lcd_setmargins(0, 0);
570 lcd_setfont(FONT_SYSFIXED);
571 lcd_clear_display();
573 lcd_puts(0, line++, "[Hardware info]");
575 if (got_id)
576 snprintf(buf, 32, "Flash: M=%04x D=%04x", manu, id);
577 else
578 snprintf(buf, 32, "Flash: M=???? D=????"); /* unknown, sorry */
579 lcd_puts(0, line++, buf);
581 #ifdef IAUDIO_X5
583 struct ds2411_id id;
585 lcd_puts(0, ++line, "Serial Number:");
587 got_id = ds2411_read_id(&id);
589 if (got_id == DS2411_OK)
591 snprintf(buf, 32, " FC=%02x", (unsigned)id.family_code);
592 lcd_puts(0, ++line, buf);
593 snprintf(buf, 32, " ID=%02X %02X %02X %02X %02X %02X",
594 (unsigned)id.uid[0], (unsigned)id.uid[1], (unsigned)id.uid[2],
595 (unsigned)id.uid[3], (unsigned)id.uid[4], (unsigned)id.uid[5]);
596 lcd_puts(0, ++line, buf);
597 snprintf(buf, 32, " CRC=%02X", (unsigned)id.crc);
599 else
601 snprintf(buf, 32, "READ ERR=%d", got_id);
604 lcd_puts(0, ++line, buf);
606 #endif
608 lcd_update();
610 while (!(action_userabort(TIMEOUT_BLOCK)));
612 #elif defined(CPU_PP502x)
613 int line = 0;
614 char buf[32];
615 char pp_version[] = { (PP_VER2 >> 24) & 0xff, (PP_VER2 >> 16) & 0xff,
616 (PP_VER2 >> 8) & 0xff, (PP_VER2) & 0xff,
617 (PP_VER1 >> 24) & 0xff, (PP_VER1 >> 16) & 0xff,
618 (PP_VER1 >> 8) & 0xff, (PP_VER1) & 0xff, '\0' };
620 lcd_setmargins(0, 0);
621 lcd_setfont(FONT_SYSFIXED);
622 lcd_clear_display();
624 lcd_puts(0, line++, "[Hardware info]");
626 #ifdef IPOD_ARCH
627 snprintf(buf, sizeof(buf), "HW rev: 0x%08lx", IPOD_HW_REVISION);
628 lcd_puts(0, line++, buf);
629 #endif
631 #ifdef IPOD_COLOR
632 extern int lcd_type; /* Defined in lcd-colornano.c */
634 snprintf(buf, sizeof(buf), "LCD type: %d", lcd_type);
635 lcd_puts(0, line++, buf);
636 #endif
638 snprintf(buf, sizeof(buf), "PP version: %s", pp_version);
639 lcd_puts(0, line++, buf);
641 snprintf(buf, sizeof(buf), "Est. clock (kHz): %d", perfcheck());
642 lcd_puts(0, line++, buf);
644 lcd_update();
646 while (!(action_userabort(TIMEOUT_BLOCK)));
648 #elif CONFIG_CPU == PP5002
649 int line = 0;
650 char buf[32];
651 char pp_version[] = { (PP_VER4 >> 8) & 0xff, PP_VER4 & 0xff,
652 (PP_VER3 >> 8) & 0xff, PP_VER3 & 0xff,
653 (PP_VER2 >> 8) & 0xff, PP_VER2 & 0xff,
654 (PP_VER1 >> 8) & 0xff, PP_VER1 & 0xff, '\0' };
657 lcd_setmargins(0, 0);
658 lcd_setfont(FONT_SYSFIXED);
659 lcd_clear_display();
661 lcd_puts(0, line++, "[Hardware info]");
663 #ifdef IPOD_ARCH
664 snprintf(buf, sizeof(buf), "HW rev: 0x%08lx", IPOD_HW_REVISION);
665 lcd_puts(0, line++, buf);
666 #endif
668 snprintf(buf, sizeof(buf), "PP version: %s", pp_version);
669 lcd_puts(0, line++, buf);
671 snprintf(buf, sizeof(buf), "Est. clock (kHz): %d", perfcheck());
672 lcd_puts(0, line++, buf);
674 lcd_update();
676 while (!(action_userabort(TIMEOUT_BLOCK)));
677 #else
678 /* Define this function in your target tree */
679 return __dbg_hw_info();
680 #endif /* CONFIG_CPU */
681 return false;
683 #else /* !HAVE_LCD_BITMAP */
684 static bool dbg_hw_info(void)
686 char buf[32];
687 int button;
688 int currval = 0;
689 int rom_version = ROM_VERSION;
690 unsigned manu, id; /* flash IDs */
691 bool got_id; /* flag if we managed to get the flash IDs */
692 unsigned rom_crc = 0xffffffff; /* CRC32 of the boot ROM */
693 bool has_bootrom; /* flag for boot ROM present */
694 int oldmode; /* saved memory guard mode */
696 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
698 /* get flash ROM type */
699 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
700 if (!got_id)
701 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
703 /* check if the boot ROM area is a flash mirror */
704 has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0);
705 if (has_bootrom) /* if ROM and Flash different */
707 /* calculate CRC16 checksum of boot ROM */
708 rom_crc = crc_32((unsigned char*)0x0000, 64*1024, 0xffffffff);
711 system_memory_guard(oldmode); /* re-enable memory guard */
713 lcd_clear_display();
715 lcd_puts(0, 0, "[HW Info]");
716 while(1)
718 switch(currval)
720 case 0:
721 snprintf(buf, 32, "ROM: %d.%02d",
722 rom_version/100, rom_version%100);
723 break;
724 case 1:
725 if (got_id)
726 snprintf(buf, 32, "Flash:%02x,%02x", manu, id);
727 else
728 snprintf(buf, 32, "Flash:??,??"); /* unknown, sorry */
729 break;
730 case 2:
731 if (has_bootrom)
733 if (rom_crc == 0x56DBA4EE) /* known Version 1 */
734 snprintf(buf, 32, "BootROM: V1");
735 else if (rom_crc == 0x358099E8)
736 snprintf(buf, 32, "BootROM: V2");
737 /* alternative boot ROM found in one single player so far */
738 else
739 snprintf(buf, 32, "R: %08x", rom_crc);
741 else
742 snprintf(buf, 32, "BootROM: no");
745 lcd_puts(0, 1, buf);
746 lcd_update();
748 button = get_action(CONTEXT_SETTINGS,TIMEOUT_BLOCK);
750 switch(button)
752 case ACTION_STD_CANCEL:
753 return false;
755 case ACTION_SETTINGS_DEC:
756 currval--;
757 if(currval < 0)
758 currval = 2;
759 break;
761 case ACTION_SETTINGS_INC:
762 currval++;
763 if(currval > 2)
764 currval = 0;
765 break;
768 return false;
770 #endif /* !HAVE_LCD_BITMAP */
771 #endif /* !SIMULATOR */
773 #ifndef SIMULATOR
774 static char* dbg_partitions_getname(int selected_item, void * data, char *buffer)
776 (void)data;
777 int partition = selected_item/2;
778 struct partinfo* p = disk_partinfo(partition);
779 if (selected_item%2)
781 snprintf(buffer, MAX_PATH, " T:%x %ld MB", p->type, p->size / 2048);
783 else
785 snprintf(buffer, MAX_PATH, "P%d: S:%lx", partition, p->start);
787 return buffer;
790 bool dbg_partitions(void)
792 struct simplelist_info info;
793 simplelist_info_init(&info, "Partition Info", 4, NULL);
794 info.selection_size = 2;
795 info.hide_selection = true;
796 info.get_name = dbg_partitions_getname;
797 return simplelist_show_list(&info);
799 #endif
801 #if defined(CPU_COLDFIRE) && defined(HAVE_SPDIF_OUT)
802 static bool dbg_spdif(void)
804 char buf[128];
805 int line;
806 unsigned int control;
807 int x;
808 char *s;
809 int category;
810 int generation;
811 unsigned int interruptstat;
812 bool valnogood, symbolerr, parityerr;
813 bool done = false;
814 bool spdif_src_on;
815 int spdif_source = spdif_get_output_source(&spdif_src_on);
816 spdif_set_output_source(AUDIO_SRC_SPDIF IF_SPDIF_POWER_(, true));
818 lcd_setmargins(0, 0);
819 lcd_clear_display();
820 lcd_setfont(FONT_SYSFIXED);
822 #ifdef HAVE_SPDIF_POWER
823 spdif_power_enable(true); /* We need SPDIF power for both sending & receiving */
824 #endif
826 while (!done)
828 line = 0;
830 control = EBU1RCVCCHANNEL1;
831 interruptstat = INTERRUPTSTAT;
832 INTERRUPTCLEAR = 0x03c00000;
834 valnogood = (interruptstat & 0x01000000)?true:false;
835 symbolerr = (interruptstat & 0x00800000)?true:false;
836 parityerr = (interruptstat & 0x00400000)?true:false;
838 snprintf(buf, sizeof(buf), "Val: %s Sym: %s Par: %s",
839 valnogood?"--":"OK",
840 symbolerr?"--":"OK",
841 parityerr?"--":"OK");
842 lcd_puts(0, line++, buf);
844 snprintf(buf, sizeof(buf), "Status word: %08x", (int)control);
845 lcd_puts(0, line++, buf);
847 line++;
849 x = control >> 31;
850 snprintf(buf, sizeof(buf), "PRO: %d (%s)",
851 x, x?"Professional":"Consumer");
852 lcd_puts(0, line++, buf);
854 x = (control >> 30) & 1;
855 snprintf(buf, sizeof(buf), "Audio: %d (%s)",
856 x, x?"Non-PCM":"PCM");
857 lcd_puts(0, line++, buf);
859 x = (control >> 29) & 1;
860 snprintf(buf, sizeof(buf), "Copy: %d (%s)",
861 x, x?"Permitted":"Inhibited");
862 lcd_puts(0, line++, buf);
864 x = (control >> 27) & 7;
865 switch(x)
867 case 0:
868 s = "None";
869 break;
870 case 1:
871 s = "50/15us";
872 break;
873 default:
874 s = "Reserved";
875 break;
877 snprintf(buf, sizeof(buf), "Preemphasis: %d (%s)", x, s);
878 lcd_puts(0, line++, buf);
880 x = (control >> 24) & 3;
881 snprintf(buf, sizeof(buf), "Mode: %d", x);
882 lcd_puts(0, line++, buf);
884 category = (control >> 17) & 127;
885 switch(category)
887 case 0x00:
888 s = "General";
889 break;
890 case 0x40:
891 s = "Audio CD";
892 break;
893 default:
894 s = "Unknown";
896 snprintf(buf, sizeof(buf), "Category: 0x%02x (%s)", category, s);
897 lcd_puts(0, line++, buf);
899 x = (control >> 16) & 1;
900 generation = x;
901 if(((category & 0x70) == 0x10) ||
902 ((category & 0x70) == 0x40) ||
903 ((category & 0x78) == 0x38))
905 generation = !generation;
907 snprintf(buf, sizeof(buf), "Generation: %d (%s)",
908 x, generation?"Original":"No ind.");
909 lcd_puts(0, line++, buf);
911 x = (control >> 12) & 15;
912 snprintf(buf, sizeof(buf), "Source: %d", x);
913 lcd_puts(0, line++, buf);
915 x = (control >> 8) & 15;
916 switch(x)
918 case 0:
919 s = "Unspecified";
920 break;
921 case 8:
922 s = "A (Left)";
923 break;
924 case 4:
925 s = "B (Right)";
926 break;
927 default:
928 s = "";
929 break;
931 snprintf(buf, sizeof(buf), "Channel: %d (%s)", x, s);
932 lcd_puts(0, line++, buf);
934 x = (control >> 4) & 15;
935 switch(x)
937 case 0:
938 s = "44.1kHz";
939 break;
940 case 0x4:
941 s = "48kHz";
942 break;
943 case 0xc:
944 s = "32kHz";
945 break;
947 snprintf(buf, sizeof(buf), "Frequency: %d (%s)", x, s);
948 lcd_puts(0, line++, buf);
950 x = (control >> 2) & 3;
951 snprintf(buf, sizeof(buf), "Clock accuracy: %d", x);
952 lcd_puts(0, line++, buf);
953 line++;
955 #ifndef SIMULATOR
956 snprintf(buf, sizeof(buf), "Measured freq: %ldHz",
957 spdif_measure_frequency());
958 lcd_puts(0, line++, buf);
959 #endif
961 lcd_update();
963 if (action_userabort(HZ/10))
964 break;
967 spdif_set_output_source(spdif_source IF_SPDIF_POWER_(, spdif_src_on));
969 #ifdef HAVE_SPDIF_POWER
970 spdif_power_enable(global_settings.spdif_enable);
971 #endif
973 return false;
975 #endif /* CPU_COLDFIRE */
977 #ifndef SIMULATOR
978 #ifdef HAVE_LCD_BITMAP
979 /* button definitions */
980 #if (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
981 (CONFIG_KEYPAD == IRIVER_H300_PAD)
982 # define DEBUG_CANCEL BUTTON_OFF
984 #elif CONFIG_KEYPAD == RECORDER_PAD
985 # define DEBUG_CANCEL BUTTON_OFF
987 #elif CONFIG_KEYPAD == ONDIO_PAD
988 # define DEBUG_CANCEL BUTTON_MENU
990 #elif (CONFIG_KEYPAD == IPOD_1G2G_PAD) || \
991 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
992 (CONFIG_KEYPAD == IPOD_4G_PAD)
993 # define DEBUG_CANCEL BUTTON_MENU
995 #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
996 # define DEBUG_CANCEL BUTTON_PLAY
998 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
999 # define DEBUG_CANCEL BUTTON_REC
1001 #elif (CONFIG_KEYPAD == IAUDIO_M3_PAD)
1002 # define DEBUG_CANCEL BUTTON_RC_REC
1004 #elif (CONFIG_KEYPAD == IRIVER_H10_PAD)
1005 # define DEBUG_CANCEL BUTTON_REW
1007 #elif (CONFIG_KEYPAD == MROBE100_PAD)
1008 # define DEBUG_CANCEL BUTTON_MENU
1010 #elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \
1011 (CONFIG_KEYPAD == SANSA_C200_PAD)
1012 # define DEBUG_CANCEL BUTTON_LEFT
1013 #endif /* key definitions */
1015 /* Test code!!! */
1016 bool dbg_ports(void)
1018 #if CONFIG_CPU == SH7034
1019 char buf[32];
1020 int adc_battery_voltage, adc_battery_level;
1022 lcd_setfont(FONT_SYSFIXED);
1023 lcd_setmargins(0, 0);
1024 lcd_clear_display();
1026 while(1)
1028 snprintf(buf, 32, "PADR: %04x", (unsigned short)PADR);
1029 lcd_puts(0, 0, buf);
1030 snprintf(buf, 32, "PBDR: %04x", (unsigned short)PBDR);
1031 lcd_puts(0, 1, buf);
1033 snprintf(buf, 32, "AN0: %03x AN4: %03x", adc_read(0), adc_read(4));
1034 lcd_puts(0, 2, buf);
1035 snprintf(buf, 32, "AN1: %03x AN5: %03x", adc_read(1), adc_read(5));
1036 lcd_puts(0, 3, buf);
1037 snprintf(buf, 32, "AN2: %03x AN6: %03x", adc_read(2), adc_read(6));
1038 lcd_puts(0, 4, buf);
1039 snprintf(buf, 32, "AN3: %03x AN7: %03x", adc_read(3), adc_read(7));
1040 lcd_puts(0, 5, buf);
1042 battery_read_info(&adc_battery_voltage, &adc_battery_level);
1043 snprintf(buf, 32, "Batt: %d.%03dV %d%% ", adc_battery_voltage / 1000,
1044 adc_battery_voltage % 1000, adc_battery_level);
1045 lcd_puts(0, 6, buf);
1047 lcd_update();
1048 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1049 return false;
1051 #elif defined(CPU_COLDFIRE)
1052 unsigned int gpio_out;
1053 unsigned int gpio1_out;
1054 unsigned int gpio_read;
1055 unsigned int gpio1_read;
1056 unsigned int gpio_function;
1057 unsigned int gpio1_function;
1058 unsigned int gpio_enable;
1059 unsigned int gpio1_enable;
1060 int adc_buttons, adc_remote;
1061 int adc_battery_voltage, adc_battery_level;
1062 char buf[128];
1063 int line;
1065 lcd_setmargins(0, 0);
1066 lcd_clear_display();
1067 lcd_setfont(FONT_SYSFIXED);
1069 while(1)
1071 line = 0;
1072 gpio_read = GPIO_READ;
1073 gpio1_read = GPIO1_READ;
1074 gpio_out = GPIO_OUT;
1075 gpio1_out = GPIO1_OUT;
1076 gpio_function = GPIO_FUNCTION;
1077 gpio1_function = GPIO1_FUNCTION;
1078 gpio_enable = GPIO_ENABLE;
1079 gpio1_enable = GPIO1_ENABLE;
1081 snprintf(buf, sizeof(buf), "GPIO_READ: %08x", gpio_read);
1082 lcd_puts(0, line++, buf);
1083 snprintf(buf, sizeof(buf), "GPIO_OUT: %08x", gpio_out);
1084 lcd_puts(0, line++, buf);
1085 snprintf(buf, sizeof(buf), "GPIO_FUNC: %08x", gpio_function);
1086 lcd_puts(0, line++, buf);
1087 snprintf(buf, sizeof(buf), "GPIO_ENA: %08x", gpio_enable);
1088 lcd_puts(0, line++, buf);
1090 snprintf(buf, sizeof(buf), "GPIO1_READ: %08x", gpio1_read);
1091 lcd_puts(0, line++, buf);
1092 snprintf(buf, sizeof(buf), "GPIO1_OUT: %08x", gpio1_out);
1093 lcd_puts(0, line++, buf);
1094 snprintf(buf, sizeof(buf), "GPIO1_FUNC: %08x", gpio1_function);
1095 lcd_puts(0, line++, buf);
1096 snprintf(buf, sizeof(buf), "GPIO1_ENA: %08x", gpio1_enable);
1097 lcd_puts(0, line++, buf);
1099 adc_buttons = adc_read(ADC_BUTTONS);
1100 adc_remote = adc_read(ADC_REMOTE);
1101 battery_read_info(&adc_battery_voltage, &adc_battery_level);
1102 #if defined(IAUDIO_X5) || defined(IAUDIO_M5) || defined(IRIVER_H300_SERIES)
1103 snprintf(buf, sizeof(buf), "ADC_BUTTONS (%c): %02x",
1104 button_scan_enabled() ? '+' : '-', adc_buttons);
1105 #else
1106 snprintf(buf, sizeof(buf), "ADC_BUTTONS: %02x", adc_buttons);
1107 #endif
1108 lcd_puts(0, line++, buf);
1109 #if defined(IAUDIO_X5) || defined(IAUDIO_M5)
1110 snprintf(buf, sizeof(buf), "ADC_REMOTE (%c): %02x",
1111 remote_detect() ? '+' : '-', adc_remote);
1112 #else
1113 snprintf(buf, sizeof(buf), "ADC_REMOTE: %02x", adc_remote);
1114 #endif
1115 lcd_puts(0, line++, buf);
1116 #if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES)
1117 snprintf(buf, sizeof(buf), "ADC_REMOTEDETECT: %02x",
1118 adc_read(ADC_REMOTEDETECT));
1119 lcd_puts(0, line++, buf);
1120 #endif
1122 snprintf(buf, 32, "Batt: %d.%03dV %d%% ", adc_battery_voltage / 1000,
1123 adc_battery_voltage % 1000, adc_battery_level);
1124 lcd_puts(0, line++, buf);
1126 #if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES)
1127 snprintf(buf, sizeof(buf), "remotetype: %d", remote_type());
1128 lcd_puts(0, line++, buf);
1129 #endif
1131 lcd_update();
1132 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1133 return false;
1136 #elif defined(CPU_PP502x)
1138 char buf[128];
1139 int line;
1141 lcd_setmargins(0, 0);
1142 lcd_clear_display();
1143 lcd_setfont(FONT_SYSFIXED);
1145 while(1)
1147 line = 0;
1148 lcd_puts(0, line++, "GPIO STATES:");
1149 snprintf(buf, sizeof(buf), "A: %02x E: %02x I: %02x",
1150 (unsigned int)GPIOA_INPUT_VAL,
1151 (unsigned int)GPIOE_INPUT_VAL,
1152 (unsigned int)GPIOI_INPUT_VAL);
1153 lcd_puts(0, line++, buf);
1154 snprintf(buf, sizeof(buf), "B: %02x F: %02x J: %02x",
1155 (unsigned int)GPIOB_INPUT_VAL,
1156 (unsigned int)GPIOF_INPUT_VAL,
1157 (unsigned int)GPIOJ_INPUT_VAL);
1158 lcd_puts(0, line++, buf);
1159 snprintf(buf, sizeof(buf), "C: %02x G: %02x K: %02x",
1160 (unsigned int)GPIOC_INPUT_VAL,
1161 (unsigned int)GPIOG_INPUT_VAL,
1162 (unsigned int)GPIOK_INPUT_VAL);
1163 lcd_puts(0, line++, buf);
1164 snprintf(buf, sizeof(buf), "D: %02x H: %02x L: %02x",
1165 (unsigned int)GPIOD_INPUT_VAL,
1166 (unsigned int)GPIOH_INPUT_VAL,
1167 (unsigned int)GPIOL_INPUT_VAL);
1168 lcd_puts(0, line++, buf);
1169 line++;
1170 snprintf(buf, sizeof(buf), "GPO32_VAL: %08lx", GPO32_VAL);
1171 lcd_puts(0, line++, buf);
1172 snprintf(buf, sizeof(buf), "GPO32_EN: %08lx", GPO32_ENABLE);
1173 lcd_puts(0, line++, buf);
1174 snprintf(buf, sizeof(buf), "DEV_EN: %08lx", DEV_EN);
1175 lcd_puts(0, line++, buf);
1176 snprintf(buf, sizeof(buf), "DEV_EN2: %08lx", DEV_EN2);
1177 lcd_puts(0, line++, buf);
1178 snprintf(buf, sizeof(buf), "DEV_EN3: %08lx", inl(0x60006044));
1179 lcd_puts(0, line++, buf); /* to be verified */
1180 snprintf(buf, sizeof(buf), "DEV_INIT1: %08lx", DEV_INIT1);
1181 lcd_puts(0, line++, buf);
1182 snprintf(buf, sizeof(buf), "DEV_INIT2: %08lx", DEV_INIT2);
1183 lcd_puts(0, line++, buf);
1185 #if defined(IRIVER_H10) || defined(IRIVER_H10_5GB)
1186 line++;
1187 snprintf(buf, sizeof(buf), "BATT: %03x UNK1: %03x",
1188 adc_read(ADC_BATTERY), adc_read(ADC_UNKNOWN_1));
1189 lcd_puts(0, line++, buf);
1190 snprintf(buf, sizeof(buf), "REM: %03x PAD: %03x",
1191 adc_read(ADC_REMOTE), adc_read(ADC_SCROLLPAD));
1192 lcd_puts(0, line++, buf);
1193 #elif defined(SANSA_E200)
1194 snprintf(buf, sizeof(buf), "ADC_BVDD: %4d", adc_read(ADC_BVDD));
1195 lcd_puts(0, line++, buf);
1196 snprintf(buf, sizeof(buf), "ADC_RTCSUP: %4d", adc_read(ADC_RTCSUP));
1197 lcd_puts(0, line++, buf);
1198 snprintf(buf, sizeof(buf), "ADC_UVDD: %4d", adc_read(ADC_UVDD));
1199 lcd_puts(0, line++, buf);
1200 snprintf(buf, sizeof(buf), "ADC_CHG_IN: %4d", adc_read(ADC_CHG_IN));
1201 lcd_puts(0, line++, buf);
1202 snprintf(buf, sizeof(buf), "ADC_CVDD: %4d", adc_read(ADC_CVDD));
1203 lcd_puts(0, line++, buf);
1204 snprintf(buf, sizeof(buf), "ADC_BATTEMP: %4d", adc_read(ADC_BATTEMP));
1205 lcd_puts(0, line++, buf);
1206 snprintf(buf, sizeof(buf), "ADC_MICSUP1: %4d", adc_read(ADC_MICSUP1));
1207 lcd_puts(0, line++, buf);
1208 snprintf(buf, sizeof(buf), "ADC_MICSUP2: %4d", adc_read(ADC_MICSUP2));
1209 lcd_puts(0, line++, buf);
1210 snprintf(buf, sizeof(buf), "ADC_VBE1: %4d", adc_read(ADC_VBE1));
1211 lcd_puts(0, line++, buf);
1212 snprintf(buf, sizeof(buf), "ADC_VBE2: %4d", adc_read(ADC_VBE2));
1213 lcd_puts(0, line++, buf);
1214 snprintf(buf, sizeof(buf), "ADC_I_MICSUP1:%4d", adc_read(ADC_I_MICSUP1));
1215 lcd_puts(0, line++, buf);
1216 snprintf(buf, sizeof(buf), "ADC_I_MICSUP2:%4d", adc_read(ADC_I_MICSUP2));
1217 lcd_puts(0, line++, buf);
1218 snprintf(buf, sizeof(buf), "ADC_VBAT: %4d", adc_read(ADC_VBAT));
1219 lcd_puts(0, line++, buf);
1220 snprintf(buf, sizeof(buf), "CHARGER: %02X/%02X", i2c_readbyte(AS3514_I2C_ADDR, CHRGR), i2c_readbyte(AS3514_I2C_ADDR, IRQ_ENRD0));
1221 lcd_puts(0, line++, buf);
1222 #endif
1223 lcd_update();
1224 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1225 return false;
1228 #elif CONFIG_CPU == PP5002
1229 char buf[128];
1230 int line;
1232 lcd_setmargins(0, 0);
1233 lcd_clear_display();
1234 lcd_setfont(FONT_SYSFIXED);
1236 while(1)
1238 line = 0;
1239 snprintf(buf, sizeof(buf), "GPIO_A: %02x GPIO_B: %02x",
1240 (unsigned int)GPIOA_INPUT_VAL, (unsigned int)GPIOB_INPUT_VAL);
1241 lcd_puts(0, line++, buf);
1242 snprintf(buf, sizeof(buf), "GPIO_C: %02x GPIO_D: %02x",
1243 (unsigned int)GPIOC_INPUT_VAL, (unsigned int)GPIOD_INPUT_VAL);
1244 lcd_puts(0, line++, buf);
1246 snprintf(buf, sizeof(buf), "DEV_EN: %08lx", DEV_EN);
1247 lcd_puts(0, line++, buf);
1248 snprintf(buf, sizeof(buf), "CLOCK_ENABLE: %08lx", CLOCK_ENABLE);
1249 lcd_puts(0, line++, buf);
1250 snprintf(buf, sizeof(buf), "CLOCK_SOURCE: %08lx", CLOCK_SOURCE);
1251 lcd_puts(0, line++, buf);
1252 snprintf(buf, sizeof(buf), "PLL_CONTROL: %08lx", PLL_CONTROL);
1253 lcd_puts(0, line++, buf);
1254 snprintf(buf, sizeof(buf), "PLL_DIV: %08lx", PLL_DIV);
1255 lcd_puts(0, line++, buf);
1256 snprintf(buf, sizeof(buf), "PLL_MULT: %08lx", PLL_MULT);
1257 lcd_puts(0, line++, buf);
1258 snprintf(buf, sizeof(buf), "TIMING1_CTL: %08lx", TIMING1_CTL);
1259 lcd_puts(0, line++, buf);
1260 snprintf(buf, sizeof(buf), "TIMING2_CTL: %08lx", TIMING2_CTL);
1261 lcd_puts(0, line++, buf);
1263 lcd_update();
1264 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1265 return false;
1267 #else
1268 return __dbg_ports();
1269 #endif /* CPU */
1270 return false;
1272 #else /* !HAVE_LCD_BITMAP */
1273 bool dbg_ports(void)
1275 char buf[32];
1276 int button;
1277 int adc_battery_voltage;
1278 int currval = 0;
1280 lcd_clear_display();
1282 while(1)
1284 switch(currval)
1286 case 0:
1287 snprintf(buf, 32, "PADR: %04x", (unsigned short)PADR);
1288 break;
1289 case 1:
1290 snprintf(buf, 32, "PBDR: %04x", (unsigned short)PBDR);
1291 break;
1292 case 2:
1293 snprintf(buf, 32, "AN0: %03x", adc_read(0));
1294 break;
1295 case 3:
1296 snprintf(buf, 32, "AN1: %03x", adc_read(1));
1297 break;
1298 case 4:
1299 snprintf(buf, 32, "AN2: %03x", adc_read(2));
1300 break;
1301 case 5:
1302 snprintf(buf, 32, "AN3: %03x", adc_read(3));
1303 break;
1304 case 6:
1305 snprintf(buf, 32, "AN4: %03x", adc_read(4));
1306 break;
1307 case 7:
1308 snprintf(buf, 32, "AN5: %03x", adc_read(5));
1309 break;
1310 case 8:
1311 snprintf(buf, 32, "AN6: %03x", adc_read(6));
1312 break;
1313 case 9:
1314 snprintf(buf, 32, "AN7: %03x", adc_read(7));
1315 break;
1316 break;
1318 lcd_puts(0, 0, buf);
1320 battery_read_info(&adc_battery_voltage, NULL);
1321 snprintf(buf, 32, "Batt: %d.%03dV", adc_battery_voltage / 1000,
1322 adc_battery_voltage % 1000);
1323 lcd_puts(0, 1, buf);
1324 lcd_update();
1326 button = get_action(CONTEXT_SETTINGS,HZ/5);
1328 switch(button)
1330 case ACTION_STD_CANCEL:
1331 return false;
1333 case ACTION_SETTINGS_DEC:
1334 currval--;
1335 if(currval < 0)
1336 currval = 9;
1337 break;
1339 case ACTION_SETTINGS_INC:
1340 currval++;
1341 if(currval > 9)
1342 currval = 0;
1343 break;
1346 return false;
1348 #endif /* !HAVE_LCD_BITMAP */
1349 #endif /* !SIMULATOR */
1351 #if (CONFIG_RTC == RTC_PCF50605) && !defined(SIMULATOR)
1352 static bool dbg_pcf(void)
1354 char buf[128];
1355 int line;
1357 #ifdef HAVE_LCD_BITMAP
1358 lcd_setmargins(0, 0);
1359 lcd_setfont(FONT_SYSFIXED);
1360 #endif
1361 lcd_clear_display();
1363 while(1)
1365 line = 0;
1367 snprintf(buf, sizeof(buf), "DCDC1: %02x", pcf50605_read(0x1b));
1368 lcd_puts(0, line++, buf);
1369 snprintf(buf, sizeof(buf), "DCDC2: %02x", pcf50605_read(0x1c));
1370 lcd_puts(0, line++, buf);
1371 snprintf(buf, sizeof(buf), "DCDC3: %02x", pcf50605_read(0x1d));
1372 lcd_puts(0, line++, buf);
1373 snprintf(buf, sizeof(buf), "DCDC4: %02x", pcf50605_read(0x1e));
1374 lcd_puts(0, line++, buf);
1375 snprintf(buf, sizeof(buf), "DCDEC1: %02x", pcf50605_read(0x1f));
1376 lcd_puts(0, line++, buf);
1377 snprintf(buf, sizeof(buf), "DCDEC2: %02x", pcf50605_read(0x20));
1378 lcd_puts(0, line++, buf);
1379 snprintf(buf, sizeof(buf), "DCUDC1: %02x", pcf50605_read(0x21));
1380 lcd_puts(0, line++, buf);
1381 snprintf(buf, sizeof(buf), "DCUDC2: %02x", pcf50605_read(0x22));
1382 lcd_puts(0, line++, buf);
1383 snprintf(buf, sizeof(buf), "IOREGC: %02x", pcf50605_read(0x23));
1384 lcd_puts(0, line++, buf);
1385 snprintf(buf, sizeof(buf), "D1REGC: %02x", pcf50605_read(0x24));
1386 lcd_puts(0, line++, buf);
1387 snprintf(buf, sizeof(buf), "D2REGC: %02x", pcf50605_read(0x25));
1388 lcd_puts(0, line++, buf);
1389 snprintf(buf, sizeof(buf), "D3REGC: %02x", pcf50605_read(0x26));
1390 lcd_puts(0, line++, buf);
1391 snprintf(buf, sizeof(buf), "LPREG1: %02x", pcf50605_read(0x27));
1392 lcd_puts(0, line++, buf);
1394 lcd_update();
1395 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1397 return false;
1401 return false;
1403 #endif
1405 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
1406 static bool dbg_cpufreq(void)
1408 char buf[128];
1409 int line;
1410 int button;
1412 #ifdef HAVE_LCD_BITMAP
1413 lcd_setmargins(0, 0);
1414 lcd_setfont(FONT_SYSFIXED);
1415 #endif
1416 lcd_clear_display();
1418 while(1)
1420 line = 0;
1422 snprintf(buf, sizeof(buf), "Frequency: %ld", FREQ);
1423 lcd_puts(0, line++, buf);
1425 snprintf(buf, sizeof(buf), "boost_counter: %d", get_cpu_boost_counter());
1426 lcd_puts(0, line++, buf);
1428 lcd_update();
1429 button = get_action(CONTEXT_STD,HZ/10);
1431 switch(button)
1433 case ACTION_STD_PREV:
1434 cpu_boost(true);
1435 break;
1437 case ACTION_STD_NEXT:
1438 cpu_boost(false);
1439 break;
1441 case ACTION_STD_OK:
1442 while (get_cpu_boost_counter() > 0)
1443 cpu_boost(false);
1444 set_cpu_frequency(CPUFREQ_DEFAULT);
1445 break;
1447 case ACTION_STD_CANCEL:
1448 return false;
1452 return false;
1454 #endif /* HAVE_ADJUSTABLE_CPU_FREQ */
1456 #if defined(HAVE_TSC2100) && !defined(SIMULATOR)
1457 #include "tsc2100.h"
1458 char *itob(int n, int len)
1460 static char binary[64];
1461 int i,j;
1462 for (i=1, j=0;i<=len;i++)
1464 binary[j++] = n&(1<<(len-i))?'1':'0';
1465 if (i%4 == 0)
1466 binary[j++] = ' ';
1468 binary[j] = '\0';
1469 return binary;
1471 static char* tsc2100_debug_getname(int selected_item, void * data, char *buffer)
1473 int *page = (int*)data;
1474 bool reserved = false;
1475 switch (*page)
1477 case 0:
1478 if ((selected_item > 0x0a) ||
1479 (selected_item == 0x04) ||
1480 (selected_item == 0x08))
1481 reserved = true;
1482 break;
1483 case 1:
1484 if ((selected_item > 0x05) ||
1485 (selected_item == 0x02))
1486 reserved = true;
1487 break;
1488 case 2:
1489 if (selected_item > 0x1e)
1490 reserved = true;
1491 break;
1493 if (reserved)
1494 snprintf(buffer, MAX_PATH, "%02x: RESERVED", selected_item);
1495 else
1496 snprintf(buffer, MAX_PATH, "%02x: %s", selected_item,
1497 itob(tsc2100_readreg(*page, selected_item)&0xffff,16));
1498 return buffer;
1500 static int tsc2100debug_action_callback(int action, struct gui_synclist *lists)
1502 int *page = (int*)lists->data;
1503 if (action == ACTION_STD_OK)
1505 *page = (*page+1)%3;
1506 snprintf(lists->title, 32,
1507 "tsc2100 registers - Page %d", *page);
1508 return ACTION_REDRAW;
1510 return action;
1512 bool tsc2100_debug(void)
1514 int page = 0;
1515 char title[32] = "tsc2100 registers - Page 0";
1516 struct simplelist_info info;
1517 simplelist_info_init(&info, title, 32, &page);
1518 info.timeout = HZ/100;
1519 info.get_name = tsc2100_debug_getname;
1520 info.action_callback= tsc2100debug_action_callback;
1521 return simplelist_show_list(&info);
1523 #endif
1524 #ifndef SIMULATOR
1525 #ifdef HAVE_LCD_BITMAP
1527 * view_battery() shows a automatically scaled graph of the battery voltage
1528 * over time. Usable for estimating battery life / charging rate.
1529 * The power_history array is updated in power_thread of powermgmt.c.
1532 #define BAT_LAST_VAL MIN(LCD_WIDTH, POWER_HISTORY_LEN)
1533 #define BAT_YSPACE (LCD_HEIGHT - 20)
1535 static bool view_battery(void)
1537 int view = 0;
1538 int i, x, y;
1539 unsigned short maxv, minv;
1540 char buf[32];
1542 lcd_setmargins(0, 0);
1543 lcd_setfont(FONT_SYSFIXED);
1545 while(1)
1547 lcd_clear_display();
1548 switch (view) {
1549 case 0: /* voltage history graph */
1550 /* Find maximum and minimum voltage for scaling */
1551 minv = power_history[0];
1552 maxv = minv + 1;
1553 for (i = 1; i < BAT_LAST_VAL && power_history[i]; i++) {
1554 if (power_history[i] > maxv)
1555 maxv = power_history[i];
1556 if (power_history[i] < minv)
1557 minv = power_history[i];
1560 snprintf(buf, 30, "Battery %d.%03d", power_history[0] / 1000,
1561 power_history[0] % 1000);
1562 lcd_puts(0, 0, buf);
1563 snprintf(buf, 30, "scale %d.%03d-%d.%03dV",
1564 minv / 1000, minv % 1000, maxv / 1000, maxv % 1000);
1565 lcd_puts(0, 1, buf);
1567 x = 0;
1568 for (i = BAT_LAST_VAL - 1; i >= 0; i--) {
1569 y = (power_history[i] - minv) * BAT_YSPACE / (maxv - minv);
1570 lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
1571 lcd_vline(x, LCD_HEIGHT-1, 20);
1572 lcd_set_drawmode(DRMODE_SOLID);
1573 lcd_vline(x, LCD_HEIGHT-1,
1574 MIN(MAX(LCD_HEIGHT-1 - y, 20), LCD_HEIGHT-1));
1575 x++;
1578 break;
1580 case 1: /* status: */
1581 lcd_puts(0, 0, "Power status:");
1583 battery_read_info(&y, NULL);
1584 snprintf(buf, 30, "Battery: %d.%03d V", y / 1000, y % 1000);
1585 lcd_puts(0, 1, buf);
1586 #ifdef ADC_EXT_POWER
1587 y = (adc_read(ADC_EXT_POWER) * EXT_SCALE_FACTOR) / 1000;
1588 snprintf(buf, 30, "External: %d.%03d V", y / 1000, y % 1000);
1589 lcd_puts(0, 2, buf);
1590 #endif
1591 #if CONFIG_CHARGING
1592 #if CONFIG_CHARGING == CHARGING_CONTROL
1593 snprintf(buf, 30, "Chgr: %s %s",
1594 charger_inserted() ? "present" : "absent",
1595 charger_enabled ? "on" : "off");
1596 lcd_puts(0, 3, buf);
1597 snprintf(buf, 30, "short delta: %d", short_delta);
1598 lcd_puts(0, 5, buf);
1599 snprintf(buf, 30, "long delta: %d", long_delta);
1600 lcd_puts(0, 6, buf);
1601 lcd_puts(0, 7, power_message);
1602 snprintf(buf, 30, "USB Inserted: %s",
1603 usb_inserted() ? "yes" : "no");
1604 lcd_puts(0, 8, buf);
1605 #if defined IRIVER_H300_SERIES
1606 snprintf(buf, 30, "USB Charging Enabled: %s",
1607 usb_charging_enabled() ? "yes" : "no");
1608 lcd_puts(0, 9, buf);
1609 #endif
1610 #else /* CONFIG_CHARGING != CHARGING_CONTROL */
1611 #if defined IPOD_NANO || defined IPOD_VIDEO
1612 int usb_pwr = (GPIOL_INPUT_VAL & 0x10)?true:false;
1613 int ext_pwr = (GPIOL_INPUT_VAL & 0x08)?false:true;
1614 int dock = (GPIOA_INPUT_VAL & 0x10)?true:false;
1615 int charging = (GPIOB_INPUT_VAL & 0x01)?false:true;
1616 int headphone= (GPIOA_INPUT_VAL & 0x80)?true:false;
1618 snprintf(buf, 30, "USB pwr: %s",
1619 usb_pwr ? "present" : "absent");
1620 lcd_puts(0, 3, buf);
1621 snprintf(buf, 30, "EXT pwr: %s",
1622 ext_pwr ? "present" : "absent");
1623 lcd_puts(0, 4, buf);
1624 snprintf(buf, 30, "Battery: %s",
1625 charging ? "charging" : (usb_pwr||ext_pwr) ? "charged" : "discharging");
1626 lcd_puts(0, 5, buf);
1627 snprintf(buf, 30, "Dock mode: %s",
1628 dock ? "enabled" : "disabled");
1629 lcd_puts(0, 6, buf);
1630 snprintf(buf, 30, "Headphone: %s",
1631 headphone ? "connected" : "disconnected");
1632 lcd_puts(0, 7, buf);
1633 #else
1634 snprintf(buf, 30, "Charger: %s",
1635 charger_inserted() ? "present" : "absent");
1636 lcd_puts(0, 3, buf);
1637 #endif
1638 #endif /* CONFIG_CHARGING != CHARGING_CONTROL */
1639 #endif /* CONFIG_CHARGING */
1640 break;
1642 case 2: /* voltage deltas: */
1643 lcd_puts(0, 0, "Voltage deltas:");
1645 for (i = 0; i <= 6; i++) {
1646 y = power_history[i] - power_history[i+1];
1647 snprintf(buf, 30, "-%d min: %s%d.%03d V", i,
1648 (y < 0) ? "-" : "", ((y < 0) ? y * -1 : y) / 1000,
1649 ((y < 0) ? y * -1 : y ) % 1000);
1650 lcd_puts(0, i+1, buf);
1652 break;
1654 case 3: /* remaining time estimation: */
1656 #if CONFIG_CHARGING == CHARGING_CONTROL
1657 snprintf(buf, 30, "charge_state: %d", charge_state);
1658 lcd_puts(0, 0, buf);
1660 snprintf(buf, 30, "Cycle time: %d m", powermgmt_last_cycle_startstop_min);
1661 lcd_puts(0, 1, buf);
1663 snprintf(buf, 30, "Lvl@cyc st: %d%%", powermgmt_last_cycle_level);
1664 lcd_puts(0, 2, buf);
1666 snprintf(buf, 30, "P=%2d I=%2d", pid_p, pid_i);
1667 lcd_puts(0, 3, buf);
1669 snprintf(buf, 30, "Trickle sec: %d/60", trickle_sec);
1670 lcd_puts(0, 4, buf);
1671 #endif /* CONFIG_CHARGING == CHARGING_CONTROL */
1673 snprintf(buf, 30, "Last PwrHist: %d.%03dV",
1674 power_history[0] / 1000,
1675 power_history[0] % 1000);
1676 lcd_puts(0, 5, buf);
1678 snprintf(buf, 30, "battery level: %d%%", battery_level());
1679 lcd_puts(0, 6, buf);
1681 snprintf(buf, 30, "Est. remain: %d m", battery_time());
1682 lcd_puts(0, 7, buf);
1683 break;
1686 lcd_update();
1688 switch(get_action(CONTEXT_SETTINGS,HZ/2))
1690 case ACTION_SETTINGS_DEC:
1691 if (view)
1692 view--;
1693 break;
1695 case ACTION_SETTINGS_INC:
1696 if (view < 3)
1697 view++;
1698 break;
1700 case ACTION_STD_CANCEL:
1701 return false;
1704 return false;
1707 #endif /* HAVE_LCD_BITMAP */
1708 #endif
1710 #ifndef SIMULATOR
1711 #if defined(HAVE_MMC) || defined(HAVE_HOTSWAP)
1712 #if defined(HAVE_MMC)
1713 #define CARDTYPE "MMC"
1714 #else
1715 #define CARDTYPE "microSD"
1716 #endif
1717 static int disk_callback(int btn, struct gui_synclist *lists)
1719 tCardInfo *card;
1720 int *cardnum = (int*)lists->data;
1721 unsigned char card_name[7];
1722 unsigned char pbuf[32];
1723 char *title = lists->title;
1724 static const unsigned char i_vmin[] = { 0, 1, 5, 10, 25, 35, 60, 100 };
1725 static const unsigned char i_vmax[] = { 1, 5, 10, 25, 35, 45, 80, 200 };
1726 static const unsigned char *kbit_units[] = { "kBit/s", "MBit/s", "GBit/s" };
1727 static const unsigned char *nsec_units[] = { "ns", "�s", "ms" };
1728 static const char *spec_vers[] = { "1.0-1.2", "1.4", "2.0-2.2",
1729 "3.1-3.31", "4.0" };
1730 if ((btn == ACTION_STD_OK) || (btn == SYS_FS_CHANGED) || (btn == ACTION_REDRAW))
1732 if (btn == ACTION_STD_OK)
1734 *cardnum ^= 0x1; /* change cards */
1737 simplelist_set_line_count(0);
1739 card = card_get_info(*cardnum);
1741 if (card->initialized > 0)
1743 card_name[6] = '\0';
1744 strncpy(card_name, ((unsigned char*)card->cid) + 3, 6);
1745 simplelist_addline(SIMPLELIST_ADD_LINE,
1746 "%s Rev %d.%d", card_name,
1747 (int) card_extract_bits(card->cid, 72, 4),
1748 (int) card_extract_bits(card->cid, 76, 4));
1749 simplelist_addline(SIMPLELIST_ADD_LINE,
1750 "Prod: %d/%d",
1751 (int) card_extract_bits(card->cid, 112, 4),
1752 (int) card_extract_bits(card->cid, 116, 4) + 1997);
1753 simplelist_addline(SIMPLELIST_ADD_LINE,
1754 "Ser#: 0x%08lx",
1755 card_extract_bits(card->cid, 80, 32));
1756 simplelist_addline(SIMPLELIST_ADD_LINE,
1757 "M=%02x, O=%04x",
1758 (int) card_extract_bits(card->cid, 0, 8),
1759 (int) card_extract_bits(card->cid, 8, 16));
1760 int temp = card_extract_bits(card->csd, 2, 4);
1761 simplelist_addline(SIMPLELIST_ADD_LINE,
1762 CARDTYPE " v%s", temp < 5 ?
1763 spec_vers[temp] : "?.?");
1764 simplelist_addline(SIMPLELIST_ADD_LINE,
1765 "Blocks: 0x%06lx", card->numblocks);
1766 simplelist_addline(SIMPLELIST_ADD_LINE,
1767 "Blksz.: %d P:%c%c", card->blocksize,
1768 card_extract_bits(card->csd, 48, 1) ? 'R' : '-',
1769 card_extract_bits(card->csd, 106, 1) ? 'W' : '-');
1770 output_dyn_value(pbuf, sizeof pbuf, card->speed / 1000,
1771 kbit_units, false);
1772 simplelist_addline(SIMPLELIST_ADD_LINE,
1773 "Speed: %s", pbuf);
1774 output_dyn_value(pbuf, sizeof pbuf, card->tsac,
1775 nsec_units, false);
1776 simplelist_addline(SIMPLELIST_ADD_LINE,
1777 "Tsac: %s", pbuf);
1778 simplelist_addline(SIMPLELIST_ADD_LINE,
1779 "Nsac: %d clk", card->nsac);
1780 simplelist_addline(SIMPLELIST_ADD_LINE,
1781 "R2W: *%d", card->r2w_factor);
1782 simplelist_addline(SIMPLELIST_ADD_LINE,
1783 "IRmax: %d..%d mA",
1784 i_vmin[card_extract_bits(card->csd, 66, 3)],
1785 i_vmax[card_extract_bits(card->csd, 69, 3)]);
1786 simplelist_addline(SIMPLELIST_ADD_LINE,
1787 "IWmax: %d..%d mA",
1788 i_vmin[card_extract_bits(card->csd, 72, 3)],
1789 i_vmax[card_extract_bits(card->csd, 75, 3)]);
1791 else if (card->initialized == 0)
1793 simplelist_addline(SIMPLELIST_ADD_LINE, "Not Found!");
1795 #ifndef HAVE_MMC
1796 else /* card->initialized < 0 */
1798 simplelist_addline(SIMPLELIST_ADD_LINE, "Init Error! (%d)", card->initialized);
1800 #endif
1801 snprintf(title, 16, "[" CARDTYPE " %d]", *cardnum);
1802 gui_synclist_set_title(lists, title, Icon_NOICON);
1803 gui_synclist_set_nb_items(lists, simplelist_get_line_count());
1804 gui_synclist_select_item(lists, 0);
1805 btn = ACTION_REDRAW;
1807 return btn;
1809 #else /* !defined(HAVE_MMC) && !defined(HAVE_HOTSWAP) */
1810 static int disk_callback(int btn, struct gui_synclist *lists)
1812 (void)lists;
1813 int i;
1814 char buf[128];
1815 unsigned short* identify_info = ata_get_identify();
1816 bool timing_info_present = false;
1817 (void)btn;
1819 simplelist_set_line_count(0);
1821 for (i=0; i < 20; i++)
1822 ((unsigned short*)buf)[i]=htobe16(identify_info[i+27]);
1823 buf[40]=0;
1824 /* kill trailing space */
1825 for (i=39; i && buf[i]==' '; i--)
1826 buf[i] = 0;
1827 simplelist_addline(SIMPLELIST_ADD_LINE, "Model: %s", buf);
1828 for (i=0; i < 4; i++)
1829 ((unsigned short*)buf)[i]=htobe16(identify_info[i+23]);
1830 buf[8]=0;
1831 simplelist_addline(SIMPLELIST_ADD_LINE,
1832 "Firmware: %s", buf);
1833 snprintf(buf, sizeof buf, "%ld MB",
1834 ((unsigned long)identify_info[61] << 16 |
1835 (unsigned long)identify_info[60]) / 2048 );
1836 simplelist_addline(SIMPLELIST_ADD_LINE,
1837 "Size: %s", buf);
1838 unsigned long free;
1839 fat_size( IF_MV2(0,) NULL, &free );
1840 simplelist_addline(SIMPLELIST_ADD_LINE,
1841 "Free: %ld MB", free / 1024);
1842 simplelist_addline(SIMPLELIST_ADD_LINE,
1843 "Spinup time: %d ms", ata_spinup_time * (1000/HZ));
1844 i = identify_info[83] & (1<<3);
1845 simplelist_addline(SIMPLELIST_ADD_LINE,
1846 "Power mgmt: %s", i ? "enabled" : "unsupported");
1847 i = identify_info[83] & (1<<9);
1848 simplelist_addline(SIMPLELIST_ADD_LINE,
1849 "Noise mgmt: %s", i ? "enabled" : "unsupported");
1850 i = identify_info[82] & (1<<6);
1851 simplelist_addline(SIMPLELIST_ADD_LINE,
1852 "Read-ahead: %s", i ? "enabled" : "unsupported");
1853 timing_info_present = identify_info[53] & (1<<1);
1854 if(timing_info_present) {
1855 char pio3[2], pio4[2];pio3[1] = 0;
1856 pio4[1] = 0;
1857 pio3[0] = (identify_info[64] & (1<<0)) ? '3' : 0;
1858 pio4[0] = (identify_info[64] & (1<<1)) ? '4' : 0;
1859 simplelist_addline(SIMPLELIST_ADD_LINE,
1860 "PIO modes: 0 1 2 %s %s", pio3, pio4);
1862 else {
1863 simplelist_addline(SIMPLELIST_ADD_LINE,
1864 "No PIO mode info");
1866 timing_info_present = identify_info[53] & (1<<1);
1867 if(timing_info_present) {
1868 simplelist_addline(SIMPLELIST_ADD_LINE,
1869 "Cycle times %dns/%dns",
1870 identify_info[67],
1871 identify_info[68] );
1872 } else {
1873 simplelist_addline(SIMPLELIST_ADD_LINE,
1874 "No timing info");
1876 timing_info_present = identify_info[53] & (1<<1);
1877 if(timing_info_present) {
1878 i = identify_info[49] & (1<<11);
1879 simplelist_addline(SIMPLELIST_ADD_LINE,
1880 "IORDY support: %s", i ? "yes" : "no");
1881 i = identify_info[49] & (1<<10);
1882 simplelist_addline(SIMPLELIST_ADD_LINE,
1883 "IORDY disable: %s", i ? "yes" : "no");
1884 } else {
1885 simplelist_addline(SIMPLELIST_ADD_LINE,
1886 "No timing info");
1888 simplelist_addline(SIMPLELIST_ADD_LINE,
1889 "Cluster size: %d bytes", fat_get_cluster_size(IF_MV(0)));
1890 return btn;
1893 static bool dbg_identify_info(void)
1895 int fd = creat("/identify_info.bin");
1896 if(fd >= 0)
1898 #ifdef ROCKBOX_LITTLE_ENDIAN
1899 ecwrite(fd, ata_get_identify(), SECTOR_SIZE/2, "s", true);
1900 #else
1901 write(fd, ata_get_identify(), SECTOR_SIZE);
1902 #endif
1903 close(fd);
1905 return false;
1907 #endif /* !defined(HAVE_MMC) && !defined(HAVE_HOTSWAP) */
1908 static bool dbg_disk_info(void)
1910 struct simplelist_info info;
1911 simplelist_info_init(&info, "Disk Info", 1, NULL);
1912 #if defined(HAVE_MMC) || defined(HAVE_HOTSWAP)
1913 char title[16];
1914 int card = 0;
1915 info.callback_data = (void*)&card;
1916 info.title = title;
1917 #endif
1918 info.action_callback = disk_callback;
1919 info.hide_selection = true;
1920 return simplelist_show_list(&info);
1922 #endif /* !SIMULATOR */
1924 #ifdef HAVE_DIRCACHE
1925 static int dircache_callback(int btn, struct gui_synclist *lists)
1927 (void)btn; (void)lists;
1928 simplelist_set_line_count(0);
1929 simplelist_addline(SIMPLELIST_ADD_LINE, "Cache initialized: %s",
1930 dircache_is_enabled() ? "Yes" : "No");
1931 simplelist_addline(SIMPLELIST_ADD_LINE, "Cache size: %d B",
1932 dircache_get_cache_size());
1933 simplelist_addline(SIMPLELIST_ADD_LINE, "Last size: %d B",
1934 global_status.dircache_size);
1935 simplelist_addline(SIMPLELIST_ADD_LINE, "Limit: %d B",
1936 DIRCACHE_LIMIT);
1937 simplelist_addline(SIMPLELIST_ADD_LINE, "Reserve: %d/%d B",
1938 dircache_get_reserve_used(), DIRCACHE_RESERVE);
1939 simplelist_addline(SIMPLELIST_ADD_LINE, "Scanning took: %d s",
1940 dircache_get_build_ticks() / HZ);
1941 simplelist_addline(SIMPLELIST_ADD_LINE, "Entry count: %d",
1942 dircache_get_entry_count());
1943 return btn;
1946 static bool dbg_dircache_info(void)
1948 struct simplelist_info info;
1949 simplelist_info_init(&info, "Dircache Info", 7, NULL);
1950 info.action_callback = dircache_callback;
1951 info.hide_selection = true;
1952 return simplelist_show_list(&info);
1955 #endif /* HAVE_DIRCACHE */
1957 #ifdef HAVE_TAGCACHE
1958 static int database_callback(int btn, struct gui_synclist *lists)
1960 (void)lists;
1961 struct tagcache_stat *stat = tagcache_get_stat();
1962 static bool synced = false;
1964 simplelist_set_line_count(0);
1966 simplelist_addline(SIMPLELIST_ADD_LINE, "Initialized: %s",
1967 stat->initialized ? "Yes" : "No");
1968 simplelist_addline(SIMPLELIST_ADD_LINE, "DB Ready: %s",
1969 stat->ready ? "Yes" : "No");
1970 simplelist_addline(SIMPLELIST_ADD_LINE, "RAM Cache: %s",
1971 stat->ramcache ? "Yes" : "No");
1972 simplelist_addline(SIMPLELIST_ADD_LINE, "RAM: %d/%d B",
1973 stat->ramcache_used, stat->ramcache_allocated);
1974 simplelist_addline(SIMPLELIST_ADD_LINE, "Progress: %d%% (%d entries)",
1975 stat->progress, stat->processed_entries);
1976 simplelist_addline(SIMPLELIST_ADD_LINE, "Curfile: %s",
1977 stat->curentry ? stat->curentry : "---");
1978 simplelist_addline(SIMPLELIST_ADD_LINE, "Commit step: %d",
1979 stat->commit_step);
1980 simplelist_addline(SIMPLELIST_ADD_LINE, "Commit delayed: %s",
1981 stat->commit_delayed ? "Yes" : "No");
1983 simplelist_addline(SIMPLELIST_ADD_LINE, "Queue length: %d",
1984 stat->queue_length);
1986 if (synced)
1988 synced = false;
1989 tagcache_screensync_event();
1992 if (!btn && stat->curentry)
1994 synced = true;
1995 return ACTION_REDRAW;
1998 if (btn == ACTION_STD_CANCEL)
1999 tagcache_screensync_enable(false);
2001 return btn;
2003 static bool dbg_tagcache_info(void)
2005 struct simplelist_info info;
2006 simplelist_info_init(&info, "Database Info", 8, NULL);
2007 info.action_callback = database_callback;
2008 info.hide_selection = true;
2010 /* Don't do nonblock here, must give enough processing time
2011 for tagcache thread. */
2012 /* info.timeout = TIMEOUT_NOBLOCK; */
2013 info.timeout = 1;
2014 tagcache_screensync_enable(true);
2015 return simplelist_show_list(&info);
2017 #endif
2019 #if CONFIG_CPU == SH7034
2020 static bool dbg_save_roms(void)
2022 int fd;
2023 int oldmode = system_memory_guard(MEMGUARD_NONE);
2025 fd = creat("/internal_rom_0000-FFFF.bin");
2026 if(fd >= 0)
2028 write(fd, (void *)0, 0x10000);
2029 close(fd);
2032 fd = creat("/internal_rom_2000000-203FFFF.bin");
2033 if(fd >= 0)
2035 write(fd, (void *)0x2000000, 0x40000);
2036 close(fd);
2039 system_memory_guard(oldmode);
2040 return false;
2042 #elif defined CPU_COLDFIRE
2043 static bool dbg_save_roms(void)
2045 int fd;
2046 int oldmode = system_memory_guard(MEMGUARD_NONE);
2048 #if defined(IRIVER_H100_SERIES)
2049 fd = creat("/internal_rom_000000-1FFFFF.bin");
2050 #elif defined(IRIVER_H300_SERIES)
2051 fd = creat("/internal_rom_000000-3FFFFF.bin");
2052 #elif defined(IAUDIO_X5) || defined(IAUDIO_M5) || defined(IAUDIO_M3)
2053 fd = creat("/internal_rom_000000-3FFFFF.bin");
2054 #endif
2055 if(fd >= 0)
2057 write(fd, (void *)0, FLASH_SIZE);
2058 close(fd);
2060 system_memory_guard(oldmode);
2062 #ifdef HAVE_EEPROM
2063 fd = creat("/internal_eeprom.bin");
2064 if (fd >= 0)
2066 int old_irq_level;
2067 char buf[EEPROM_SIZE];
2068 int err;
2070 old_irq_level = disable_irq_save();
2072 err = eeprom_24cxx_read(0, buf, sizeof buf);
2074 restore_irq(old_irq_level);
2076 if (err)
2077 gui_syncsplash(HZ*3, "Eeprom read failure (%d)",err);
2078 else
2080 write(fd, buf, sizeof buf);
2083 close(fd);
2085 #endif
2087 return false;
2089 #elif defined(CPU_PP) && !(defined(SANSA_E200) || defined(SANSA_C200))
2090 static bool dbg_save_roms(void)
2092 int fd;
2094 fd = creat("/internal_rom_000000-0FFFFF.bin");
2095 if(fd >= 0)
2097 write(fd, (void *)0x20000000, FLASH_SIZE);
2098 close(fd);
2101 return false;
2103 #endif /* CPU */
2105 #ifndef SIMULATOR
2106 #if CONFIG_TUNER
2107 static int radio_callback(int btn, struct gui_synclist *lists)
2109 (void)lists;
2110 if (btn == ACTION_STD_CANCEL)
2111 return btn;
2112 simplelist_set_line_count(1);
2114 #if (CONFIG_TUNER & LV24020LP)
2115 simplelist_addline(SIMPLELIST_ADD_LINE,
2116 "CTRL_STAT: %02X", lv24020lp_get(LV24020LP_CTRL_STAT) );
2117 simplelist_addline(SIMPLELIST_ADD_LINE,
2118 "RADIO_STAT: %02X", lv24020lp_get(LV24020LP_REG_STAT) );
2119 simplelist_addline(SIMPLELIST_ADD_LINE,
2120 "MSS_FM: %d kHz", lv24020lp_get(LV24020LP_MSS_FM) );
2121 simplelist_addline(SIMPLELIST_ADD_LINE,
2122 "MSS_IF: %d Hz", lv24020lp_get(LV24020LP_MSS_IF) );
2123 simplelist_addline(SIMPLELIST_ADD_LINE,
2124 "MSS_SD: %d Hz", lv24020lp_get(LV24020LP_MSS_SD) );
2125 simplelist_addline(SIMPLELIST_ADD_LINE,
2126 "if_set: %d Hz", lv24020lp_get(LV24020LP_IF_SET) );
2127 simplelist_addline(SIMPLELIST_ADD_LINE,
2128 "sd_set: %d Hz", lv24020lp_get(LV24020LP_SD_SET) );
2129 #endif
2130 #if (CONFIG_TUNER & S1A0903X01)
2131 simplelist_addline(SIMPLELIST_ADD_LINE,
2132 "Samsung regs: %08X", s1a0903x01_get(RADIO_ALL));
2133 /* This one doesn't return dynamic data atm */
2134 #endif
2135 #if (CONFIG_TUNER & TEA5767)
2136 struct tea5767_dbg_info nfo;
2137 tea5767_dbg_info(&nfo);
2138 simplelist_addline(SIMPLELIST_ADD_LINE, "Philips regs:");
2139 simplelist_addline(SIMPLELIST_ADD_LINE,
2140 " Read: %02X %02X %02X %02X %02X",
2141 (unsigned)nfo.read_regs[0], (unsigned)nfo.read_regs[1],
2142 (unsigned)nfo.read_regs[2], (unsigned)nfo.read_regs[3],
2143 (unsigned)nfo.read_regs[4]);
2144 simplelist_addline(SIMPLELIST_ADD_LINE,
2145 " Write: %02X %02X %02X %02X %02X",
2146 (unsigned)nfo.write_regs[0], (unsigned)nfo.write_regs[1],
2147 (unsigned)nfo.write_regs[2], (unsigned)nfo.write_regs[3],
2148 (unsigned)nfo.write_regs[4]);
2149 #endif
2150 return ACTION_REDRAW;
2152 static bool dbg_fm_radio(void)
2154 struct simplelist_info info;
2155 simplelist_info_init(&info, "FM Radio", 1, NULL);
2156 simplelist_set_line_count(0);
2157 simplelist_addline(SIMPLELIST_ADD_LINE, "HW detected: %s",
2158 radio_hardware_present() ? "yes" : "no");
2160 info.action_callback = radio_hardware_present()?radio_callback : NULL;
2161 info.hide_selection = true;
2162 return simplelist_show_list(&info);
2164 #endif /* CONFIG_TUNER */
2165 #endif /* !SIMULATOR */
2167 #ifdef HAVE_LCD_BITMAP
2168 extern bool do_screendump_instead_of_usb;
2170 static bool dbg_screendump(void)
2172 do_screendump_instead_of_usb = !do_screendump_instead_of_usb;
2173 gui_syncsplash(HZ, "Screendump %s",
2174 do_screendump_instead_of_usb?"enabled":"disabled");
2175 return false;
2177 #endif /* HAVE_LCD_BITMAP */
2179 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
2180 static bool dbg_set_memory_guard(void)
2182 static const struct opt_items names[MAXMEMGUARD] = {
2183 { "None", -1 },
2184 { "Flash ROM writes", -1 },
2185 { "Zero area (all)", -1 }
2187 int mode = system_memory_guard(MEMGUARD_KEEP);
2189 set_option( "Catch mem accesses", &mode, INT, names, MAXMEMGUARD, NULL);
2190 system_memory_guard(mode);
2192 return false;
2194 #endif /* CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) */
2196 #if defined(TOSHIBA_GIGABEAT_F) && !defined(SIMULATOR)
2198 extern volatile bool lcd_poweroff;
2200 static bool dbg_lcd_power_off(void)
2202 lcd_setmargins(0, 0);
2204 while(1)
2206 int button;
2208 lcd_clear_display();
2209 lcd_puts(0, 0, "LCD Power Off");
2210 if(lcd_poweroff)
2211 lcd_puts(1, 1, "Yes");
2212 else
2213 lcd_puts(1, 1, "No");
2215 lcd_update();
2217 button = get_action(CONTEXT_STD,HZ/5);
2218 switch(button)
2220 case ACTION_STD_PREV:
2221 case ACTION_STD_NEXT:
2222 lcd_poweroff = !lcd_poweroff;
2223 break;
2224 case ACTION_STD_OK:
2225 case ACTION_STD_CANCEL:
2226 return false;
2227 default:
2228 sleep(HZ/10);
2229 break;
2232 return false;
2234 #endif
2236 #if defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS)
2237 static bool dbg_write_eeprom(void)
2239 int fd;
2240 int rc;
2241 int old_irq_level;
2242 char buf[EEPROM_SIZE];
2243 int err;
2245 fd = open("/internal_eeprom.bin", O_RDONLY);
2247 if (fd >= 0)
2249 rc = read(fd, buf, EEPROM_SIZE);
2251 if(rc == EEPROM_SIZE)
2253 old_irq_level = disable_irq_save();
2255 err = eeprom_24cxx_write(0, buf, sizeof buf);
2256 if (err)
2257 gui_syncsplash(HZ*3, "Eeprom write failure (%d)",err);
2258 else
2259 gui_syncsplash(HZ*3, "Eeprom written successfully");
2261 restore_irq(old_irq_level);
2263 else
2265 gui_syncsplash(HZ*3, "File read error (%d)",rc);
2267 close(fd);
2269 else
2271 gui_syncsplash(HZ*3, "Failed to open 'internal_eeprom.bin'");
2274 return false;
2276 #endif /* defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS) */
2277 #ifdef CPU_BOOST_LOGGING
2278 static bool cpu_boost_log(void)
2280 int i = 0,j=0;
2281 int count = cpu_boost_log_getcount();
2282 int lines = LCD_HEIGHT/SYSFONT_HEIGHT;
2283 char *str;
2284 bool done;
2285 lcd_setmargins(0, 0);
2286 lcd_setfont(FONT_SYSFIXED);
2287 str = cpu_boost_log_getlog_first();
2288 while (i < count)
2290 lcd_clear_display();
2291 for(j=0; j<lines; j++,i++)
2293 if (!str)
2294 str = cpu_boost_log_getlog_next();
2295 if (str)
2297 lcd_puts(0, j,str);
2299 str = NULL;
2301 lcd_update();
2302 done = false;
2303 while (!done)
2305 switch(get_action(CONTEXT_STD,TIMEOUT_BLOCK))
2307 case ACTION_STD_OK:
2308 case ACTION_STD_PREV:
2309 case ACTION_STD_NEXT:
2310 done = true;
2311 break;
2312 case ACTION_STD_CANCEL:
2313 i = count;
2314 done = true;
2315 break;
2319 get_action(CONTEXT_STD,TIMEOUT_BLOCK);
2320 lcd_setfont(FONT_UI);
2321 return false;
2323 #endif
2325 #if (defined(HAVE_SCROLLWHEEL) && (CONFIG_KEYPAD==IPOD_4G_PAD) && !defined(SIMULATOR))
2326 extern bool wheel_is_touched;
2327 extern int old_wheel_value;
2328 extern int new_wheel_value;
2329 extern int wheel_delta;
2330 extern unsigned int accumulated_wheel_delta;
2331 extern unsigned int wheel_velocity;
2333 static bool dbg_scrollwheel(void)
2335 char buf[64];
2336 unsigned int speed;
2338 lcd_setmargins(0, 0);
2339 lcd_setfont(FONT_SYSFIXED);
2341 while (1)
2343 if (action_userabort(HZ/10))
2344 return false;
2346 lcd_clear_display();
2348 /* show internal variables of scrollwheel driver */
2349 snprintf(buf, sizeof(buf), "wheel touched: %s", (wheel_is_touched) ? "true" : "false");
2350 lcd_puts(0, 0, buf);
2351 snprintf(buf, sizeof(buf), "new position: %2d", new_wheel_value);
2352 lcd_puts(0, 1, buf);
2353 snprintf(buf, sizeof(buf), "old position: %2d", old_wheel_value);
2354 lcd_puts(0, 2, buf);
2355 snprintf(buf, sizeof(buf), "wheel delta: %2d", wheel_delta);
2356 lcd_puts(0, 3, buf);
2357 snprintf(buf, sizeof(buf), "accumulated delta: %2d", accumulated_wheel_delta);
2358 lcd_puts(0, 4, buf);
2359 snprintf(buf, sizeof(buf), "velo [deg/s]: %4d", (int)wheel_velocity);
2360 lcd_puts(0, 5, buf);
2362 /* show effective accelerated scrollspeed */
2363 speed = button_apply_acceleration( (1<<31)|(1<<24)|wheel_velocity);
2364 snprintf(buf, sizeof(buf), "accel. speed: %4d", speed);
2365 lcd_puts(0, 6, buf);
2367 lcd_update();
2369 return false;
2371 #endif
2373 #if defined(HAVE_USBSTACK) && defined(ROCKBOX_HAS_LOGF) && defined(USB_SERIAL)
2374 static bool logf_usb_serial(void)
2376 bool serial_enabled = !usb_core_driver_enabled(USB_DRIVER_SERIAL);
2377 usb_core_enable_driver(USB_DRIVER_SERIAL,serial_enabled);
2378 gui_syncsplash(HZ, "USB logf %s",
2379 serial_enabled?"enabled":"disabled");
2380 return false;
2382 #endif
2384 #if defined(HAVE_USBSTACK) && defined(USB_STORAGE)
2385 static bool usb_reconnect(void)
2387 gui_syncsplash(HZ, "Reconnect mass storage");
2388 usb_storage_reconnect();
2389 return false;
2391 #endif
2394 /****** The menu *********/
2395 struct the_menu_item {
2396 unsigned char *desc; /* string or ID */
2397 bool (*function) (void); /* return true if USB was connected */
2399 static const struct the_menu_item menuitems[] = {
2400 #if defined(TOSHIBA_GIGABEAT_F) && !defined(SIMULATOR)
2401 { "LCD Power Off", dbg_lcd_power_off },
2402 #endif
2403 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || \
2404 (defined(CPU_PP) && !(defined(SANSA_E200) || defined(SANSA_C200)))
2405 { "Dump ROM contents", dbg_save_roms },
2406 #endif
2407 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || defined(CPU_PP) || CONFIG_CPU == S3C2440
2408 { "View I/O ports", dbg_ports },
2409 #endif
2410 #if (CONFIG_RTC == RTC_PCF50605) && !defined(SIMULATOR)
2411 { "View PCF registers", dbg_pcf },
2412 #endif
2413 #if defined(HAVE_TSC2100) && !defined(SIMULATOR)
2414 { "TSC2100 debug", tsc2100_debug },
2415 #endif
2416 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
2417 { "CPU frequency", dbg_cpufreq },
2418 #endif
2419 #if defined(IRIVER_H100_SERIES) && !defined(SIMULATOR)
2420 { "S/PDIF analyzer", dbg_spdif },
2421 #endif
2422 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
2423 { "Catch mem accesses", dbg_set_memory_guard },
2424 #endif
2425 { "View OS stacks", dbg_os },
2426 #ifdef HAVE_LCD_BITMAP
2427 #ifndef SIMULATOR
2428 { "View battery", view_battery },
2429 #endif
2430 { "Screendump", dbg_screendump },
2431 #endif
2432 #ifndef SIMULATOR
2433 { "View HW info", dbg_hw_info },
2434 #endif
2435 #ifndef SIMULATOR
2436 { "View partitions", dbg_partitions },
2437 #endif
2438 #ifndef SIMULATOR
2439 { "View disk info", dbg_disk_info },
2440 #if !defined(HAVE_MMC) && !defined(HAVE_HOTSWAP)
2441 { "Dump ATA identify info", dbg_identify_info},
2442 #endif
2443 #endif
2444 #ifdef HAVE_DIRCACHE
2445 { "View dircache info", dbg_dircache_info },
2446 #endif
2447 #ifdef HAVE_TAGCACHE
2448 { "View database info", dbg_tagcache_info },
2449 #endif
2450 #ifdef HAVE_LCD_BITMAP
2451 #if CONFIG_CODEC == SWCODEC
2452 { "View buffering thread", dbg_buffering_thread },
2453 #elif !defined(SIMULATOR)
2454 { "View audio thread", dbg_audio_thread },
2455 #endif
2456 #ifdef PM_DEBUG
2457 { "pm histogram", peak_meter_histogram},
2458 #endif /* PM_DEBUG */
2459 #endif /* HAVE_LCD_BITMAP */
2460 #ifndef SIMULATOR
2461 #if CONFIG_TUNER
2462 { "FM Radio", dbg_fm_radio },
2463 #endif
2464 #endif
2465 #if defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS)
2466 { "Write back EEPROM", dbg_write_eeprom },
2467 #endif
2468 #ifdef ROCKBOX_HAS_LOGF
2469 {"logf", logfdisplay },
2470 {"logfdump", logfdump },
2471 #endif
2472 #if defined(HAVE_USBSTACK) && defined(ROCKBOX_HAS_LOGF) && defined(USB_SERIAL)
2473 {"logf over usb",logf_usb_serial },
2474 #endif
2475 #if defined(HAVE_USBSTACK) && defined(USB_STORAGE)
2476 {"reconnect usb storage",usb_reconnect},
2477 #endif
2478 #ifdef CPU_BOOST_LOGGING
2479 {"cpu_boost log",cpu_boost_log},
2480 #endif
2481 #if (defined(HAVE_SCROLLWHEEL) && (CONFIG_KEYPAD==IPOD_4G_PAD) && !defined(SIMULATOR))
2482 {"Debug scrollwheel", dbg_scrollwheel},
2483 #endif
2485 static int menu_action_callback(int btn, struct gui_synclist *lists)
2487 if (btn == ACTION_STD_OK)
2489 menuitems[gui_synclist_get_sel_pos(lists)].function();
2490 btn = ACTION_REDRAW;
2492 return btn;
2494 static char* dbg_menu_getname(int item, void * data, char *buffer)
2496 (void)data; (void)buffer;
2497 return menuitems[item].desc;
2499 bool debug_menu(void)
2501 struct simplelist_info info;
2503 simplelist_info_init(&info, "Debug Menu", ARRAYLEN(menuitems), NULL);
2504 info.action_callback = menu_action_callback;
2505 info.get_name = dbg_menu_getname;
2507 return simplelist_show_list(&info);