When looking for album art in /.rockbox/albumart/, use album artist rather than artis...
[kugel-rb.git] / apps / debug_menu.c
bloba2cf055446c812570f45c22d921167c24408d415
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 || CONFIG_CPU == IMX31L
99 #include "debug-target.h"
100 #endif
102 #if defined(SANSA_E200)
103 #include "i2c-pp.h"
104 #include "as3514.h"
105 #endif
107 #if defined(HAVE_USBSTACK)
108 #include "usb_core.h"
109 #endif
110 #ifdef USB_STORAGE
111 #include "../firmware/usbstack/usb_storage.h"
112 #endif
114 /*---------------------------------------------------*/
115 /* SPECIAL DEBUG STUFF */
116 /*---------------------------------------------------*/
117 extern struct thread_entry threads[MAXTHREADS];
119 static char thread_status_char(unsigned status)
121 static const char thread_status_chars[THREAD_NUM_STATES+1] =
123 [0 ... THREAD_NUM_STATES] = '?',
124 [STATE_RUNNING] = 'R',
125 [STATE_BLOCKED] = 'B',
126 [STATE_SLEEPING] = 'S',
127 [STATE_BLOCKED_W_TMO] = 'T',
128 [STATE_FROZEN] = 'F',
129 [STATE_KILLED] = 'K',
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,
139 char *buffer, size_t buffer_len)
141 (void)data;
142 struct thread_entry *thread;
143 char name[32];
145 #if NUM_CORES > 1
146 if (selected_item < (int)NUM_CORES)
148 snprintf(buffer, buffer_len, "Idle (%d): %2d%%", selected_item,
149 idle_stack_usage(selected_item));
150 return buffer;
153 selected_item -= NUM_CORES;
154 #endif
156 thread = &threads[selected_item];
158 if (thread->state == STATE_KILLED)
160 snprintf(buffer, buffer_len, "%2d: ---", selected_item);
161 return buffer;
164 thread_get_name(name, 32, thread);
166 snprintf(buffer, buffer_len,
167 "%2d: " IF_COP("(%d) ") "%c%c " IF_PRIO("%d %d ") "%2d%% %s",
168 selected_item,
169 IF_COP(thread->core,)
170 #ifdef HAVE_SCHEDULER_BOOSTCTRL
171 (thread->cpu_boost) ? '+' :
172 #endif
173 ((thread->state == STATE_RUNNING) ? '*' : ' '),
174 thread_status_char(thread->state),
175 IF_PRIO(thread->base_priority, thread->priority, )
176 thread_stack_usage(thread), name);
178 return buffer;
180 static int dbg_threads_action_callback(int action, struct gui_synclist *lists)
182 (void)lists;
183 #ifdef ROCKBOX_HAS_LOGF
184 if (action == ACTION_STD_OK)
186 int selpos = gui_synclist_get_sel_pos(lists);
187 #if NUM_CORES > 1
188 if (selpos >= NUM_CORES)
189 remove_thread(&threads[selpos - NUM_CORES]);
190 #else
191 remove_thread(&threads[selpos]);
192 #endif
193 return ACTION_REDRAW;
195 #endif /* ROCKBOX_HAS_LOGF */
196 if (action == ACTION_NONE)
197 action = ACTION_REDRAW;
198 return action;
200 /* Test code!!! */
201 static bool dbg_os(void)
203 struct simplelist_info info;
204 simplelist_info_init(&info, IF_COP("Core and ") "Stack usage:",
205 #if NUM_CORES == 1
206 MAXTHREADS,
207 #else
208 MAXTHREADS+NUM_CORES,
209 #endif
210 NULL);
211 #ifndef ROCKBOX_HAS_LOGF
212 info.hide_selection = true;
213 #endif
214 info.action_callback = dbg_threads_action_callback;
215 info.get_name = threads_getname;
216 return simplelist_show_list(&info);
219 #ifdef HAVE_LCD_BITMAP
220 #if CONFIG_CODEC != SWCODEC
221 #ifndef SIMULATOR
222 static bool dbg_audio_thread(void)
224 char buf[32];
225 struct audio_debug d;
227 lcd_setmargins(0, 0);
228 lcd_setfont(FONT_SYSFIXED);
230 while(1)
232 if (action_userabort(HZ/5))
233 return false;
235 audio_get_debugdata(&d);
237 lcd_clear_display();
239 snprintf(buf, sizeof(buf), "read: %x", d.audiobuf_read);
240 lcd_puts(0, 0, buf);
241 snprintf(buf, sizeof(buf), "write: %x", d.audiobuf_write);
242 lcd_puts(0, 1, buf);
243 snprintf(buf, sizeof(buf), "swap: %x", d.audiobuf_swapwrite);
244 lcd_puts(0, 2, buf);
245 snprintf(buf, sizeof(buf), "playing: %d", d.playing);
246 lcd_puts(0, 3, buf);
247 snprintf(buf, sizeof(buf), "playable: %x", d.playable_space);
248 lcd_puts(0, 4, buf);
249 snprintf(buf, sizeof(buf), "unswapped: %x", d.unswapped_space);
250 lcd_puts(0, 5, buf);
252 /* Playable space left */
253 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, 6*8, 112, 4, d.audiobuflen, 0,
254 d.playable_space, HORIZONTAL);
256 /* Show the watermark limit */
257 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, 6*8+4, 112, 4, d.audiobuflen, 0,
258 d.low_watermark_level, HORIZONTAL);
260 snprintf(buf, sizeof(buf), "wm: %x - %x",
261 d.low_watermark_level, d.lowest_watermark_level);
262 lcd_puts(0, 7, buf);
264 lcd_update();
266 return false;
268 #endif /* !SIMULATOR */
269 #else /* CONFIG_CODEC == SWCODEC */
270 extern size_t filebuflen;
271 /* This is a size_t, but call it a long so it puts a - when it's bad. */
273 static unsigned int ticks, boost_ticks, freq_sum;
275 static void dbg_audio_task(void)
277 #ifndef SIMULATOR
278 if(FREQ > CPUFREQ_NORMAL)
279 boost_ticks++;
280 freq_sum += FREQ/1000000; /* in MHz */
281 #endif
282 ticks++;
285 static bool dbg_buffering_thread(void)
287 char buf[32];
288 int button;
289 int line;
290 bool done = false;
291 size_t bufused;
292 size_t bufsize = pcmbuf_get_bufsize();
293 int pcmbufdescs = pcmbuf_descs();
294 struct buffering_debug d;
296 ticks = boost_ticks = freq_sum = 0;
298 tick_add_task(dbg_audio_task);
300 lcd_setmargins(0, 0);
301 lcd_setfont(FONT_SYSFIXED);
302 while(!done)
304 button = get_action(CONTEXT_STD,HZ/5);
305 switch(button)
307 case ACTION_STD_NEXT:
308 audio_next();
309 break;
310 case ACTION_STD_PREV:
311 audio_prev();
312 break;
313 case ACTION_STD_CANCEL:
314 done = true;
315 break;
318 buffering_get_debugdata(&d);
320 line = 0;
321 lcd_clear_display();
323 bufused = bufsize - pcmbuf_free();
325 snprintf(buf, sizeof(buf), "pcm: %7ld/%7ld", (long) bufused, (long) bufsize);
326 lcd_puts(0, line++, buf);
328 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6,
329 bufsize, 0, bufused, HORIZONTAL);
330 line++;
332 snprintf(buf, sizeof(buf), "alloc: %8ld/%8ld", audio_filebufused(),
333 (long) filebuflen);
334 lcd_puts(0, line++, buf);
336 #if LCD_HEIGHT > 80
337 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6,
338 filebuflen, 0, audio_filebufused(), HORIZONTAL);
339 line++;
341 snprintf(buf, sizeof(buf), "real: %8ld/%8ld", (long)d.buffered_data,
342 (long)filebuflen);
343 lcd_puts(0, line++, buf);
345 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6,
346 filebuflen, 0, (long)d.buffered_data, HORIZONTAL);
347 line++;
348 #endif
350 snprintf(buf, sizeof(buf), "usefl: %8ld/%8ld", (long)(d.useful_data),
351 (long)filebuflen);
352 lcd_puts(0, line++, buf);
354 #if LCD_HEIGHT > 80
355 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6,
356 filebuflen, 0, d.useful_data, HORIZONTAL);
357 line++;
358 #endif
360 snprintf(buf, sizeof(buf), "data_rem: %ld", (long)d.data_rem);
361 lcd_puts(0, line++, buf);
363 snprintf(buf, sizeof(buf), "track count: %2d", audio_track_count());
364 lcd_puts(0, line++, buf);
366 snprintf(buf, sizeof(buf), "handle count: %d", (int)d.num_handles);
367 lcd_puts(0, line++, buf);
369 #ifndef SIMULATOR
370 snprintf(buf, sizeof(buf), "cpu freq: %3dMHz",
371 (int)((FREQ + 500000) / 1000000));
372 lcd_puts(0, line++, buf);
373 #endif
375 if (ticks > 0)
377 int boostquota = boost_ticks * 1000 / ticks; /* in °/oo */
378 int avgclock = freq_sum * 10 / ticks; /* in 100 kHz */
379 snprintf(buf, sizeof(buf), "boost ratio: %3d.%d%% (%2d.%dMHz)",
380 boostquota/10, boostquota%10, avgclock/10, avgclock%10);
381 lcd_puts(0, line++, buf);
384 snprintf(buf, sizeof(buf), "pcmbufdesc: %2d/%2d",
385 pcmbuf_used_descs(), pcmbufdescs);
386 lcd_puts(0, line++, buf);
388 lcd_update();
391 tick_remove_task(dbg_audio_task);
393 return false;
395 #endif /* CONFIG_CODEC */
396 #endif /* HAVE_LCD_BITMAP */
399 #if (CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE))
400 /* Tool function to read the flash manufacturer and type, if available.
401 Only chips which could be reprogrammed in system will return values.
402 (The mode switch addresses vary between flash manufacturers, hence addr1/2) */
403 /* In IRAM to avoid problems when running directly from Flash */
404 static bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
405 unsigned addr1, unsigned addr2)
406 ICODE_ATTR __attribute__((noinline));
407 static bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
408 unsigned addr1, unsigned addr2)
411 unsigned not_manu, not_id; /* read values before switching to ID mode */
412 unsigned manu, id; /* read values when in ID mode */
414 #if CONFIG_CPU == SH7034
415 volatile unsigned char* flash = (unsigned char*)0x2000000; /* flash mapping */
416 #elif defined(CPU_COLDFIRE)
417 volatile unsigned short* flash = (unsigned short*)0; /* flash mapping */
418 #endif
419 int old_level; /* saved interrupt level */
421 not_manu = flash[0]; /* read the normal content */
422 not_id = flash[1]; /* should be 'A' (0x41) and 'R' (0x52) from the "ARCH" marker */
424 /* disable interrupts, prevent any stray flash access */
425 old_level = disable_irq_save();
427 flash[addr1] = 0xAA; /* enter command mode */
428 flash[addr2] = 0x55;
429 flash[addr1] = 0x90; /* ID command */
430 /* Atmel wants 20ms pause here */
431 /* sleep(HZ/50); no sleeping possible while interrupts are disabled */
433 manu = flash[0]; /* read the IDs */
434 id = flash[1];
436 flash[0] = 0xF0; /* reset flash (back to normal read mode) */
437 /* Atmel wants 20ms pause here */
438 /* sleep(HZ/50); no sleeping possible while interrupts are disabled */
440 restore_irq(old_level); /* enable interrupts again */
442 /* I assume success if the obtained values are different from
443 the normal flash content. This is not perfectly bulletproof, they
444 could theoretically be the same by chance, causing us to fail. */
445 if (not_manu != manu || not_id != id) /* a value has changed */
447 *p_manufacturer = manu; /* return the results */
448 *p_device = id;
449 return true; /* success */
451 return false; /* fail */
453 #endif /* (CONFIG_CPU == SH7034 || CPU_COLDFIRE) */
455 #ifndef SIMULATOR
456 #ifdef CPU_PP
457 static int perfcheck(void)
459 int result;
461 asm (
462 "mrs r2, CPSR \n"
463 "orr r0, r2, #0xc0 \n" /* disable IRQ and FIQ */
464 "msr CPSR_c, r0 \n"
465 "mov %[res], #0 \n"
466 "ldr r0, [%[timr]] \n"
467 "add r0, r0, %[tmo] \n"
468 "1: \n"
469 "add %[res], %[res], #1 \n"
470 "ldr r1, [%[timr]] \n"
471 "cmp r1, r0 \n"
472 "bmi 1b \n"
473 "msr CPSR_c, r2 \n" /* reset IRQ and FIQ state */
475 [res]"=&r"(result)
477 [timr]"r"(&USEC_TIMER),
478 [tmo]"r"(
479 #if CONFIG_CPU == PP5002
480 16000
481 #else /* PP5020/5022/5024 */
482 10226
483 #endif
486 "r0", "r1", "r2"
488 return result;
490 #endif
492 #ifdef HAVE_LCD_BITMAP
493 static bool dbg_hw_info(void)
495 #if CONFIG_CPU == SH7034
496 char buf[32];
497 int bitmask = HW_MASK;
498 int rom_version = ROM_VERSION;
499 unsigned manu, id; /* flash IDs */
500 bool got_id; /* flag if we managed to get the flash IDs */
501 unsigned rom_crc = 0xffffffff; /* CRC32 of the boot ROM */
502 bool has_bootrom; /* flag for boot ROM present */
503 int oldmode; /* saved memory guard mode */
505 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
507 /* get flash ROM type */
508 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
509 if (!got_id)
510 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
512 /* check if the boot ROM area is a flash mirror */
513 has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0);
514 if (has_bootrom) /* if ROM and Flash different */
516 /* calculate CRC16 checksum of boot ROM */
517 rom_crc = crc_32((unsigned char*)0x0000, 64*1024, 0xffffffff);
520 system_memory_guard(oldmode); /* re-enable memory guard */
522 lcd_setmargins(0, 0);
523 lcd_setfont(FONT_SYSFIXED);
524 lcd_clear_display();
526 lcd_puts(0, 0, "[Hardware info]");
528 snprintf(buf, 32, "ROM: %d.%02d", rom_version/100, rom_version%100);
529 lcd_puts(0, 1, buf);
531 snprintf(buf, 32, "Mask: 0x%04x", bitmask);
532 lcd_puts(0, 2, buf);
534 if (got_id)
535 snprintf(buf, 32, "Flash: M=%02x D=%02x", manu, id);
536 else
537 snprintf(buf, 32, "Flash: M=?? D=??"); /* unknown, sorry */
538 lcd_puts(0, 3, buf);
540 if (has_bootrom)
542 if (rom_crc == 0x56DBA4EE) /* known Version 1 */
543 snprintf(buf, 32, "Boot ROM: V1");
544 else
545 snprintf(buf, 32, "ROMcrc: 0x%08x", rom_crc);
547 else
549 snprintf(buf, 32, "Boot ROM: none");
551 lcd_puts(0, 4, buf);
553 lcd_update();
555 while (!(action_userabort(TIMEOUT_BLOCK)));
557 #elif CONFIG_CPU == MCF5249 || CONFIG_CPU == MCF5250
558 char buf[32];
559 unsigned manu, id; /* flash IDs */
560 int got_id; /* flag if we managed to get the flash IDs */
561 int oldmode; /* saved memory guard mode */
562 int line = 0;
564 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
566 /* get flash ROM type */
567 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
568 if (!got_id)
569 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
571 system_memory_guard(oldmode); /* re-enable memory guard */
573 lcd_setmargins(0, 0);
574 lcd_setfont(FONT_SYSFIXED);
575 lcd_clear_display();
577 lcd_puts(0, line++, "[Hardware info]");
579 if (got_id)
580 snprintf(buf, 32, "Flash: M=%04x D=%04x", manu, id);
581 else
582 snprintf(buf, 32, "Flash: M=???? D=????"); /* unknown, sorry */
583 lcd_puts(0, line++, buf);
585 #ifdef IAUDIO_X5
587 struct ds2411_id id;
589 lcd_puts(0, ++line, "Serial Number:");
591 got_id = ds2411_read_id(&id);
593 if (got_id == DS2411_OK)
595 snprintf(buf, 32, " FC=%02x", (unsigned)id.family_code);
596 lcd_puts(0, ++line, buf);
597 snprintf(buf, 32, " ID=%02X %02X %02X %02X %02X %02X",
598 (unsigned)id.uid[0], (unsigned)id.uid[1], (unsigned)id.uid[2],
599 (unsigned)id.uid[3], (unsigned)id.uid[4], (unsigned)id.uid[5]);
600 lcd_puts(0, ++line, buf);
601 snprintf(buf, 32, " CRC=%02X", (unsigned)id.crc);
603 else
605 snprintf(buf, 32, "READ ERR=%d", got_id);
608 lcd_puts(0, ++line, buf);
610 #endif
612 lcd_update();
614 while (!(action_userabort(TIMEOUT_BLOCK)));
616 #elif defined(CPU_PP502x)
617 int line = 0;
618 char buf[32];
619 char pp_version[] = { (PP_VER2 >> 24) & 0xff, (PP_VER2 >> 16) & 0xff,
620 (PP_VER2 >> 8) & 0xff, (PP_VER2) & 0xff,
621 (PP_VER1 >> 24) & 0xff, (PP_VER1 >> 16) & 0xff,
622 (PP_VER1 >> 8) & 0xff, (PP_VER1) & 0xff, '\0' };
624 lcd_setmargins(0, 0);
625 lcd_setfont(FONT_SYSFIXED);
626 lcd_clear_display();
628 lcd_puts(0, line++, "[Hardware info]");
630 #ifdef IPOD_ARCH
631 snprintf(buf, sizeof(buf), "HW rev: 0x%08lx", IPOD_HW_REVISION);
632 lcd_puts(0, line++, buf);
633 #endif
635 #ifdef IPOD_COLOR
636 extern int lcd_type; /* Defined in lcd-colornano.c */
638 snprintf(buf, sizeof(buf), "LCD type: %d", lcd_type);
639 lcd_puts(0, line++, buf);
640 #endif
642 snprintf(buf, sizeof(buf), "PP version: %s", pp_version);
643 lcd_puts(0, line++, buf);
645 snprintf(buf, sizeof(buf), "Est. clock (kHz): %d", perfcheck());
646 lcd_puts(0, line++, buf);
648 lcd_update();
650 while (!(action_userabort(TIMEOUT_BLOCK)));
652 #elif CONFIG_CPU == PP5002
653 int line = 0;
654 char buf[32];
655 char pp_version[] = { (PP_VER4 >> 8) & 0xff, PP_VER4 & 0xff,
656 (PP_VER3 >> 8) & 0xff, PP_VER3 & 0xff,
657 (PP_VER2 >> 8) & 0xff, PP_VER2 & 0xff,
658 (PP_VER1 >> 8) & 0xff, PP_VER1 & 0xff, '\0' };
661 lcd_setmargins(0, 0);
662 lcd_setfont(FONT_SYSFIXED);
663 lcd_clear_display();
665 lcd_puts(0, line++, "[Hardware info]");
667 #ifdef IPOD_ARCH
668 snprintf(buf, sizeof(buf), "HW rev: 0x%08lx", IPOD_HW_REVISION);
669 lcd_puts(0, line++, buf);
670 #endif
672 snprintf(buf, sizeof(buf), "PP version: %s", pp_version);
673 lcd_puts(0, line++, buf);
675 snprintf(buf, sizeof(buf), "Est. clock (kHz): %d", perfcheck());
676 lcd_puts(0, line++, buf);
678 lcd_update();
680 while (!(action_userabort(TIMEOUT_BLOCK)));
681 #else
682 /* Define this function in your target tree */
683 return __dbg_hw_info();
684 #endif /* CONFIG_CPU */
685 return false;
687 #else /* !HAVE_LCD_BITMAP */
688 static bool dbg_hw_info(void)
690 char buf[32];
691 int button;
692 int currval = 0;
693 int rom_version = ROM_VERSION;
694 unsigned manu, id; /* flash IDs */
695 bool got_id; /* flag if we managed to get the flash IDs */
696 unsigned rom_crc = 0xffffffff; /* CRC32 of the boot ROM */
697 bool has_bootrom; /* flag for boot ROM present */
698 int oldmode; /* saved memory guard mode */
700 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
702 /* get flash ROM type */
703 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
704 if (!got_id)
705 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
707 /* check if the boot ROM area is a flash mirror */
708 has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0);
709 if (has_bootrom) /* if ROM and Flash different */
711 /* calculate CRC16 checksum of boot ROM */
712 rom_crc = crc_32((unsigned char*)0x0000, 64*1024, 0xffffffff);
715 system_memory_guard(oldmode); /* re-enable memory guard */
717 lcd_clear_display();
719 lcd_puts(0, 0, "[HW Info]");
720 while(1)
722 switch(currval)
724 case 0:
725 snprintf(buf, 32, "ROM: %d.%02d",
726 rom_version/100, rom_version%100);
727 break;
728 case 1:
729 if (got_id)
730 snprintf(buf, 32, "Flash:%02x,%02x", manu, id);
731 else
732 snprintf(buf, 32, "Flash:??,??"); /* unknown, sorry */
733 break;
734 case 2:
735 if (has_bootrom)
737 if (rom_crc == 0x56DBA4EE) /* known Version 1 */
738 snprintf(buf, 32, "BootROM: V1");
739 else if (rom_crc == 0x358099E8)
740 snprintf(buf, 32, "BootROM: V2");
741 /* alternative boot ROM found in one single player so far */
742 else
743 snprintf(buf, 32, "R: %08x", rom_crc);
745 else
746 snprintf(buf, 32, "BootROM: no");
749 lcd_puts(0, 1, buf);
750 lcd_update();
752 button = get_action(CONTEXT_SETTINGS,TIMEOUT_BLOCK);
754 switch(button)
756 case ACTION_STD_CANCEL:
757 return false;
759 case ACTION_SETTINGS_DEC:
760 currval--;
761 if(currval < 0)
762 currval = 2;
763 break;
765 case ACTION_SETTINGS_INC:
766 currval++;
767 if(currval > 2)
768 currval = 0;
769 break;
772 return false;
774 #endif /* !HAVE_LCD_BITMAP */
775 #endif /* !SIMULATOR */
777 #ifndef SIMULATOR
778 static char* dbg_partitions_getname(int selected_item, void *data,
779 char *buffer, size_t buffer_len)
781 (void)data;
782 int partition = selected_item/2;
783 struct partinfo* p = disk_partinfo(partition);
784 if (selected_item%2)
786 snprintf(buffer, buffer_len, " T:%x %ld MB", p->type, p->size / 2048);
788 else
790 snprintf(buffer, buffer_len, "P%d: S:%lx", partition, p->start);
792 return buffer;
795 bool dbg_partitions(void)
797 struct simplelist_info info;
798 simplelist_info_init(&info, "Partition Info", 4, NULL);
799 info.selection_size = 2;
800 info.hide_selection = true;
801 info.get_name = dbg_partitions_getname;
802 return simplelist_show_list(&info);
804 #endif
806 #if defined(CPU_COLDFIRE) && defined(HAVE_SPDIF_OUT)
807 static bool dbg_spdif(void)
809 char buf[128];
810 int line;
811 unsigned int control;
812 int x;
813 char *s;
814 int category;
815 int generation;
816 unsigned int interruptstat;
817 bool valnogood, symbolerr, parityerr;
818 bool done = false;
819 bool spdif_src_on;
820 int spdif_source = spdif_get_output_source(&spdif_src_on);
821 spdif_set_output_source(AUDIO_SRC_SPDIF IF_SPDIF_POWER_(, true));
823 lcd_setmargins(0, 0);
824 lcd_clear_display();
825 lcd_setfont(FONT_SYSFIXED);
827 #ifdef HAVE_SPDIF_POWER
828 spdif_power_enable(true); /* We need SPDIF power for both sending & receiving */
829 #endif
831 while (!done)
833 line = 0;
835 control = EBU1RCVCCHANNEL1;
836 interruptstat = INTERRUPTSTAT;
837 INTERRUPTCLEAR = 0x03c00000;
839 valnogood = (interruptstat & 0x01000000)?true:false;
840 symbolerr = (interruptstat & 0x00800000)?true:false;
841 parityerr = (interruptstat & 0x00400000)?true:false;
843 snprintf(buf, sizeof(buf), "Val: %s Sym: %s Par: %s",
844 valnogood?"--":"OK",
845 symbolerr?"--":"OK",
846 parityerr?"--":"OK");
847 lcd_puts(0, line++, buf);
849 snprintf(buf, sizeof(buf), "Status word: %08x", (int)control);
850 lcd_puts(0, line++, buf);
852 line++;
854 x = control >> 31;
855 snprintf(buf, sizeof(buf), "PRO: %d (%s)",
856 x, x?"Professional":"Consumer");
857 lcd_puts(0, line++, buf);
859 x = (control >> 30) & 1;
860 snprintf(buf, sizeof(buf), "Audio: %d (%s)",
861 x, x?"Non-PCM":"PCM");
862 lcd_puts(0, line++, buf);
864 x = (control >> 29) & 1;
865 snprintf(buf, sizeof(buf), "Copy: %d (%s)",
866 x, x?"Permitted":"Inhibited");
867 lcd_puts(0, line++, buf);
869 x = (control >> 27) & 7;
870 switch(x)
872 case 0:
873 s = "None";
874 break;
875 case 1:
876 s = "50/15us";
877 break;
878 default:
879 s = "Reserved";
880 break;
882 snprintf(buf, sizeof(buf), "Preemphasis: %d (%s)", x, s);
883 lcd_puts(0, line++, buf);
885 x = (control >> 24) & 3;
886 snprintf(buf, sizeof(buf), "Mode: %d", x);
887 lcd_puts(0, line++, buf);
889 category = (control >> 17) & 127;
890 switch(category)
892 case 0x00:
893 s = "General";
894 break;
895 case 0x40:
896 s = "Audio CD";
897 break;
898 default:
899 s = "Unknown";
901 snprintf(buf, sizeof(buf), "Category: 0x%02x (%s)", category, s);
902 lcd_puts(0, line++, buf);
904 x = (control >> 16) & 1;
905 generation = x;
906 if(((category & 0x70) == 0x10) ||
907 ((category & 0x70) == 0x40) ||
908 ((category & 0x78) == 0x38))
910 generation = !generation;
912 snprintf(buf, sizeof(buf), "Generation: %d (%s)",
913 x, generation?"Original":"No ind.");
914 lcd_puts(0, line++, buf);
916 x = (control >> 12) & 15;
917 snprintf(buf, sizeof(buf), "Source: %d", x);
918 lcd_puts(0, line++, buf);
920 x = (control >> 8) & 15;
921 switch(x)
923 case 0:
924 s = "Unspecified";
925 break;
926 case 8:
927 s = "A (Left)";
928 break;
929 case 4:
930 s = "B (Right)";
931 break;
932 default:
933 s = "";
934 break;
936 snprintf(buf, sizeof(buf), "Channel: %d (%s)", x, s);
937 lcd_puts(0, line++, buf);
939 x = (control >> 4) & 15;
940 switch(x)
942 case 0:
943 s = "44.1kHz";
944 break;
945 case 0x4:
946 s = "48kHz";
947 break;
948 case 0xc:
949 s = "32kHz";
950 break;
952 snprintf(buf, sizeof(buf), "Frequency: %d (%s)", x, s);
953 lcd_puts(0, line++, buf);
955 x = (control >> 2) & 3;
956 snprintf(buf, sizeof(buf), "Clock accuracy: %d", x);
957 lcd_puts(0, line++, buf);
958 line++;
960 #ifndef SIMULATOR
961 snprintf(buf, sizeof(buf), "Measured freq: %ldHz",
962 spdif_measure_frequency());
963 lcd_puts(0, line++, buf);
964 #endif
966 lcd_update();
968 if (action_userabort(HZ/10))
969 break;
972 spdif_set_output_source(spdif_source IF_SPDIF_POWER_(, spdif_src_on));
974 #ifdef HAVE_SPDIF_POWER
975 spdif_power_enable(global_settings.spdif_enable);
976 #endif
978 return false;
980 #endif /* CPU_COLDFIRE */
982 #ifndef SIMULATOR
983 #ifdef HAVE_LCD_BITMAP
984 /* button definitions */
985 #if (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
986 (CONFIG_KEYPAD == IRIVER_H300_PAD)
987 # define DEBUG_CANCEL BUTTON_OFF
989 #elif CONFIG_KEYPAD == RECORDER_PAD
990 # define DEBUG_CANCEL BUTTON_OFF
992 #elif CONFIG_KEYPAD == ONDIO_PAD
993 # define DEBUG_CANCEL BUTTON_MENU
995 #elif (CONFIG_KEYPAD == IPOD_1G2G_PAD) || \
996 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
997 (CONFIG_KEYPAD == IPOD_4G_PAD)
998 # define DEBUG_CANCEL BUTTON_MENU
1000 #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
1001 # define DEBUG_CANCEL BUTTON_PLAY
1003 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
1004 # define DEBUG_CANCEL BUTTON_REC
1006 #elif (CONFIG_KEYPAD == IAUDIO_M3_PAD)
1007 # define DEBUG_CANCEL BUTTON_RC_REC
1009 #elif (CONFIG_KEYPAD == IRIVER_H10_PAD)
1010 # define DEBUG_CANCEL BUTTON_REW
1012 #elif (CONFIG_KEYPAD == MROBE100_PAD)
1013 # define DEBUG_CANCEL BUTTON_MENU
1015 #elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \
1016 (CONFIG_KEYPAD == SANSA_C200_PAD)
1017 # define DEBUG_CANCEL BUTTON_LEFT
1018 #endif /* key definitions */
1020 /* Test code!!! */
1021 bool dbg_ports(void)
1023 #if CONFIG_CPU == SH7034
1024 char buf[32];
1025 int adc_battery_voltage, adc_battery_level;
1027 lcd_setfont(FONT_SYSFIXED);
1028 lcd_setmargins(0, 0);
1029 lcd_clear_display();
1031 while(1)
1033 snprintf(buf, 32, "PADR: %04x", (unsigned short)PADR);
1034 lcd_puts(0, 0, buf);
1035 snprintf(buf, 32, "PBDR: %04x", (unsigned short)PBDR);
1036 lcd_puts(0, 1, buf);
1038 snprintf(buf, 32, "AN0: %03x AN4: %03x", adc_read(0), adc_read(4));
1039 lcd_puts(0, 2, buf);
1040 snprintf(buf, 32, "AN1: %03x AN5: %03x", adc_read(1), adc_read(5));
1041 lcd_puts(0, 3, buf);
1042 snprintf(buf, 32, "AN2: %03x AN6: %03x", adc_read(2), adc_read(6));
1043 lcd_puts(0, 4, buf);
1044 snprintf(buf, 32, "AN3: %03x AN7: %03x", adc_read(3), adc_read(7));
1045 lcd_puts(0, 5, buf);
1047 battery_read_info(&adc_battery_voltage, &adc_battery_level);
1048 snprintf(buf, 32, "Batt: %d.%03dV %d%% ", adc_battery_voltage / 1000,
1049 adc_battery_voltage % 1000, adc_battery_level);
1050 lcd_puts(0, 6, buf);
1052 lcd_update();
1053 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1054 return false;
1056 #elif defined(CPU_COLDFIRE)
1057 unsigned int gpio_out;
1058 unsigned int gpio1_out;
1059 unsigned int gpio_read;
1060 unsigned int gpio1_read;
1061 unsigned int gpio_function;
1062 unsigned int gpio1_function;
1063 unsigned int gpio_enable;
1064 unsigned int gpio1_enable;
1065 int adc_buttons, adc_remote;
1066 int adc_battery_voltage, adc_battery_level;
1067 char buf[128];
1068 int line;
1070 lcd_setmargins(0, 0);
1071 lcd_clear_display();
1072 lcd_setfont(FONT_SYSFIXED);
1074 while(1)
1076 line = 0;
1077 gpio_read = GPIO_READ;
1078 gpio1_read = GPIO1_READ;
1079 gpio_out = GPIO_OUT;
1080 gpio1_out = GPIO1_OUT;
1081 gpio_function = GPIO_FUNCTION;
1082 gpio1_function = GPIO1_FUNCTION;
1083 gpio_enable = GPIO_ENABLE;
1084 gpio1_enable = GPIO1_ENABLE;
1086 snprintf(buf, sizeof(buf), "GPIO_READ: %08x", gpio_read);
1087 lcd_puts(0, line++, buf);
1088 snprintf(buf, sizeof(buf), "GPIO_OUT: %08x", gpio_out);
1089 lcd_puts(0, line++, buf);
1090 snprintf(buf, sizeof(buf), "GPIO_FUNC: %08x", gpio_function);
1091 lcd_puts(0, line++, buf);
1092 snprintf(buf, sizeof(buf), "GPIO_ENA: %08x", gpio_enable);
1093 lcd_puts(0, line++, buf);
1095 snprintf(buf, sizeof(buf), "GPIO1_READ: %08x", gpio1_read);
1096 lcd_puts(0, line++, buf);
1097 snprintf(buf, sizeof(buf), "GPIO1_OUT: %08x", gpio1_out);
1098 lcd_puts(0, line++, buf);
1099 snprintf(buf, sizeof(buf), "GPIO1_FUNC: %08x", gpio1_function);
1100 lcd_puts(0, line++, buf);
1101 snprintf(buf, sizeof(buf), "GPIO1_ENA: %08x", gpio1_enable);
1102 lcd_puts(0, line++, buf);
1104 adc_buttons = adc_read(ADC_BUTTONS);
1105 adc_remote = adc_read(ADC_REMOTE);
1106 battery_read_info(&adc_battery_voltage, &adc_battery_level);
1107 #if defined(IAUDIO_X5) || defined(IAUDIO_M5) || defined(IRIVER_H300_SERIES)
1108 snprintf(buf, sizeof(buf), "ADC_BUTTONS (%c): %02x",
1109 button_scan_enabled() ? '+' : '-', adc_buttons);
1110 #else
1111 snprintf(buf, sizeof(buf), "ADC_BUTTONS: %02x", adc_buttons);
1112 #endif
1113 lcd_puts(0, line++, buf);
1114 #if defined(IAUDIO_X5) || defined(IAUDIO_M5)
1115 snprintf(buf, sizeof(buf), "ADC_REMOTE (%c): %02x",
1116 remote_detect() ? '+' : '-', adc_remote);
1117 #else
1118 snprintf(buf, sizeof(buf), "ADC_REMOTE: %02x", adc_remote);
1119 #endif
1120 lcd_puts(0, line++, buf);
1121 #if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES)
1122 snprintf(buf, sizeof(buf), "ADC_REMOTEDETECT: %02x",
1123 adc_read(ADC_REMOTEDETECT));
1124 lcd_puts(0, line++, buf);
1125 #endif
1127 snprintf(buf, 32, "Batt: %d.%03dV %d%% ", adc_battery_voltage / 1000,
1128 adc_battery_voltage % 1000, adc_battery_level);
1129 lcd_puts(0, line++, buf);
1131 #if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES)
1132 snprintf(buf, sizeof(buf), "remotetype: %d", remote_type());
1133 lcd_puts(0, line++, buf);
1134 #endif
1136 lcd_update();
1137 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1138 return false;
1141 #elif defined(CPU_PP502x)
1143 char buf[128];
1144 int line;
1146 lcd_setmargins(0, 0);
1147 lcd_clear_display();
1148 lcd_setfont(FONT_SYSFIXED);
1150 while(1)
1152 line = 0;
1153 lcd_puts(0, line++, "GPIO STATES:");
1154 snprintf(buf, sizeof(buf), "A: %02x E: %02x I: %02x",
1155 (unsigned int)GPIOA_INPUT_VAL,
1156 (unsigned int)GPIOE_INPUT_VAL,
1157 (unsigned int)GPIOI_INPUT_VAL);
1158 lcd_puts(0, line++, buf);
1159 snprintf(buf, sizeof(buf), "B: %02x F: %02x J: %02x",
1160 (unsigned int)GPIOB_INPUT_VAL,
1161 (unsigned int)GPIOF_INPUT_VAL,
1162 (unsigned int)GPIOJ_INPUT_VAL);
1163 lcd_puts(0, line++, buf);
1164 snprintf(buf, sizeof(buf), "C: %02x G: %02x K: %02x",
1165 (unsigned int)GPIOC_INPUT_VAL,
1166 (unsigned int)GPIOG_INPUT_VAL,
1167 (unsigned int)GPIOK_INPUT_VAL);
1168 lcd_puts(0, line++, buf);
1169 snprintf(buf, sizeof(buf), "D: %02x H: %02x L: %02x",
1170 (unsigned int)GPIOD_INPUT_VAL,
1171 (unsigned int)GPIOH_INPUT_VAL,
1172 (unsigned int)GPIOL_INPUT_VAL);
1173 lcd_puts(0, line++, buf);
1174 line++;
1175 snprintf(buf, sizeof(buf), "GPO32_VAL: %08lx", GPO32_VAL);
1176 lcd_puts(0, line++, buf);
1177 snprintf(buf, sizeof(buf), "GPO32_EN: %08lx", GPO32_ENABLE);
1178 lcd_puts(0, line++, buf);
1179 snprintf(buf, sizeof(buf), "DEV_EN: %08lx", DEV_EN);
1180 lcd_puts(0, line++, buf);
1181 snprintf(buf, sizeof(buf), "DEV_EN2: %08lx", DEV_EN2);
1182 lcd_puts(0, line++, buf);
1183 snprintf(buf, sizeof(buf), "DEV_EN3: %08lx", inl(0x60006044));
1184 lcd_puts(0, line++, buf); /* to be verified */
1185 snprintf(buf, sizeof(buf), "DEV_INIT1: %08lx", DEV_INIT1);
1186 lcd_puts(0, line++, buf);
1187 snprintf(buf, sizeof(buf), "DEV_INIT2: %08lx", DEV_INIT2);
1188 lcd_puts(0, line++, buf);
1190 #if defined(IRIVER_H10) || defined(IRIVER_H10_5GB)
1191 line++;
1192 snprintf(buf, sizeof(buf), "BATT: %03x UNK1: %03x",
1193 adc_read(ADC_BATTERY), adc_read(ADC_UNKNOWN_1));
1194 lcd_puts(0, line++, buf);
1195 snprintf(buf, sizeof(buf), "REM: %03x PAD: %03x",
1196 adc_read(ADC_REMOTE), adc_read(ADC_SCROLLPAD));
1197 lcd_puts(0, line++, buf);
1198 #elif defined(SANSA_E200)
1199 snprintf(buf, sizeof(buf), "ADC_BVDD: %4d", adc_read(ADC_BVDD));
1200 lcd_puts(0, line++, buf);
1201 snprintf(buf, sizeof(buf), "ADC_RTCSUP: %4d", adc_read(ADC_RTCSUP));
1202 lcd_puts(0, line++, buf);
1203 snprintf(buf, sizeof(buf), "ADC_UVDD: %4d", adc_read(ADC_UVDD));
1204 lcd_puts(0, line++, buf);
1205 snprintf(buf, sizeof(buf), "ADC_CHG_IN: %4d", adc_read(ADC_CHG_IN));
1206 lcd_puts(0, line++, buf);
1207 snprintf(buf, sizeof(buf), "ADC_CVDD: %4d", adc_read(ADC_CVDD));
1208 lcd_puts(0, line++, buf);
1209 snprintf(buf, sizeof(buf), "ADC_BATTEMP: %4d", adc_read(ADC_BATTEMP));
1210 lcd_puts(0, line++, buf);
1211 snprintf(buf, sizeof(buf), "ADC_MICSUP1: %4d", adc_read(ADC_MICSUP1));
1212 lcd_puts(0, line++, buf);
1213 snprintf(buf, sizeof(buf), "ADC_MICSUP2: %4d", adc_read(ADC_MICSUP2));
1214 lcd_puts(0, line++, buf);
1215 snprintf(buf, sizeof(buf), "ADC_VBE1: %4d", adc_read(ADC_VBE1));
1216 lcd_puts(0, line++, buf);
1217 snprintf(buf, sizeof(buf), "ADC_VBE2: %4d", adc_read(ADC_VBE2));
1218 lcd_puts(0, line++, buf);
1219 snprintf(buf, sizeof(buf), "ADC_I_MICSUP1:%4d", adc_read(ADC_I_MICSUP1));
1220 lcd_puts(0, line++, buf);
1221 snprintf(buf, sizeof(buf), "ADC_I_MICSUP2:%4d", adc_read(ADC_I_MICSUP2));
1222 lcd_puts(0, line++, buf);
1223 snprintf(buf, sizeof(buf), "ADC_VBAT: %4d", adc_read(ADC_VBAT));
1224 lcd_puts(0, line++, buf);
1225 snprintf(buf, sizeof(buf), "CHARGER: %02X/%02X", i2c_readbyte(AS3514_I2C_ADDR, AS3514_CHARGER), i2c_readbyte(AS3514_I2C_ADDR, AS3514_IRQ_ENRD0));
1226 lcd_puts(0, line++, buf);
1227 #endif
1228 lcd_update();
1229 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1230 return false;
1233 #elif CONFIG_CPU == PP5002
1234 char buf[128];
1235 int line;
1237 lcd_setmargins(0, 0);
1238 lcd_clear_display();
1239 lcd_setfont(FONT_SYSFIXED);
1241 while(1)
1243 line = 0;
1244 snprintf(buf, sizeof(buf), "GPIO_A: %02x GPIO_B: %02x",
1245 (unsigned int)GPIOA_INPUT_VAL, (unsigned int)GPIOB_INPUT_VAL);
1246 lcd_puts(0, line++, buf);
1247 snprintf(buf, sizeof(buf), "GPIO_C: %02x GPIO_D: %02x",
1248 (unsigned int)GPIOC_INPUT_VAL, (unsigned int)GPIOD_INPUT_VAL);
1249 lcd_puts(0, line++, buf);
1251 snprintf(buf, sizeof(buf), "DEV_EN: %08lx", DEV_EN);
1252 lcd_puts(0, line++, buf);
1253 snprintf(buf, sizeof(buf), "CLOCK_ENABLE: %08lx", CLOCK_ENABLE);
1254 lcd_puts(0, line++, buf);
1255 snprintf(buf, sizeof(buf), "CLOCK_SOURCE: %08lx", CLOCK_SOURCE);
1256 lcd_puts(0, line++, buf);
1257 snprintf(buf, sizeof(buf), "PLL_CONTROL: %08lx", PLL_CONTROL);
1258 lcd_puts(0, line++, buf);
1259 snprintf(buf, sizeof(buf), "PLL_DIV: %08lx", PLL_DIV);
1260 lcd_puts(0, line++, buf);
1261 snprintf(buf, sizeof(buf), "PLL_MULT: %08lx", PLL_MULT);
1262 lcd_puts(0, line++, buf);
1263 snprintf(buf, sizeof(buf), "TIMING1_CTL: %08lx", TIMING1_CTL);
1264 lcd_puts(0, line++, buf);
1265 snprintf(buf, sizeof(buf), "TIMING2_CTL: %08lx", TIMING2_CTL);
1266 lcd_puts(0, line++, buf);
1268 lcd_update();
1269 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1270 return false;
1272 #else
1273 return __dbg_ports();
1274 #endif /* CPU */
1275 return false;
1277 #else /* !HAVE_LCD_BITMAP */
1278 bool dbg_ports(void)
1280 char buf[32];
1281 int button;
1282 int adc_battery_voltage;
1283 int currval = 0;
1285 lcd_clear_display();
1287 while(1)
1289 switch(currval)
1291 case 0:
1292 snprintf(buf, 32, "PADR: %04x", (unsigned short)PADR);
1293 break;
1294 case 1:
1295 snprintf(buf, 32, "PBDR: %04x", (unsigned short)PBDR);
1296 break;
1297 case 2:
1298 snprintf(buf, 32, "AN0: %03x", adc_read(0));
1299 break;
1300 case 3:
1301 snprintf(buf, 32, "AN1: %03x", adc_read(1));
1302 break;
1303 case 4:
1304 snprintf(buf, 32, "AN2: %03x", adc_read(2));
1305 break;
1306 case 5:
1307 snprintf(buf, 32, "AN3: %03x", adc_read(3));
1308 break;
1309 case 6:
1310 snprintf(buf, 32, "AN4: %03x", adc_read(4));
1311 break;
1312 case 7:
1313 snprintf(buf, 32, "AN5: %03x", adc_read(5));
1314 break;
1315 case 8:
1316 snprintf(buf, 32, "AN6: %03x", adc_read(6));
1317 break;
1318 case 9:
1319 snprintf(buf, 32, "AN7: %03x", adc_read(7));
1320 break;
1321 break;
1323 lcd_puts(0, 0, buf);
1325 battery_read_info(&adc_battery_voltage, NULL);
1326 snprintf(buf, 32, "Batt: %d.%03dV", adc_battery_voltage / 1000,
1327 adc_battery_voltage % 1000);
1328 lcd_puts(0, 1, buf);
1329 lcd_update();
1331 button = get_action(CONTEXT_SETTINGS,HZ/5);
1333 switch(button)
1335 case ACTION_STD_CANCEL:
1336 return false;
1338 case ACTION_SETTINGS_DEC:
1339 currval--;
1340 if(currval < 0)
1341 currval = 9;
1342 break;
1344 case ACTION_SETTINGS_INC:
1345 currval++;
1346 if(currval > 9)
1347 currval = 0;
1348 break;
1351 return false;
1353 #endif /* !HAVE_LCD_BITMAP */
1354 #endif /* !SIMULATOR */
1356 #if (CONFIG_RTC == RTC_PCF50605) && !defined(SIMULATOR)
1357 static bool dbg_pcf(void)
1359 char buf[128];
1360 int line;
1362 #ifdef HAVE_LCD_BITMAP
1363 lcd_setmargins(0, 0);
1364 lcd_setfont(FONT_SYSFIXED);
1365 #endif
1366 lcd_clear_display();
1368 while(1)
1370 line = 0;
1372 snprintf(buf, sizeof(buf), "DCDC1: %02x", pcf50605_read(0x1b));
1373 lcd_puts(0, line++, buf);
1374 snprintf(buf, sizeof(buf), "DCDC2: %02x", pcf50605_read(0x1c));
1375 lcd_puts(0, line++, buf);
1376 snprintf(buf, sizeof(buf), "DCDC3: %02x", pcf50605_read(0x1d));
1377 lcd_puts(0, line++, buf);
1378 snprintf(buf, sizeof(buf), "DCDC4: %02x", pcf50605_read(0x1e));
1379 lcd_puts(0, line++, buf);
1380 snprintf(buf, sizeof(buf), "DCDEC1: %02x", pcf50605_read(0x1f));
1381 lcd_puts(0, line++, buf);
1382 snprintf(buf, sizeof(buf), "DCDEC2: %02x", pcf50605_read(0x20));
1383 lcd_puts(0, line++, buf);
1384 snprintf(buf, sizeof(buf), "DCUDC1: %02x", pcf50605_read(0x21));
1385 lcd_puts(0, line++, buf);
1386 snprintf(buf, sizeof(buf), "DCUDC2: %02x", pcf50605_read(0x22));
1387 lcd_puts(0, line++, buf);
1388 snprintf(buf, sizeof(buf), "IOREGC: %02x", pcf50605_read(0x23));
1389 lcd_puts(0, line++, buf);
1390 snprintf(buf, sizeof(buf), "D1REGC: %02x", pcf50605_read(0x24));
1391 lcd_puts(0, line++, buf);
1392 snprintf(buf, sizeof(buf), "D2REGC: %02x", pcf50605_read(0x25));
1393 lcd_puts(0, line++, buf);
1394 snprintf(buf, sizeof(buf), "D3REGC: %02x", pcf50605_read(0x26));
1395 lcd_puts(0, line++, buf);
1396 snprintf(buf, sizeof(buf), "LPREG1: %02x", pcf50605_read(0x27));
1397 lcd_puts(0, line++, buf);
1399 lcd_update();
1400 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1402 return false;
1406 return false;
1408 #endif
1410 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
1411 static bool dbg_cpufreq(void)
1413 char buf[128];
1414 int line;
1415 int button;
1417 #ifdef HAVE_LCD_BITMAP
1418 lcd_setmargins(0, 0);
1419 lcd_setfont(FONT_SYSFIXED);
1420 #endif
1421 lcd_clear_display();
1423 while(1)
1425 line = 0;
1427 snprintf(buf, sizeof(buf), "Frequency: %ld", FREQ);
1428 lcd_puts(0, line++, buf);
1430 snprintf(buf, sizeof(buf), "boost_counter: %d", get_cpu_boost_counter());
1431 lcd_puts(0, line++, buf);
1433 lcd_update();
1434 button = get_action(CONTEXT_STD,HZ/10);
1436 switch(button)
1438 case ACTION_STD_PREV:
1439 cpu_boost(true);
1440 break;
1442 case ACTION_STD_NEXT:
1443 cpu_boost(false);
1444 break;
1446 case ACTION_STD_OK:
1447 while (get_cpu_boost_counter() > 0)
1448 cpu_boost(false);
1449 set_cpu_frequency(CPUFREQ_DEFAULT);
1450 break;
1452 case ACTION_STD_CANCEL:
1453 return false;
1457 return false;
1459 #endif /* HAVE_ADJUSTABLE_CPU_FREQ */
1461 #if defined(HAVE_TSC2100) && !defined(SIMULATOR)
1462 #include "tsc2100.h"
1463 char *itob(int n, int len)
1465 static char binary[64];
1466 int i,j;
1467 for (i=1, j=0;i<=len;i++)
1469 binary[j++] = n&(1<<(len-i))?'1':'0';
1470 if (i%4 == 0)
1471 binary[j++] = ' ';
1473 binary[j] = '\0';
1474 return binary;
1476 static char* tsc2100_debug_getname(int selected_item, void * data,
1477 char *buffer, size_t buffer_len)
1479 int *page = (int*)data;
1480 bool reserved = false;
1481 switch (*page)
1483 case 0:
1484 if ((selected_item > 0x0a) ||
1485 (selected_item == 0x04) ||
1486 (selected_item == 0x08))
1487 reserved = true;
1488 break;
1489 case 1:
1490 if ((selected_item > 0x05) ||
1491 (selected_item == 0x02))
1492 reserved = true;
1493 break;
1494 case 2:
1495 if (selected_item > 0x1e)
1496 reserved = true;
1497 break;
1499 if (reserved)
1500 snprintf(buffer, buffer_len, "%02x: RESERVED", selected_item);
1501 else
1502 snprintf(buffer, buffer_len, "%02x: %s", selected_item,
1503 itob(tsc2100_readreg(*page, selected_item)&0xffff,16));
1504 return buffer;
1506 static int tsc2100debug_action_callback(int action, struct gui_synclist *lists)
1508 int *page = (int*)lists->data;
1509 if (action == ACTION_STD_OK)
1511 *page = (*page+1)%3;
1512 snprintf(lists->title, 32,
1513 "tsc2100 registers - Page %d", *page);
1514 return ACTION_REDRAW;
1516 return action;
1518 bool tsc2100_debug(void)
1520 int page = 0;
1521 char title[32] = "tsc2100 registers - Page 0";
1522 struct simplelist_info info;
1523 simplelist_info_init(&info, title, 32, &page);
1524 info.timeout = HZ/100;
1525 info.get_name = tsc2100_debug_getname;
1526 info.action_callback= tsc2100debug_action_callback;
1527 return simplelist_show_list(&info);
1529 #endif
1530 #ifndef SIMULATOR
1531 #ifdef HAVE_LCD_BITMAP
1533 * view_battery() shows a automatically scaled graph of the battery voltage
1534 * over time. Usable for estimating battery life / charging rate.
1535 * The power_history array is updated in power_thread of powermgmt.c.
1538 #define BAT_LAST_VAL MIN(LCD_WIDTH, POWER_HISTORY_LEN)
1539 #define BAT_YSPACE (LCD_HEIGHT - 20)
1541 static bool view_battery(void)
1543 int view = 0;
1544 int i, x, y;
1545 unsigned short maxv, minv;
1546 char buf[32];
1548 lcd_setmargins(0, 0);
1549 lcd_setfont(FONT_SYSFIXED);
1551 while(1)
1553 lcd_clear_display();
1554 switch (view) {
1555 case 0: /* voltage history graph */
1556 /* Find maximum and minimum voltage for scaling */
1557 minv = power_history[0];
1558 maxv = minv + 1;
1559 for (i = 1; i < BAT_LAST_VAL && power_history[i]; i++) {
1560 if (power_history[i] > maxv)
1561 maxv = power_history[i];
1562 if (power_history[i] < minv)
1563 minv = power_history[i];
1566 snprintf(buf, 30, "Battery %d.%03d", power_history[0] / 1000,
1567 power_history[0] % 1000);
1568 lcd_puts(0, 0, buf);
1569 snprintf(buf, 30, "scale %d.%03d-%d.%03dV",
1570 minv / 1000, minv % 1000, maxv / 1000, maxv % 1000);
1571 lcd_puts(0, 1, buf);
1573 x = 0;
1574 for (i = BAT_LAST_VAL - 1; i >= 0; i--) {
1575 y = (power_history[i] - minv) * BAT_YSPACE / (maxv - minv);
1576 lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
1577 lcd_vline(x, LCD_HEIGHT-1, 20);
1578 lcd_set_drawmode(DRMODE_SOLID);
1579 lcd_vline(x, LCD_HEIGHT-1,
1580 MIN(MAX(LCD_HEIGHT-1 - y, 20), LCD_HEIGHT-1));
1581 x++;
1584 break;
1586 case 1: /* status: */
1587 lcd_puts(0, 0, "Power status:");
1589 battery_read_info(&y, NULL);
1590 snprintf(buf, 30, "Battery: %d.%03d V", y / 1000, y % 1000);
1591 lcd_puts(0, 1, buf);
1592 #ifdef ADC_EXT_POWER
1593 y = (adc_read(ADC_EXT_POWER) * EXT_SCALE_FACTOR) / 1000;
1594 snprintf(buf, 30, "External: %d.%03d V", y / 1000, y % 1000);
1595 lcd_puts(0, 2, buf);
1596 #endif
1597 #if CONFIG_CHARGING
1598 #if CONFIG_CHARGING == CHARGING_CONTROL
1599 snprintf(buf, 30, "Chgr: %s %s",
1600 charger_inserted() ? "present" : "absent",
1601 charger_enabled ? "on" : "off");
1602 lcd_puts(0, 3, buf);
1603 snprintf(buf, 30, "short delta: %d", short_delta);
1604 lcd_puts(0, 5, buf);
1605 snprintf(buf, 30, "long delta: %d", long_delta);
1606 lcd_puts(0, 6, buf);
1607 lcd_puts(0, 7, power_message);
1608 snprintf(buf, 30, "USB Inserted: %s",
1609 usb_inserted() ? "yes" : "no");
1610 lcd_puts(0, 8, buf);
1611 #if defined IRIVER_H300_SERIES
1612 snprintf(buf, 30, "USB Charging Enabled: %s",
1613 usb_charging_enabled() ? "yes" : "no");
1614 lcd_puts(0, 9, buf);
1615 #endif
1616 #else /* CONFIG_CHARGING != CHARGING_CONTROL */
1617 #if defined IPOD_NANO || defined IPOD_VIDEO
1618 int usb_pwr = (GPIOL_INPUT_VAL & 0x10)?true:false;
1619 int ext_pwr = (GPIOL_INPUT_VAL & 0x08)?false:true;
1620 int dock = (GPIOA_INPUT_VAL & 0x10)?true:false;
1621 int charging = (GPIOB_INPUT_VAL & 0x01)?false:true;
1622 int headphone= (GPIOA_INPUT_VAL & 0x80)?true:false;
1624 snprintf(buf, 30, "USB pwr: %s",
1625 usb_pwr ? "present" : "absent");
1626 lcd_puts(0, 3, buf);
1627 snprintf(buf, 30, "EXT pwr: %s",
1628 ext_pwr ? "present" : "absent");
1629 lcd_puts(0, 4, buf);
1630 snprintf(buf, 30, "Battery: %s",
1631 charging ? "charging" : (usb_pwr||ext_pwr) ? "charged" : "discharging");
1632 lcd_puts(0, 5, buf);
1633 snprintf(buf, 30, "Dock mode: %s",
1634 dock ? "enabled" : "disabled");
1635 lcd_puts(0, 6, buf);
1636 snprintf(buf, 30, "Headphone: %s",
1637 headphone ? "connected" : "disconnected");
1638 lcd_puts(0, 7, buf);
1639 #else
1640 snprintf(buf, 30, "Charger: %s",
1641 charger_inserted() ? "present" : "absent");
1642 lcd_puts(0, 3, buf);
1643 #endif
1644 #endif /* CONFIG_CHARGING != CHARGING_CONTROL */
1645 #endif /* CONFIG_CHARGING */
1646 break;
1648 case 2: /* voltage deltas: */
1649 lcd_puts(0, 0, "Voltage deltas:");
1651 for (i = 0; i <= 6; i++) {
1652 y = power_history[i] - power_history[i+1];
1653 snprintf(buf, 30, "-%d min: %s%d.%03d V", i,
1654 (y < 0) ? "-" : "", ((y < 0) ? y * -1 : y) / 1000,
1655 ((y < 0) ? y * -1 : y ) % 1000);
1656 lcd_puts(0, i+1, buf);
1658 break;
1660 case 3: /* remaining time estimation: */
1662 #if CONFIG_CHARGING == CHARGING_CONTROL
1663 snprintf(buf, 30, "charge_state: %d", charge_state);
1664 lcd_puts(0, 0, buf);
1666 snprintf(buf, 30, "Cycle time: %d m", powermgmt_last_cycle_startstop_min);
1667 lcd_puts(0, 1, buf);
1669 snprintf(buf, 30, "Lvl@cyc st: %d%%", powermgmt_last_cycle_level);
1670 lcd_puts(0, 2, buf);
1672 snprintf(buf, 30, "P=%2d I=%2d", pid_p, pid_i);
1673 lcd_puts(0, 3, buf);
1675 snprintf(buf, 30, "Trickle sec: %d/60", trickle_sec);
1676 lcd_puts(0, 4, buf);
1677 #endif /* CONFIG_CHARGING == CHARGING_CONTROL */
1679 snprintf(buf, 30, "Last PwrHist: %d.%03dV",
1680 power_history[0] / 1000,
1681 power_history[0] % 1000);
1682 lcd_puts(0, 5, buf);
1684 snprintf(buf, 30, "battery level: %d%%", battery_level());
1685 lcd_puts(0, 6, buf);
1687 snprintf(buf, 30, "Est. remain: %d m", battery_time());
1688 lcd_puts(0, 7, buf);
1689 break;
1692 lcd_update();
1694 switch(get_action(CONTEXT_SETTINGS,HZ/2))
1696 case ACTION_SETTINGS_DEC:
1697 if (view)
1698 view--;
1699 break;
1701 case ACTION_SETTINGS_INC:
1702 if (view < 3)
1703 view++;
1704 break;
1706 case ACTION_STD_CANCEL:
1707 return false;
1710 return false;
1713 #endif /* HAVE_LCD_BITMAP */
1714 #endif
1716 #ifndef SIMULATOR
1717 #if defined(HAVE_MMC) || defined(HAVE_HOTSWAP)
1718 #if defined(HAVE_MMC)
1719 #define CARDTYPE "MMC"
1720 #else
1721 #define CARDTYPE "microSD"
1722 #endif
1723 static int disk_callback(int btn, struct gui_synclist *lists)
1725 tCardInfo *card;
1726 int *cardnum = (int*)lists->data;
1727 unsigned char card_name[7];
1728 unsigned char pbuf[32];
1729 char *title = lists->title;
1730 static const unsigned char i_vmin[] = { 0, 1, 5, 10, 25, 35, 60, 100 };
1731 static const unsigned char i_vmax[] = { 1, 5, 10, 25, 35, 45, 80, 200 };
1732 static const unsigned char *kbit_units[] = { "kBit/s", "MBit/s", "GBit/s" };
1733 static const unsigned char *nsec_units[] = { "ns", "�s", "ms" };
1734 static const char *spec_vers[] = { "1.0-1.2", "1.4", "2.0-2.2",
1735 "3.1-3.31", "4.0" };
1736 if ((btn == ACTION_STD_OK) || (btn == SYS_FS_CHANGED) || (btn == ACTION_REDRAW))
1738 if (btn == ACTION_STD_OK)
1740 *cardnum ^= 0x1; /* change cards */
1743 simplelist_set_line_count(0);
1745 card = card_get_info(*cardnum);
1747 if (card->initialized > 0)
1749 card_name[6] = '\0';
1750 strncpy(card_name, ((unsigned char*)card->cid) + 3, 6);
1751 simplelist_addline(SIMPLELIST_ADD_LINE,
1752 "%s Rev %d.%d", card_name,
1753 (int) card_extract_bits(card->cid, 72, 4),
1754 (int) card_extract_bits(card->cid, 76, 4));
1755 simplelist_addline(SIMPLELIST_ADD_LINE,
1756 "Prod: %d/%d",
1757 (int) card_extract_bits(card->cid, 112, 4),
1758 (int) card_extract_bits(card->cid, 116, 4) + 1997);
1759 simplelist_addline(SIMPLELIST_ADD_LINE,
1760 "Ser#: 0x%08lx",
1761 card_extract_bits(card->cid, 80, 32));
1762 simplelist_addline(SIMPLELIST_ADD_LINE,
1763 "M=%02x, O=%04x",
1764 (int) card_extract_bits(card->cid, 0, 8),
1765 (int) card_extract_bits(card->cid, 8, 16));
1766 int temp = card_extract_bits(card->csd, 2, 4);
1767 simplelist_addline(SIMPLELIST_ADD_LINE,
1768 CARDTYPE " v%s", temp < 5 ?
1769 spec_vers[temp] : "?.?");
1770 simplelist_addline(SIMPLELIST_ADD_LINE,
1771 "Blocks: 0x%06lx", card->numblocks);
1772 simplelist_addline(SIMPLELIST_ADD_LINE,
1773 "Blksz.: %d P:%c%c", card->blocksize,
1774 card_extract_bits(card->csd, 48, 1) ? 'R' : '-',
1775 card_extract_bits(card->csd, 106, 1) ? 'W' : '-');
1776 output_dyn_value(pbuf, sizeof pbuf, card->speed / 1000,
1777 kbit_units, false);
1778 simplelist_addline(SIMPLELIST_ADD_LINE,
1779 "Speed: %s", pbuf);
1780 output_dyn_value(pbuf, sizeof pbuf, card->tsac,
1781 nsec_units, false);
1782 simplelist_addline(SIMPLELIST_ADD_LINE,
1783 "Tsac: %s", pbuf);
1784 simplelist_addline(SIMPLELIST_ADD_LINE,
1785 "Nsac: %d clk", card->nsac);
1786 simplelist_addline(SIMPLELIST_ADD_LINE,
1787 "R2W: *%d", card->r2w_factor);
1788 simplelist_addline(SIMPLELIST_ADD_LINE,
1789 "IRmax: %d..%d mA",
1790 i_vmin[card_extract_bits(card->csd, 66, 3)],
1791 i_vmax[card_extract_bits(card->csd, 69, 3)]);
1792 simplelist_addline(SIMPLELIST_ADD_LINE,
1793 "IWmax: %d..%d mA",
1794 i_vmin[card_extract_bits(card->csd, 72, 3)],
1795 i_vmax[card_extract_bits(card->csd, 75, 3)]);
1797 else if (card->initialized == 0)
1799 simplelist_addline(SIMPLELIST_ADD_LINE, "Not Found!");
1801 #ifndef HAVE_MMC
1802 else /* card->initialized < 0 */
1804 simplelist_addline(SIMPLELIST_ADD_LINE, "Init Error! (%d)", card->initialized);
1806 #endif
1807 snprintf(title, 16, "[" CARDTYPE " %d]", *cardnum);
1808 gui_synclist_set_title(lists, title, Icon_NOICON);
1809 gui_synclist_set_nb_items(lists, simplelist_get_line_count());
1810 gui_synclist_select_item(lists, 0);
1811 btn = ACTION_REDRAW;
1813 return btn;
1815 #else /* !defined(HAVE_MMC) && !defined(HAVE_HOTSWAP) */
1816 static int disk_callback(int btn, struct gui_synclist *lists)
1818 (void)lists;
1819 int i;
1820 char buf[128];
1821 unsigned short* identify_info = ata_get_identify();
1822 bool timing_info_present = false;
1823 (void)btn;
1825 simplelist_set_line_count(0);
1827 for (i=0; i < 20; i++)
1828 ((unsigned short*)buf)[i]=htobe16(identify_info[i+27]);
1829 buf[40]=0;
1830 /* kill trailing space */
1831 for (i=39; i && buf[i]==' '; i--)
1832 buf[i] = 0;
1833 simplelist_addline(SIMPLELIST_ADD_LINE, "Model: %s", buf);
1834 for (i=0; i < 4; i++)
1835 ((unsigned short*)buf)[i]=htobe16(identify_info[i+23]);
1836 buf[8]=0;
1837 simplelist_addline(SIMPLELIST_ADD_LINE,
1838 "Firmware: %s", buf);
1839 snprintf(buf, sizeof buf, "%ld MB",
1840 ((unsigned long)identify_info[61] << 16 |
1841 (unsigned long)identify_info[60]) / 2048 );
1842 simplelist_addline(SIMPLELIST_ADD_LINE,
1843 "Size: %s", buf);
1844 unsigned long free;
1845 fat_size( IF_MV2(0,) NULL, &free );
1846 simplelist_addline(SIMPLELIST_ADD_LINE,
1847 "Free: %ld MB", free / 1024);
1848 simplelist_addline(SIMPLELIST_ADD_LINE,
1849 "Spinup time: %d ms", ata_spinup_time * (1000/HZ));
1850 i = identify_info[83] & (1<<3);
1851 simplelist_addline(SIMPLELIST_ADD_LINE,
1852 "Power mgmt: %s", i ? "enabled" : "unsupported");
1853 i = identify_info[83] & (1<<9);
1854 simplelist_addline(SIMPLELIST_ADD_LINE,
1855 "Noise mgmt: %s", i ? "enabled" : "unsupported");
1856 i = identify_info[82] & (1<<6);
1857 simplelist_addline(SIMPLELIST_ADD_LINE,
1858 "Read-ahead: %s", i ? "enabled" : "unsupported");
1859 timing_info_present = identify_info[53] & (1<<1);
1860 if(timing_info_present) {
1861 char pio3[2], pio4[2];pio3[1] = 0;
1862 pio4[1] = 0;
1863 pio3[0] = (identify_info[64] & (1<<0)) ? '3' : 0;
1864 pio4[0] = (identify_info[64] & (1<<1)) ? '4' : 0;
1865 simplelist_addline(SIMPLELIST_ADD_LINE,
1866 "PIO modes: 0 1 2 %s %s", pio3, pio4);
1868 else {
1869 simplelist_addline(SIMPLELIST_ADD_LINE,
1870 "No PIO mode info");
1872 timing_info_present = identify_info[53] & (1<<1);
1873 if(timing_info_present) {
1874 simplelist_addline(SIMPLELIST_ADD_LINE,
1875 "Cycle times %dns/%dns",
1876 identify_info[67],
1877 identify_info[68] );
1878 } else {
1879 simplelist_addline(SIMPLELIST_ADD_LINE,
1880 "No timing info");
1882 timing_info_present = identify_info[53] & (1<<1);
1883 if(timing_info_present) {
1884 i = identify_info[49] & (1<<11);
1885 simplelist_addline(SIMPLELIST_ADD_LINE,
1886 "IORDY support: %s", i ? "yes" : "no");
1887 i = identify_info[49] & (1<<10);
1888 simplelist_addline(SIMPLELIST_ADD_LINE,
1889 "IORDY disable: %s", i ? "yes" : "no");
1890 } else {
1891 simplelist_addline(SIMPLELIST_ADD_LINE,
1892 "No timing info");
1894 simplelist_addline(SIMPLELIST_ADD_LINE,
1895 "Cluster size: %d bytes", fat_get_cluster_size(IF_MV(0)));
1896 return btn;
1899 static bool dbg_identify_info(void)
1901 int fd = creat("/identify_info.bin");
1902 if(fd >= 0)
1904 #ifdef ROCKBOX_LITTLE_ENDIAN
1905 ecwrite(fd, ata_get_identify(), SECTOR_SIZE/2, "s", true);
1906 #else
1907 write(fd, ata_get_identify(), SECTOR_SIZE);
1908 #endif
1909 close(fd);
1911 return false;
1913 #endif /* !defined(HAVE_MMC) && !defined(HAVE_HOTSWAP) */
1914 static bool dbg_disk_info(void)
1916 struct simplelist_info info;
1917 simplelist_info_init(&info, "Disk Info", 1, NULL);
1918 #if defined(HAVE_MMC) || defined(HAVE_HOTSWAP)
1919 char title[16];
1920 int card = 0;
1921 info.callback_data = (void*)&card;
1922 info.title = title;
1923 #endif
1924 info.action_callback = disk_callback;
1925 info.hide_selection = true;
1926 return simplelist_show_list(&info);
1928 #endif /* !SIMULATOR */
1930 #ifdef HAVE_DIRCACHE
1931 static int dircache_callback(int btn, struct gui_synclist *lists)
1933 (void)btn; (void)lists;
1934 simplelist_set_line_count(0);
1935 simplelist_addline(SIMPLELIST_ADD_LINE, "Cache initialized: %s",
1936 dircache_is_enabled() ? "Yes" : "No");
1937 simplelist_addline(SIMPLELIST_ADD_LINE, "Cache size: %d B",
1938 dircache_get_cache_size());
1939 simplelist_addline(SIMPLELIST_ADD_LINE, "Last size: %d B",
1940 global_status.dircache_size);
1941 simplelist_addline(SIMPLELIST_ADD_LINE, "Limit: %d B",
1942 DIRCACHE_LIMIT);
1943 simplelist_addline(SIMPLELIST_ADD_LINE, "Reserve: %d/%d B",
1944 dircache_get_reserve_used(), DIRCACHE_RESERVE);
1945 simplelist_addline(SIMPLELIST_ADD_LINE, "Scanning took: %d s",
1946 dircache_get_build_ticks() / HZ);
1947 simplelist_addline(SIMPLELIST_ADD_LINE, "Entry count: %d",
1948 dircache_get_entry_count());
1949 return btn;
1952 static bool dbg_dircache_info(void)
1954 struct simplelist_info info;
1955 simplelist_info_init(&info, "Dircache Info", 7, NULL);
1956 info.action_callback = dircache_callback;
1957 info.hide_selection = true;
1958 return simplelist_show_list(&info);
1961 #endif /* HAVE_DIRCACHE */
1963 #ifdef HAVE_TAGCACHE
1964 static int database_callback(int btn, struct gui_synclist *lists)
1966 (void)lists;
1967 struct tagcache_stat *stat = tagcache_get_stat();
1968 static bool synced = false;
1970 simplelist_set_line_count(0);
1972 simplelist_addline(SIMPLELIST_ADD_LINE, "Initialized: %s",
1973 stat->initialized ? "Yes" : "No");
1974 simplelist_addline(SIMPLELIST_ADD_LINE, "DB Ready: %s",
1975 stat->ready ? "Yes" : "No");
1976 simplelist_addline(SIMPLELIST_ADD_LINE, "RAM Cache: %s",
1977 stat->ramcache ? "Yes" : "No");
1978 simplelist_addline(SIMPLELIST_ADD_LINE, "RAM: %d/%d B",
1979 stat->ramcache_used, stat->ramcache_allocated);
1980 simplelist_addline(SIMPLELIST_ADD_LINE, "Progress: %d%% (%d entries)",
1981 stat->progress, stat->processed_entries);
1982 simplelist_addline(SIMPLELIST_ADD_LINE, "Curfile: %s",
1983 stat->curentry ? stat->curentry : "---");
1984 simplelist_addline(SIMPLELIST_ADD_LINE, "Commit step: %d",
1985 stat->commit_step);
1986 simplelist_addline(SIMPLELIST_ADD_LINE, "Commit delayed: %s",
1987 stat->commit_delayed ? "Yes" : "No");
1989 simplelist_addline(SIMPLELIST_ADD_LINE, "Queue length: %d",
1990 stat->queue_length);
1992 if (synced)
1994 synced = false;
1995 tagcache_screensync_event();
1998 if (!btn && stat->curentry)
2000 synced = true;
2001 return ACTION_REDRAW;
2004 if (btn == ACTION_STD_CANCEL)
2005 tagcache_screensync_enable(false);
2007 return btn;
2009 static bool dbg_tagcache_info(void)
2011 struct simplelist_info info;
2012 simplelist_info_init(&info, "Database Info", 8, NULL);
2013 info.action_callback = database_callback;
2014 info.hide_selection = true;
2016 /* Don't do nonblock here, must give enough processing time
2017 for tagcache thread. */
2018 /* info.timeout = TIMEOUT_NOBLOCK; */
2019 info.timeout = 1;
2020 tagcache_screensync_enable(true);
2021 return simplelist_show_list(&info);
2023 #endif
2025 #if CONFIG_CPU == SH7034
2026 static bool dbg_save_roms(void)
2028 int fd;
2029 int oldmode = system_memory_guard(MEMGUARD_NONE);
2031 fd = creat("/internal_rom_0000-FFFF.bin");
2032 if(fd >= 0)
2034 write(fd, (void *)0, 0x10000);
2035 close(fd);
2038 fd = creat("/internal_rom_2000000-203FFFF.bin");
2039 if(fd >= 0)
2041 write(fd, (void *)0x2000000, 0x40000);
2042 close(fd);
2045 system_memory_guard(oldmode);
2046 return false;
2048 #elif defined CPU_COLDFIRE
2049 static bool dbg_save_roms(void)
2051 int fd;
2052 int oldmode = system_memory_guard(MEMGUARD_NONE);
2054 #if defined(IRIVER_H100_SERIES)
2055 fd = creat("/internal_rom_000000-1FFFFF.bin");
2056 #elif defined(IRIVER_H300_SERIES)
2057 fd = creat("/internal_rom_000000-3FFFFF.bin");
2058 #elif defined(IAUDIO_X5) || defined(IAUDIO_M5) || defined(IAUDIO_M3)
2059 fd = creat("/internal_rom_000000-3FFFFF.bin");
2060 #endif
2061 if(fd >= 0)
2063 write(fd, (void *)0, FLASH_SIZE);
2064 close(fd);
2066 system_memory_guard(oldmode);
2068 #ifdef HAVE_EEPROM
2069 fd = creat("/internal_eeprom.bin");
2070 if (fd >= 0)
2072 int old_irq_level;
2073 char buf[EEPROM_SIZE];
2074 int err;
2076 old_irq_level = disable_irq_save();
2078 err = eeprom_24cxx_read(0, buf, sizeof buf);
2080 restore_irq(old_irq_level);
2082 if (err)
2083 gui_syncsplash(HZ*3, "Eeprom read failure (%d)",err);
2084 else
2086 write(fd, buf, sizeof buf);
2089 close(fd);
2091 #endif
2093 return false;
2095 #elif defined(CPU_PP) && !(defined(SANSA_E200) || defined(SANSA_C200))
2096 static bool dbg_save_roms(void)
2098 int fd;
2100 fd = creat("/internal_rom_000000-0FFFFF.bin");
2101 if(fd >= 0)
2103 write(fd, (void *)0x20000000, FLASH_SIZE);
2104 close(fd);
2107 return false;
2109 #endif /* CPU */
2111 #ifndef SIMULATOR
2112 #if CONFIG_TUNER
2113 static int radio_callback(int btn, struct gui_synclist *lists)
2115 (void)lists;
2116 if (btn == ACTION_STD_CANCEL)
2117 return btn;
2118 simplelist_set_line_count(1);
2120 #if (CONFIG_TUNER & LV24020LP)
2121 simplelist_addline(SIMPLELIST_ADD_LINE,
2122 "CTRL_STAT: %02X", lv24020lp_get(LV24020LP_CTRL_STAT) );
2123 simplelist_addline(SIMPLELIST_ADD_LINE,
2124 "RADIO_STAT: %02X", lv24020lp_get(LV24020LP_REG_STAT) );
2125 simplelist_addline(SIMPLELIST_ADD_LINE,
2126 "MSS_FM: %d kHz", lv24020lp_get(LV24020LP_MSS_FM) );
2127 simplelist_addline(SIMPLELIST_ADD_LINE,
2128 "MSS_IF: %d Hz", lv24020lp_get(LV24020LP_MSS_IF) );
2129 simplelist_addline(SIMPLELIST_ADD_LINE,
2130 "MSS_SD: %d Hz", lv24020lp_get(LV24020LP_MSS_SD) );
2131 simplelist_addline(SIMPLELIST_ADD_LINE,
2132 "if_set: %d Hz", lv24020lp_get(LV24020LP_IF_SET) );
2133 simplelist_addline(SIMPLELIST_ADD_LINE,
2134 "sd_set: %d Hz", lv24020lp_get(LV24020LP_SD_SET) );
2135 #endif
2136 #if (CONFIG_TUNER & S1A0903X01)
2137 simplelist_addline(SIMPLELIST_ADD_LINE,
2138 "Samsung regs: %08X", s1a0903x01_get(RADIO_ALL));
2139 /* This one doesn't return dynamic data atm */
2140 #endif
2141 #if (CONFIG_TUNER & TEA5767)
2142 struct tea5767_dbg_info nfo;
2143 tea5767_dbg_info(&nfo);
2144 simplelist_addline(SIMPLELIST_ADD_LINE, "Philips regs:");
2145 simplelist_addline(SIMPLELIST_ADD_LINE,
2146 " Read: %02X %02X %02X %02X %02X",
2147 (unsigned)nfo.read_regs[0], (unsigned)nfo.read_regs[1],
2148 (unsigned)nfo.read_regs[2], (unsigned)nfo.read_regs[3],
2149 (unsigned)nfo.read_regs[4]);
2150 simplelist_addline(SIMPLELIST_ADD_LINE,
2151 " Write: %02X %02X %02X %02X %02X",
2152 (unsigned)nfo.write_regs[0], (unsigned)nfo.write_regs[1],
2153 (unsigned)nfo.write_regs[2], (unsigned)nfo.write_regs[3],
2154 (unsigned)nfo.write_regs[4]);
2155 #endif
2156 return ACTION_REDRAW;
2158 static bool dbg_fm_radio(void)
2160 struct simplelist_info info;
2161 simplelist_info_init(&info, "FM Radio", 1, NULL);
2162 simplelist_set_line_count(0);
2163 simplelist_addline(SIMPLELIST_ADD_LINE, "HW detected: %s",
2164 radio_hardware_present() ? "yes" : "no");
2166 info.action_callback = radio_hardware_present()?radio_callback : NULL;
2167 info.hide_selection = true;
2168 return simplelist_show_list(&info);
2170 #endif /* CONFIG_TUNER */
2171 #endif /* !SIMULATOR */
2173 #ifdef HAVE_LCD_BITMAP
2174 extern bool do_screendump_instead_of_usb;
2176 static bool dbg_screendump(void)
2178 do_screendump_instead_of_usb = !do_screendump_instead_of_usb;
2179 gui_syncsplash(HZ, "Screendump %s",
2180 do_screendump_instead_of_usb?"enabled":"disabled");
2181 return false;
2183 #endif /* HAVE_LCD_BITMAP */
2185 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
2186 static bool dbg_set_memory_guard(void)
2188 static const struct opt_items names[MAXMEMGUARD] = {
2189 { "None", -1 },
2190 { "Flash ROM writes", -1 },
2191 { "Zero area (all)", -1 }
2193 int mode = system_memory_guard(MEMGUARD_KEEP);
2195 set_option( "Catch mem accesses", &mode, INT, names, MAXMEMGUARD, NULL);
2196 system_memory_guard(mode);
2198 return false;
2200 #endif /* CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) */
2202 #if defined(TOSHIBA_GIGABEAT_F) && !defined(SIMULATOR)
2204 extern volatile bool lcd_poweroff;
2206 static bool dbg_lcd_power_off(void)
2208 lcd_setmargins(0, 0);
2210 while(1)
2212 int button;
2214 lcd_clear_display();
2215 lcd_puts(0, 0, "LCD Power Off");
2216 if(lcd_poweroff)
2217 lcd_puts(1, 1, "Yes");
2218 else
2219 lcd_puts(1, 1, "No");
2221 lcd_update();
2223 button = get_action(CONTEXT_STD,HZ/5);
2224 switch(button)
2226 case ACTION_STD_PREV:
2227 case ACTION_STD_NEXT:
2228 lcd_poweroff = !lcd_poweroff;
2229 break;
2230 case ACTION_STD_OK:
2231 case ACTION_STD_CANCEL:
2232 return false;
2233 default:
2234 sleep(HZ/10);
2235 break;
2238 return false;
2240 #endif
2242 #if defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS)
2243 static bool dbg_write_eeprom(void)
2245 int fd;
2246 int rc;
2247 int old_irq_level;
2248 char buf[EEPROM_SIZE];
2249 int err;
2251 fd = open("/internal_eeprom.bin", O_RDONLY);
2253 if (fd >= 0)
2255 rc = read(fd, buf, EEPROM_SIZE);
2257 if(rc == EEPROM_SIZE)
2259 old_irq_level = disable_irq_save();
2261 err = eeprom_24cxx_write(0, buf, sizeof buf);
2262 if (err)
2263 gui_syncsplash(HZ*3, "Eeprom write failure (%d)",err);
2264 else
2265 gui_syncsplash(HZ*3, "Eeprom written successfully");
2267 restore_irq(old_irq_level);
2269 else
2271 gui_syncsplash(HZ*3, "File read error (%d)",rc);
2273 close(fd);
2275 else
2277 gui_syncsplash(HZ*3, "Failed to open 'internal_eeprom.bin'");
2280 return false;
2282 #endif /* defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS) */
2283 #ifdef CPU_BOOST_LOGGING
2284 static bool cpu_boost_log(void)
2286 int i = 0,j=0;
2287 int count = cpu_boost_log_getcount();
2288 int lines = LCD_HEIGHT/SYSFONT_HEIGHT;
2289 char *str;
2290 bool done;
2291 lcd_setmargins(0, 0);
2292 lcd_setfont(FONT_SYSFIXED);
2293 str = cpu_boost_log_getlog_first();
2294 while (i < count)
2296 lcd_clear_display();
2297 for(j=0; j<lines; j++,i++)
2299 if (!str)
2300 str = cpu_boost_log_getlog_next();
2301 if (str)
2303 lcd_puts(0, j,str);
2305 str = NULL;
2307 lcd_update();
2308 done = false;
2309 while (!done)
2311 switch(get_action(CONTEXT_STD,TIMEOUT_BLOCK))
2313 case ACTION_STD_OK:
2314 case ACTION_STD_PREV:
2315 case ACTION_STD_NEXT:
2316 done = true;
2317 break;
2318 case ACTION_STD_CANCEL:
2319 i = count;
2320 done = true;
2321 break;
2325 get_action(CONTEXT_STD,TIMEOUT_BLOCK);
2326 lcd_setfont(FONT_UI);
2327 return false;
2329 #endif
2331 #if (defined(HAVE_SCROLLWHEEL) && (CONFIG_KEYPAD==IPOD_4G_PAD) && !defined(SIMULATOR))
2332 extern bool wheel_is_touched;
2333 extern int old_wheel_value;
2334 extern int new_wheel_value;
2335 extern int wheel_delta;
2336 extern unsigned int accumulated_wheel_delta;
2337 extern unsigned int wheel_velocity;
2339 static bool dbg_scrollwheel(void)
2341 char buf[64];
2342 unsigned int speed;
2344 lcd_setmargins(0, 0);
2345 lcd_setfont(FONT_SYSFIXED);
2347 while (1)
2349 if (action_userabort(HZ/10))
2350 return false;
2352 lcd_clear_display();
2354 /* show internal variables of scrollwheel driver */
2355 snprintf(buf, sizeof(buf), "wheel touched: %s", (wheel_is_touched) ? "true" : "false");
2356 lcd_puts(0, 0, buf);
2357 snprintf(buf, sizeof(buf), "new position: %2d", new_wheel_value);
2358 lcd_puts(0, 1, buf);
2359 snprintf(buf, sizeof(buf), "old position: %2d", old_wheel_value);
2360 lcd_puts(0, 2, buf);
2361 snprintf(buf, sizeof(buf), "wheel delta: %2d", wheel_delta);
2362 lcd_puts(0, 3, buf);
2363 snprintf(buf, sizeof(buf), "accumulated delta: %2d", accumulated_wheel_delta);
2364 lcd_puts(0, 4, buf);
2365 snprintf(buf, sizeof(buf), "velo [deg/s]: %4d", (int)wheel_velocity);
2366 lcd_puts(0, 5, buf);
2368 /* show effective accelerated scrollspeed */
2369 speed = button_apply_acceleration( (1<<31)|(1<<24)|wheel_velocity);
2370 snprintf(buf, sizeof(buf), "accel. speed: %4d", speed);
2371 lcd_puts(0, 6, buf);
2373 lcd_update();
2375 return false;
2377 #endif
2379 #if defined(HAVE_USBSTACK) && defined(ROCKBOX_HAS_LOGF) && defined(USB_SERIAL)
2380 static bool logf_usb_serial(void)
2382 bool serial_enabled = !usb_core_driver_enabled(USB_DRIVER_SERIAL);
2383 usb_core_enable_driver(USB_DRIVER_SERIAL,serial_enabled);
2384 gui_syncsplash(HZ, "USB logf %s",
2385 serial_enabled?"enabled":"disabled");
2386 return false;
2388 #endif
2390 #if defined(HAVE_USBSTACK) && defined(USB_STORAGE)
2391 static bool usb_reconnect(void)
2393 gui_syncsplash(HZ, "Reconnect mass storage");
2394 usb_storage_reconnect();
2395 return false;
2397 #endif
2400 /****** The menu *********/
2401 struct the_menu_item {
2402 unsigned char *desc; /* string or ID */
2403 bool (*function) (void); /* return true if USB was connected */
2405 static const struct the_menu_item menuitems[] = {
2406 #if defined(TOSHIBA_GIGABEAT_F) && !defined(SIMULATOR)
2407 { "LCD Power Off", dbg_lcd_power_off },
2408 #endif
2409 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || \
2410 (defined(CPU_PP) && !(defined(SANSA_E200) || defined(SANSA_C200)))
2411 { "Dump ROM contents", dbg_save_roms },
2412 #endif
2413 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || defined(CPU_PP) \
2414 || CONFIG_CPU == S3C2440 || CONFIG_CPU == IMX31L
2415 { "View I/O ports", dbg_ports },
2416 #endif
2417 #if (CONFIG_RTC == RTC_PCF50605) && !defined(SIMULATOR)
2418 { "View PCF registers", dbg_pcf },
2419 #endif
2420 #if defined(HAVE_TSC2100) && !defined(SIMULATOR)
2421 { "TSC2100 debug", tsc2100_debug },
2422 #endif
2423 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
2424 { "CPU frequency", dbg_cpufreq },
2425 #endif
2426 #if defined(IRIVER_H100_SERIES) && !defined(SIMULATOR)
2427 { "S/PDIF analyzer", dbg_spdif },
2428 #endif
2429 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
2430 { "Catch mem accesses", dbg_set_memory_guard },
2431 #endif
2432 { "View OS stacks", dbg_os },
2433 #ifdef HAVE_LCD_BITMAP
2434 #ifndef SIMULATOR
2435 { "View battery", view_battery },
2436 #endif
2437 { "Screendump", dbg_screendump },
2438 #endif
2439 #ifndef SIMULATOR
2440 { "View HW info", dbg_hw_info },
2441 #endif
2442 #ifndef SIMULATOR
2443 { "View partitions", dbg_partitions },
2444 #endif
2445 #ifndef SIMULATOR
2446 { "View disk info", dbg_disk_info },
2447 #if !defined(HAVE_MMC) && !defined(HAVE_HOTSWAP)
2448 { "Dump ATA identify info", dbg_identify_info},
2449 #endif
2450 #endif
2451 #ifdef HAVE_DIRCACHE
2452 { "View dircache info", dbg_dircache_info },
2453 #endif
2454 #ifdef HAVE_TAGCACHE
2455 { "View database info", dbg_tagcache_info },
2456 #endif
2457 #ifdef HAVE_LCD_BITMAP
2458 #if CONFIG_CODEC == SWCODEC
2459 { "View buffering thread", dbg_buffering_thread },
2460 #elif !defined(SIMULATOR)
2461 { "View audio thread", dbg_audio_thread },
2462 #endif
2463 #ifdef PM_DEBUG
2464 { "pm histogram", peak_meter_histogram},
2465 #endif /* PM_DEBUG */
2466 #endif /* HAVE_LCD_BITMAP */
2467 #ifndef SIMULATOR
2468 #if CONFIG_TUNER
2469 { "FM Radio", dbg_fm_radio },
2470 #endif
2471 #endif
2472 #if defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS)
2473 { "Write back EEPROM", dbg_write_eeprom },
2474 #endif
2475 #ifdef ROCKBOX_HAS_LOGF
2476 {"logf", logfdisplay },
2477 {"logfdump", logfdump },
2478 #endif
2479 #if defined(HAVE_USBSTACK) && defined(ROCKBOX_HAS_LOGF) && defined(USB_SERIAL)
2480 {"logf over usb",logf_usb_serial },
2481 #endif
2482 #if defined(HAVE_USBSTACK) && defined(USB_STORAGE)
2483 {"reconnect usb storage",usb_reconnect},
2484 #endif
2485 #ifdef CPU_BOOST_LOGGING
2486 {"cpu_boost log",cpu_boost_log},
2487 #endif
2488 #if (defined(HAVE_SCROLLWHEEL) && (CONFIG_KEYPAD==IPOD_4G_PAD) && !defined(SIMULATOR))
2489 {"Debug scrollwheel", dbg_scrollwheel},
2490 #endif
2492 static int menu_action_callback(int btn, struct gui_synclist *lists)
2494 if (btn == ACTION_STD_OK)
2496 menuitems[gui_synclist_get_sel_pos(lists)].function();
2497 btn = ACTION_REDRAW;
2499 return btn;
2501 static char* dbg_menu_getname(int item, void * data,
2502 char *buffer, size_t buffer_len)
2504 (void)data; (void)buffer; (void)buffer_len;
2505 return menuitems[item].desc;
2507 bool debug_menu(void)
2509 struct simplelist_info info;
2511 simplelist_info_init(&info, "Debug Menu", ARRAYLEN(menuitems), NULL);
2512 info.action_callback = menu_action_callback;
2513 info.get_name = dbg_menu_getname;
2515 return simplelist_show_list(&info);