Fix wps image tags description.
[Rockbox.git] / apps / debug_menu.c
blobd21dc032a8885dfadddf16fd7745bf904c2710fb
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2002 Heikki Hannikainen
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
20 #include "config.h"
21 #include <stdio.h>
22 #include <stdbool.h>
23 #include <string.h>
24 #include "lcd.h"
25 #include "menu.h"
26 #include "debug_menu.h"
27 #include "kernel.h"
28 #include "sprintf.h"
29 #include "structec.h"
30 #include "action.h"
31 #include "debug.h"
32 #include "thread.h"
33 #include "powermgmt.h"
34 #include "system.h"
35 #include "font.h"
36 #include "audio.h"
37 #include "mp3_playback.h"
38 #include "settings.h"
39 #include "list.h"
40 #include "statusbar.h"
41 #include "dir.h"
42 #include "panic.h"
43 #include "screens.h"
44 #include "misc.h"
45 #include "splash.h"
46 #include "dircache.h"
47 #ifdef HAVE_TAGCACHE
48 #include "tagcache.h"
49 #endif
50 #include "lcd-remote.h"
51 #include "crc32.h"
52 #include "logf.h"
53 #ifndef SIMULATOR
54 #include "disk.h"
55 #include "adc.h"
56 #include "power.h"
57 #include "usb.h"
58 #include "rtc.h"
59 #include "ata.h"
60 #include "fat.h"
61 #include "mas.h"
62 #include "eeprom_24cxx.h"
63 #if defined(HAVE_MMC) || defined(HAVE_HOTSWAP)
64 #include "ata_mmc.h"
65 #endif
66 #if CONFIG_TUNER
67 #include "tuner.h"
68 #include "radio.h"
69 #endif
70 #endif
72 #ifdef HAVE_LCD_BITMAP
73 #include "scrollbar.h"
74 #include "peakmeter.h"
75 #endif
76 #include "logfdisp.h"
77 #if CONFIG_CODEC == SWCODEC
78 #include "pcmbuf.h"
79 #include "buffering.h"
80 #if defined(HAVE_SPDIF_OUT) || defined(HAVE_SPDIF_IN)
81 #include "spdif.h"
82 #endif
83 #endif
84 #ifdef IRIVER_H300_SERIES
85 #include "pcf50606.h" /* for pcf50606_read */
86 #endif
87 #ifdef IAUDIO_X5
88 #include "ds2411.h"
89 #endif
90 #include "hwcompat.h"
91 #include "button.h"
92 #if CONFIG_RTC == RTC_PCF50605
93 #include "pcf50605.h"
94 #endif
96 #if CONFIG_CPU == DM320 || CONFIG_CPU == S3C2440 || CONFIG_CPU == TCC7801
97 #include "debug-target.h"
98 #endif
100 #if defined(SANSA_E200)
101 #include "i2c-pp.h"
102 #include "as3514.h"
103 #endif
105 #if defined(HAVE_USBSTACK)
106 #include "usb_core.h"
107 #endif
108 #ifdef USB_STORAGE
109 #include "../firmware/usbstack/usb_storage.h"
110 #endif
112 /*---------------------------------------------------*/
113 /* SPECIAL DEBUG STUFF */
114 /*---------------------------------------------------*/
115 extern struct thread_entry threads[MAXTHREADS];
117 static char thread_status_char(unsigned status)
119 static const char thread_status_chars[THREAD_NUM_STATES+1] =
121 [0 ... THREAD_NUM_STATES] = '?',
122 [STATE_RUNNING] = 'R',
123 [STATE_BLOCKED] = 'B',
124 [STATE_SLEEPING] = 'S',
125 [STATE_BLOCKED_W_TMO] = 'T',
126 [STATE_FROZEN] = 'F',
127 [STATE_KILLED] = 'K',
130 if (status > THREAD_NUM_STATES)
131 status = THREAD_NUM_STATES;
133 return thread_status_chars[status];
136 static char* threads_getname(int selected_item, void * data, char *buffer)
138 (void)data;
139 struct thread_entry *thread;
140 char name[32];
142 #if NUM_CORES > 1
143 if (selected_item < (int)NUM_CORES)
145 snprintf(buffer, MAX_PATH, "Idle (%d): %2d%%", selected_item,
146 idle_stack_usage(selected_item));
147 return buffer;
150 selected_item -= NUM_CORES;
151 #endif
153 thread = &threads[selected_item];
155 if (thread->state == STATE_KILLED)
157 snprintf(buffer, MAX_PATH, "%2d: ---", selected_item);
158 return buffer;
161 thread_get_name(name, 32, thread);
163 snprintf(buffer, MAX_PATH,
164 "%2d: " IF_COP("(%d) ") "%c%c " IF_PRIO("%d %d ") "%2d%% %s",
165 selected_item,
166 IF_COP(thread->core,)
167 #ifdef HAVE_SCHEDULER_BOOSTCTRL
168 (thread->cpu_boost) ? '+' :
169 #endif
170 ((thread->state == STATE_RUNNING) ? '*' : ' '),
171 thread_status_char(thread->state),
172 IF_PRIO(thread->base_priority, thread->priority, )
173 thread_stack_usage(thread), name);
175 return buffer;
177 static int dbg_threads_action_callback(int action, struct gui_synclist *lists)
179 (void)lists;
180 #ifdef ROCKBOX_HAS_LOGF
181 if (action == ACTION_STD_OK)
183 int selpos = gui_synclist_get_sel_pos(lists);
184 #if NUM_CORES > 1
185 if (selpos >= NUM_CORES)
186 remove_thread(&threads[selpos - NUM_CORES]);
187 #else
188 remove_thread(&threads[selpos]);
189 #endif
190 return ACTION_REDRAW;
192 #endif /* ROCKBOX_HAS_LOGF */
193 if (action == ACTION_NONE)
194 action = ACTION_REDRAW;
195 return action;
197 /* Test code!!! */
198 static bool dbg_os(void)
200 struct simplelist_info info;
201 simplelist_info_init(&info, IF_COP("Core and ") "Stack usage:",
202 #if NUM_CORES == 1
203 MAXTHREADS,
204 #else
205 MAXTHREADS+NUM_CORES,
206 #endif
207 NULL);
208 #ifndef ROCKBOX_HAS_LOGF
209 info.hide_selection = true;
210 #endif
211 info.action_callback = dbg_threads_action_callback;
212 info.get_name = threads_getname;
213 return simplelist_show_list(&info);
216 #ifdef HAVE_LCD_BITMAP
217 #if CONFIG_CODEC != SWCODEC
218 #ifndef SIMULATOR
219 static bool dbg_audio_thread(void)
221 char buf[32];
222 struct audio_debug d;
224 lcd_setmargins(0, 0);
225 lcd_setfont(FONT_SYSFIXED);
227 while(1)
229 if (action_userabort(HZ/5))
230 return false;
232 audio_get_debugdata(&d);
234 lcd_clear_display();
236 snprintf(buf, sizeof(buf), "read: %x", d.audiobuf_read);
237 lcd_puts(0, 0, buf);
238 snprintf(buf, sizeof(buf), "write: %x", d.audiobuf_write);
239 lcd_puts(0, 1, buf);
240 snprintf(buf, sizeof(buf), "swap: %x", d.audiobuf_swapwrite);
241 lcd_puts(0, 2, buf);
242 snprintf(buf, sizeof(buf), "playing: %d", d.playing);
243 lcd_puts(0, 3, buf);
244 snprintf(buf, sizeof(buf), "playable: %x", d.playable_space);
245 lcd_puts(0, 4, buf);
246 snprintf(buf, sizeof(buf), "unswapped: %x", d.unswapped_space);
247 lcd_puts(0, 5, buf);
249 /* Playable space left */
250 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, 6*8, 112, 4, d.audiobuflen, 0,
251 d.playable_space, HORIZONTAL);
253 /* Show the watermark limit */
254 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, 6*8+4, 112, 4, d.audiobuflen, 0,
255 d.low_watermark_level, HORIZONTAL);
257 snprintf(buf, sizeof(buf), "wm: %x - %x",
258 d.low_watermark_level, d.lowest_watermark_level);
259 lcd_puts(0, 7, buf);
261 lcd_update();
263 return false;
265 #endif /* !SIMULATOR */
266 #else /* CONFIG_CODEC == SWCODEC */
267 extern size_t filebuflen;
268 /* This is a size_t, but call it a long so it puts a - when it's bad. */
270 static unsigned int ticks, boost_ticks;
272 static void dbg_audio_task(void)
274 #ifndef SIMULATOR
275 if(FREQ > CPUFREQ_NORMAL)
276 boost_ticks++;
277 #endif
279 ticks++;
282 static bool dbg_buffering_thread(void)
284 char buf[32];
285 int button;
286 int line;
287 bool done = false;
288 size_t bufused;
289 size_t bufsize = pcmbuf_get_bufsize();
290 int pcmbufdescs = pcmbuf_descs();
291 struct buffering_debug d;
293 ticks = boost_ticks = 0;
295 tick_add_task(dbg_audio_task);
297 lcd_setmargins(0, 0);
298 lcd_setfont(FONT_SYSFIXED);
299 while(!done)
301 button = get_action(CONTEXT_STD,HZ/5);
302 switch(button)
304 case ACTION_STD_NEXT:
305 audio_next();
306 break;
307 case ACTION_STD_PREV:
308 audio_prev();
309 break;
310 case ACTION_STD_CANCEL:
311 done = true;
312 break;
315 buffering_get_debugdata(&d);
317 line = 0;
318 lcd_clear_display();
320 bufused = bufsize - pcmbuf_free();
322 snprintf(buf, sizeof(buf), "pcm: %7ld/%7ld", (long) bufused, (long) bufsize);
323 lcd_puts(0, line++, buf);
325 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6,
326 bufsize, 0, bufused, HORIZONTAL);
327 line++;
329 snprintf(buf, sizeof(buf), "alloc: %8ld/%8ld", audio_filebufused(),
330 (long) filebuflen);
331 lcd_puts(0, line++, buf);
333 #if LCD_HEIGHT > 80
334 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6,
335 filebuflen, 0, audio_filebufused(), HORIZONTAL);
336 line++;
338 snprintf(buf, sizeof(buf), "real: %8ld/%8ld", (long)d.buffered_data,
339 (long)filebuflen);
340 lcd_puts(0, line++, buf);
342 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6,
343 filebuflen, 0, (long)d.buffered_data, HORIZONTAL);
344 line++;
345 #endif
347 snprintf(buf, sizeof(buf), "usefl: %8ld/%8ld", (long)(d.useful_data),
348 (long)filebuflen);
349 lcd_puts(0, line++, buf);
351 #if LCD_HEIGHT > 80
352 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6,
353 filebuflen, 0, d.useful_data, HORIZONTAL);
354 line++;
355 #endif
357 snprintf(buf, sizeof(buf), "data_rem: %ld", (long)d.data_rem);
358 lcd_puts(0, line++, buf);
360 snprintf(buf, sizeof(buf), "track count: %2d", audio_track_count());
361 lcd_puts(0, line++, buf);
363 snprintf(buf, sizeof(buf), "handle count: %d", (int)d.num_handles);
364 lcd_puts(0, line++, buf);
366 #ifndef SIMULATOR
367 snprintf(buf, sizeof(buf), "cpu freq: %3dMHz",
368 (int)((FREQ + 500000) / 1000000));
369 lcd_puts(0, line++, buf);
370 #endif
372 if (ticks > 0)
374 snprintf(buf, sizeof(buf), "boost ratio: %3d%%",
375 boost_ticks * 100 / ticks);
376 lcd_puts(0, line++, buf);
379 snprintf(buf, sizeof(buf), "pcmbufdesc: %2d/%2d",
380 pcmbuf_used_descs(), pcmbufdescs);
381 lcd_puts(0, line++, buf);
383 lcd_update();
386 tick_remove_task(dbg_audio_task);
388 return false;
390 #endif /* CONFIG_CODEC */
391 #endif /* HAVE_LCD_BITMAP */
394 #if (CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE))
395 /* Tool function to read the flash manufacturer and type, if available.
396 Only chips which could be reprogrammed in system will return values.
397 (The mode switch addresses vary between flash manufacturers, hence addr1/2) */
398 /* In IRAM to avoid problems when running directly from Flash */
399 static bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
400 unsigned addr1, unsigned addr2)
401 ICODE_ATTR __attribute__((noinline));
402 static bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
403 unsigned addr1, unsigned addr2)
406 unsigned not_manu, not_id; /* read values before switching to ID mode */
407 unsigned manu, id; /* read values when in ID mode */
409 #if CONFIG_CPU == SH7034
410 volatile unsigned char* flash = (unsigned char*)0x2000000; /* flash mapping */
411 #elif defined(CPU_COLDFIRE)
412 volatile unsigned short* flash = (unsigned short*)0; /* flash mapping */
413 #endif
414 int old_level; /* saved interrupt level */
416 not_manu = flash[0]; /* read the normal content */
417 not_id = flash[1]; /* should be 'A' (0x41) and 'R' (0x52) from the "ARCH" marker */
419 /* disable interrupts, prevent any stray flash access */
420 old_level = disable_irq_save();
422 flash[addr1] = 0xAA; /* enter command mode */
423 flash[addr2] = 0x55;
424 flash[addr1] = 0x90; /* ID command */
425 /* Atmel wants 20ms pause here */
426 /* sleep(HZ/50); no sleeping possible while interrupts are disabled */
428 manu = flash[0]; /* read the IDs */
429 id = flash[1];
431 flash[0] = 0xF0; /* reset flash (back to normal read mode) */
432 /* Atmel wants 20ms pause here */
433 /* sleep(HZ/50); no sleeping possible while interrupts are disabled */
435 restore_irq(old_level); /* enable interrupts again */
437 /* I assume success if the obtained values are different from
438 the normal flash content. This is not perfectly bulletproof, they
439 could theoretically be the same by chance, causing us to fail. */
440 if (not_manu != manu || not_id != id) /* a value has changed */
442 *p_manufacturer = manu; /* return the results */
443 *p_device = id;
444 return true; /* success */
446 return false; /* fail */
448 #endif /* (CONFIG_CPU == SH7034 || CPU_COLDFIRE) */
450 #ifndef SIMULATOR
451 #ifdef CPU_PP
452 static int perfcheck(void)
454 int result;
456 asm (
457 "mrs r2, CPSR \n"
458 "orr r0, r2, #0xc0 \n" /* disable IRQ and FIQ */
459 "msr CPSR_c, r0 \n"
460 "mov %[res], #0 \n"
461 "ldr r0, [%[timr]] \n"
462 "add r0, r0, %[tmo] \n"
463 "1: \n"
464 "add %[res], %[res], #1 \n"
465 "ldr r1, [%[timr]] \n"
466 "cmp r1, r0 \n"
467 "bmi 1b \n"
468 "msr CPSR_c, r2 \n" /* reset IRQ and FIQ state */
470 [res]"=&r"(result)
472 [timr]"r"(&USEC_TIMER),
473 [tmo]"r"(
474 #if CONFIG_CPU == PP5002
475 16000
476 #else /* PP5020/5022/5024 */
477 10226
478 #endif
481 "r0", "r1", "r2"
483 return result;
485 #endif
487 #ifdef HAVE_LCD_BITMAP
488 static bool dbg_hw_info(void)
490 #if CONFIG_CPU == SH7034
491 char buf[32];
492 int bitmask = HW_MASK;
493 int rom_version = ROM_VERSION;
494 unsigned manu, id; /* flash IDs */
495 bool got_id; /* flag if we managed to get the flash IDs */
496 unsigned rom_crc = 0xffffffff; /* CRC32 of the boot ROM */
497 bool has_bootrom; /* flag for boot ROM present */
498 int oldmode; /* saved memory guard mode */
500 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
502 /* get flash ROM type */
503 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
504 if (!got_id)
505 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
507 /* check if the boot ROM area is a flash mirror */
508 has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0);
509 if (has_bootrom) /* if ROM and Flash different */
511 /* calculate CRC16 checksum of boot ROM */
512 rom_crc = crc_32((unsigned char*)0x0000, 64*1024, 0xffffffff);
515 system_memory_guard(oldmode); /* re-enable memory guard */
517 lcd_setmargins(0, 0);
518 lcd_setfont(FONT_SYSFIXED);
519 lcd_clear_display();
521 lcd_puts(0, 0, "[Hardware info]");
523 snprintf(buf, 32, "ROM: %d.%02d", rom_version/100, rom_version%100);
524 lcd_puts(0, 1, buf);
526 snprintf(buf, 32, "Mask: 0x%04x", bitmask);
527 lcd_puts(0, 2, buf);
529 if (got_id)
530 snprintf(buf, 32, "Flash: M=%02x D=%02x", manu, id);
531 else
532 snprintf(buf, 32, "Flash: M=?? D=??"); /* unknown, sorry */
533 lcd_puts(0, 3, buf);
535 if (has_bootrom)
537 if (rom_crc == 0x56DBA4EE) /* known Version 1 */
538 snprintf(buf, 32, "Boot ROM: V1");
539 else
540 snprintf(buf, 32, "ROMcrc: 0x%08x", rom_crc);
542 else
544 snprintf(buf, 32, "Boot ROM: none");
546 lcd_puts(0, 4, buf);
548 lcd_update();
550 while (!(action_userabort(TIMEOUT_BLOCK)));
552 #elif CONFIG_CPU == MCF5249 || CONFIG_CPU == MCF5250
553 char buf[32];
554 unsigned manu, id; /* flash IDs */
555 int got_id; /* flag if we managed to get the flash IDs */
556 int oldmode; /* saved memory guard mode */
557 int line = 0;
559 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
561 /* get flash ROM type */
562 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
563 if (!got_id)
564 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
566 system_memory_guard(oldmode); /* re-enable memory guard */
568 lcd_setmargins(0, 0);
569 lcd_setfont(FONT_SYSFIXED);
570 lcd_clear_display();
572 lcd_puts(0, line++, "[Hardware info]");
574 if (got_id)
575 snprintf(buf, 32, "Flash: M=%04x D=%04x", manu, id);
576 else
577 snprintf(buf, 32, "Flash: M=???? D=????"); /* unknown, sorry */
578 lcd_puts(0, line++, buf);
580 #ifdef IAUDIO_X5
582 struct ds2411_id id;
584 lcd_puts(0, ++line, "Serial Number:");
586 got_id = ds2411_read_id(&id);
588 if (got_id == DS2411_OK)
590 snprintf(buf, 32, " FC=%02x", (unsigned)id.family_code);
591 lcd_puts(0, ++line, buf);
592 snprintf(buf, 32, " ID=%02X %02X %02X %02X %02X %02X",
593 (unsigned)id.uid[0], (unsigned)id.uid[1], (unsigned)id.uid[2],
594 (unsigned)id.uid[3], (unsigned)id.uid[4], (unsigned)id.uid[5]);
595 lcd_puts(0, ++line, buf);
596 snprintf(buf, 32, " CRC=%02X", (unsigned)id.crc);
598 else
600 snprintf(buf, 32, "READ ERR=%d", got_id);
603 lcd_puts(0, ++line, buf);
605 #endif
607 lcd_update();
609 while (!(action_userabort(TIMEOUT_BLOCK)));
611 #elif defined(CPU_PP502x)
612 int line = 0;
613 char buf[32];
614 char pp_version[] = { (PP_VER2 >> 24) & 0xff, (PP_VER2 >> 16) & 0xff,
615 (PP_VER2 >> 8) & 0xff, (PP_VER2) & 0xff,
616 (PP_VER1 >> 24) & 0xff, (PP_VER1 >> 16) & 0xff,
617 (PP_VER1 >> 8) & 0xff, (PP_VER1) & 0xff, '\0' };
619 lcd_setmargins(0, 0);
620 lcd_setfont(FONT_SYSFIXED);
621 lcd_clear_display();
623 lcd_puts(0, line++, "[Hardware info]");
625 #ifdef IPOD_ARCH
626 snprintf(buf, sizeof(buf), "HW rev: 0x%08lx", IPOD_HW_REVISION);
627 lcd_puts(0, line++, buf);
628 #endif
630 #ifdef IPOD_COLOR
631 extern int lcd_type; /* Defined in lcd-colornano.c */
633 snprintf(buf, sizeof(buf), "LCD type: %d", lcd_type);
634 lcd_puts(0, line++, buf);
635 #endif
637 snprintf(buf, sizeof(buf), "PP version: %s", pp_version);
638 lcd_puts(0, line++, buf);
640 snprintf(buf, sizeof(buf), "Est. clock (kHz): %d", perfcheck());
641 lcd_puts(0, line++, buf);
643 lcd_update();
645 while (!(action_userabort(TIMEOUT_BLOCK)));
647 #elif CONFIG_CPU == PP5002
648 int line = 0;
649 char buf[32];
650 char pp_version[] = { (PP_VER4 >> 8) & 0xff, PP_VER4 & 0xff,
651 (PP_VER3 >> 8) & 0xff, PP_VER3 & 0xff,
652 (PP_VER2 >> 8) & 0xff, PP_VER2 & 0xff,
653 (PP_VER1 >> 8) & 0xff, PP_VER1 & 0xff, '\0' };
656 lcd_setmargins(0, 0);
657 lcd_setfont(FONT_SYSFIXED);
658 lcd_clear_display();
660 lcd_puts(0, line++, "[Hardware info]");
662 #ifdef IPOD_ARCH
663 snprintf(buf, sizeof(buf), "HW rev: 0x%08lx", IPOD_HW_REVISION);
664 lcd_puts(0, line++, buf);
665 #endif
667 snprintf(buf, sizeof(buf), "PP version: %s", pp_version);
668 lcd_puts(0, line++, buf);
670 snprintf(buf, sizeof(buf), "Est. clock (kHz): %d", perfcheck());
671 lcd_puts(0, line++, buf);
673 lcd_update();
675 while (!(action_userabort(TIMEOUT_BLOCK)));
676 #else
677 /* Define this function in your target tree */
678 return __dbg_hw_info();
679 #endif /* CONFIG_CPU */
680 return false;
682 #else /* !HAVE_LCD_BITMAP */
683 static bool dbg_hw_info(void)
685 char buf[32];
686 int button;
687 int currval = 0;
688 int rom_version = ROM_VERSION;
689 unsigned manu, id; /* flash IDs */
690 bool got_id; /* flag if we managed to get the flash IDs */
691 unsigned rom_crc = 0xffffffff; /* CRC32 of the boot ROM */
692 bool has_bootrom; /* flag for boot ROM present */
693 int oldmode; /* saved memory guard mode */
695 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
697 /* get flash ROM type */
698 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
699 if (!got_id)
700 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
702 /* check if the boot ROM area is a flash mirror */
703 has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0);
704 if (has_bootrom) /* if ROM and Flash different */
706 /* calculate CRC16 checksum of boot ROM */
707 rom_crc = crc_32((unsigned char*)0x0000, 64*1024, 0xffffffff);
710 system_memory_guard(oldmode); /* re-enable memory guard */
712 lcd_clear_display();
714 lcd_puts(0, 0, "[HW Info]");
715 while(1)
717 switch(currval)
719 case 0:
720 snprintf(buf, 32, "ROM: %d.%02d",
721 rom_version/100, rom_version%100);
722 break;
723 case 1:
724 if (got_id)
725 snprintf(buf, 32, "Flash:%02x,%02x", manu, id);
726 else
727 snprintf(buf, 32, "Flash:??,??"); /* unknown, sorry */
728 break;
729 case 2:
730 if (has_bootrom)
732 if (rom_crc == 0x56DBA4EE) /* known Version 1 */
733 snprintf(buf, 32, "BootROM: V1");
734 else if (rom_crc == 0x358099E8)
735 snprintf(buf, 32, "BootROM: V2");
736 /* alternative boot ROM found in one single player so far */
737 else
738 snprintf(buf, 32, "R: %08x", rom_crc);
740 else
741 snprintf(buf, 32, "BootROM: no");
744 lcd_puts(0, 1, buf);
745 lcd_update();
747 button = get_action(CONTEXT_SETTINGS,TIMEOUT_BLOCK);
749 switch(button)
751 case ACTION_STD_CANCEL:
752 return false;
754 case ACTION_SETTINGS_DEC:
755 currval--;
756 if(currval < 0)
757 currval = 2;
758 break;
760 case ACTION_SETTINGS_INC:
761 currval++;
762 if(currval > 2)
763 currval = 0;
764 break;
767 return false;
769 #endif /* !HAVE_LCD_BITMAP */
770 #endif /* !SIMULATOR */
772 #ifndef SIMULATOR
773 static char* dbg_partitions_getname(int selected_item, void * data, char *buffer)
775 (void)data;
776 int partition = selected_item/2;
777 struct partinfo* p = disk_partinfo(partition);
778 if (selected_item%2)
780 snprintf(buffer, MAX_PATH, " T:%x %ld MB", p->type, p->size / 2048);
782 else
784 snprintf(buffer, MAX_PATH, "P%d: S:%lx", partition, p->start);
786 return buffer;
789 bool dbg_partitions(void)
791 struct simplelist_info info;
792 simplelist_info_init(&info, "Partition Info", 4, NULL);
793 info.selection_size = 2;
794 info.hide_selection = true;
795 info.get_name = dbg_partitions_getname;
796 return simplelist_show_list(&info);
798 #endif
800 #if defined(CPU_COLDFIRE) && defined(HAVE_SPDIF_OUT)
801 static bool dbg_spdif(void)
803 char buf[128];
804 int line;
805 unsigned int control;
806 int x;
807 char *s;
808 int category;
809 int generation;
810 unsigned int interruptstat;
811 bool valnogood, symbolerr, parityerr;
812 bool done = false;
813 bool spdif_src_on;
814 int spdif_source = spdif_get_output_source(&spdif_src_on);
815 spdif_set_output_source(AUDIO_SRC_SPDIF IF_SPDIF_POWER_(, true));
817 lcd_setmargins(0, 0);
818 lcd_clear_display();
819 lcd_setfont(FONT_SYSFIXED);
821 #ifdef HAVE_SPDIF_POWER
822 spdif_power_enable(true); /* We need SPDIF power for both sending & receiving */
823 #endif
825 while (!done)
827 line = 0;
829 control = EBU1RCVCCHANNEL1;
830 interruptstat = INTERRUPTSTAT;
831 INTERRUPTCLEAR = 0x03c00000;
833 valnogood = (interruptstat & 0x01000000)?true:false;
834 symbolerr = (interruptstat & 0x00800000)?true:false;
835 parityerr = (interruptstat & 0x00400000)?true:false;
837 snprintf(buf, sizeof(buf), "Val: %s Sym: %s Par: %s",
838 valnogood?"--":"OK",
839 symbolerr?"--":"OK",
840 parityerr?"--":"OK");
841 lcd_puts(0, line++, buf);
843 snprintf(buf, sizeof(buf), "Status word: %08x", (int)control);
844 lcd_puts(0, line++, buf);
846 line++;
848 x = control >> 31;
849 snprintf(buf, sizeof(buf), "PRO: %d (%s)",
850 x, x?"Professional":"Consumer");
851 lcd_puts(0, line++, buf);
853 x = (control >> 30) & 1;
854 snprintf(buf, sizeof(buf), "Audio: %d (%s)",
855 x, x?"Non-PCM":"PCM");
856 lcd_puts(0, line++, buf);
858 x = (control >> 29) & 1;
859 snprintf(buf, sizeof(buf), "Copy: %d (%s)",
860 x, x?"Permitted":"Inhibited");
861 lcd_puts(0, line++, buf);
863 x = (control >> 27) & 7;
864 switch(x)
866 case 0:
867 s = "None";
868 break;
869 case 1:
870 s = "50/15us";
871 break;
872 default:
873 s = "Reserved";
874 break;
876 snprintf(buf, sizeof(buf), "Preemphasis: %d (%s)", x, s);
877 lcd_puts(0, line++, buf);
879 x = (control >> 24) & 3;
880 snprintf(buf, sizeof(buf), "Mode: %d", x);
881 lcd_puts(0, line++, buf);
883 category = (control >> 17) & 127;
884 switch(category)
886 case 0x00:
887 s = "General";
888 break;
889 case 0x40:
890 s = "Audio CD";
891 break;
892 default:
893 s = "Unknown";
895 snprintf(buf, sizeof(buf), "Category: 0x%02x (%s)", category, s);
896 lcd_puts(0, line++, buf);
898 x = (control >> 16) & 1;
899 generation = x;
900 if(((category & 0x70) == 0x10) ||
901 ((category & 0x70) == 0x40) ||
902 ((category & 0x78) == 0x38))
904 generation = !generation;
906 snprintf(buf, sizeof(buf), "Generation: %d (%s)",
907 x, generation?"Original":"No ind.");
908 lcd_puts(0, line++, buf);
910 x = (control >> 12) & 15;
911 snprintf(buf, sizeof(buf), "Source: %d", x);
912 lcd_puts(0, line++, buf);
914 x = (control >> 8) & 15;
915 switch(x)
917 case 0:
918 s = "Unspecified";
919 break;
920 case 8:
921 s = "A (Left)";
922 break;
923 case 4:
924 s = "B (Right)";
925 break;
926 default:
927 s = "";
928 break;
930 snprintf(buf, sizeof(buf), "Channel: %d (%s)", x, s);
931 lcd_puts(0, line++, buf);
933 x = (control >> 4) & 15;
934 switch(x)
936 case 0:
937 s = "44.1kHz";
938 break;
939 case 0x4:
940 s = "48kHz";
941 break;
942 case 0xc:
943 s = "32kHz";
944 break;
946 snprintf(buf, sizeof(buf), "Frequency: %d (%s)", x, s);
947 lcd_puts(0, line++, buf);
949 x = (control >> 2) & 3;
950 snprintf(buf, sizeof(buf), "Clock accuracy: %d", x);
951 lcd_puts(0, line++, buf);
952 line++;
954 #ifndef SIMULATOR
955 snprintf(buf, sizeof(buf), "Measured freq: %ldHz",
956 spdif_measure_frequency());
957 lcd_puts(0, line++, buf);
958 #endif
960 lcd_update();
962 if (action_userabort(HZ/10))
963 break;
966 spdif_set_output_source(spdif_source IF_SPDIF_POWER_(, spdif_src_on));
968 #ifdef HAVE_SPDIF_POWER
969 spdif_power_enable(global_settings.spdif_enable);
970 #endif
972 return false;
974 #endif /* CPU_COLDFIRE */
976 #ifndef SIMULATOR
977 #ifdef HAVE_LCD_BITMAP
978 /* button definitions */
979 #if (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
980 (CONFIG_KEYPAD == IRIVER_H300_PAD)
981 # define DEBUG_CANCEL BUTTON_OFF
983 #elif CONFIG_KEYPAD == RECORDER_PAD
984 # define DEBUG_CANCEL BUTTON_OFF
986 #elif CONFIG_KEYPAD == ONDIO_PAD
987 # define DEBUG_CANCEL BUTTON_MENU
989 #elif (CONFIG_KEYPAD == IPOD_1G2G_PAD) || \
990 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
991 (CONFIG_KEYPAD == IPOD_4G_PAD)
992 # define DEBUG_CANCEL BUTTON_MENU
994 #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
995 # define DEBUG_CANCEL BUTTON_PLAY
997 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
998 # define DEBUG_CANCEL BUTTON_REC
1000 #elif (CONFIG_KEYPAD == IAUDIO_M3_PAD)
1001 # define DEBUG_CANCEL BUTTON_RC_REC
1003 #elif (CONFIG_KEYPAD == IRIVER_H10_PAD)
1004 # define DEBUG_CANCEL BUTTON_REW
1006 #elif (CONFIG_KEYPAD == MROBE100_PAD)
1007 # define DEBUG_CANCEL BUTTON_MENU
1009 #elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \
1010 (CONFIG_KEYPAD == SANSA_C200_PAD)
1011 # define DEBUG_CANCEL BUTTON_LEFT
1012 #endif /* key definitions */
1014 /* Test code!!! */
1015 bool dbg_ports(void)
1017 #if CONFIG_CPU == SH7034
1018 char buf[32];
1019 int adc_battery_voltage, adc_battery_level;
1021 lcd_setfont(FONT_SYSFIXED);
1022 lcd_setmargins(0, 0);
1023 lcd_clear_display();
1025 while(1)
1027 snprintf(buf, 32, "PADR: %04x", (unsigned short)PADR);
1028 lcd_puts(0, 0, buf);
1029 snprintf(buf, 32, "PBDR: %04x", (unsigned short)PBDR);
1030 lcd_puts(0, 1, buf);
1032 snprintf(buf, 32, "AN0: %03x AN4: %03x", adc_read(0), adc_read(4));
1033 lcd_puts(0, 2, buf);
1034 snprintf(buf, 32, "AN1: %03x AN5: %03x", adc_read(1), adc_read(5));
1035 lcd_puts(0, 3, buf);
1036 snprintf(buf, 32, "AN2: %03x AN6: %03x", adc_read(2), adc_read(6));
1037 lcd_puts(0, 4, buf);
1038 snprintf(buf, 32, "AN3: %03x AN7: %03x", adc_read(3), adc_read(7));
1039 lcd_puts(0, 5, buf);
1041 battery_read_info(&adc_battery_voltage, &adc_battery_level);
1042 snprintf(buf, 32, "Batt: %d.%03dV %d%% ", adc_battery_voltage / 1000,
1043 adc_battery_voltage % 1000, adc_battery_level);
1044 lcd_puts(0, 6, buf);
1046 lcd_update();
1047 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1048 return false;
1050 #elif defined(CPU_COLDFIRE)
1051 unsigned int gpio_out;
1052 unsigned int gpio1_out;
1053 unsigned int gpio_read;
1054 unsigned int gpio1_read;
1055 unsigned int gpio_function;
1056 unsigned int gpio1_function;
1057 unsigned int gpio_enable;
1058 unsigned int gpio1_enable;
1059 int adc_buttons, adc_remote;
1060 int adc_battery_voltage, adc_battery_level;
1061 char buf[128];
1062 int line;
1064 lcd_setmargins(0, 0);
1065 lcd_clear_display();
1066 lcd_setfont(FONT_SYSFIXED);
1068 while(1)
1070 line = 0;
1071 gpio_read = GPIO_READ;
1072 gpio1_read = GPIO1_READ;
1073 gpio_out = GPIO_OUT;
1074 gpio1_out = GPIO1_OUT;
1075 gpio_function = GPIO_FUNCTION;
1076 gpio1_function = GPIO1_FUNCTION;
1077 gpio_enable = GPIO_ENABLE;
1078 gpio1_enable = GPIO1_ENABLE;
1080 snprintf(buf, sizeof(buf), "GPIO_READ: %08x", gpio_read);
1081 lcd_puts(0, line++, buf);
1082 snprintf(buf, sizeof(buf), "GPIO_OUT: %08x", gpio_out);
1083 lcd_puts(0, line++, buf);
1084 snprintf(buf, sizeof(buf), "GPIO_FUNC: %08x", gpio_function);
1085 lcd_puts(0, line++, buf);
1086 snprintf(buf, sizeof(buf), "GPIO_ENA: %08x", gpio_enable);
1087 lcd_puts(0, line++, buf);
1089 snprintf(buf, sizeof(buf), "GPIO1_READ: %08x", gpio1_read);
1090 lcd_puts(0, line++, buf);
1091 snprintf(buf, sizeof(buf), "GPIO1_OUT: %08x", gpio1_out);
1092 lcd_puts(0, line++, buf);
1093 snprintf(buf, sizeof(buf), "GPIO1_FUNC: %08x", gpio1_function);
1094 lcd_puts(0, line++, buf);
1095 snprintf(buf, sizeof(buf), "GPIO1_ENA: %08x", gpio1_enable);
1096 lcd_puts(0, line++, buf);
1098 adc_buttons = adc_read(ADC_BUTTONS);
1099 adc_remote = adc_read(ADC_REMOTE);
1100 battery_read_info(&adc_battery_voltage, &adc_battery_level);
1101 #if defined(IAUDIO_X5) || defined(IAUDIO_M5) || defined(IRIVER_H300_SERIES)
1102 snprintf(buf, sizeof(buf), "ADC_BUTTONS (%c): %02x",
1103 button_scan_enabled() ? '+' : '-', adc_buttons);
1104 #else
1105 snprintf(buf, sizeof(buf), "ADC_BUTTONS: %02x", adc_buttons);
1106 #endif
1107 lcd_puts(0, line++, buf);
1108 #if defined(IAUDIO_X5) || defined(IAUDIO_M5)
1109 snprintf(buf, sizeof(buf), "ADC_REMOTE (%c): %02x",
1110 remote_detect() ? '+' : '-', adc_remote);
1111 #else
1112 snprintf(buf, sizeof(buf), "ADC_REMOTE: %02x", adc_remote);
1113 #endif
1114 lcd_puts(0, line++, buf);
1115 #if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES)
1116 snprintf(buf, sizeof(buf), "ADC_REMOTEDETECT: %02x",
1117 adc_read(ADC_REMOTEDETECT));
1118 lcd_puts(0, line++, buf);
1119 #endif
1121 snprintf(buf, 32, "Batt: %d.%03dV %d%% ", adc_battery_voltage / 1000,
1122 adc_battery_voltage % 1000, adc_battery_level);
1123 lcd_puts(0, line++, buf);
1125 #if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES)
1126 snprintf(buf, sizeof(buf), "remotetype: %d", remote_type());
1127 lcd_puts(0, line++, buf);
1128 #endif
1130 lcd_update();
1131 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1132 return false;
1135 #elif defined(CPU_PP502x)
1137 char buf[128];
1138 int line;
1140 lcd_setmargins(0, 0);
1141 lcd_clear_display();
1142 lcd_setfont(FONT_SYSFIXED);
1144 while(1)
1146 line = 0;
1147 lcd_puts(0, line++, "GPIO STATES:");
1148 snprintf(buf, sizeof(buf), "A: %02x E: %02x I: %02x",
1149 (unsigned int)GPIOA_INPUT_VAL,
1150 (unsigned int)GPIOE_INPUT_VAL,
1151 (unsigned int)GPIOI_INPUT_VAL);
1152 lcd_puts(0, line++, buf);
1153 snprintf(buf, sizeof(buf), "B: %02x F: %02x J: %02x",
1154 (unsigned int)GPIOB_INPUT_VAL,
1155 (unsigned int)GPIOF_INPUT_VAL,
1156 (unsigned int)GPIOJ_INPUT_VAL);
1157 lcd_puts(0, line++, buf);
1158 snprintf(buf, sizeof(buf), "C: %02x G: %02x K: %02x",
1159 (unsigned int)GPIOC_INPUT_VAL,
1160 (unsigned int)GPIOG_INPUT_VAL,
1161 (unsigned int)GPIOK_INPUT_VAL);
1162 lcd_puts(0, line++, buf);
1163 snprintf(buf, sizeof(buf), "D: %02x H: %02x L: %02x",
1164 (unsigned int)GPIOD_INPUT_VAL,
1165 (unsigned int)GPIOH_INPUT_VAL,
1166 (unsigned int)GPIOL_INPUT_VAL);
1167 lcd_puts(0, line++, buf);
1168 line++;
1169 snprintf(buf, sizeof(buf), "GPO32_VAL: %08lx", GPO32_VAL);
1170 lcd_puts(0, line++, buf);
1171 snprintf(buf, sizeof(buf), "GPO32_EN: %08lx", GPO32_ENABLE);
1172 lcd_puts(0, line++, buf);
1173 snprintf(buf, sizeof(buf), "DEV_EN: %08lx", DEV_EN);
1174 lcd_puts(0, line++, buf);
1175 snprintf(buf, sizeof(buf), "DEV_EN2: %08lx", DEV_EN2);
1176 lcd_puts(0, line++, buf);
1177 snprintf(buf, sizeof(buf), "DEV_EN3: %08lx", inl(0x60006044));
1178 lcd_puts(0, line++, buf); /* to be verified */
1179 snprintf(buf, sizeof(buf), "DEV_INIT1: %08lx", DEV_INIT1);
1180 lcd_puts(0, line++, buf);
1181 snprintf(buf, sizeof(buf), "DEV_INIT2: %08lx", DEV_INIT2);
1182 lcd_puts(0, line++, buf);
1184 #if defined(IRIVER_H10) || defined(IRIVER_H10_5GB)
1185 line++;
1186 snprintf(buf, sizeof(buf), "BATT: %03x UNK1: %03x",
1187 adc_read(ADC_BATTERY), adc_read(ADC_UNKNOWN_1));
1188 lcd_puts(0, line++, buf);
1189 snprintf(buf, sizeof(buf), "REM: %03x PAD: %03x",
1190 adc_read(ADC_REMOTE), adc_read(ADC_SCROLLPAD));
1191 lcd_puts(0, line++, buf);
1192 #elif defined(SANSA_E200)
1193 snprintf(buf, sizeof(buf), "ADC_BVDD: %4d", adc_read(ADC_BVDD));
1194 lcd_puts(0, line++, buf);
1195 snprintf(buf, sizeof(buf), "ADC_RTCSUP: %4d", adc_read(ADC_RTCSUP));
1196 lcd_puts(0, line++, buf);
1197 snprintf(buf, sizeof(buf), "ADC_UVDD: %4d", adc_read(ADC_UVDD));
1198 lcd_puts(0, line++, buf);
1199 snprintf(buf, sizeof(buf), "ADC_CHG_IN: %4d", adc_read(ADC_CHG_IN));
1200 lcd_puts(0, line++, buf);
1201 snprintf(buf, sizeof(buf), "ADC_CVDD: %4d", adc_read(ADC_CVDD));
1202 lcd_puts(0, line++, buf);
1203 snprintf(buf, sizeof(buf), "ADC_BATTEMP: %4d", adc_read(ADC_BATTEMP));
1204 lcd_puts(0, line++, buf);
1205 snprintf(buf, sizeof(buf), "ADC_MICSUP1: %4d", adc_read(ADC_MICSUP1));
1206 lcd_puts(0, line++, buf);
1207 snprintf(buf, sizeof(buf), "ADC_MICSUP2: %4d", adc_read(ADC_MICSUP2));
1208 lcd_puts(0, line++, buf);
1209 snprintf(buf, sizeof(buf), "ADC_VBE1: %4d", adc_read(ADC_VBE1));
1210 lcd_puts(0, line++, buf);
1211 snprintf(buf, sizeof(buf), "ADC_VBE2: %4d", adc_read(ADC_VBE2));
1212 lcd_puts(0, line++, buf);
1213 snprintf(buf, sizeof(buf), "ADC_I_MICSUP1:%4d", adc_read(ADC_I_MICSUP1));
1214 lcd_puts(0, line++, buf);
1215 snprintf(buf, sizeof(buf), "ADC_I_MICSUP2:%4d", adc_read(ADC_I_MICSUP2));
1216 lcd_puts(0, line++, buf);
1217 snprintf(buf, sizeof(buf), "ADC_VBAT: %4d", adc_read(ADC_VBAT));
1218 lcd_puts(0, line++, buf);
1219 snprintf(buf, sizeof(buf), "CHARGER: %02X/%02X", i2c_readbyte(AS3514_I2C_ADDR, CHRGR), i2c_readbyte(AS3514_I2C_ADDR, IRQ_ENRD0));
1220 lcd_puts(0, line++, buf);
1221 #endif
1222 lcd_update();
1223 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1224 return false;
1227 #elif CONFIG_CPU == PP5002
1228 char buf[128];
1229 int line;
1231 lcd_setmargins(0, 0);
1232 lcd_clear_display();
1233 lcd_setfont(FONT_SYSFIXED);
1235 while(1)
1237 line = 0;
1238 snprintf(buf, sizeof(buf), "GPIO_A: %02x GPIO_B: %02x",
1239 (unsigned int)GPIOA_INPUT_VAL, (unsigned int)GPIOB_INPUT_VAL);
1240 lcd_puts(0, line++, buf);
1241 snprintf(buf, sizeof(buf), "GPIO_C: %02x GPIO_D: %02x",
1242 (unsigned int)GPIOC_INPUT_VAL, (unsigned int)GPIOD_INPUT_VAL);
1243 lcd_puts(0, line++, buf);
1245 snprintf(buf, sizeof(buf), "DEV_EN: %08lx", DEV_EN);
1246 lcd_puts(0, line++, buf);
1247 snprintf(buf, sizeof(buf), "CLOCK_ENABLE: %08lx", CLOCK_ENABLE);
1248 lcd_puts(0, line++, buf);
1249 snprintf(buf, sizeof(buf), "CLOCK_SOURCE: %08lx", CLOCK_SOURCE);
1250 lcd_puts(0, line++, buf);
1251 snprintf(buf, sizeof(buf), "PLL_CONTROL: %08lx", PLL_CONTROL);
1252 lcd_puts(0, line++, buf);
1253 snprintf(buf, sizeof(buf), "PLL_DIV: %08lx", PLL_DIV);
1254 lcd_puts(0, line++, buf);
1255 snprintf(buf, sizeof(buf), "PLL_MULT: %08lx", PLL_MULT);
1256 lcd_puts(0, line++, buf);
1257 snprintf(buf, sizeof(buf), "TIMING1_CTL: %08lx", TIMING1_CTL);
1258 lcd_puts(0, line++, buf);
1259 snprintf(buf, sizeof(buf), "TIMING2_CTL: %08lx", TIMING2_CTL);
1260 lcd_puts(0, line++, buf);
1262 lcd_update();
1263 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1264 return false;
1266 #else
1267 return __dbg_ports();
1268 #endif /* CPU */
1269 return false;
1271 #else /* !HAVE_LCD_BITMAP */
1272 bool dbg_ports(void)
1274 char buf[32];
1275 int button;
1276 int adc_battery_voltage;
1277 int currval = 0;
1279 lcd_clear_display();
1281 while(1)
1283 switch(currval)
1285 case 0:
1286 snprintf(buf, 32, "PADR: %04x", (unsigned short)PADR);
1287 break;
1288 case 1:
1289 snprintf(buf, 32, "PBDR: %04x", (unsigned short)PBDR);
1290 break;
1291 case 2:
1292 snprintf(buf, 32, "AN0: %03x", adc_read(0));
1293 break;
1294 case 3:
1295 snprintf(buf, 32, "AN1: %03x", adc_read(1));
1296 break;
1297 case 4:
1298 snprintf(buf, 32, "AN2: %03x", adc_read(2));
1299 break;
1300 case 5:
1301 snprintf(buf, 32, "AN3: %03x", adc_read(3));
1302 break;
1303 case 6:
1304 snprintf(buf, 32, "AN4: %03x", adc_read(4));
1305 break;
1306 case 7:
1307 snprintf(buf, 32, "AN5: %03x", adc_read(5));
1308 break;
1309 case 8:
1310 snprintf(buf, 32, "AN6: %03x", adc_read(6));
1311 break;
1312 case 9:
1313 snprintf(buf, 32, "AN7: %03x", adc_read(7));
1314 break;
1315 break;
1317 lcd_puts(0, 0, buf);
1319 battery_read_info(&adc_battery_voltage, NULL);
1320 snprintf(buf, 32, "Batt: %d.%03dV", adc_battery_voltage / 1000,
1321 adc_battery_voltage % 1000);
1322 lcd_puts(0, 1, buf);
1323 lcd_update();
1325 button = get_action(CONTEXT_SETTINGS,HZ/5);
1327 switch(button)
1329 case ACTION_STD_CANCEL:
1330 return false;
1332 case ACTION_SETTINGS_DEC:
1333 currval--;
1334 if(currval < 0)
1335 currval = 9;
1336 break;
1338 case ACTION_SETTINGS_INC:
1339 currval++;
1340 if(currval > 9)
1341 currval = 0;
1342 break;
1345 return false;
1347 #endif /* !HAVE_LCD_BITMAP */
1348 #endif /* !SIMULATOR */
1350 #if (CONFIG_RTC == RTC_PCF50605) && !defined(SIMULATOR)
1351 static bool dbg_pcf(void)
1353 char buf[128];
1354 int line;
1356 #ifdef HAVE_LCD_BITMAP
1357 lcd_setmargins(0, 0);
1358 lcd_setfont(FONT_SYSFIXED);
1359 #endif
1360 lcd_clear_display();
1362 while(1)
1364 line = 0;
1366 snprintf(buf, sizeof(buf), "DCDC1: %02x", pcf50605_read(0x1b));
1367 lcd_puts(0, line++, buf);
1368 snprintf(buf, sizeof(buf), "DCDC2: %02x", pcf50605_read(0x1c));
1369 lcd_puts(0, line++, buf);
1370 snprintf(buf, sizeof(buf), "DCDC3: %02x", pcf50605_read(0x1d));
1371 lcd_puts(0, line++, buf);
1372 snprintf(buf, sizeof(buf), "DCDC4: %02x", pcf50605_read(0x1e));
1373 lcd_puts(0, line++, buf);
1374 snprintf(buf, sizeof(buf), "DCDEC1: %02x", pcf50605_read(0x1f));
1375 lcd_puts(0, line++, buf);
1376 snprintf(buf, sizeof(buf), "DCDEC2: %02x", pcf50605_read(0x20));
1377 lcd_puts(0, line++, buf);
1378 snprintf(buf, sizeof(buf), "DCUDC1: %02x", pcf50605_read(0x21));
1379 lcd_puts(0, line++, buf);
1380 snprintf(buf, sizeof(buf), "DCUDC2: %02x", pcf50605_read(0x22));
1381 lcd_puts(0, line++, buf);
1382 snprintf(buf, sizeof(buf), "IOREGC: %02x", pcf50605_read(0x23));
1383 lcd_puts(0, line++, buf);
1384 snprintf(buf, sizeof(buf), "D1REGC: %02x", pcf50605_read(0x24));
1385 lcd_puts(0, line++, buf);
1386 snprintf(buf, sizeof(buf), "D2REGC: %02x", pcf50605_read(0x25));
1387 lcd_puts(0, line++, buf);
1388 snprintf(buf, sizeof(buf), "D3REGC: %02x", pcf50605_read(0x26));
1389 lcd_puts(0, line++, buf);
1390 snprintf(buf, sizeof(buf), "LPREG1: %02x", pcf50605_read(0x27));
1391 lcd_puts(0, line++, buf);
1393 lcd_update();
1394 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1396 return false;
1400 return false;
1402 #endif
1404 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
1405 static bool dbg_cpufreq(void)
1407 char buf[128];
1408 int line;
1409 int button;
1411 #ifdef HAVE_LCD_BITMAP
1412 lcd_setmargins(0, 0);
1413 lcd_setfont(FONT_SYSFIXED);
1414 #endif
1415 lcd_clear_display();
1417 while(1)
1419 line = 0;
1421 snprintf(buf, sizeof(buf), "Frequency: %ld", FREQ);
1422 lcd_puts(0, line++, buf);
1424 snprintf(buf, sizeof(buf), "boost_counter: %d", get_cpu_boost_counter());
1425 lcd_puts(0, line++, buf);
1427 lcd_update();
1428 button = get_action(CONTEXT_STD,HZ/10);
1430 switch(button)
1432 case ACTION_STD_PREV:
1433 cpu_boost(true);
1434 break;
1436 case ACTION_STD_NEXT:
1437 cpu_boost(false);
1438 break;
1440 case ACTION_STD_OK:
1441 while (get_cpu_boost_counter() > 0)
1442 cpu_boost(false);
1443 set_cpu_frequency(CPUFREQ_DEFAULT);
1444 break;
1446 case ACTION_STD_CANCEL:
1447 return false;
1451 return false;
1453 #endif /* HAVE_ADJUSTABLE_CPU_FREQ */
1455 #if defined(HAVE_TSC2100) && !defined(SIMULATOR)
1456 #include "tsc2100.h"
1457 char *itob(int n, int len)
1459 static char binary[64];
1460 int i,j;
1461 for (i=1, j=0;i<=len;i++)
1463 binary[j++] = n&(1<<(len-i))?'1':'0';
1464 if (i%4 == 0)
1465 binary[j++] = ' ';
1467 binary[j] = '\0';
1468 return binary;
1470 static char* tsc2100_debug_getname(int selected_item, void * data, char *buffer)
1472 int *page = (int*)data;
1473 bool reserved = false;
1474 switch (*page)
1476 case 0:
1477 if ((selected_item > 0x0a) ||
1478 (selected_item == 0x04) ||
1479 (selected_item == 0x08))
1480 reserved = true;
1481 break;
1482 case 1:
1483 if ((selected_item > 0x05) ||
1484 (selected_item == 0x02))
1485 reserved = true;
1486 break;
1487 case 2:
1488 if (selected_item > 0x1e)
1489 reserved = true;
1490 break;
1492 if (reserved)
1493 snprintf(buffer, MAX_PATH, "%02x: RESERVED", selected_item);
1494 else
1495 snprintf(buffer, MAX_PATH, "%02x: %s", selected_item,
1496 itob(tsc2100_readreg(*page, selected_item)&0xffff,16));
1497 return buffer;
1499 static int tsc2100debug_action_callback(int action, struct gui_synclist *lists)
1501 int *page = (int*)lists->data;
1502 if (action == ACTION_STD_OK)
1504 *page = (*page+1)%3;
1505 snprintf(lists->title, 32,
1506 "tsc2100 registers - Page %d", *page);
1507 return ACTION_REDRAW;
1509 return action;
1511 bool tsc2100_debug(void)
1513 int page = 0;
1514 char title[32] = "tsc2100 registers - Page 0";
1515 struct simplelist_info info;
1516 simplelist_info_init(&info, title, 32, &page);
1517 info.timeout = HZ/100;
1518 info.get_name = tsc2100_debug_getname;
1519 info.action_callback= tsc2100debug_action_callback;
1520 return simplelist_show_list(&info);
1522 #endif
1523 #ifndef SIMULATOR
1524 #ifdef HAVE_LCD_BITMAP
1526 * view_battery() shows a automatically scaled graph of the battery voltage
1527 * over time. Usable for estimating battery life / charging rate.
1528 * The power_history array is updated in power_thread of powermgmt.c.
1531 #define BAT_LAST_VAL MIN(LCD_WIDTH, POWER_HISTORY_LEN)
1532 #define BAT_YSPACE (LCD_HEIGHT - 20)
1534 static bool view_battery(void)
1536 int view = 0;
1537 int i, x, y;
1538 unsigned short maxv, minv;
1539 char buf[32];
1541 lcd_setmargins(0, 0);
1542 lcd_setfont(FONT_SYSFIXED);
1544 while(1)
1546 lcd_clear_display();
1547 switch (view) {
1548 case 0: /* voltage history graph */
1549 /* Find maximum and minimum voltage for scaling */
1550 minv = power_history[0];
1551 maxv = minv + 1;
1552 for (i = 1; i < BAT_LAST_VAL && power_history[i]; i++) {
1553 if (power_history[i] > maxv)
1554 maxv = power_history[i];
1555 if (power_history[i] < minv)
1556 minv = power_history[i];
1559 snprintf(buf, 30, "Battery %d.%03d", power_history[0] / 1000,
1560 power_history[0] % 1000);
1561 lcd_puts(0, 0, buf);
1562 snprintf(buf, 30, "scale %d.%03d-%d.%03dV",
1563 minv / 1000, minv % 1000, maxv / 1000, maxv % 1000);
1564 lcd_puts(0, 1, buf);
1566 x = 0;
1567 for (i = BAT_LAST_VAL - 1; i >= 0; i--) {
1568 y = (power_history[i] - minv) * BAT_YSPACE / (maxv - minv);
1569 lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
1570 lcd_vline(x, LCD_HEIGHT-1, 20);
1571 lcd_set_drawmode(DRMODE_SOLID);
1572 lcd_vline(x, LCD_HEIGHT-1,
1573 MIN(MAX(LCD_HEIGHT-1 - y, 20), LCD_HEIGHT-1));
1574 x++;
1577 break;
1579 case 1: /* status: */
1580 lcd_puts(0, 0, "Power status:");
1582 battery_read_info(&y, NULL);
1583 snprintf(buf, 30, "Battery: %d.%03d V", y / 1000, y % 1000);
1584 lcd_puts(0, 1, buf);
1585 #ifdef ADC_EXT_POWER
1586 y = (adc_read(ADC_EXT_POWER) * EXT_SCALE_FACTOR) / 1000;
1587 snprintf(buf, 30, "External: %d.%03d V", y / 1000, y % 1000);
1588 lcd_puts(0, 2, buf);
1589 #endif
1590 #if CONFIG_CHARGING
1591 #if CONFIG_CHARGING == CHARGING_CONTROL
1592 snprintf(buf, 30, "Chgr: %s %s",
1593 charger_inserted() ? "present" : "absent",
1594 charger_enabled ? "on" : "off");
1595 lcd_puts(0, 3, buf);
1596 snprintf(buf, 30, "short delta: %d", short_delta);
1597 lcd_puts(0, 5, buf);
1598 snprintf(buf, 30, "long delta: %d", long_delta);
1599 lcd_puts(0, 6, buf);
1600 lcd_puts(0, 7, power_message);
1601 snprintf(buf, 30, "USB Inserted: %s",
1602 usb_inserted() ? "yes" : "no");
1603 lcd_puts(0, 8, buf);
1604 #if defined IRIVER_H300_SERIES
1605 snprintf(buf, 30, "USB Charging Enabled: %s",
1606 usb_charging_enabled() ? "yes" : "no");
1607 lcd_puts(0, 9, buf);
1608 #endif
1609 #else /* CONFIG_CHARGING != CHARGING_CONTROL */
1610 #if defined IPOD_NANO || defined IPOD_VIDEO
1611 int usb_pwr = (GPIOL_INPUT_VAL & 0x10)?true:false;
1612 int ext_pwr = (GPIOL_INPUT_VAL & 0x08)?false:true;
1613 int dock = (GPIOA_INPUT_VAL & 0x10)?true:false;
1614 int charging = (GPIOB_INPUT_VAL & 0x01)?false:true;
1615 int headphone= (GPIOA_INPUT_VAL & 0x80)?true:false;
1617 snprintf(buf, 30, "USB pwr: %s",
1618 usb_pwr ? "present" : "absent");
1619 lcd_puts(0, 3, buf);
1620 snprintf(buf, 30, "EXT pwr: %s",
1621 ext_pwr ? "present" : "absent");
1622 lcd_puts(0, 4, buf);
1623 snprintf(buf, 30, "Battery: %s",
1624 charging ? "charging" : (usb_pwr||ext_pwr) ? "charged" : "discharging");
1625 lcd_puts(0, 5, buf);
1626 snprintf(buf, 30, "Dock mode: %s",
1627 dock ? "enabled" : "disabled");
1628 lcd_puts(0, 6, buf);
1629 snprintf(buf, 30, "Headphone: %s",
1630 headphone ? "connected" : "disconnected");
1631 lcd_puts(0, 7, buf);
1632 #else
1633 snprintf(buf, 30, "Charger: %s",
1634 charger_inserted() ? "present" : "absent");
1635 lcd_puts(0, 3, buf);
1636 #endif
1637 #endif /* CONFIG_CHARGING != CHARGING_CONTROL */
1638 #endif /* CONFIG_CHARGING */
1639 break;
1641 case 2: /* voltage deltas: */
1642 lcd_puts(0, 0, "Voltage deltas:");
1644 for (i = 0; i <= 6; i++) {
1645 y = power_history[i] - power_history[i+1];
1646 snprintf(buf, 30, "-%d min: %s%d.%03d V", i,
1647 (y < 0) ? "-" : "", ((y < 0) ? y * -1 : y) / 1000,
1648 ((y < 0) ? y * -1 : y ) % 1000);
1649 lcd_puts(0, i+1, buf);
1651 break;
1653 case 3: /* remaining time estimation: */
1655 #if CONFIG_CHARGING == CHARGING_CONTROL
1656 snprintf(buf, 30, "charge_state: %d", charge_state);
1657 lcd_puts(0, 0, buf);
1659 snprintf(buf, 30, "Cycle time: %d m", powermgmt_last_cycle_startstop_min);
1660 lcd_puts(0, 1, buf);
1662 snprintf(buf, 30, "Lvl@cyc st: %d%%", powermgmt_last_cycle_level);
1663 lcd_puts(0, 2, buf);
1665 snprintf(buf, 30, "P=%2d I=%2d", pid_p, pid_i);
1666 lcd_puts(0, 3, buf);
1668 snprintf(buf, 30, "Trickle sec: %d/60", trickle_sec);
1669 lcd_puts(0, 4, buf);
1670 #endif /* CONFIG_CHARGING == CHARGING_CONTROL */
1672 snprintf(buf, 30, "Last PwrHist: %d.%03dV",
1673 power_history[0] / 1000,
1674 power_history[0] % 1000);
1675 lcd_puts(0, 5, buf);
1677 snprintf(buf, 30, "battery level: %d%%", battery_level());
1678 lcd_puts(0, 6, buf);
1680 snprintf(buf, 30, "Est. remain: %d m", battery_time());
1681 lcd_puts(0, 7, buf);
1682 break;
1685 lcd_update();
1687 switch(get_action(CONTEXT_SETTINGS,HZ/2))
1689 case ACTION_SETTINGS_DEC:
1690 if (view)
1691 view--;
1692 break;
1694 case ACTION_SETTINGS_INC:
1695 if (view < 3)
1696 view++;
1697 break;
1699 case ACTION_STD_CANCEL:
1700 return false;
1703 return false;
1706 #endif /* HAVE_LCD_BITMAP */
1707 #endif
1709 #ifndef SIMULATOR
1710 #if defined(HAVE_MMC) || defined(HAVE_HOTSWAP)
1711 #if defined(HAVE_MMC)
1712 #define CARDTYPE "MMC"
1713 #else
1714 #define CARDTYPE "microSD"
1715 #endif
1716 static int disk_callback(int btn, struct gui_synclist *lists)
1718 tCardInfo *card;
1719 int *cardnum = (int*)lists->data;
1720 unsigned char card_name[7];
1721 unsigned char pbuf[32];
1722 char *title = lists->title;
1723 static const unsigned char i_vmin[] = { 0, 1, 5, 10, 25, 35, 60, 100 };
1724 static const unsigned char i_vmax[] = { 1, 5, 10, 25, 35, 45, 80, 200 };
1725 static const unsigned char *kbit_units[] = { "kBit/s", "MBit/s", "GBit/s" };
1726 static const unsigned char *nsec_units[] = { "ns", "�s", "ms" };
1727 static const char *spec_vers[] = { "1.0-1.2", "1.4", "2.0-2.2",
1728 "3.1-3.31", "4.0" };
1729 if ((btn == ACTION_STD_OK) || (btn == SYS_FS_CHANGED) || (btn == ACTION_REDRAW))
1731 if (btn == ACTION_STD_OK)
1733 *cardnum ^= 0x1; /* change cards */
1736 simplelist_set_line_count(0);
1738 card = card_get_info(*cardnum);
1740 if (card->initialized > 0)
1742 card_name[6] = '\0';
1743 strncpy(card_name, ((unsigned char*)card->cid) + 3, 6);
1744 simplelist_addline(SIMPLELIST_ADD_LINE,
1745 "%s Rev %d.%d", card_name,
1746 (int) card_extract_bits(card->cid, 72, 4),
1747 (int) card_extract_bits(card->cid, 76, 4));
1748 simplelist_addline(SIMPLELIST_ADD_LINE,
1749 "Prod: %d/%d",
1750 (int) card_extract_bits(card->cid, 112, 4),
1751 (int) card_extract_bits(card->cid, 116, 4) + 1997);
1752 simplelist_addline(SIMPLELIST_ADD_LINE,
1753 "Ser#: 0x%08lx",
1754 card_extract_bits(card->cid, 80, 32));
1755 simplelist_addline(SIMPLELIST_ADD_LINE,
1756 "M=%02x, O=%04x",
1757 (int) card_extract_bits(card->cid, 0, 8),
1758 (int) card_extract_bits(card->cid, 8, 16));
1759 int temp = card_extract_bits(card->csd, 2, 4);
1760 simplelist_addline(SIMPLELIST_ADD_LINE,
1761 CARDTYPE " v%s", temp < 5 ?
1762 spec_vers[temp] : "?.?");
1763 simplelist_addline(SIMPLELIST_ADD_LINE,
1764 "Blocks: 0x%06lx", card->numblocks);
1765 simplelist_addline(SIMPLELIST_ADD_LINE,
1766 "Blksz.: %d P:%c%c", card->blocksize,
1767 card_extract_bits(card->csd, 48, 1) ? 'R' : '-',
1768 card_extract_bits(card->csd, 106, 1) ? 'W' : '-');
1769 output_dyn_value(pbuf, sizeof pbuf, card->speed / 1000,
1770 kbit_units, false);
1771 simplelist_addline(SIMPLELIST_ADD_LINE,
1772 "Speed: %s", pbuf);
1773 output_dyn_value(pbuf, sizeof pbuf, card->tsac,
1774 nsec_units, false);
1775 simplelist_addline(SIMPLELIST_ADD_LINE,
1776 "Tsac: %s", pbuf);
1777 simplelist_addline(SIMPLELIST_ADD_LINE,
1778 "Nsac: %d clk", card->nsac);
1779 simplelist_addline(SIMPLELIST_ADD_LINE,
1780 "R2W: *%d", card->r2w_factor);
1781 simplelist_addline(SIMPLELIST_ADD_LINE,
1782 "IRmax: %d..%d mA",
1783 i_vmin[card_extract_bits(card->csd, 66, 3)],
1784 i_vmax[card_extract_bits(card->csd, 69, 3)]);
1785 simplelist_addline(SIMPLELIST_ADD_LINE,
1786 "IWmax: %d..%d mA",
1787 i_vmin[card_extract_bits(card->csd, 72, 3)],
1788 i_vmax[card_extract_bits(card->csd, 75, 3)]);
1790 else if (card->initialized == 0)
1792 simplelist_addline(SIMPLELIST_ADD_LINE, "Not Found!");
1794 #ifndef HAVE_MMC
1795 else /* card->initialized < 0 */
1797 simplelist_addline(SIMPLELIST_ADD_LINE, "Init Error! (%d)", card->initialized);
1799 #endif
1800 snprintf(title, 16, "[" CARDTYPE " %d]", *cardnum);
1801 gui_synclist_set_title(lists, title, Icon_NOICON);
1802 gui_synclist_set_nb_items(lists, simplelist_get_line_count());
1803 gui_synclist_select_item(lists, 0);
1804 btn = ACTION_REDRAW;
1806 return btn;
1808 #else /* !defined(HAVE_MMC) && !defined(HAVE_HOTSWAP) */
1809 static int disk_callback(int btn, struct gui_synclist *lists)
1811 (void)lists;
1812 int i;
1813 char buf[128];
1814 unsigned short* identify_info = ata_get_identify();
1815 bool timing_info_present = false;
1816 (void)btn;
1818 simplelist_set_line_count(0);
1820 for (i=0; i < 20; i++)
1821 ((unsigned short*)buf)[i]=htobe16(identify_info[i+27]);
1822 buf[40]=0;
1823 /* kill trailing space */
1824 for (i=39; i && buf[i]==' '; i--)
1825 buf[i] = 0;
1826 simplelist_addline(SIMPLELIST_ADD_LINE, "Model: %s", buf);
1827 for (i=0; i < 4; i++)
1828 ((unsigned short*)buf)[i]=htobe16(identify_info[i+23]);
1829 buf[8]=0;
1830 simplelist_addline(SIMPLELIST_ADD_LINE,
1831 "Firmware: %s", buf);
1832 snprintf(buf, sizeof buf, "%ld MB",
1833 ((unsigned long)identify_info[61] << 16 |
1834 (unsigned long)identify_info[60]) / 2048 );
1835 simplelist_addline(SIMPLELIST_ADD_LINE,
1836 "Size: %s", buf);
1837 unsigned long free;
1838 fat_size( IF_MV2(0,) NULL, &free );
1839 simplelist_addline(SIMPLELIST_ADD_LINE,
1840 "Free: %ld MB", free / 1024);
1841 simplelist_addline(SIMPLELIST_ADD_LINE,
1842 "Spinup time: %d ms", ata_spinup_time * (1000/HZ));
1843 i = identify_info[83] & (1<<3);
1844 simplelist_addline(SIMPLELIST_ADD_LINE,
1845 "Power mgmt: %s", i ? "enabled" : "unsupported");
1846 i = identify_info[83] & (1<<9);
1847 simplelist_addline(SIMPLELIST_ADD_LINE,
1848 "Noise mgmt: %s", i ? "enabled" : "unsupported");
1849 i = identify_info[82] & (1<<6);
1850 simplelist_addline(SIMPLELIST_ADD_LINE,
1851 "Read-ahead: %s", i ? "enabled" : "unsupported");
1852 timing_info_present = identify_info[53] & (1<<1);
1853 if(timing_info_present) {
1854 char pio3[2], pio4[2];pio3[1] = 0;
1855 pio4[1] = 0;
1856 pio3[0] = (identify_info[64] & (1<<0)) ? '3' : 0;
1857 pio4[0] = (identify_info[64] & (1<<1)) ? '4' : 0;
1858 simplelist_addline(SIMPLELIST_ADD_LINE,
1859 "PIO modes: 0 1 2 %s %s", pio3, pio4);
1861 else {
1862 simplelist_addline(SIMPLELIST_ADD_LINE,
1863 "No PIO mode info");
1865 timing_info_present = identify_info[53] & (1<<1);
1866 if(timing_info_present) {
1867 simplelist_addline(SIMPLELIST_ADD_LINE,
1868 "Cycle times %dns/%dns",
1869 identify_info[67],
1870 identify_info[68] );
1871 } else {
1872 simplelist_addline(SIMPLELIST_ADD_LINE,
1873 "No timing info");
1875 timing_info_present = identify_info[53] & (1<<1);
1876 if(timing_info_present) {
1877 i = identify_info[49] & (1<<11);
1878 simplelist_addline(SIMPLELIST_ADD_LINE,
1879 "IORDY support: %s", i ? "yes" : "no");
1880 i = identify_info[49] & (1<<10);
1881 simplelist_addline(SIMPLELIST_ADD_LINE,
1882 "IORDY disable: %s", i ? "yes" : "no");
1883 } else {
1884 simplelist_addline(SIMPLELIST_ADD_LINE,
1885 "No timing info");
1887 simplelist_addline(SIMPLELIST_ADD_LINE,
1888 "Cluster size: %d bytes", fat_get_cluster_size(IF_MV(0)));
1889 return btn;
1892 static bool dbg_identify_info(void)
1894 int fd = creat("/identify_info.bin");
1895 if(fd >= 0)
1897 #ifdef ROCKBOX_LITTLE_ENDIAN
1898 ecwrite(fd, ata_get_identify(), SECTOR_SIZE/2, "s", true);
1899 #else
1900 write(fd, ata_get_identify(), SECTOR_SIZE);
1901 #endif
1902 close(fd);
1904 return false;
1906 #endif /* !defined(HAVE_MMC) && !defined(HAVE_HOTSWAP) */
1907 static bool dbg_disk_info(void)
1909 struct simplelist_info info;
1910 simplelist_info_init(&info, "Disk Info", 1, NULL);
1911 #if defined(HAVE_MMC) || defined(HAVE_HOTSWAP)
1912 char title[16];
1913 int card = 0;
1914 info.callback_data = (void*)&card;
1915 info.title = title;
1916 #endif
1917 info.action_callback = disk_callback;
1918 info.hide_selection = true;
1919 return simplelist_show_list(&info);
1921 #endif /* !SIMULATOR */
1923 #ifdef HAVE_DIRCACHE
1924 static int dircache_callback(int btn, struct gui_synclist *lists)
1926 (void)btn; (void)lists;
1927 simplelist_set_line_count(0);
1928 simplelist_addline(SIMPLELIST_ADD_LINE, "Cache initialized: %s",
1929 dircache_is_enabled() ? "Yes" : "No");
1930 simplelist_addline(SIMPLELIST_ADD_LINE, "Cache size: %d B",
1931 dircache_get_cache_size());
1932 simplelist_addline(SIMPLELIST_ADD_LINE, "Last size: %d B",
1933 global_status.dircache_size);
1934 simplelist_addline(SIMPLELIST_ADD_LINE, "Limit: %d B",
1935 DIRCACHE_LIMIT);
1936 simplelist_addline(SIMPLELIST_ADD_LINE, "Reserve: %d/%d B",
1937 dircache_get_reserve_used(), DIRCACHE_RESERVE);
1938 simplelist_addline(SIMPLELIST_ADD_LINE, "Scanning took: %d s",
1939 dircache_get_build_ticks() / HZ);
1940 simplelist_addline(SIMPLELIST_ADD_LINE, "Entry count: %d",
1941 dircache_get_entry_count());
1942 return btn;
1945 static bool dbg_dircache_info(void)
1947 struct simplelist_info info;
1948 simplelist_info_init(&info, "Dircache Info", 7, NULL);
1949 info.action_callback = dircache_callback;
1950 info.hide_selection = true;
1951 return simplelist_show_list(&info);
1954 #endif /* HAVE_DIRCACHE */
1956 #ifdef HAVE_TAGCACHE
1957 static int database_callback(int btn, struct gui_synclist *lists)
1959 (void)lists;
1960 struct tagcache_stat *stat = tagcache_get_stat();
1961 static bool synced = false;
1963 simplelist_set_line_count(0);
1965 simplelist_addline(SIMPLELIST_ADD_LINE, "Initialized: %s",
1966 stat->initialized ? "Yes" : "No");
1967 simplelist_addline(SIMPLELIST_ADD_LINE, "DB Ready: %s",
1968 stat->ready ? "Yes" : "No");
1969 simplelist_addline(SIMPLELIST_ADD_LINE, "RAM Cache: %s",
1970 stat->ramcache ? "Yes" : "No");
1971 simplelist_addline(SIMPLELIST_ADD_LINE, "RAM: %d/%d B",
1972 stat->ramcache_used, stat->ramcache_allocated);
1973 simplelist_addline(SIMPLELIST_ADD_LINE, "Progress: %d%% (%d entries)",
1974 stat->progress, stat->processed_entries);
1975 simplelist_addline(SIMPLELIST_ADD_LINE, "Curfile: %s",
1976 stat->curentry ? stat->curentry : "---");
1977 simplelist_addline(SIMPLELIST_ADD_LINE, "Commit step: %d",
1978 stat->commit_step);
1979 simplelist_addline(SIMPLELIST_ADD_LINE, "Commit delayed: %s",
1980 stat->commit_delayed ? "Yes" : "No");
1982 simplelist_addline(SIMPLELIST_ADD_LINE, "Queue length: %d",
1983 stat->queue_length);
1985 if (synced)
1987 synced = false;
1988 tagcache_screensync_event();
1991 if (!btn && stat->curentry)
1993 synced = true;
1994 return ACTION_REDRAW;
1997 if (btn == ACTION_STD_CANCEL)
1998 tagcache_screensync_enable(false);
2000 return btn;
2002 static bool dbg_tagcache_info(void)
2004 struct simplelist_info info;
2005 simplelist_info_init(&info, "Database Info", 8, NULL);
2006 info.action_callback = database_callback;
2007 info.hide_selection = true;
2009 /* Don't do nonblock here, must give enough processing time
2010 for tagcache thread. */
2011 /* info.timeout = TIMEOUT_NOBLOCK; */
2012 info.timeout = 1;
2013 tagcache_screensync_enable(true);
2014 return simplelist_show_list(&info);
2016 #endif
2018 #if CONFIG_CPU == SH7034
2019 static bool dbg_save_roms(void)
2021 int fd;
2022 int oldmode = system_memory_guard(MEMGUARD_NONE);
2024 fd = creat("/internal_rom_0000-FFFF.bin");
2025 if(fd >= 0)
2027 write(fd, (void *)0, 0x10000);
2028 close(fd);
2031 fd = creat("/internal_rom_2000000-203FFFF.bin");
2032 if(fd >= 0)
2034 write(fd, (void *)0x2000000, 0x40000);
2035 close(fd);
2038 system_memory_guard(oldmode);
2039 return false;
2041 #elif defined CPU_COLDFIRE
2042 static bool dbg_save_roms(void)
2044 int fd;
2045 int oldmode = system_memory_guard(MEMGUARD_NONE);
2047 #if defined(IRIVER_H100_SERIES)
2048 fd = creat("/internal_rom_000000-1FFFFF.bin");
2049 #elif defined(IRIVER_H300_SERIES)
2050 fd = creat("/internal_rom_000000-3FFFFF.bin");
2051 #elif defined(IAUDIO_X5) || defined(IAUDIO_M5) || defined(IAUDIO_M3)
2052 fd = creat("/internal_rom_000000-3FFFFF.bin");
2053 #endif
2054 if(fd >= 0)
2056 write(fd, (void *)0, FLASH_SIZE);
2057 close(fd);
2059 system_memory_guard(oldmode);
2061 #ifdef HAVE_EEPROM
2062 fd = creat("/internal_eeprom.bin");
2063 if (fd >= 0)
2065 int old_irq_level;
2066 char buf[EEPROM_SIZE];
2067 int err;
2069 old_irq_level = disable_irq_save();
2071 err = eeprom_24cxx_read(0, buf, sizeof buf);
2073 restore_irq(old_irq_level);
2075 if (err)
2076 gui_syncsplash(HZ*3, "Eeprom read failure (%d)",err);
2077 else
2079 write(fd, buf, sizeof buf);
2082 close(fd);
2084 #endif
2086 return false;
2088 #elif defined(CPU_PP) && !(defined(SANSA_E200) || defined(SANSA_C200))
2089 static bool dbg_save_roms(void)
2091 int fd;
2093 fd = creat("/internal_rom_000000-0FFFFF.bin");
2094 if(fd >= 0)
2096 write(fd, (void *)0x20000000, FLASH_SIZE);
2097 close(fd);
2100 return false;
2102 #endif /* CPU */
2104 #ifndef SIMULATOR
2105 #if CONFIG_TUNER
2106 static int radio_callback(int btn, struct gui_synclist *lists)
2108 (void)lists;
2109 if (btn == ACTION_STD_CANCEL)
2110 return btn;
2111 simplelist_set_line_count(1);
2113 #if (CONFIG_TUNER & LV24020LP)
2114 simplelist_addline(SIMPLELIST_ADD_LINE,
2115 "CTRL_STAT: %02X", lv24020lp_get(LV24020LP_CTRL_STAT) );
2116 simplelist_addline(SIMPLELIST_ADD_LINE,
2117 "RADIO_STAT: %02X", lv24020lp_get(LV24020LP_REG_STAT) );
2118 simplelist_addline(SIMPLELIST_ADD_LINE,
2119 "MSS_FM: %d kHz", lv24020lp_get(LV24020LP_MSS_FM) );
2120 simplelist_addline(SIMPLELIST_ADD_LINE,
2121 "MSS_IF: %d Hz", lv24020lp_get(LV24020LP_MSS_IF) );
2122 simplelist_addline(SIMPLELIST_ADD_LINE,
2123 "MSS_SD: %d Hz", lv24020lp_get(LV24020LP_MSS_SD) );
2124 simplelist_addline(SIMPLELIST_ADD_LINE,
2125 "if_set: %d Hz", lv24020lp_get(LV24020LP_IF_SET) );
2126 simplelist_addline(SIMPLELIST_ADD_LINE,
2127 "sd_set: %d Hz", lv24020lp_get(LV24020LP_SD_SET) );
2128 #endif
2129 #if (CONFIG_TUNER & S1A0903X01)
2130 simplelist_addline(SIMPLELIST_ADD_LINE,
2131 "Samsung regs: %08X", s1a0903x01_get(RADIO_ALL));
2132 /* This one doesn't return dynamic data atm */
2133 #endif
2134 #if (CONFIG_TUNER & TEA5767)
2135 struct tea5767_dbg_info nfo;
2136 tea5767_dbg_info(&nfo);
2137 simplelist_addline(SIMPLELIST_ADD_LINE, "Philips regs:");
2138 simplelist_addline(SIMPLELIST_ADD_LINE,
2139 " Read: %02X %02X %02X %02X %02X",
2140 (unsigned)nfo.read_regs[0], (unsigned)nfo.read_regs[1],
2141 (unsigned)nfo.read_regs[2], (unsigned)nfo.read_regs[3],
2142 (unsigned)nfo.read_regs[4]);
2143 simplelist_addline(SIMPLELIST_ADD_LINE,
2144 " Write: %02X %02X %02X %02X %02X",
2145 (unsigned)nfo.write_regs[0], (unsigned)nfo.write_regs[1],
2146 (unsigned)nfo.write_regs[2], (unsigned)nfo.write_regs[3],
2147 (unsigned)nfo.write_regs[4]);
2148 #endif
2149 return ACTION_REDRAW;
2151 static bool dbg_fm_radio(void)
2153 struct simplelist_info info;
2154 simplelist_info_init(&info, "FM Radio", 1, NULL);
2155 simplelist_set_line_count(0);
2156 simplelist_addline(SIMPLELIST_ADD_LINE, "HW detected: %s",
2157 radio_hardware_present() ? "yes" : "no");
2159 info.action_callback = radio_hardware_present()?radio_callback : NULL;
2160 info.hide_selection = true;
2161 return simplelist_show_list(&info);
2163 #endif /* CONFIG_TUNER */
2164 #endif /* !SIMULATOR */
2166 #ifdef HAVE_LCD_BITMAP
2167 extern bool do_screendump_instead_of_usb;
2169 static bool dbg_screendump(void)
2171 do_screendump_instead_of_usb = !do_screendump_instead_of_usb;
2172 gui_syncsplash(HZ, "Screendump %s",
2173 do_screendump_instead_of_usb?"enabled":"disabled");
2174 return false;
2176 #endif /* HAVE_LCD_BITMAP */
2178 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
2179 static bool dbg_set_memory_guard(void)
2181 static const struct opt_items names[MAXMEMGUARD] = {
2182 { "None", -1 },
2183 { "Flash ROM writes", -1 },
2184 { "Zero area (all)", -1 }
2186 int mode = system_memory_guard(MEMGUARD_KEEP);
2188 set_option( "Catch mem accesses", &mode, INT, names, MAXMEMGUARD, NULL);
2189 system_memory_guard(mode);
2191 return false;
2193 #endif /* CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) */
2195 #if defined(TOSHIBA_GIGABEAT_F) && !defined(SIMULATOR)
2197 extern volatile bool lcd_poweroff;
2199 static bool dbg_lcd_power_off(void)
2201 lcd_setmargins(0, 0);
2203 while(1)
2205 int button;
2207 lcd_clear_display();
2208 lcd_puts(0, 0, "LCD Power Off");
2209 if(lcd_poweroff)
2210 lcd_puts(1, 1, "Yes");
2211 else
2212 lcd_puts(1, 1, "No");
2214 lcd_update();
2216 button = get_action(CONTEXT_STD,HZ/5);
2217 switch(button)
2219 case ACTION_STD_PREV:
2220 case ACTION_STD_NEXT:
2221 lcd_poweroff = !lcd_poweroff;
2222 break;
2223 case ACTION_STD_OK:
2224 case ACTION_STD_CANCEL:
2225 return false;
2226 default:
2227 sleep(HZ/10);
2228 break;
2231 return false;
2233 #endif
2235 #if defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS)
2236 static bool dbg_write_eeprom(void)
2238 int fd;
2239 int rc;
2240 int old_irq_level;
2241 char buf[EEPROM_SIZE];
2242 int err;
2244 fd = open("/internal_eeprom.bin", O_RDONLY);
2246 if (fd >= 0)
2248 rc = read(fd, buf, EEPROM_SIZE);
2250 if(rc == EEPROM_SIZE)
2252 old_irq_level = disable_irq_save();
2254 err = eeprom_24cxx_write(0, buf, sizeof buf);
2255 if (err)
2256 gui_syncsplash(HZ*3, "Eeprom write failure (%d)",err);
2257 else
2258 gui_syncsplash(HZ*3, "Eeprom written successfully");
2260 restore_irq(old_irq_level);
2262 else
2264 gui_syncsplash(HZ*3, "File read error (%d)",rc);
2266 close(fd);
2268 else
2270 gui_syncsplash(HZ*3, "Failed to open 'internal_eeprom.bin'");
2273 return false;
2275 #endif /* defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS) */
2276 #ifdef CPU_BOOST_LOGGING
2277 static bool cpu_boost_log(void)
2279 int i = 0,j=0;
2280 int count = cpu_boost_log_getcount();
2281 int lines = LCD_HEIGHT/SYSFONT_HEIGHT;
2282 char *str;
2283 bool done;
2284 lcd_setmargins(0, 0);
2285 lcd_setfont(FONT_SYSFIXED);
2286 str = cpu_boost_log_getlog_first();
2287 while (i < count)
2289 lcd_clear_display();
2290 for(j=0; j<lines; j++,i++)
2292 if (!str)
2293 str = cpu_boost_log_getlog_next();
2294 if (str)
2296 lcd_puts(0, j,str);
2298 str = NULL;
2300 lcd_update();
2301 done = false;
2302 while (!done)
2304 switch(get_action(CONTEXT_STD,TIMEOUT_BLOCK))
2306 case ACTION_STD_OK:
2307 case ACTION_STD_PREV:
2308 case ACTION_STD_NEXT:
2309 done = true;
2310 break;
2311 case ACTION_STD_CANCEL:
2312 i = count;
2313 done = true;
2314 break;
2318 get_action(CONTEXT_STD,TIMEOUT_BLOCK);
2319 lcd_setfont(FONT_UI);
2320 return false;
2322 #endif
2324 #if (defined(HAVE_SCROLLWHEEL) && (CONFIG_KEYPAD==IPOD_4G_PAD) && !defined(SIMULATOR))
2325 extern bool wheel_is_touched;
2326 extern int old_wheel_value;
2327 extern int new_wheel_value;
2328 extern int wheel_delta;
2329 extern unsigned int accumulated_wheel_delta;
2330 extern unsigned int wheel_velocity;
2332 static bool dbg_scrollwheel(void)
2334 char buf[64];
2335 unsigned int speed;
2337 lcd_setmargins(0, 0);
2338 lcd_setfont(FONT_SYSFIXED);
2340 while (1)
2342 if (action_userabort(HZ/10))
2343 return false;
2345 lcd_clear_display();
2347 /* show internal variables of scrollwheel driver */
2348 snprintf(buf, sizeof(buf), "wheel touched: %s", (wheel_is_touched) ? "true" : "false");
2349 lcd_puts(0, 0, buf);
2350 snprintf(buf, sizeof(buf), "new position: %2d", new_wheel_value);
2351 lcd_puts(0, 1, buf);
2352 snprintf(buf, sizeof(buf), "old position: %2d", old_wheel_value);
2353 lcd_puts(0, 2, buf);
2354 snprintf(buf, sizeof(buf), "wheel delta: %2d", wheel_delta);
2355 lcd_puts(0, 3, buf);
2356 snprintf(buf, sizeof(buf), "accumulated delta: %2d", accumulated_wheel_delta);
2357 lcd_puts(0, 4, buf);
2358 snprintf(buf, sizeof(buf), "velo [deg/s]: %4d", (int)wheel_velocity);
2359 lcd_puts(0, 5, buf);
2361 /* show effective accelerated scrollspeed */
2362 speed = button_apply_acceleration( (1<<31)|(1<<24)|wheel_velocity);
2363 snprintf(buf, sizeof(buf), "accel. speed: %4d", speed);
2364 lcd_puts(0, 6, buf);
2366 lcd_update();
2368 return false;
2370 #endif
2372 #if defined(HAVE_USBSTACK) && defined(ROCKBOX_HAS_LOGF) && defined(USB_SERIAL)
2373 static bool logf_usb_serial(void)
2375 bool serial_enabled = !usb_core_driver_enabled(USB_DRIVER_SERIAL);
2376 usb_core_enable_driver(USB_DRIVER_SERIAL,serial_enabled);
2377 gui_syncsplash(HZ, "USB logf %s",
2378 serial_enabled?"enabled":"disabled");
2379 return false;
2381 #endif
2383 #if defined(HAVE_USBSTACK) && defined(USB_STORAGE)
2384 static bool usb_reconnect(void)
2386 gui_syncsplash(HZ, "Reconnect mass storage");
2387 usb_storage_reconnect();
2388 return false;
2390 #endif
2393 /****** The menu *********/
2394 struct the_menu_item {
2395 unsigned char *desc; /* string or ID */
2396 bool (*function) (void); /* return true if USB was connected */
2398 static const struct the_menu_item menuitems[] = {
2399 #if defined(TOSHIBA_GIGABEAT_F) && !defined(SIMULATOR)
2400 { "LCD Power Off", dbg_lcd_power_off },
2401 #endif
2402 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || \
2403 (defined(CPU_PP) && !(defined(SANSA_E200) || defined(SANSA_C200)))
2404 { "Dump ROM contents", dbg_save_roms },
2405 #endif
2406 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || defined(CPU_PP) || CONFIG_CPU == S3C2440
2407 { "View I/O ports", dbg_ports },
2408 #endif
2409 #if (CONFIG_RTC == RTC_PCF50605) && !defined(SIMULATOR)
2410 { "View PCF registers", dbg_pcf },
2411 #endif
2412 #if defined(HAVE_TSC2100) && !defined(SIMULATOR)
2413 { "TSC2100 debug", tsc2100_debug },
2414 #endif
2415 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
2416 { "CPU frequency", dbg_cpufreq },
2417 #endif
2418 #if defined(IRIVER_H100_SERIES) && !defined(SIMULATOR)
2419 { "S/PDIF analyzer", dbg_spdif },
2420 #endif
2421 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
2422 { "Catch mem accesses", dbg_set_memory_guard },
2423 #endif
2424 { "View OS stacks", dbg_os },
2425 #ifdef HAVE_LCD_BITMAP
2426 #ifndef SIMULATOR
2427 { "View battery", view_battery },
2428 #endif
2429 { "Screendump", dbg_screendump },
2430 #endif
2431 #ifndef SIMULATOR
2432 { "View HW info", dbg_hw_info },
2433 #endif
2434 #ifndef SIMULATOR
2435 { "View partitions", dbg_partitions },
2436 #endif
2437 #ifndef SIMULATOR
2438 { "View disk info", dbg_disk_info },
2439 #if !defined(HAVE_MMC) && !defined(HAVE_HOTSWAP)
2440 { "Dump ATA identify info", dbg_identify_info},
2441 #endif
2442 #endif
2443 #ifdef HAVE_DIRCACHE
2444 { "View dircache info", dbg_dircache_info },
2445 #endif
2446 #ifdef HAVE_TAGCACHE
2447 { "View database info", dbg_tagcache_info },
2448 #endif
2449 #ifdef HAVE_LCD_BITMAP
2450 #if CONFIG_CODEC == SWCODEC
2451 { "View buffering thread", dbg_buffering_thread },
2452 #elif !defined(SIMULATOR)
2453 { "View audio thread", dbg_audio_thread },
2454 #endif
2455 #ifdef PM_DEBUG
2456 { "pm histogram", peak_meter_histogram},
2457 #endif /* PM_DEBUG */
2458 #endif /* HAVE_LCD_BITMAP */
2459 #ifndef SIMULATOR
2460 #if CONFIG_TUNER
2461 { "FM Radio", dbg_fm_radio },
2462 #endif
2463 #endif
2464 #if defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS)
2465 { "Write back EEPROM", dbg_write_eeprom },
2466 #endif
2467 #ifdef ROCKBOX_HAS_LOGF
2468 {"logf", logfdisplay },
2469 {"logfdump", logfdump },
2470 #endif
2471 #if defined(HAVE_USBSTACK) && defined(ROCKBOX_HAS_LOGF) && defined(USB_SERIAL)
2472 {"logf over usb",logf_usb_serial },
2473 #endif
2474 #if defined(HAVE_USBSTACK) && defined(USB_STORAGE)
2475 {"reconnect usb storage",usb_reconnect},
2476 #endif
2477 #ifdef CPU_BOOST_LOGGING
2478 {"cpu_boost log",cpu_boost_log},
2479 #endif
2480 #if (defined(HAVE_SCROLLWHEEL) && (CONFIG_KEYPAD==IPOD_4G_PAD) && !defined(SIMULATOR))
2481 {"Debug scrollwheel", dbg_scrollwheel},
2482 #endif
2484 static int menu_action_callback(int btn, struct gui_synclist *lists)
2486 if (btn == ACTION_STD_OK)
2488 menuitems[gui_synclist_get_sel_pos(lists)].function();
2489 btn = ACTION_REDRAW;
2491 return btn;
2493 static char* dbg_menu_getname(int item, void * data, char *buffer)
2495 (void)data; (void)buffer;
2496 return menuitems[item].desc;
2498 bool debug_menu(void)
2500 struct simplelist_info info;
2502 simplelist_info_init(&info, "Debug Menu", ARRAYLEN(menuitems), NULL);
2503 info.action_callback = menu_action_callback;
2504 info.get_name = dbg_menu_getname;
2506 return simplelist_show_list(&info);