SPC codec: The inline asm 'memory' clobbers should be unneeded since the ASM either...
[kugel-rb.git] / apps / debug_menu.c
blob1288d9acac2a7ba0f7cc87622cad8e750f5b3e8b
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2002 Heikki Hannikainen
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
22 #include "config.h"
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <stdbool.h>
26 #include <string.h>
27 #include "lcd.h"
28 #include "menu.h"
29 #include "debug_menu.h"
30 #include "kernel.h"
31 #include "structec.h"
32 #include "action.h"
33 #include "debug.h"
34 #include "thread.h"
35 #include "powermgmt.h"
36 #include "system.h"
37 #include "font.h"
38 #include "audio.h"
39 #include "mp3_playback.h"
40 #include "settings.h"
41 #include "list.h"
42 #include "statusbar.h"
43 #include "dir.h"
44 #include "panic.h"
45 #include "screens.h"
46 #include "misc.h"
47 #include "splash.h"
48 #include "dircache.h"
49 #include "viewport.h"
50 #ifdef HAVE_TAGCACHE
51 #include "tagcache.h"
52 #endif
53 #include "lcd-remote.h"
54 #include "crc32.h"
55 #include "logf.h"
56 #ifndef SIMULATOR
57 #include "disk.h"
58 #include "adc.h"
59 #include "power.h"
60 #include "usb.h"
61 #include "rtc.h"
62 #include "storage.h"
63 #include "fat.h"
64 #include "mas.h"
65 #include "eeprom_24cxx.h"
66 #if (CONFIG_STORAGE & STORAGE_MMC) || (CONFIG_STORAGE & STORAGE_SD)
67 #include "hotswap.h"
68 #endif
69 #if (CONFIG_STORAGE & STORAGE_ATA)
70 #include "ata.h"
71 #endif
72 #if CONFIG_TUNER
73 #include "tuner.h"
74 #include "radio.h"
75 #endif
76 #endif
78 #ifdef HAVE_LCD_BITMAP
79 #include "scrollbar.h"
80 #include "peakmeter.h"
81 #endif
82 #include "logfdisp.h"
83 #if CONFIG_CODEC == SWCODEC
84 #include "pcmbuf.h"
85 #include "buffering.h"
86 #include "playback.h"
87 #if defined(HAVE_SPDIF_OUT) || defined(HAVE_SPDIF_IN)
88 #include "spdif.h"
89 #endif
90 #endif
91 #ifdef IRIVER_H300_SERIES
92 #include "pcf50606.h" /* for pcf50606_read */
93 #endif
94 #ifdef IAUDIO_X5
95 #include "ds2411.h"
96 #endif
97 #include "hwcompat.h"
98 #include "button.h"
99 #if CONFIG_RTC == RTC_PCF50605
100 #include "pcf50605.h"
101 #endif
102 #include "appevents.h"
104 #if CONFIG_CPU == DM320 || CONFIG_CPU == S3C2440 || CONFIG_CPU == TCC7801 \
105 || CONFIG_CPU == IMX31L || CONFIG_CPU == AS3525 || CONFIG_CPU == JZ4732 \
106 || defined(CPU_S5L870X) || CONFIG_CPU == AS3525v2
107 #include "debug-target.h"
108 #endif
110 #if defined(SANSA_E200) || defined(SANSA_C200) || defined(PHILIPS_SA9200) \
111 || (CONFIG_CPU == AS3525 && defined(CONFIG_CHARGING)) \
112 || CONFIG_CPU == AS3525v2
113 #include "ascodec.h"
114 #include "as3514.h"
115 #endif
117 #ifdef IPOD_NANO2G
118 #include "pmu-target.h"
119 #endif
121 #ifdef HAVE_USBSTACK
122 #include "usb_core.h"
123 #endif
125 /*---------------------------------------------------*/
126 /* SPECIAL DEBUG STUFF */
127 /*---------------------------------------------------*/
128 extern struct thread_entry threads[MAXTHREADS];
130 static char thread_status_char(unsigned status)
132 static const char thread_status_chars[THREAD_NUM_STATES+1] =
134 [0 ... THREAD_NUM_STATES] = '?',
135 [STATE_RUNNING] = 'R',
136 [STATE_BLOCKED] = 'B',
137 [STATE_SLEEPING] = 'S',
138 [STATE_BLOCKED_W_TMO] = 'T',
139 [STATE_FROZEN] = 'F',
140 [STATE_KILLED] = 'K',
143 if (status > THREAD_NUM_STATES)
144 status = THREAD_NUM_STATES;
146 return thread_status_chars[status];
149 static const char* threads_getname(int selected_item, void *data,
150 char *buffer, size_t buffer_len)
152 (void)data;
153 struct thread_entry *thread;
154 char name[32];
156 #if NUM_CORES > 1
157 if (selected_item < (int)NUM_CORES)
159 snprintf(buffer, buffer_len, "Idle (%d): %2d%%", selected_item,
160 idle_stack_usage(selected_item));
161 return buffer;
164 selected_item -= NUM_CORES;
165 #endif
167 thread = &threads[selected_item];
169 if (thread->state == STATE_KILLED)
171 snprintf(buffer, buffer_len, "%2d: ---", selected_item);
172 return buffer;
175 thread_get_name(name, 32, thread);
177 snprintf(buffer, buffer_len,
178 "%2d: " IF_COP("(%d) ") "%c%c " IF_PRIO("%d %d ") "%2d%% %s",
179 selected_item,
180 IF_COP(thread->core,)
181 #ifdef HAVE_SCHEDULER_BOOSTCTRL
182 (thread->cpu_boost) ? '+' :
183 #endif
184 ((thread->state == STATE_RUNNING) ? '*' : ' '),
185 thread_status_char(thread->state),
186 IF_PRIO(thread->base_priority, thread->priority, )
187 thread_stack_usage(thread), name);
189 return buffer;
192 static int dbg_threads_action_callback(int action, struct gui_synclist *lists)
194 (void)lists;
195 #ifdef ROCKBOX_HAS_LOGF
196 if (action == ACTION_STD_OK)
198 int selpos = gui_synclist_get_sel_pos(lists);
199 #if NUM_CORES > 1
200 if (selpos >= NUM_CORES)
201 remove_thread(threads[selpos - NUM_CORES].id);
202 #else
203 remove_thread(threads[selpos].id);
204 #endif
205 return ACTION_REDRAW;
207 #endif /* ROCKBOX_HAS_LOGF */
208 if (action == ACTION_NONE)
209 action = ACTION_REDRAW;
210 return action;
212 /* Test code!!! */
213 static bool dbg_os(void)
215 struct simplelist_info info;
216 simplelist_info_init(&info, IF_COP("Core and ") "Stack usage:",
217 #if NUM_CORES == 1
218 MAXTHREADS,
219 #else
220 MAXTHREADS+NUM_CORES,
221 #endif
222 NULL);
223 #ifndef ROCKBOX_HAS_LOGF
224 info.hide_selection = true;
225 info.scroll_all = true;
226 #endif
227 info.action_callback = dbg_threads_action_callback;
228 info.get_name = threads_getname;
229 return simplelist_show_list(&info);
232 #ifdef HAVE_LCD_BITMAP
233 #if CONFIG_CODEC != SWCODEC
234 #ifndef SIMULATOR
235 static bool dbg_audio_thread(void)
237 struct audio_debug d;
239 lcd_setfont(FONT_SYSFIXED);
241 while(1)
243 if (action_userabort(HZ/5))
244 return false;
246 audio_get_debugdata(&d);
248 lcd_clear_display();
250 lcd_putsf(0, 0, "read: %x", d.audiobuf_read);
251 lcd_putsf(0, 1, "write: %x", d.audiobuf_write);
252 lcd_putsf(0, 2, "swap: %x", d.audiobuf_swapwrite);
253 lcd_putsf(0, 3, "playing: %d", d.playing);
254 lcd_putsf(0, 4, "playable: %x", d.playable_space);
255 lcd_putsf(0, 5, "unswapped: %x", d.unswapped_space);
257 /* Playable space left */
258 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, 6*8, 112, 4, d.audiobuflen, 0,
259 d.playable_space, HORIZONTAL);
261 /* Show the watermark limit */
262 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, 6*8+4, 112, 4, d.audiobuflen, 0,
263 d.low_watermark_level, HORIZONTAL);
265 lcd_putsf(0, 7, "wm: %x - %x",
266 d.low_watermark_level, d.lowest_watermark_level);
268 lcd_update();
270 lcd_setfont(FONT_UI);
271 return false;
273 #endif /* !SIMULATOR */
274 #else /* CONFIG_CODEC == SWCODEC */
275 static unsigned int ticks, boost_ticks, freq_sum;
277 static void dbg_audio_task(void)
279 #ifndef SIMULATOR
280 if(FREQ > CPUFREQ_NORMAL)
281 boost_ticks++;
282 freq_sum += FREQ/1000000; /* in MHz */
283 #endif
284 ticks++;
287 static bool dbg_buffering_thread(void)
289 int button;
290 int line, i;
291 bool done = false;
292 size_t bufused;
293 size_t bufsize = pcmbuf_get_bufsize();
294 int pcmbufdescs = pcmbuf_descs();
295 struct buffering_debug d;
296 size_t filebuflen = audio_get_filebuflen();
297 /* This is a size_t, but call it a long so it puts a - when it's bad. */
299 ticks = boost_ticks = freq_sum = 0;
301 tick_add_task(dbg_audio_task);
303 FOR_NB_SCREENS(i)
304 screens[i].setfont(FONT_SYSFIXED);
306 while(!done)
308 button = get_action(CONTEXT_STD,HZ/5);
309 switch(button)
311 case ACTION_STD_NEXT:
312 audio_next();
313 break;
314 case ACTION_STD_PREV:
315 audio_prev();
316 break;
317 case ACTION_STD_CANCEL:
318 done = true;
319 break;
322 buffering_get_debugdata(&d);
323 bufused = bufsize - pcmbuf_free();
325 FOR_NB_SCREENS(i)
327 line = 0;
328 screens[i].clear_display();
331 screens[i].putsf(0, line++, "pcm: %6ld/%ld", (long) bufused, (long) bufsize);
333 gui_scrollbar_draw(&screens[i],0, line*8, screens[i].lcdwidth, 6,
334 bufsize, 0, bufused, HORIZONTAL);
335 line++;
337 screens[i].putsf(0, line++, "alloc: %6ld/%ld", audio_filebufused(),
338 (long) filebuflen);
340 #if LCD_HEIGHT > 80 || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_HEIGHT > 80)
341 if (screens[i].lcdheight > 80)
343 gui_scrollbar_draw(&screens[i],0, line*8, screens[i].lcdwidth, 6,
344 filebuflen, 0, audio_filebufused(), HORIZONTAL);
345 line++;
347 screens[i].putsf(0, line++, "real: %6ld/%ld", (long)d.buffered_data,
348 (long)filebuflen);
350 gui_scrollbar_draw(&screens[i],0, line*8, screens[i].lcdwidth, 6,
351 filebuflen, 0, (long)d.buffered_data, HORIZONTAL);
352 line++;
354 #endif
356 screens[i].putsf(0, line++, "usefl: %6ld/%ld", (long)(d.useful_data),
357 (long)filebuflen);
359 #if LCD_HEIGHT > 80 || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_HEIGHT > 80)
360 if (screens[i].lcdheight > 80)
362 gui_scrollbar_draw(&screens[i],0, line*8, screens[i].lcdwidth, 6,
363 filebuflen, 0, d.useful_data, HORIZONTAL);
364 line++;
366 #endif
368 screens[i].putsf(0, line++, "data_rem: %ld", (long)d.data_rem);
370 screens[i].putsf(0, line++, "track count: %2d", audio_track_count());
372 screens[i].putsf(0, line++, "handle count: %d", (int)d.num_handles);
374 #ifndef SIMULATOR
375 screens[i].putsf(0, line++, "cpu freq: %3dMHz",
376 (int)((FREQ + 500000) / 1000000));
377 #endif
379 if (ticks > 0)
381 int boostquota = boost_ticks * 1000 / ticks; /* in 0.1 % */
382 int avgclock = freq_sum * 10 / ticks; /* in 100 kHz */
383 screens[i].putsf(0, line++, "boost:%3d.%d%% (%d.%dMHz)",
384 boostquota/10, boostquota%10, avgclock/10, avgclock%10);
387 screens[i].putsf(0, line++, "pcmbufdesc: %2d/%2d",
388 pcmbuf_used_descs(), pcmbufdescs);
389 screens[i].putsf(0, line++, "watermark: %6d",
390 (int)(d.watermark));
392 screens[i].update();
396 tick_remove_task(dbg_audio_task);
398 FOR_NB_SCREENS(i)
399 screens[i].setfont(FONT_UI);
401 return false;
403 #endif /* CONFIG_CODEC */
404 #endif /* HAVE_LCD_BITMAP */
407 #if (CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE))
408 /* Tool function to read the flash manufacturer and type, if available.
409 Only chips which could be reprogrammed in system will return values.
410 (The mode switch addresses vary between flash manufacturers, hence addr1/2) */
411 /* In IRAM to avoid problems when running directly from Flash */
412 static bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
413 unsigned addr1, unsigned addr2)
414 ICODE_ATTR __attribute__((noinline));
415 static bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
416 unsigned addr1, unsigned addr2)
419 unsigned not_manu, not_id; /* read values before switching to ID mode */
420 unsigned manu, id; /* read values when in ID mode */
422 #if CONFIG_CPU == SH7034
423 volatile unsigned char* flash = (unsigned char*)0x2000000; /* flash mapping */
424 #elif defined(CPU_COLDFIRE)
425 volatile unsigned short* flash = (unsigned short*)0; /* flash mapping */
426 #endif
427 int old_level; /* saved interrupt level */
429 not_manu = flash[0]; /* read the normal content */
430 not_id = flash[1]; /* should be 'A' (0x41) and 'R' (0x52) from the "ARCH" marker */
432 /* disable interrupts, prevent any stray flash access */
433 old_level = disable_irq_save();
435 flash[addr1] = 0xAA; /* enter command mode */
436 flash[addr2] = 0x55;
437 flash[addr1] = 0x90; /* ID command */
438 /* Atmel wants 20ms pause here */
439 /* sleep(HZ/50); no sleeping possible while interrupts are disabled */
441 manu = flash[0]; /* read the IDs */
442 id = flash[1];
444 flash[0] = 0xF0; /* reset flash (back to normal read mode) */
445 /* Atmel wants 20ms pause here */
446 /* sleep(HZ/50); no sleeping possible while interrupts are disabled */
448 restore_irq(old_level); /* enable interrupts again */
450 /* I assume success if the obtained values are different from
451 the normal flash content. This is not perfectly bulletproof, they
452 could theoretically be the same by chance, causing us to fail. */
453 if (not_manu != manu || not_id != id) /* a value has changed */
455 *p_manufacturer = manu; /* return the results */
456 *p_device = id;
457 return true; /* success */
459 return false; /* fail */
461 #endif /* (CONFIG_CPU == SH7034 || CPU_COLDFIRE) */
463 #ifndef SIMULATOR
464 #ifdef CPU_PP
465 static int perfcheck(void)
467 int result;
469 asm (
470 "mrs r2, CPSR \n"
471 "orr r0, r2, #0xc0 \n" /* disable IRQ and FIQ */
472 "msr CPSR_c, r0 \n"
473 "mov %[res], #0 \n"
474 "ldr r0, [%[timr]] \n"
475 "add r0, r0, %[tmo] \n"
476 "1: \n"
477 "add %[res], %[res], #1 \n"
478 "ldr r1, [%[timr]] \n"
479 "cmp r1, r0 \n"
480 "bmi 1b \n"
481 "msr CPSR_c, r2 \n" /* reset IRQ and FIQ state */
483 [res]"=&r"(result)
485 [timr]"r"(&USEC_TIMER),
486 [tmo]"r"(
487 #if CONFIG_CPU == PP5002
488 16000
489 #else /* PP5020/5022/5024 */
490 10226
491 #endif
494 "r0", "r1", "r2"
496 return result;
498 #endif
500 #ifdef HAVE_LCD_BITMAP
501 static bool dbg_hw_info(void)
503 #if CONFIG_CPU == SH7034
504 int bitmask = HW_MASK;
505 int rom_version = ROM_VERSION;
506 unsigned manu, id; /* flash IDs */
507 bool got_id; /* flag if we managed to get the flash IDs */
508 unsigned rom_crc = 0xffffffff; /* CRC32 of the boot ROM */
509 bool has_bootrom; /* flag for boot ROM present */
510 int oldmode; /* saved memory guard mode */
512 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
514 /* get flash ROM type */
515 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
516 if (!got_id)
517 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
519 /* check if the boot ROM area is a flash mirror */
520 has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0);
521 if (has_bootrom) /* if ROM and Flash different */
523 /* calculate CRC16 checksum of boot ROM */
524 rom_crc = crc_32((unsigned char*)0x0000, 64*1024, 0xffffffff);
527 system_memory_guard(oldmode); /* re-enable memory guard */
529 lcd_setfont(FONT_SYSFIXED);
530 lcd_clear_display();
532 lcd_puts(0, 0, "[Hardware info]");
534 lcd_putsf(0, 1, "ROM: %d.%02d", rom_version/100, rom_version%100);
536 lcd_putsf(0, 2, "Mask: 0x%04x", bitmask);
538 if (got_id)
539 lcd_putsf(0, 3, "Flash: M=%02x D=%02x", manu, id);
540 else
541 lcd_puts(0, 3, "Flash: M=?? D=??"); /* unknown, sorry */
543 if (has_bootrom)
545 if (rom_crc == 0x56DBA4EE) /* known Version 1 */
546 lcd_puts(0, 4, "Boot ROM: V1");
547 else
548 lcd_putsf(0, 4, "ROMcrc: 0x%08x", rom_crc);
550 else
552 lcd_puts(0, 4, "Boot ROM: none");
555 lcd_update();
557 while (!(action_userabort(TIMEOUT_BLOCK)));
559 #elif CONFIG_CPU == MCF5249 || CONFIG_CPU == MCF5250
560 unsigned manu, id; /* flash IDs */
561 int got_id; /* flag if we managed to get the flash IDs */
562 int oldmode; /* saved memory guard mode */
563 int line = 0;
565 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
567 /* get flash ROM type */
568 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
569 if (!got_id)
570 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
572 system_memory_guard(oldmode); /* re-enable memory guard */
574 lcd_setfont(FONT_SYSFIXED);
575 lcd_clear_display();
577 lcd_puts(0, line++, "[Hardware info]");
579 if (got_id)
580 lcd_putsf(0, line++, "Flash: M=%04x D=%04x", manu, id);
581 else
582 lcd_puts(0, line++, "Flash: M=???? D=????"); /* unknown, sorry */
584 #ifdef IAUDIO_X5
586 struct ds2411_id id;
588 lcd_puts(0, ++line, "Serial Number:");
590 got_id = ds2411_read_id(&id);
592 if (got_id == DS2411_OK)
594 lcd_putsf(0, ++line, " FC=%02x", (unsigned)id.family_code);
595 lcd_putsf(0, ++line, " ID=%02X %02X %02X %02X %02X %02X",
596 (unsigned)id.uid[0], (unsigned)id.uid[1], (unsigned)id.uid[2],
597 (unsigned)id.uid[3], (unsigned)id.uid[4], (unsigned)id.uid[5]);
598 lcd_putsf(0, ++line, " CRC=%02X", (unsigned)id.crc);
600 else
602 lcd_putsf(0, ++line, "READ ERR=%d", got_id);
605 #endif
607 lcd_update();
609 while (!(action_userabort(TIMEOUT_BLOCK)));
611 #elif defined(CPU_PP502x)
612 int line = 0;
613 char pp_version[] = { (PP_VER2 >> 24) & 0xff, (PP_VER2 >> 16) & 0xff,
614 (PP_VER2 >> 8) & 0xff, (PP_VER2) & 0xff,
615 (PP_VER1 >> 24) & 0xff, (PP_VER1 >> 16) & 0xff,
616 (PP_VER1 >> 8) & 0xff, (PP_VER1) & 0xff, '\0' };
618 lcd_setfont(FONT_SYSFIXED);
619 lcd_clear_display();
621 lcd_puts(0, line++, "[Hardware info]");
623 #ifdef IPOD_ARCH
624 lcd_putsf(0, line++, "HW rev: 0x%08lx", IPOD_HW_REVISION);
625 #endif
627 #ifdef IPOD_COLOR
628 extern int lcd_type; /* Defined in lcd-colornano.c */
630 lcd_putsf(0, line++, "LCD type: %d", lcd_type);
631 #endif
633 lcd_putsf(0, line++, "PP version: %s", pp_version);
635 lcd_putsf(0, line++, "Est. clock (kHz): %d", perfcheck());
637 lcd_update();
639 while (!(action_userabort(TIMEOUT_BLOCK)));
641 #elif CONFIG_CPU == PP5002
642 int line = 0;
643 char pp_version[] = { (PP_VER4 >> 8) & 0xff, PP_VER4 & 0xff,
644 (PP_VER3 >> 8) & 0xff, PP_VER3 & 0xff,
645 (PP_VER2 >> 8) & 0xff, PP_VER2 & 0xff,
646 (PP_VER1 >> 8) & 0xff, PP_VER1 & 0xff, '\0' };
649 lcd_setfont(FONT_SYSFIXED);
650 lcd_clear_display();
652 lcd_puts(0, line++, "[Hardware info]");
654 #ifdef IPOD_ARCH
655 lcd_putsf(0, line++, "HW rev: 0x%08lx", IPOD_HW_REVISION);
656 #endif
658 lcd_putsf(0, line++, "PP version: %s", pp_version);
660 lcd_putsf(0, line++, "Est. clock (kHz): %d", perfcheck());
662 lcd_update();
664 while (!(action_userabort(TIMEOUT_BLOCK)));
666 #else
667 /* Define this function in your target tree */
668 return __dbg_hw_info();
669 #endif /* CONFIG_CPU */
670 lcd_setfont(FONT_UI);
671 return false;
673 #else /* !HAVE_LCD_BITMAP */
674 static bool dbg_hw_info(void)
676 int button;
677 int currval = 0;
678 int rom_version = ROM_VERSION;
679 unsigned manu, id; /* flash IDs */
680 bool got_id; /* flag if we managed to get the flash IDs */
681 unsigned rom_crc = 0xffffffff; /* CRC32 of the boot ROM */
682 bool has_bootrom; /* flag for boot ROM present */
683 int oldmode; /* saved memory guard mode */
685 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
687 /* get flash ROM type */
688 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
689 if (!got_id)
690 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
692 /* check if the boot ROM area is a flash mirror */
693 has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0);
694 if (has_bootrom) /* if ROM and Flash different */
696 /* calculate CRC16 checksum of boot ROM */
697 rom_crc = crc_32((unsigned char*)0x0000, 64*1024, 0xffffffff);
700 system_memory_guard(oldmode); /* re-enable memory guard */
702 lcd_clear_display();
704 lcd_puts(0, 0, "[HW Info]");
705 while(1)
707 switch(currval)
709 case 0:
710 lcd_putsf(0, 1, "ROM: %d.%02d",
711 rom_version/100, rom_version%100);
712 break;
713 case 1:
714 if (got_id)
715 lcd_putsf(0, 1, "Flash:%02x,%02x", manu, id);
716 else
717 lcd_puts(0, 1, "Flash:??,??"); /* unknown, sorry */
718 break;
719 case 2:
720 if (has_bootrom)
722 if (rom_crc == 0x56DBA4EE) /* known Version 1 */
723 lcd_puts(0, 1, "BootROM: V1");
724 else if (rom_crc == 0x358099E8)
725 lcd_puts(0, 1, "BootROM: V2");
726 /* alternative boot ROM found in one single player so far */
727 else
728 lcd_putsf(0, 1, "R: %08x", rom_crc);
730 else
731 lcd_puts(0, 1, "BootROM: no");
734 lcd_update();
736 button = get_action(CONTEXT_SETTINGS,TIMEOUT_BLOCK);
738 switch(button)
740 case ACTION_STD_CANCEL:
741 return false;
743 case ACTION_SETTINGS_DEC:
744 currval--;
745 if(currval < 0)
746 currval = 2;
747 break;
749 case ACTION_SETTINGS_INC:
750 currval++;
751 if(currval > 2)
752 currval = 0;
753 break;
756 return false;
758 #endif /* !HAVE_LCD_BITMAP */
759 #endif /* !SIMULATOR */
761 #ifndef SIMULATOR
762 static const char* dbg_partitions_getname(int selected_item, void *data,
763 char *buffer, size_t buffer_len)
765 (void)data;
766 int partition = selected_item/2;
767 struct partinfo* p = disk_partinfo(partition);
768 if (selected_item%2)
770 snprintf(buffer, buffer_len, " T:%x %ld MB", p->type, p->size / ( 2048 / ( SECTOR_SIZE / 512 )));
772 else
774 snprintf(buffer, buffer_len, "P%d: S:%lx", partition, p->start);
776 return buffer;
779 bool dbg_partitions(void)
781 struct simplelist_info info;
782 simplelist_info_init(&info, "Partition Info", 4, NULL);
783 info.selection_size = 2;
784 info.hide_selection = true;
785 info.scroll_all = true;
786 info.get_name = dbg_partitions_getname;
787 return simplelist_show_list(&info);
789 #endif
791 #if defined(CPU_COLDFIRE) && defined(HAVE_SPDIF_OUT)
792 static bool dbg_spdif(void)
794 int line;
795 unsigned int control;
796 int x;
797 char *s;
798 int category;
799 int generation;
800 unsigned int interruptstat;
801 bool valnogood, symbolerr, parityerr;
802 bool done = false;
803 bool spdif_src_on;
804 int spdif_source = spdif_get_output_source(&spdif_src_on);
805 spdif_set_output_source(AUDIO_SRC_SPDIF IF_SPDIF_POWER_(, true));
807 lcd_clear_display();
808 lcd_setfont(FONT_SYSFIXED);
810 #ifdef HAVE_SPDIF_POWER
811 spdif_power_enable(true); /* We need SPDIF power for both sending & receiving */
812 #endif
814 while (!done)
816 line = 0;
818 control = EBU1RCVCCHANNEL1;
819 interruptstat = INTERRUPTSTAT;
820 INTERRUPTCLEAR = 0x03c00000;
822 valnogood = (interruptstat & 0x01000000)?true:false;
823 symbolerr = (interruptstat & 0x00800000)?true:false;
824 parityerr = (interruptstat & 0x00400000)?true:false;
826 lcd_putsf(0, line++, "Val: %s Sym: %s Par: %s",
827 valnogood?"--":"OK",
828 symbolerr?"--":"OK",
829 parityerr?"--":"OK");
831 lcd_putsf(0, line++, "Status word: %08x", (int)control);
833 line++;
835 x = control >> 31;
836 lcd_putsf(0, line++, "PRO: %d (%s)",
837 x, x?"Professional":"Consumer");
839 x = (control >> 30) & 1;
840 lcd_putsf(0, line++, "Audio: %d (%s)",
841 x, x?"Non-PCM":"PCM");
843 x = (control >> 29) & 1;
844 lcd_putsf(0, line++, "Copy: %d (%s)",
845 x, x?"Permitted":"Inhibited");
847 x = (control >> 27) & 7;
848 switch(x)
850 case 0:
851 s = "None";
852 break;
853 case 1:
854 s = "50/15us";
855 break;
856 default:
857 s = "Reserved";
858 break;
860 lcd_putsf(0, line++, "Preemphasis: %d (%s)", x, s);
862 x = (control >> 24) & 3;
863 lcd_putsf(0, line++, "Mode: %d", x);
865 category = (control >> 17) & 127;
866 switch(category)
868 case 0x00:
869 s = "General";
870 break;
871 case 0x40:
872 s = "Audio CD";
873 break;
874 default:
875 s = "Unknown";
877 lcd_putsf(0, line++, "Category: 0x%02x (%s)", category, s);
879 x = (control >> 16) & 1;
880 generation = x;
881 if(((category & 0x70) == 0x10) ||
882 ((category & 0x70) == 0x40) ||
883 ((category & 0x78) == 0x38))
885 generation = !generation;
887 lcd_putsf(0, line++, "Generation: %d (%s)",
888 x, generation?"Original":"No ind.");
890 x = (control >> 12) & 15;
891 lcd_putsf(0, line++, "Source: %d", x);
894 x = (control >> 8) & 15;
895 switch(x)
897 case 0:
898 s = "Unspecified";
899 break;
900 case 8:
901 s = "A (Left)";
902 break;
903 case 4:
904 s = "B (Right)";
905 break;
906 default:
907 s = "";
908 break;
910 lcd_putsf(0, line++, "Channel: %d (%s)", x, s);
912 x = (control >> 4) & 15;
913 switch(x)
915 case 0:
916 s = "44.1kHz";
917 break;
918 case 0x4:
919 s = "48kHz";
920 break;
921 case 0xc:
922 s = "32kHz";
923 break;
925 lcd_putsf(0, line++, "Frequency: %d (%s)", x, s);
927 x = (control >> 2) & 3;
928 lcd_putsf(0, line++, "Clock accuracy: %d", x);
929 line++;
931 #ifndef SIMULATOR
932 lcd_putsf(0, line++, "Measured freq: %ldHz",
933 spdif_measure_frequency());
934 #endif
936 lcd_update();
938 if (action_userabort(HZ/10))
939 break;
942 spdif_set_output_source(spdif_source IF_SPDIF_POWER_(, spdif_src_on));
944 #ifdef HAVE_SPDIF_POWER
945 spdif_power_enable(global_settings.spdif_enable);
946 #endif
948 lcd_setfont(FONT_UI);
949 return false;
951 #endif /* CPU_COLDFIRE */
953 #ifndef SIMULATOR
954 #ifdef HAVE_LCD_BITMAP
955 /* button definitions */
956 #if (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
957 (CONFIG_KEYPAD == IRIVER_H300_PAD)
958 # define DEBUG_CANCEL BUTTON_OFF
960 #elif CONFIG_KEYPAD == RECORDER_PAD
961 # define DEBUG_CANCEL BUTTON_OFF
963 #elif CONFIG_KEYPAD == ONDIO_PAD
964 # define DEBUG_CANCEL BUTTON_MENU
966 #elif (CONFIG_KEYPAD == IPOD_1G2G_PAD) || \
967 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
968 (CONFIG_KEYPAD == IPOD_4G_PAD)
969 # define DEBUG_CANCEL BUTTON_MENU
971 #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
972 # define DEBUG_CANCEL BUTTON_PLAY
974 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
975 # define DEBUG_CANCEL BUTTON_REC
977 #elif (CONFIG_KEYPAD == IAUDIO_M3_PAD)
978 # define DEBUG_CANCEL BUTTON_RC_REC
980 #elif (CONFIG_KEYPAD == IRIVER_H10_PAD)
981 # define DEBUG_CANCEL BUTTON_REW
983 #elif (CONFIG_KEYPAD == MROBE100_PAD)
984 # define DEBUG_CANCEL BUTTON_MENU
986 #elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \
987 (CONFIG_KEYPAD == SANSA_C200_PAD) || \
988 (CONFIG_KEYPAD == SANSA_FUZE_PAD)
989 # define DEBUG_CANCEL BUTTON_LEFT
991 /* This is temporary until the SA9200 touchpad works */
992 #elif (CONFIG_KEYPAD == PHILIPS_SA9200_PAD) || \
993 (CONFIG_KEYPAD == PHILIPS_HDD1630_PAD) || \
994 (CONFIG_KEYPAD == PHILIPS_HDD6330_PAD)
995 # define DEBUG_CANCEL BUTTON_POWER
997 #elif (CONFIG_KEYPAD == SAMSUNG_YH_PAD)
998 # define DEBUG_CANCEL BUTTON_PLAY
1000 #elif (CONFIG_KEYPAD == PBELL_VIBE500_PAD)
1001 # define DEBUG_CANCEL BUTTON_CANCEL
1003 #elif (CONFIG_KEYPAD == MPIO_HD200_PAD)
1004 # define DEBUG_CANCEL BUTTON_REC
1006 #endif /* key definitions */
1008 /* Test code!!! */
1009 bool dbg_ports(void)
1011 #if CONFIG_CPU == SH7034
1012 int adc_battery_voltage, adc_battery_level;
1014 lcd_setfont(FONT_SYSFIXED);
1015 lcd_clear_display();
1017 while(1)
1019 lcd_putsf(0, 0, "PADR: %04x", (unsigned short)PADR);
1020 lcd_putsf(0, 1, "PBDR: %04x", (unsigned short)PBDR);
1022 lcd_putsf(0, 2, "AN0: %03x AN4: %03x", adc_read(0), adc_read(4));
1023 lcd_putsf(0, 3, "AN1: %03x AN5: %03x", adc_read(1), adc_read(5));
1024 lcd_putsf(0, 4, "AN2: %03x AN6: %03x", adc_read(2), adc_read(6));
1025 lcd_putsf(0, 5, "AN3: %03x AN7: %03x", adc_read(3), adc_read(7));
1027 battery_read_info(&adc_battery_voltage, &adc_battery_level);
1028 lcd_putsf(0, 6, "Batt: %d.%03dV %d%% ", adc_battery_voltage / 1000,
1029 adc_battery_voltage % 1000, adc_battery_level);
1031 lcd_update();
1032 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1034 lcd_setfont(FONT_UI);
1035 return false;
1038 #elif defined(CPU_COLDFIRE)
1039 unsigned int gpio_out;
1040 unsigned int gpio1_out;
1041 unsigned int gpio_read;
1042 unsigned int gpio1_read;
1043 unsigned int gpio_function;
1044 unsigned int gpio1_function;
1045 unsigned int gpio_enable;
1046 unsigned int gpio1_enable;
1047 int adc_buttons, adc_remote;
1048 int adc_battery_voltage, adc_battery_level;
1049 int line;
1051 lcd_clear_display();
1052 lcd_setfont(FONT_SYSFIXED);
1054 while(1)
1056 line = 0;
1057 gpio_read = GPIO_READ;
1058 gpio1_read = GPIO1_READ;
1059 gpio_out = GPIO_OUT;
1060 gpio1_out = GPIO1_OUT;
1061 gpio_function = GPIO_FUNCTION;
1062 gpio1_function = GPIO1_FUNCTION;
1063 gpio_enable = GPIO_ENABLE;
1064 gpio1_enable = GPIO1_ENABLE;
1066 lcd_putsf(0, line++, "GPIO_READ: %08x", gpio_read);
1067 lcd_putsf(0, line++, "GPIO_OUT: %08x", gpio_out);
1068 lcd_putsf(0, line++, "GPIO_FUNC: %08x", gpio_function);
1069 lcd_putsf(0, line++, "GPIO_ENA: %08x", gpio_enable);
1071 lcd_putsf(0, line++, "GPIO1_READ: %08x", gpio1_read);
1072 lcd_putsf(0, line++, "GPIO1_OUT: %08x", gpio1_out);
1073 lcd_putsf(0, line++, "GPIO1_FUNC: %08x", gpio1_function);
1074 lcd_putsf(0, line++, "GPIO1_ENA: %08x", gpio1_enable);
1076 adc_buttons = adc_read(ADC_BUTTONS);
1077 adc_remote = adc_read(ADC_REMOTE);
1078 battery_read_info(&adc_battery_voltage, &adc_battery_level);
1079 #if defined(IAUDIO_X5) || defined(IAUDIO_M5) || defined(IRIVER_H300_SERIES)
1080 lcd_putsf(0, line++, "ADC_BUTTONS (%c): %02x",
1081 button_scan_enabled() ? '+' : '-', adc_buttons);
1082 #else
1083 lcd_putsf(0, line++, "ADC_BUTTONS: %02x", adc_buttons);
1084 #endif
1085 #if defined(IAUDIO_X5) || defined(IAUDIO_M5)
1086 lcd_putsf(0, line++, "ADC_REMOTE (%c): %02x",
1087 remote_detect() ? '+' : '-', adc_remote);
1088 #else
1089 lcd_putsf(0, line++, "ADC_REMOTE: %02x", adc_remote);
1090 #endif
1091 #if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES)
1092 lcd_putsf(0, line++, "ADC_REMOTEDETECT: %02x",
1093 adc_read(ADC_REMOTEDETECT));
1094 #endif
1096 lcd_putsf(0, line++, "Batt: %d.%03dV %d%% ", adc_battery_voltage / 1000,
1097 adc_battery_voltage % 1000, adc_battery_level);
1099 #if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES)
1100 lcd_putsf(0, line++, "remotetype: %d", remote_type());
1101 #endif
1103 lcd_update();
1104 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1106 lcd_setfont(FONT_UI);
1107 return false;
1111 #elif defined(CPU_PP502x)
1112 int line;
1114 lcd_clear_display();
1115 lcd_setfont(FONT_SYSFIXED);
1117 while(1)
1119 line = 0;
1120 #if (LCD_HEIGHT >= 176) /* Only for displays with appropriate height. */
1121 lcd_puts(0, line++, "GPIO ENABLE:");
1122 lcd_putsf(0, line++, "A: %02x E: %02x I: %02x",
1123 (unsigned int)GPIOA_ENABLE,
1124 (unsigned int)GPIOE_ENABLE,
1125 (unsigned int)GPIOI_ENABLE);
1126 lcd_putsf(0, line++, "B: %02x F: %02x J: %02x",
1127 (unsigned int)GPIOB_ENABLE,
1128 (unsigned int)GPIOF_ENABLE,
1129 (unsigned int)GPIOJ_ENABLE);
1130 lcd_putsf(0, line++, "C: %02x G: %02x K: %02x",
1131 (unsigned int)GPIOC_ENABLE,
1132 (unsigned int)GPIOG_ENABLE,
1133 (unsigned int)GPIOK_ENABLE);
1134 lcd_putsf(0, line++, "D: %02x H: %02x L: %02x",
1135 (unsigned int)GPIOD_ENABLE,
1136 (unsigned int)GPIOH_ENABLE,
1137 (unsigned int)GPIOL_ENABLE);
1138 line++;
1139 #endif
1140 lcd_puts(0, line++, "GPIO INPUT VAL:");
1141 lcd_putsf(0, line++, "A: %02x E: %02x I: %02x",
1142 (unsigned int)GPIOA_INPUT_VAL,
1143 (unsigned int)GPIOE_INPUT_VAL,
1144 (unsigned int)GPIOI_INPUT_VAL);
1145 lcd_putsf(0, line++, "B: %02x F: %02x J: %02x",
1146 (unsigned int)GPIOB_INPUT_VAL,
1147 (unsigned int)GPIOF_INPUT_VAL,
1148 (unsigned int)GPIOJ_INPUT_VAL);
1149 lcd_putsf(0, line++, "C: %02x G: %02x K: %02x",
1150 (unsigned int)GPIOC_INPUT_VAL,
1151 (unsigned int)GPIOG_INPUT_VAL,
1152 (unsigned int)GPIOK_INPUT_VAL);
1153 lcd_putsf(0, line++, "D: %02x H: %02x L: %02x",
1154 (unsigned int)GPIOD_INPUT_VAL,
1155 (unsigned int)GPIOH_INPUT_VAL,
1156 (unsigned int)GPIOL_INPUT_VAL);
1157 line++;
1158 lcd_putsf(0, line++, "GPO32_VAL: %08lx", GPO32_VAL);
1159 lcd_putsf(0, line++, "GPO32_EN: %08lx", GPO32_ENABLE);
1160 lcd_putsf(0, line++, "DEV_EN: %08lx", DEV_EN);
1161 lcd_putsf(0, line++, "DEV_EN2: %08lx", DEV_EN2);
1162 lcd_putsf(0, line++, "DEV_EN3: %08lx", inl(0x60006044)); /* to be verified */
1163 lcd_putsf(0, line++, "DEV_INIT1: %08lx", DEV_INIT1);
1164 lcd_putsf(0, line++, "DEV_INIT2: %08lx", DEV_INIT2);
1165 #ifdef ADC_ACCESSORY
1166 lcd_putsf(0, line++, "ACCESSORY: %d", adc_read(ADC_ACCESSORY));
1167 #endif
1168 #ifdef IPOD_VIDEO
1169 lcd_putsf(0, line++, "4066_ISTAT: %d", adc_read(ADC_4066_ISTAT));
1170 #endif
1172 #if defined(IPOD_ACCESSORY_PROTOCOL)
1173 extern unsigned char serbuf[];
1174 lcd_putsf(0, line++, "IAP PACKET: %02x %02x %02x %02x %02x %02x %02x %02x",
1175 serbuf[0], serbuf[1], serbuf[2], serbuf[3], serbuf[4], serbuf[5],
1176 serbuf[6], serbuf[7]);
1177 #endif
1179 #if defined(IRIVER_H10) || defined(IRIVER_H10_5GB)
1180 line++;
1181 lcd_putsf(0, line++, "BATT: %03x UNK1: %03x",
1182 adc_read(ADC_BATTERY), adc_read(ADC_UNKNOWN_1));
1183 lcd_putsf(0, line++, "REM: %03x PAD: %03x",
1184 adc_read(ADC_REMOTE), adc_read(ADC_SCROLLPAD));
1185 #elif defined(PHILIPS_HDD1630) || defined(PHILIPS_HDD6330)
1186 line++;
1187 lcd_putsf(0, line++, "BATT: %03x UNK1: %03x",
1188 adc_read(ADC_BATTERY), adc_read(ADC_UNKNOWN_1));
1189 #elif defined(SANSA_E200) || defined(PHILIPS_SA9200)
1190 lcd_putsf(0, line++, "ADC_BVDD: %4d", adc_read(ADC_BVDD));
1191 lcd_putsf(0, line++, "ADC_RTCSUP: %4d", adc_read(ADC_RTCSUP));
1192 lcd_putsf(0, line++, "ADC_UVDD: %4d", adc_read(ADC_UVDD));
1193 lcd_putsf(0, line++, "ADC_CHG_IN: %4d", adc_read(ADC_CHG_IN));
1194 lcd_putsf(0, line++, "ADC_CVDD: %4d", adc_read(ADC_CVDD));
1195 lcd_putsf(0, line++, "ADC_BATTEMP: %4d", adc_read(ADC_BATTEMP));
1196 lcd_putsf(0, line++, "ADC_MICSUP1: %4d", adc_read(ADC_MICSUP1));
1197 lcd_putsf(0, line++, "ADC_MICSUP2: %4d", adc_read(ADC_MICSUP2));
1198 lcd_putsf(0, line++, "ADC_VBE1: %4d", adc_read(ADC_VBE1));
1199 lcd_putsf(0, line++, "ADC_VBE2: %4d", adc_read(ADC_VBE2));
1200 lcd_putsf(0, line++, "ADC_I_MICSUP1:%4d", adc_read(ADC_I_MICSUP1));
1201 #if !defined(PHILIPS_SA9200)
1202 lcd_putsf(0, line++, "ADC_I_MICSUP2:%4d", adc_read(ADC_I_MICSUP2));
1203 lcd_putsf(0, line++, "ADC_VBAT: %4d", adc_read(ADC_VBAT));
1204 #endif
1205 #endif
1206 lcd_update();
1207 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1209 lcd_setfont(FONT_UI);
1210 return false;
1214 #elif CONFIG_CPU == PP5002
1215 int line;
1217 lcd_clear_display();
1218 lcd_setfont(FONT_SYSFIXED);
1220 while(1)
1222 line = 0;
1223 lcd_putsf(0, line++, "GPIO_A: %02x GPIO_B: %02x",
1224 (unsigned int)GPIOA_INPUT_VAL, (unsigned int)GPIOB_INPUT_VAL);
1225 lcd_putsf(0, line++, "GPIO_C: %02x GPIO_D: %02x",
1226 (unsigned int)GPIOC_INPUT_VAL, (unsigned int)GPIOD_INPUT_VAL);
1228 lcd_putsf(0, line++, "DEV_EN: %08lx", DEV_EN);
1229 lcd_putsf(0, line++, "CLOCK_ENABLE: %08lx", CLOCK_ENABLE);
1230 lcd_putsf(0, line++, "CLOCK_SOURCE: %08lx", CLOCK_SOURCE);
1231 lcd_putsf(0, line++, "PLL_CONTROL: %08lx", PLL_CONTROL);
1232 lcd_putsf(0, line++, "PLL_DIV: %08lx", PLL_DIV);
1233 lcd_putsf(0, line++, "PLL_MULT: %08lx", PLL_MULT);
1234 lcd_putsf(0, line++, "TIMING1_CTL: %08lx", TIMING1_CTL);
1235 lcd_putsf(0, line++, "TIMING2_CTL: %08lx", TIMING2_CTL);
1237 lcd_update();
1238 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1240 lcd_setfont(FONT_UI);
1241 return false;
1244 lcd_setfont(FONT_UI);
1245 #else
1246 return __dbg_ports();
1247 #endif /* CPU */
1248 return false;
1250 #else /* !HAVE_LCD_BITMAP */
1251 bool dbg_ports(void)
1253 char buf[32];
1254 int button;
1255 int adc_battery_voltage;
1256 int currval = 0;
1258 lcd_clear_display();
1260 while(1)
1262 switch(currval)
1264 case 0:
1265 snprintf(buf, 32, "PADR: %04x", (unsigned short)PADR);
1266 break;
1267 case 1:
1268 snprintf(buf, 32, "PBDR: %04x", (unsigned short)PBDR);
1269 break;
1270 case 2:
1271 snprintf(buf, 32, "AN0: %03x", adc_read(0));
1272 break;
1273 case 3:
1274 snprintf(buf, 32, "AN1: %03x", adc_read(1));
1275 break;
1276 case 4:
1277 snprintf(buf, 32, "AN2: %03x", adc_read(2));
1278 break;
1279 case 5:
1280 snprintf(buf, 32, "AN3: %03x", adc_read(3));
1281 break;
1282 case 6:
1283 snprintf(buf, 32, "AN4: %03x", adc_read(4));
1284 break;
1285 case 7:
1286 snprintf(buf, 32, "AN5: %03x", adc_read(5));
1287 break;
1288 case 8:
1289 snprintf(buf, 32, "AN6: %03x", adc_read(6));
1290 break;
1291 case 9:
1292 snprintf(buf, 32, "AN7: %03x", adc_read(7));
1293 break;
1295 lcd_puts(0, 0, buf);
1297 battery_read_info(&adc_battery_voltage, NULL);
1298 lcd_putsf(0, 1, "Batt: %d.%03dV", adc_battery_voltage / 1000,
1299 adc_battery_voltage % 1000);
1300 lcd_update();
1302 button = get_action(CONTEXT_SETTINGS,HZ/5);
1304 switch(button)
1306 case ACTION_STD_CANCEL:
1307 return false;
1309 case ACTION_SETTINGS_DEC:
1310 currval--;
1311 if(currval < 0)
1312 currval = 9;
1313 break;
1315 case ACTION_SETTINGS_INC:
1316 currval++;
1317 if(currval > 9)
1318 currval = 0;
1319 break;
1322 return false;
1324 #endif /* !HAVE_LCD_BITMAP */
1325 #endif /* !SIMULATOR */
1327 #if (CONFIG_RTC == RTC_PCF50605) && !defined(SIMULATOR)
1328 static bool dbg_pcf(void)
1330 int line;
1332 #ifdef HAVE_LCD_BITMAP
1333 lcd_setfont(FONT_SYSFIXED);
1334 #endif
1335 lcd_clear_display();
1337 while(1)
1339 line = 0;
1341 lcd_putsf(0, line++, "DCDC1: %02x", pcf50605_read(0x1b));
1342 lcd_putsf(0, line++, "DCDC2: %02x", pcf50605_read(0x1c));
1343 lcd_putsf(0, line++, "DCDC3: %02x", pcf50605_read(0x1d));
1344 lcd_putsf(0, line++, "DCDC4: %02x", pcf50605_read(0x1e));
1345 lcd_putsf(0, line++, "DCDEC1: %02x", pcf50605_read(0x1f));
1346 lcd_putsf(0, line++, "DCDEC2: %02x", pcf50605_read(0x20));
1347 lcd_putsf(0, line++, "DCUDC1: %02x", pcf50605_read(0x21));
1348 lcd_putsf(0, line++, "DCUDC2: %02x", pcf50605_read(0x22));
1349 lcd_putsf(0, line++, "IOREGC: %02x", pcf50605_read(0x23));
1350 lcd_putsf(0, line++, "D1REGC: %02x", pcf50605_read(0x24));
1351 lcd_putsf(0, line++, "D2REGC: %02x", pcf50605_read(0x25));
1352 lcd_putsf(0, line++, "D3REGC: %02x", pcf50605_read(0x26));
1353 lcd_putsf(0, line++, "LPREG1: %02x", pcf50605_read(0x27));
1354 lcd_update();
1355 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1357 lcd_setfont(FONT_UI);
1358 return false;
1362 lcd_setfont(FONT_UI);
1363 return false;
1365 #endif
1367 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
1368 static bool dbg_cpufreq(void)
1370 int line;
1371 int button;
1373 #ifdef HAVE_LCD_BITMAP
1374 lcd_setfont(FONT_SYSFIXED);
1375 #endif
1376 lcd_clear_display();
1378 while(1)
1380 line = 0;
1382 lcd_putsf(0, line++, "Frequency: %ld", FREQ);
1383 lcd_putsf(0, line++, "boost_counter: %d", get_cpu_boost_counter());
1385 lcd_update();
1386 button = get_action(CONTEXT_STD,HZ/10);
1388 switch(button)
1390 case ACTION_STD_PREV:
1391 cpu_boost(true);
1392 break;
1394 case ACTION_STD_NEXT:
1395 cpu_boost(false);
1396 break;
1398 case ACTION_STD_OK:
1399 while (get_cpu_boost_counter() > 0)
1400 cpu_boost(false);
1401 set_cpu_frequency(CPUFREQ_DEFAULT);
1402 break;
1404 case ACTION_STD_CANCEL:
1405 lcd_setfont(FONT_UI);
1406 return false;
1409 lcd_setfont(FONT_UI);
1410 return false;
1412 #endif /* HAVE_ADJUSTABLE_CPU_FREQ */
1414 #if defined(HAVE_TSC2100) && !defined(SIMULATOR)
1415 #include "tsc2100.h"
1416 static char *itob(int n, int len)
1418 static char binary[64];
1419 int i,j;
1420 for (i=1, j=0;i<=len;i++)
1422 binary[j++] = n&(1<<(len-i))?'1':'0';
1423 if (i%4 == 0)
1424 binary[j++] = ' ';
1426 binary[j] = '\0';
1427 return binary;
1430 static const char* tsc2100_debug_getname(int selected_item, void * data,
1431 char *buffer, size_t buffer_len)
1433 int *page = (int*)data;
1434 bool reserved = false;
1435 switch (*page)
1437 case 0:
1438 if ((selected_item > 0x0a) ||
1439 (selected_item == 0x04) ||
1440 (selected_item == 0x08))
1441 reserved = true;
1442 break;
1443 case 1:
1444 if ((selected_item > 0x05) ||
1445 (selected_item == 0x02))
1446 reserved = true;
1447 break;
1448 case 2:
1449 if (selected_item > 0x1e)
1450 reserved = true;
1451 break;
1453 if (reserved)
1454 snprintf(buffer, buffer_len, "%02x: RESERVED", selected_item);
1455 else
1456 snprintf(buffer, buffer_len, "%02x: %s", selected_item,
1457 itob(tsc2100_readreg(*page, selected_item)&0xffff,16));
1458 return buffer;
1460 static int tsc2100debug_action_callback(int action, struct gui_synclist *lists)
1462 int *page = (int*)lists->data;
1463 if (action == ACTION_STD_OK)
1465 *page = (*page+1)%3;
1466 snprintf(lists->title, 32,
1467 "tsc2100 registers - Page %d", *page);
1468 return ACTION_REDRAW;
1470 return action;
1472 static bool tsc2100_debug(void)
1474 int page = 0;
1475 char title[32] = "tsc2100 registers - Page 0";
1476 struct simplelist_info info;
1477 simplelist_info_init(&info, title, 32, &page);
1478 info.timeout = HZ/100;
1479 info.get_name = tsc2100_debug_getname;
1480 info.action_callback= tsc2100debug_action_callback;
1481 return simplelist_show_list(&info);
1483 #endif
1484 #ifndef SIMULATOR
1485 #ifdef HAVE_LCD_BITMAP
1487 * view_battery() shows a automatically scaled graph of the battery voltage
1488 * over time. Usable for estimating battery life / charging rate.
1489 * The power_history array is updated in power_thread of powermgmt.c.
1492 #define BAT_LAST_VAL MIN(LCD_WIDTH, POWER_HISTORY_LEN)
1493 #define BAT_YSPACE (LCD_HEIGHT - 20)
1495 static bool view_battery(void)
1497 int view = 0;
1498 int i, x, y;
1499 unsigned short maxv, minv;
1501 lcd_setfont(FONT_SYSFIXED);
1503 while(1)
1505 lcd_clear_display();
1506 switch (view) {
1507 case 0: /* voltage history graph */
1508 /* Find maximum and minimum voltage for scaling */
1509 minv = power_history[0];
1510 maxv = minv + 1;
1511 for (i = 1; i < BAT_LAST_VAL && power_history[i]; i++) {
1512 if (power_history[i] > maxv)
1513 maxv = power_history[i];
1514 if (power_history[i] < minv)
1515 minv = power_history[i];
1518 lcd_putsf(0, 0, "Battery %d.%03d", power_history[0] / 1000,
1519 power_history[0] % 1000);
1520 lcd_putsf(0, 1, "scale %d.%03d-%d.%03dV",
1521 minv / 1000, minv % 1000, maxv / 1000, maxv % 1000);
1523 x = 0;
1524 for (i = BAT_LAST_VAL - 1; i >= 0; i--) {
1525 y = (power_history[i] - minv) * BAT_YSPACE / (maxv - minv);
1526 lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
1527 lcd_vline(x, LCD_HEIGHT-1, 20);
1528 lcd_set_drawmode(DRMODE_SOLID);
1529 lcd_vline(x, LCD_HEIGHT-1,
1530 MIN(MAX(LCD_HEIGHT-1 - y, 20), LCD_HEIGHT-1));
1531 x++;
1534 break;
1536 case 1: /* status: */
1537 #if CONFIG_CHARGING >= CHARGING_MONITOR
1538 lcd_putsf(0, 0, "Pwr status: %s",
1539 charging_state() ? "charging" : "discharging");
1540 #else
1541 lcd_puts(0, 0, "Power status:");
1542 #endif
1543 battery_read_info(&y, NULL);
1544 lcd_putsf(0, 1, "Battery: %d.%03d V", y / 1000, y % 1000);
1545 #ifdef ADC_EXT_POWER
1546 y = (adc_read(ADC_EXT_POWER) * EXT_SCALE_FACTOR) / 1000;
1547 lcd_putsf(0, 2, "External: %d.%03d V", y / 1000, y % 1000);
1548 #endif
1549 #if CONFIG_CHARGING
1550 #if defined ARCHOS_RECORDER
1551 lcd_putsf(0, 3, "Chgr: %s %s",
1552 charger_inserted() ? "present" : "absent",
1553 charger_enabled() ? "on" : "off");
1554 lcd_putsf(0, 5, "short delta: %d", short_delta);
1555 lcd_putsf(0, 6, "long delta: %d", long_delta);
1556 lcd_puts(0, 7, power_message);
1557 lcd_putsf(0, 8, "USB Inserted: %s",
1558 usb_inserted() ? "yes" : "no");
1559 #elif defined IRIVER_H300_SERIES
1560 lcd_putsf(0, 9, "USB Charging Enabled: %s",
1561 usb_charging_enabled() ? "yes" : "no");
1562 #elif defined IPOD_NANO || defined IPOD_VIDEO
1563 int usb_pwr = (GPIOL_INPUT_VAL & 0x10)?true:false;
1564 int ext_pwr = (GPIOL_INPUT_VAL & 0x08)?false:true;
1565 int dock = (GPIOA_INPUT_VAL & 0x10)?true:false;
1566 int charging = (GPIOB_INPUT_VAL & 0x01)?false:true;
1567 int headphone= (GPIOA_INPUT_VAL & 0x80)?true:false;
1569 lcd_putsf(0, 3, "USB pwr: %s",
1570 usb_pwr ? "present" : "absent");
1571 lcd_putsf(0, 4, "EXT pwr: %s",
1572 ext_pwr ? "present" : "absent");
1573 lcd_putsf(0, 5, "Battery: %s",
1574 charging ? "charging" : (usb_pwr||ext_pwr) ? "charged" : "discharging");
1575 lcd_putsf(0, 6, "Dock mode: %s",
1576 dock ? "enabled" : "disabled");
1577 lcd_putsf(0, 7, "Headphone: %s",
1578 headphone ? "connected" : "disconnected");
1579 #ifdef IPOD_VIDEO
1580 x = (adc_read(ADC_4066_ISTAT) * 2400) /
1581 #if MEM == 64
1582 (1024 * 2);
1583 #else
1584 (1024 * 3);
1585 #endif
1586 lcd_putsf(0, 8, "Ibat: %d mA", x);
1587 lcd_putsf(0, 9, "Vbat * Ibat: %d mW", x * y / 1000);
1588 #endif
1589 #elif defined TOSHIBA_GIGABEAT_S
1590 int line = 3;
1591 unsigned int st;
1593 static const unsigned char * const chrgstate_strings[] =
1595 "Disabled",
1596 "Error",
1597 "Discharging",
1598 "Precharge",
1599 "Constant Voltage",
1600 "Constant Current",
1601 "<unknown>",
1604 lcd_putsf(0, line++, "Charger: %s",
1605 charger_inserted() ? "present" : "absent");
1607 st = power_input_status() &
1608 (POWER_INPUT_CHARGER | POWER_INPUT_BATTERY);
1609 lcd_putsf(0, line++, "%s%s",
1610 (st & POWER_INPUT_MAIN_CHARGER) ? " Main" : "",
1611 (st & POWER_INPUT_USB_CHARGER) ? " USB" : "");
1613 lcd_putsf(0, line++, "IUSB Max: %d", usb_allowed_current());
1615 y = ARRAYLEN(chrgstate_strings) - 1;
1617 switch (charge_state)
1619 case CHARGE_STATE_DISABLED: y--;
1620 case CHARGE_STATE_ERROR: y--;
1621 case DISCHARGING: y--;
1622 case TRICKLE: y--;
1623 case TOPOFF: y--;
1624 case CHARGING: y--;
1625 default:;
1628 lcd_putsf(0, line++, "State: %s", chrgstate_strings[y]);
1630 lcd_putsf(0, line++, "Battery Switch: %s",
1631 (st & POWER_INPUT_BATTERY) ? "On" : "Off");
1633 y = chrgraw_adc_voltage();
1634 lcd_putsf(0, line++, "CHRGRAW: %d.%03d V",
1635 y / 1000, y % 1000);
1637 y = application_supply_adc_voltage();
1638 lcd_putsf(0, line++, "BP : %d.%03d V",
1639 y / 1000, y % 1000);
1641 y = battery_adc_charge_current();
1642 if (y < 0) x = '-', y = -y;
1643 else x = ' ';
1644 lcd_putsf(0, line++, "CHRGISN:%c%d mA", x, y);
1646 y = cccv_regulator_dissipation();
1647 lcd_putsf(0, line++, "P CCCV : %d mW", y);
1649 y = battery_charge_current();
1650 if (y < 0) x = '-', y = -y;
1651 else x = ' ';
1652 lcd_putsf(0, line++, "I Charge:%c%d mA", x, y);
1654 y = battery_adc_temp();
1656 if (y != INT_MIN) {
1657 lcd_putsf(0, line++, "T Battery: %dC (%dF)", y,
1658 (9*y + 160) / 5);
1659 } else {
1660 /* Conversion disabled */
1661 lcd_puts(0, line++, "T Battery: ?");
1664 #elif defined(SANSA_E200) || defined(SANSA_C200) || CONFIG_CPU == AS3525 || \
1665 CONFIG_CPU == AS3525v2
1666 const int first = CHARGE_STATE_DISABLED;
1667 static const char * const chrgstate_strings[] =
1669 [CHARGE_STATE_DISABLED-first] = "Disabled",
1670 [CHARGE_STATE_ERROR-first] = "Error",
1671 [DISCHARGING-first] = "Discharging",
1672 [CHARGING-first] = "Charging",
1674 const char *str = NULL;
1676 lcd_putsf(0, 3, "Charger: %s",
1677 charger_inserted() ? "present" : "absent");
1679 y = charge_state - first;
1680 if ((unsigned)y < ARRAYLEN(chrgstate_strings))
1681 str = chrgstate_strings[y];
1683 lcd_putsf(0, 4, "State: %s",
1684 str ? str : "<unknown>");
1686 lcd_putsf(0, 5, "CHARGER: %02X", ascodec_read_charger());
1687 #elif defined(IPOD_NANO2G)
1688 y = pmu_read_battery_voltage();
1689 lcd_putsf(17, 1, "RAW: %d.%03d V", y / 1000, y % 1000);
1690 y = pmu_read_battery_current();
1691 lcd_putsf(0, 2, "Battery current: %d mA", y);
1692 lcd_putsf(0, 3, "PWRCON: %8x", PWRCON);
1693 lcd_putsf(0, 4, "PWRCONEXT: %8x", PWRCONEXT);
1694 x = pmu_read(0x1b) & 0xf;
1695 y = pmu_read(0x1a) * 25 + 625;
1696 lcd_putsf(0, 5, "AUTO: %x / %d mV", x, y);
1697 x = pmu_read(0x1f) & 0xf;
1698 y = pmu_read(0x1e) * 25 + 625;
1699 lcd_putsf(0, 6, "DOWN1: %x / %d mV", x, y);
1700 x = pmu_read(0x23) & 0xf;
1701 y = pmu_read(0x22) * 25 + 625;
1702 lcd_putsf(0, 7, "DOWN2: %x / %d mV", x, y);
1703 x = pmu_read(0x27) & 0xf;
1704 y = pmu_read(0x26) * 100 + 900;
1705 lcd_putsf(0, 8, "MEMLDO: %x / %d mV", x, y);
1706 for (i = 0; i < 6; i++)
1708 x = pmu_read(0x2e + (i << 1)) & 0xf;
1709 y = pmu_read(0x2d + (i << 1)) * 100 + 900;
1710 lcd_putsf(0, 9 + i, "LDO%d: %x / %d mV", i + 1, x, y);
1712 lcd_putsf(0, 15, "CLKCON: %8x", CLKCON);
1713 lcd_putsf(17, 15, "PLL0: %6x", PLL0PMS);
1714 #else
1715 lcd_putsf(0, 3, "Charger: %s",
1716 charger_inserted() ? "present" : "absent");
1717 #endif /* target type */
1718 #endif /* CONFIG_CHARGING */
1719 break;
1721 case 2: /* voltage deltas: */
1722 lcd_puts(0, 0, "Voltage deltas:");
1724 for (i = 0; i <= 6; i++) {
1725 y = power_history[i] - power_history[i+1];
1726 lcd_putsf(0, i+1, "-%d min: %s%d.%03d V", i,
1727 (y < 0) ? "-" : "", ((y < 0) ? y * -1 : y) / 1000,
1728 ((y < 0) ? y * -1 : y ) % 1000);
1730 break;
1732 case 3: /* remaining time estimation: */
1734 #ifdef ARCHOS_RECORDER
1735 lcd_putsf(0, 0, "charge_state: %d", charge_state);
1737 lcd_putsf(0, 1, "Cycle time: %d m", powermgmt_last_cycle_startstop_min);
1739 lcd_putsf(0, 2, "Lvl@cyc st: %d%%", powermgmt_last_cycle_level);
1741 lcd_putsf(0, 3, "P=%2d I=%2d", pid_p, pid_i);
1743 lcd_putsf(0, 4, "Trickle sec: %d/60", trickle_sec);
1744 #endif /* ARCHOS_RECORDER */
1746 lcd_putsf(0, 5, "Last PwrHist: %d.%03dV",
1747 power_history[0] / 1000,
1748 power_history[0] % 1000);
1750 lcd_putsf(0, 6, "battery level: %d%%", battery_level());
1752 lcd_putsf(0, 7, "Est. remain: %d m", battery_time());
1753 break;
1756 lcd_update();
1758 switch(get_action(CONTEXT_STD,HZ/2))
1760 case ACTION_STD_PREV:
1761 if (view)
1762 view--;
1763 break;
1765 case ACTION_STD_NEXT:
1766 if (view < 3)
1767 view++;
1768 break;
1770 case ACTION_STD_CANCEL:
1771 lcd_setfont(FONT_UI);
1772 return false;
1775 lcd_setfont(FONT_UI);
1776 return false;
1779 #endif /* HAVE_LCD_BITMAP */
1780 #endif
1782 #ifndef SIMULATOR
1783 #if (CONFIG_STORAGE & STORAGE_MMC) || (CONFIG_STORAGE & STORAGE_SD)
1785 #if (CONFIG_STORAGE & STORAGE_MMC)
1786 #define CARDTYPE "MMC"
1787 #elif (CONFIG_STORAGE & STORAGE_SD)
1788 #define CARDTYPE "microSD"
1789 #endif
1791 static int disk_callback(int btn, struct gui_synclist *lists)
1793 tCardInfo *card;
1794 int *cardnum = (int*)lists->data;
1795 unsigned char card_name[6];
1796 unsigned char pbuf[32];
1797 char *title = lists->title;
1798 static const unsigned char i_vmin[] = { 0, 1, 5, 10, 25, 35, 60, 100 };
1799 static const unsigned char i_vmax[] = { 1, 5, 10, 25, 35, 45, 80, 200 };
1800 static const unsigned char * const kbit_units[] = { "kBit/s", "MBit/s", "GBit/s" };
1801 static const unsigned char * const nsec_units[] = { "ns", "µs", "ms" };
1802 #if (CONFIG_STORAGE & STORAGE_MMC)
1803 static const char * const mmc_spec_vers[] = { "1.0-1.2", "1.4", "2.0-2.2",
1804 "3.1-3.31", "4.0" };
1805 #endif
1807 if ((btn == ACTION_STD_OK) || (btn == SYS_FS_CHANGED) || (btn == ACTION_REDRAW))
1809 #ifdef HAVE_HOTSWAP
1810 if (btn == ACTION_STD_OK)
1812 *cardnum ^= 0x1; /* change cards */
1814 #endif
1816 simplelist_set_line_count(0);
1818 card = card_get_info(*cardnum);
1820 if (card->initialized > 0)
1822 unsigned i;
1823 for (i=0; i<sizeof(card_name); i++)
1825 card_name[i] = card_extract_bits(card->cid, (103-8*i), 8);
1827 strlcpy(card_name, card_name, sizeof(card_name));
1828 simplelist_addline(SIMPLELIST_ADD_LINE,
1829 "%s Rev %d.%d", card_name,
1830 (int) card_extract_bits(card->cid, 63, 4),
1831 (int) card_extract_bits(card->cid, 59, 4));
1832 simplelist_addline(SIMPLELIST_ADD_LINE,
1833 "Prod: %d/%d",
1834 #if (CONFIG_STORAGE & STORAGE_SD)
1835 (int) card_extract_bits(card->cid, 11, 4),
1836 (int) card_extract_bits(card->cid, 19, 8) + 2000
1837 #elif (CONFIG_STORAGE & STORAGE_MMC)
1838 (int) card_extract_bits(card->cid, 15, 4),
1839 (int) card_extract_bits(card->cid, 11, 4) + 1997
1840 #endif
1842 simplelist_addline(SIMPLELIST_ADD_LINE,
1843 #if (CONFIG_STORAGE & STORAGE_SD)
1844 "Ser#: 0x%08lx",
1845 card_extract_bits(card->cid, 55, 32)
1846 #elif (CONFIG_STORAGE & STORAGE_MMC)
1847 "Ser#: 0x%04lx",
1848 card_extract_bits(card->cid, 47, 16)
1849 #endif
1852 simplelist_addline(SIMPLELIST_ADD_LINE, "M=%02x, "
1853 #if (CONFIG_STORAGE & STORAGE_SD)
1854 "O=%c%c",
1855 (int) card_extract_bits(card->cid, 127, 8),
1856 card_extract_bits(card->cid, 119, 8),
1857 card_extract_bits(card->cid, 111, 8)
1858 #elif (CONFIG_STORAGE & STORAGE_MMC)
1859 "O=%04x",
1860 (int) card_extract_bits(card->cid, 127, 8),
1861 (int) card_extract_bits(card->cid, 119, 16)
1862 #endif
1865 #if (CONFIG_STORAGE & STORAGE_MMC)
1866 int temp = card_extract_bits(card->csd, 125, 4);
1867 simplelist_addline(SIMPLELIST_ADD_LINE,
1868 "MMC v%s", temp < 5 ?
1869 mmc_spec_vers[temp] : "?.?");
1870 #endif
1871 simplelist_addline(SIMPLELIST_ADD_LINE,
1872 "Blocks: 0x%08lx", card->numblocks);
1873 output_dyn_value(pbuf, sizeof pbuf, card->speed / 1000,
1874 kbit_units, false);
1875 simplelist_addline(SIMPLELIST_ADD_LINE,
1876 "Speed: %s", pbuf);
1877 output_dyn_value(pbuf, sizeof pbuf, card->taac,
1878 nsec_units, false);
1879 simplelist_addline(SIMPLELIST_ADD_LINE,
1880 "Taac: %s", pbuf);
1881 simplelist_addline(SIMPLELIST_ADD_LINE,
1882 "Nsac: %d clk", card->nsac);
1883 simplelist_addline(SIMPLELIST_ADD_LINE,
1884 "R2W: *%d", card->r2w_factor);
1885 simplelist_addline(SIMPLELIST_ADD_LINE,
1886 "IRmax: %d..%d mA",
1887 i_vmin[card_extract_bits(card->csd, 61, 3)],
1888 i_vmax[card_extract_bits(card->csd, 58, 3)]);
1889 simplelist_addline(SIMPLELIST_ADD_LINE,
1890 "IWmax: %d..%d mA",
1891 i_vmin[card_extract_bits(card->csd, 55, 3)],
1892 i_vmax[card_extract_bits(card->csd, 52, 3)]);
1894 else if (card->initialized == 0)
1896 simplelist_addline(SIMPLELIST_ADD_LINE, "Not Found!");
1898 #if (CONFIG_STORAGE & STORAGE_SD)
1899 else /* card->initialized < 0 */
1901 simplelist_addline(SIMPLELIST_ADD_LINE, "Init Error! (%d)", card->initialized);
1903 #endif
1904 snprintf(title, 16, "[" CARDTYPE " %d]", *cardnum);
1905 gui_synclist_set_title(lists, title, Icon_NOICON);
1906 gui_synclist_set_nb_items(lists, simplelist_get_line_count());
1907 gui_synclist_select_item(lists, 0);
1908 btn = ACTION_REDRAW;
1910 return btn;
1912 #elif (CONFIG_STORAGE & STORAGE_ATA)
1913 static int disk_callback(int btn, struct gui_synclist *lists)
1915 (void)lists;
1916 int i;
1917 char buf[128];
1918 unsigned short* identify_info = ata_get_identify();
1919 bool timing_info_present = false;
1920 (void)btn;
1922 simplelist_set_line_count(0);
1924 for (i=0; i < 20; i++)
1925 ((unsigned short*)buf)[i]=htobe16(identify_info[i+27]);
1926 buf[40]=0;
1927 /* kill trailing space */
1928 for (i=39; i && buf[i]==' '; i--)
1929 buf[i] = 0;
1930 simplelist_addline(SIMPLELIST_ADD_LINE, "Model: %s", buf);
1931 for (i=0; i < 4; i++)
1932 ((unsigned short*)buf)[i]=htobe16(identify_info[i+23]);
1933 buf[8]=0;
1934 simplelist_addline(SIMPLELIST_ADD_LINE,
1935 "Firmware: %s", buf);
1936 snprintf(buf, sizeof buf, "%ld MB",
1937 ((unsigned long)identify_info[61] << 16 |
1938 (unsigned long)identify_info[60]) / 2048 );
1939 simplelist_addline(SIMPLELIST_ADD_LINE,
1940 "Size: %s", buf);
1941 unsigned long free;
1942 fat_size( IF_MV2(0,) NULL, &free );
1943 simplelist_addline(SIMPLELIST_ADD_LINE,
1944 "Free: %ld MB", free / 1024);
1945 simplelist_addline(SIMPLELIST_ADD_LINE,
1946 "Spinup time: %d ms", storage_spinup_time() * (1000/HZ));
1947 i = identify_info[83] & (1<<3);
1948 simplelist_addline(SIMPLELIST_ADD_LINE,
1949 "Power mgmt: %s", i ? "enabled" : "unsupported");
1950 i = identify_info[83] & (1<<9);
1951 simplelist_addline(SIMPLELIST_ADD_LINE,
1952 "Noise mgmt: %s", i ? "enabled" : "unsupported");
1953 i = identify_info[82] & (1<<6);
1954 simplelist_addline(SIMPLELIST_ADD_LINE,
1955 "Read-ahead: %s", i ? "enabled" : "unsupported");
1956 timing_info_present = identify_info[53] & (1<<1);
1957 if(timing_info_present) {
1958 char pio3[2], pio4[2];pio3[1] = 0;
1959 pio4[1] = 0;
1960 pio3[0] = (identify_info[64] & (1<<0)) ? '3' : 0;
1961 pio4[0] = (identify_info[64] & (1<<1)) ? '4' : 0;
1962 simplelist_addline(SIMPLELIST_ADD_LINE,
1963 "PIO modes: 0 1 2 %s %s", pio3, pio4);
1965 else {
1966 simplelist_addline(SIMPLELIST_ADD_LINE,
1967 "No PIO mode info");
1969 timing_info_present = identify_info[53] & (1<<1);
1970 if(timing_info_present) {
1971 simplelist_addline(SIMPLELIST_ADD_LINE,
1972 "Cycle times %dns/%dns",
1973 identify_info[67],
1974 identify_info[68] );
1975 } else {
1976 simplelist_addline(SIMPLELIST_ADD_LINE,
1977 "No timing info");
1979 int sector_size = 512;
1980 if((identify_info[106] & 0xe000) == 0x6000)
1981 sector_size *= BIT_N(identify_info[106] & 0x000f);
1982 simplelist_addline(SIMPLELIST_ADD_LINE,
1983 "Physical sector size: %d", sector_size);
1984 #ifdef HAVE_ATA_DMA
1985 if (identify_info[63] & (1<<0)) {
1986 char mdma0[2], mdma1[2], mdma2[2];
1987 mdma0[1] = mdma1[1] = mdma2[1] = 0;
1988 mdma0[0] = (identify_info[63] & (1<<0)) ? '0' : 0;
1989 mdma1[0] = (identify_info[63] & (1<<1)) ? '1' : 0;
1990 mdma2[0] = (identify_info[63] & (1<<2)) ? '2' : 0;
1991 simplelist_addline(SIMPLELIST_ADD_LINE,
1992 "MDMA modes: %s %s %s", mdma0, mdma1, mdma2);
1993 simplelist_addline(SIMPLELIST_ADD_LINE,
1994 "MDMA Cycle times %dns/%dns",
1995 identify_info[65],
1996 identify_info[66] );
1998 else {
1999 simplelist_addline(SIMPLELIST_ADD_LINE,
2000 "No MDMA mode info");
2002 if (identify_info[53] & (1<<2)) {
2003 char udma0[2], udma1[2], udma2[2], udma3[2], udma4[2], udma5[2], udma6[2];
2004 udma0[1] = udma1[1] = udma2[1] = udma3[1] = udma4[1] = udma5[1] = udma6[1] = 0;
2005 udma0[0] = (identify_info[88] & (1<<0)) ? '0' : 0;
2006 udma1[0] = (identify_info[88] & (1<<1)) ? '1' : 0;
2007 udma2[0] = (identify_info[88] & (1<<2)) ? '2' : 0;
2008 udma3[0] = (identify_info[88] & (1<<3)) ? '3' : 0;
2009 udma4[0] = (identify_info[88] & (1<<4)) ? '4' : 0;
2010 udma5[0] = (identify_info[88] & (1<<5)) ? '5' : 0;
2011 udma6[0] = (identify_info[88] & (1<<6)) ? '6' : 0;
2012 simplelist_addline(SIMPLELIST_ADD_LINE,
2013 "UDMA modes: %s %s %s %s %s %s %s", udma0, udma1, udma2,
2014 udma3, udma4, udma5, udma6);
2016 else {
2017 simplelist_addline(SIMPLELIST_ADD_LINE,
2018 "No UDMA mode info");
2020 #endif /* HAVE_ATA_DMA */
2021 timing_info_present = identify_info[53] & (1<<1);
2022 if(timing_info_present) {
2023 i = identify_info[49] & (1<<11);
2024 simplelist_addline(SIMPLELIST_ADD_LINE,
2025 "IORDY support: %s", i ? "yes" : "no");
2026 i = identify_info[49] & (1<<10);
2027 simplelist_addline(SIMPLELIST_ADD_LINE,
2028 "IORDY disable: %s", i ? "yes" : "no");
2029 } else {
2030 simplelist_addline(SIMPLELIST_ADD_LINE,
2031 "No timing info");
2033 simplelist_addline(SIMPLELIST_ADD_LINE,
2034 "Cluster size: %d bytes", fat_get_cluster_size(IF_MV(0)));
2035 #ifdef HAVE_ATA_DMA
2036 i = ata_get_dma_mode();
2037 if (i == 0) {
2038 simplelist_addline(SIMPLELIST_ADD_LINE,
2039 "DMA not enabled");
2040 } else {
2041 simplelist_addline(SIMPLELIST_ADD_LINE,
2042 "DMA mode: %s %c",
2043 (i & 0x40) ? "UDMA" : "MDMA",
2044 '0' + (i & 7));
2046 #endif /* HAVE_ATA_DMA */
2047 return btn;
2049 #else /* No SD, MMC or ATA */
2050 static int disk_callback(int btn, struct gui_synclist *lists)
2052 (void)btn;
2053 (void)lists;
2054 struct storage_info info;
2055 storage_get_info(0,&info);
2056 simplelist_addline(SIMPLELIST_ADD_LINE, "Vendor: %s", info.vendor);
2057 simplelist_addline(SIMPLELIST_ADD_LINE, "Model: %s", info.product);
2058 simplelist_addline(SIMPLELIST_ADD_LINE, "Firmware: %s", info.revision);
2059 simplelist_addline(SIMPLELIST_ADD_LINE,
2060 "Size: %ld MB", info.num_sectors*(info.sector_size/512)/2024);
2061 unsigned long free;
2062 fat_size( IF_MV2(0,) NULL, &free );
2063 simplelist_addline(SIMPLELIST_ADD_LINE,
2064 "Free: %ld MB", free / 1024);
2065 simplelist_addline(SIMPLELIST_ADD_LINE,
2066 "Cluster size: %d bytes", fat_get_cluster_size(IF_MV(0)));
2067 return btn;
2069 #endif
2071 #if (CONFIG_STORAGE & STORAGE_ATA)
2072 static bool dbg_identify_info(void)
2074 int fd = creat("/identify_info.bin", 0666);
2075 if(fd >= 0)
2077 #ifdef ROCKBOX_LITTLE_ENDIAN
2078 ecwrite(fd, ata_get_identify(), SECTOR_SIZE/2, "s", true);
2079 #else
2080 write(fd, ata_get_identify(), SECTOR_SIZE);
2081 #endif
2082 close(fd);
2084 return false;
2086 #endif
2088 static bool dbg_disk_info(void)
2090 struct simplelist_info info;
2091 simplelist_info_init(&info, "Disk Info", 1, NULL);
2092 #if (CONFIG_STORAGE & STORAGE_MMC) || (CONFIG_STORAGE & STORAGE_SD)
2093 char title[16];
2094 int card = 0;
2095 info.callback_data = (void*)&card;
2096 info.title = title;
2097 #endif
2098 info.action_callback = disk_callback;
2099 info.hide_selection = true;
2100 info.scroll_all = true;
2101 return simplelist_show_list(&info);
2103 #endif /* !SIMULATOR */
2105 #ifdef HAVE_DIRCACHE
2106 static int dircache_callback(int btn, struct gui_synclist *lists)
2108 (void)btn; (void)lists;
2109 simplelist_set_line_count(0);
2110 simplelist_addline(SIMPLELIST_ADD_LINE, "Cache initialized: %s",
2111 dircache_is_enabled() ? "Yes" : "No");
2112 simplelist_addline(SIMPLELIST_ADD_LINE, "Cache size: %d B",
2113 dircache_get_cache_size());
2114 simplelist_addline(SIMPLELIST_ADD_LINE, "Last size: %d B",
2115 global_status.dircache_size);
2116 simplelist_addline(SIMPLELIST_ADD_LINE, "Limit: %d B",
2117 DIRCACHE_LIMIT);
2118 simplelist_addline(SIMPLELIST_ADD_LINE, "Reserve: %d/%d B",
2119 dircache_get_reserve_used(), DIRCACHE_RESERVE);
2120 simplelist_addline(SIMPLELIST_ADD_LINE, "Scanning took: %d s",
2121 dircache_get_build_ticks() / HZ);
2122 simplelist_addline(SIMPLELIST_ADD_LINE, "Entry count: %d",
2123 dircache_get_entry_count());
2124 return btn;
2127 static bool dbg_dircache_info(void)
2129 struct simplelist_info info;
2130 simplelist_info_init(&info, "Dircache Info", 7, NULL);
2131 info.action_callback = dircache_callback;
2132 info.hide_selection = true;
2133 info.scroll_all = true;
2134 return simplelist_show_list(&info);
2137 #endif /* HAVE_DIRCACHE */
2139 #ifdef HAVE_TAGCACHE
2140 static int database_callback(int btn, struct gui_synclist *lists)
2142 (void)lists;
2143 struct tagcache_stat *stat = tagcache_get_stat();
2144 static bool synced = false;
2146 simplelist_set_line_count(0);
2148 simplelist_addline(SIMPLELIST_ADD_LINE, "Initialized: %s",
2149 stat->initialized ? "Yes" : "No");
2150 simplelist_addline(SIMPLELIST_ADD_LINE, "DB Ready: %s",
2151 stat->ready ? "Yes" : "No");
2152 simplelist_addline(SIMPLELIST_ADD_LINE, "RAM Cache: %s",
2153 stat->ramcache ? "Yes" : "No");
2154 simplelist_addline(SIMPLELIST_ADD_LINE, "RAM: %d/%d B",
2155 stat->ramcache_used, stat->ramcache_allocated);
2156 simplelist_addline(SIMPLELIST_ADD_LINE, "Progress: %d%% (%d entries)",
2157 stat->progress, stat->processed_entries);
2158 simplelist_addline(SIMPLELIST_ADD_LINE, "Curfile: %s",
2159 stat->curentry ? stat->curentry : "---");
2160 simplelist_addline(SIMPLELIST_ADD_LINE, "Commit step: %d",
2161 stat->commit_step);
2162 simplelist_addline(SIMPLELIST_ADD_LINE, "Commit delayed: %s",
2163 stat->commit_delayed ? "Yes" : "No");
2165 simplelist_addline(SIMPLELIST_ADD_LINE, "Queue length: %d",
2166 stat->queue_length);
2168 if (synced)
2170 synced = false;
2171 tagcache_screensync_event();
2174 if (!btn && stat->curentry)
2176 synced = true;
2177 return ACTION_REDRAW;
2180 if (btn == ACTION_STD_CANCEL)
2181 tagcache_screensync_enable(false);
2183 return btn;
2185 static bool dbg_tagcache_info(void)
2187 struct simplelist_info info;
2188 simplelist_info_init(&info, "Database Info", 8, NULL);
2189 info.action_callback = database_callback;
2190 info.hide_selection = true;
2191 info.scroll_all = true;
2193 /* Don't do nonblock here, must give enough processing time
2194 for tagcache thread. */
2195 /* info.timeout = TIMEOUT_NOBLOCK; */
2196 info.timeout = 1;
2197 tagcache_screensync_enable(true);
2198 return simplelist_show_list(&info);
2200 #endif
2202 #if CONFIG_CPU == SH7034
2203 static bool dbg_save_roms(void)
2205 int fd;
2206 int oldmode = system_memory_guard(MEMGUARD_NONE);
2208 fd = creat("/internal_rom_0000-FFFF.bin", 0666);
2209 if(fd >= 0)
2211 write(fd, (void *)0, 0x10000);
2212 close(fd);
2215 fd = creat("/internal_rom_2000000-203FFFF.bin", 0666);
2216 if(fd >= 0)
2218 write(fd, (void *)0x2000000, 0x40000);
2219 close(fd);
2222 system_memory_guard(oldmode);
2223 return false;
2225 #elif defined CPU_COLDFIRE
2226 static bool dbg_save_roms(void)
2228 int fd;
2229 int oldmode = system_memory_guard(MEMGUARD_NONE);
2231 #if defined(IRIVER_H100_SERIES)
2232 fd = creat("/internal_rom_000000-1FFFFF.bin", 0666);
2233 #elif defined(IRIVER_H300_SERIES)
2234 fd = creat("/internal_rom_000000-3FFFFF.bin", 0666);
2235 #elif defined(IAUDIO_X5) || defined(IAUDIO_M5) || defined(IAUDIO_M3)
2236 fd = creat("/internal_rom_000000-3FFFFF.bin", 0666);
2237 #elif defined(MPIO_HD200)
2238 fd = creat("/internal_rom_000000-1FFFFF.bin", 0666);
2239 #endif
2240 if(fd >= 0)
2242 write(fd, (void *)0, FLASH_SIZE);
2243 close(fd);
2245 system_memory_guard(oldmode);
2247 #ifdef HAVE_EEPROM
2248 fd = creat("/internal_eeprom.bin", 0666);
2249 if (fd >= 0)
2251 int old_irq_level;
2252 char buf[EEPROM_SIZE];
2253 int err;
2255 old_irq_level = disable_irq_save();
2257 err = eeprom_24cxx_read(0, buf, sizeof buf);
2259 restore_irq(old_irq_level);
2261 if (err)
2262 splashf(HZ*3, "Eeprom read failure (%d)", err);
2263 else
2265 write(fd, buf, sizeof buf);
2268 close(fd);
2270 #endif
2272 return false;
2274 #elif defined(CPU_PP) && !(CONFIG_STORAGE & STORAGE_SD)
2275 static bool dbg_save_roms(void)
2277 int fd;
2279 fd = creat("/internal_rom_000000-0FFFFF.bin", 0666);
2280 if(fd >= 0)
2282 write(fd, (void *)0x20000000, FLASH_SIZE);
2283 close(fd);
2286 return false;
2288 #elif CONFIG_CPU == IMX31L
2289 static bool dbg_save_roms(void)
2291 int fd;
2293 fd = creat("/flash_rom_A0000000-A01FFFFF.bin", 0666);
2294 if (fd >= 0)
2296 write(fd, (void*)0xa0000000, FLASH_SIZE);
2297 close(fd);
2300 return false;
2302 #elif defined(CPU_TCC780X)
2303 static bool dbg_save_roms(void)
2305 int fd;
2307 fd = creat("/eeprom_E0000000-E0001FFF.bin", 0666);
2308 if (fd >= 0)
2310 write(fd, (void*)0xe0000000, 0x2000);
2311 close(fd);
2314 return false;
2316 #endif /* CPU */
2318 #ifndef SIMULATOR
2319 #if CONFIG_TUNER
2320 static int radio_callback(int btn, struct gui_synclist *lists)
2322 (void)lists;
2323 if (btn == ACTION_STD_CANCEL)
2324 return btn;
2325 simplelist_set_line_count(1);
2327 #if (CONFIG_TUNER & LV24020LP)
2328 simplelist_addline(SIMPLELIST_ADD_LINE,
2329 "CTRL_STAT: %02X", lv24020lp_get(LV24020LP_CTRL_STAT) );
2330 simplelist_addline(SIMPLELIST_ADD_LINE,
2331 "RADIO_STAT: %02X", lv24020lp_get(LV24020LP_REG_STAT) );
2332 simplelist_addline(SIMPLELIST_ADD_LINE,
2333 "MSS_FM: %d kHz", lv24020lp_get(LV24020LP_MSS_FM) );
2334 simplelist_addline(SIMPLELIST_ADD_LINE,
2335 "MSS_IF: %d Hz", lv24020lp_get(LV24020LP_MSS_IF) );
2336 simplelist_addline(SIMPLELIST_ADD_LINE,
2337 "MSS_SD: %d Hz", lv24020lp_get(LV24020LP_MSS_SD) );
2338 simplelist_addline(SIMPLELIST_ADD_LINE,
2339 "if_set: %d Hz", lv24020lp_get(LV24020LP_IF_SET) );
2340 simplelist_addline(SIMPLELIST_ADD_LINE,
2341 "sd_set: %d Hz", lv24020lp_get(LV24020LP_SD_SET) );
2342 #endif /* LV24020LP */
2343 #if (CONFIG_TUNER & S1A0903X01)
2344 simplelist_addline(SIMPLELIST_ADD_LINE,
2345 "Samsung regs: %08X", s1a0903x01_get(RADIO_ALL));
2346 /* This one doesn't return dynamic data atm */
2347 #endif /* S1A0903X01 */
2348 #if (CONFIG_TUNER & TEA5767)
2349 struct tea5767_dbg_info nfo;
2350 tea5767_dbg_info(&nfo);
2351 simplelist_addline(SIMPLELIST_ADD_LINE, "Philips regs:");
2352 simplelist_addline(SIMPLELIST_ADD_LINE,
2353 " Read: %02X %02X %02X %02X %02X",
2354 (unsigned)nfo.read_regs[0], (unsigned)nfo.read_regs[1],
2355 (unsigned)nfo.read_regs[2], (unsigned)nfo.read_regs[3],
2356 (unsigned)nfo.read_regs[4]);
2357 simplelist_addline(SIMPLELIST_ADD_LINE,
2358 " Write: %02X %02X %02X %02X %02X",
2359 (unsigned)nfo.write_regs[0], (unsigned)nfo.write_regs[1],
2360 (unsigned)nfo.write_regs[2], (unsigned)nfo.write_regs[3],
2361 (unsigned)nfo.write_regs[4]);
2362 #endif /* TEA5767 */
2363 #if (CONFIG_TUNER & SI4700)
2364 struct si4700_dbg_info nfo;
2365 si4700_dbg_info(&nfo);
2366 simplelist_addline(SIMPLELIST_ADD_LINE, "SI4700 regs:");
2367 /* Registers */
2368 simplelist_addline(SIMPLELIST_ADD_LINE,
2369 "%04X %04X %04X %04X",
2370 (unsigned)nfo.regs[0], (unsigned)nfo.regs[1],
2371 (unsigned)nfo.regs[2], (unsigned)nfo.regs[3]);
2372 simplelist_addline(SIMPLELIST_ADD_LINE,
2373 "%04X %04X %04X %04X",
2374 (unsigned)nfo.regs[4], (unsigned)nfo.regs[5],
2375 (unsigned)nfo.regs[6], (unsigned)nfo.regs[7]);
2376 simplelist_addline(SIMPLELIST_ADD_LINE,
2377 "%04X %04X %04X %04X",
2378 (unsigned)nfo.regs[8], (unsigned)nfo.regs[9],
2379 (unsigned)nfo.regs[10], (unsigned)nfo.regs[11]);
2380 simplelist_addline(SIMPLELIST_ADD_LINE,
2381 "%04X %04X %04X %04X",
2382 (unsigned)nfo.regs[12], (unsigned)nfo.regs[13],
2383 (unsigned)nfo.regs[14], (unsigned)nfo.regs[15]);
2384 #endif /* SI4700 */
2385 return ACTION_REDRAW;
2387 static bool dbg_fm_radio(void)
2389 struct simplelist_info info;
2390 info.scroll_all = true;
2391 simplelist_info_init(&info, "FM Radio", 1, NULL);
2392 simplelist_set_line_count(0);
2393 simplelist_addline(SIMPLELIST_ADD_LINE, "HW detected: %s",
2394 radio_hardware_present() ? "yes" : "no");
2396 info.action_callback = radio_hardware_present()?radio_callback : NULL;
2397 info.hide_selection = true;
2398 return simplelist_show_list(&info);
2400 #endif /* CONFIG_TUNER */
2401 #endif /* !SIMULATOR */
2403 #ifdef HAVE_LCD_BITMAP
2404 extern bool do_screendump_instead_of_usb;
2406 static bool dbg_screendump(void)
2408 do_screendump_instead_of_usb = !do_screendump_instead_of_usb;
2409 splashf(HZ, "Screendump %s",
2410 do_screendump_instead_of_usb?"enabled":"disabled");
2411 return false;
2413 #endif /* HAVE_LCD_BITMAP */
2415 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
2416 static bool dbg_set_memory_guard(void)
2418 static const struct opt_items names[MAXMEMGUARD] = {
2419 { "None", -1 },
2420 { "Flash ROM writes", -1 },
2421 { "Zero area (all)", -1 }
2423 int mode = system_memory_guard(MEMGUARD_KEEP);
2425 set_option( "Catch mem accesses", &mode, INT, names, MAXMEMGUARD, NULL);
2426 system_memory_guard(mode);
2428 return false;
2430 #endif /* CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) */
2432 #if defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS)
2433 static bool dbg_write_eeprom(void)
2435 int fd;
2436 int rc;
2437 int old_irq_level;
2438 char buf[EEPROM_SIZE];
2439 int err;
2441 fd = open("/internal_eeprom.bin", O_RDONLY);
2443 if (fd >= 0)
2445 rc = read(fd, buf, EEPROM_SIZE);
2447 if(rc == EEPROM_SIZE)
2449 old_irq_level = disable_irq_save();
2451 err = eeprom_24cxx_write(0, buf, sizeof buf);
2452 if (err)
2453 splashf(HZ*3, "Eeprom write failure (%d)", err);
2454 else
2455 splash(HZ*3, "Eeprom written successfully");
2457 restore_irq(old_irq_level);
2459 else
2461 splashf(HZ*3, "File read error (%d)",rc);
2463 close(fd);
2465 else
2467 splash(HZ*3, "Failed to open 'internal_eeprom.bin'");
2470 return false;
2472 #endif /* defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS) */
2473 #ifdef CPU_BOOST_LOGGING
2474 static bool cpu_boost_log(void)
2476 int i = 0,j=0;
2477 int count = cpu_boost_log_getcount();
2478 int lines = LCD_HEIGHT/SYSFONT_HEIGHT;
2479 char *str;
2480 bool done;
2481 lcd_setfont(FONT_SYSFIXED);
2482 str = cpu_boost_log_getlog_first();
2483 while (i < count)
2485 lcd_clear_display();
2486 for(j=0; j<lines; j++,i++)
2488 if (!str)
2489 str = cpu_boost_log_getlog_next();
2490 if (str)
2492 if(strlen(str) > LCD_WIDTH/SYSFONT_WIDTH)
2493 lcd_puts_scroll(0, j, str);
2494 else
2495 lcd_puts(0, j,str);
2497 str = NULL;
2499 lcd_update();
2500 done = false;
2501 while (!done)
2503 switch(get_action(CONTEXT_STD,TIMEOUT_BLOCK))
2505 case ACTION_STD_OK:
2506 case ACTION_STD_PREV:
2507 case ACTION_STD_NEXT:
2508 done = true;
2509 break;
2510 case ACTION_STD_CANCEL:
2511 i = count;
2512 done = true;
2513 break;
2517 lcd_stop_scroll();
2518 get_action(CONTEXT_STD,TIMEOUT_BLOCK);
2519 lcd_setfont(FONT_UI);
2520 return false;
2522 #endif
2524 #if (defined(HAVE_WHEEL_ACCELERATION) && (CONFIG_KEYPAD==IPOD_4G_PAD) && !defined(SIMULATOR))
2525 extern bool wheel_is_touched;
2526 extern int old_wheel_value;
2527 extern int new_wheel_value;
2528 extern int wheel_delta;
2529 extern unsigned int accumulated_wheel_delta;
2530 extern unsigned int wheel_velocity;
2532 static bool dbg_scrollwheel(void)
2534 unsigned int speed;
2536 lcd_setfont(FONT_SYSFIXED);
2538 while (1)
2540 if (action_userabort(HZ/10))
2541 break;
2543 lcd_clear_display();
2545 /* show internal variables of scrollwheel driver */
2546 lcd_putsf(0, 0, "wheel touched: %s", (wheel_is_touched) ? "true" : "false");
2547 lcd_putsf(0, 1, "new position: %2d", new_wheel_value);
2548 lcd_putsf(0, 2, "old position: %2d", old_wheel_value);
2549 lcd_putsf(0, 3, "wheel delta: %2d", wheel_delta);
2550 lcd_putsf(0, 4, "accumulated delta: %2d", accumulated_wheel_delta);
2551 lcd_putsf(0, 5, "velo [deg/s]: %4d", (int)wheel_velocity);
2553 /* show effective accelerated scrollspeed */
2554 speed = button_apply_acceleration( (1<<31)|(1<<24)|wheel_velocity);
2555 lcd_putsf(0, 6, "accel. speed: %4d", speed);
2557 lcd_update();
2559 lcd_setfont(FONT_UI);
2560 return false;
2562 #endif
2564 #if defined (HAVE_USBSTACK)
2566 #if defined(ROCKBOX_HAS_LOGF) && defined(USB_ENABLE_SERIAL)
2567 static bool toggle_usb_core_driver(int driver, char *msg)
2569 bool enabled = !usb_core_driver_enabled(driver);
2571 usb_core_enable_driver(driver,enabled);
2572 splashf(HZ, "%s %s", msg, enabled?"enabled":"disabled");
2574 return false;
2577 static bool toggle_usb_serial(void)
2579 return toggle_usb_core_driver(USB_DRIVER_SERIAL,"USB Serial");
2581 #endif
2583 #endif
2585 #if CONFIG_USBOTG == USBOTG_ISP1583
2586 extern int dbg_usb_num_items(void);
2587 extern const char* dbg_usb_item(int selected_item, void *data,
2588 char *buffer, size_t buffer_len);
2590 static int isp1583_action_callback(int action, struct gui_synclist *lists)
2592 (void)lists;
2593 if (action == ACTION_NONE)
2594 action = ACTION_REDRAW;
2595 return action;
2598 static bool dbg_isp1583(void)
2600 struct simplelist_info isp1583;
2601 isp1583.scroll_all = true;
2602 simplelist_info_init(&isp1583, "ISP1583", dbg_usb_num_items(), NULL);
2603 isp1583.timeout = HZ/100;
2604 isp1583.hide_selection = true;
2605 isp1583.get_name = dbg_usb_item;
2606 isp1583.action_callback = isp1583_action_callback;
2607 return simplelist_show_list(&isp1583);
2609 #endif
2611 #if defined(CREATIVE_ZVx) && !defined(SIMULATOR)
2612 extern int pic_dbg_num_items(void);
2613 extern const char* pic_dbg_item(int selected_item, void *data,
2614 char *buffer, size_t buffer_len);
2616 static int pic_action_callback(int action, struct gui_synclist *lists)
2618 (void)lists;
2619 if (action == ACTION_NONE)
2620 action = ACTION_REDRAW;
2621 return action;
2624 static bool dbg_pic(void)
2626 struct simplelist_info pic;
2627 pic.scroll_all = true;
2628 simplelist_info_init(&pic, "PIC", pic_dbg_num_items(), NULL);
2629 pic.timeout = HZ/100;
2630 pic.hide_selection = true;
2631 pic.get_name = pic_dbg_item;
2632 pic.action_callback = pic_action_callback;
2633 return simplelist_show_list(&pic);
2635 #endif
2638 /****** The menu *********/
2639 struct the_menu_item {
2640 unsigned char *desc; /* string or ID */
2641 bool (*function) (void); /* return true if USB was connected */
2643 static const struct the_menu_item menuitems[] = {
2644 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || \
2645 (defined(CPU_PP) && !(CONFIG_STORAGE & STORAGE_SD)) || \
2646 CONFIG_CPU == IMX31L || defined(CPU_TCC780X)
2647 { "Dump ROM contents", dbg_save_roms },
2648 #endif
2649 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || defined(CPU_PP) \
2650 || CONFIG_CPU == S3C2440 || CONFIG_CPU == IMX31L || CONFIG_CPU == AS3525 \
2651 || CONFIG_CPU == DM320 || defined(CPU_S5L870X) || CONFIG_CPU == AS3525v2
2652 { "View I/O ports", dbg_ports },
2653 #endif
2654 #if (CONFIG_RTC == RTC_PCF50605) && !defined(SIMULATOR)
2655 { "View PCF registers", dbg_pcf },
2656 #endif
2657 #if defined(HAVE_TSC2100) && !defined(SIMULATOR)
2658 { "TSC2100 debug", tsc2100_debug },
2659 #endif
2660 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
2661 { "CPU frequency", dbg_cpufreq },
2662 #endif
2663 #if defined(IRIVER_H100_SERIES) && !defined(SIMULATOR)
2664 { "S/PDIF analyzer", dbg_spdif },
2665 #endif
2666 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
2667 { "Catch mem accesses", dbg_set_memory_guard },
2668 #endif
2669 { "View OS stacks", dbg_os },
2670 #ifdef HAVE_LCD_BITMAP
2671 #ifndef SIMULATOR
2672 { "View battery", view_battery },
2673 #endif
2674 { "Screendump", dbg_screendump },
2675 #endif
2676 #ifndef SIMULATOR
2677 { "View HW info", dbg_hw_info },
2678 #endif
2679 #ifndef SIMULATOR
2680 { "View partitions", dbg_partitions },
2681 #endif
2682 #ifndef SIMULATOR
2683 { "View disk info", dbg_disk_info },
2684 #if (CONFIG_STORAGE & STORAGE_ATA)
2685 { "Dump ATA identify info", dbg_identify_info},
2686 #endif
2687 #endif
2688 #ifdef HAVE_DIRCACHE
2689 { "View dircache info", dbg_dircache_info },
2690 #endif
2691 #ifdef HAVE_TAGCACHE
2692 { "View database info", dbg_tagcache_info },
2693 #endif
2694 #ifdef HAVE_LCD_BITMAP
2695 #if CONFIG_CODEC == SWCODEC
2696 { "View buffering thread", dbg_buffering_thread },
2697 #elif !defined(SIMULATOR)
2698 { "View audio thread", dbg_audio_thread },
2699 #endif
2700 #ifdef PM_DEBUG
2701 { "pm histogram", peak_meter_histogram},
2702 #endif /* PM_DEBUG */
2703 #endif /* HAVE_LCD_BITMAP */
2704 #ifndef SIMULATOR
2705 #if CONFIG_TUNER
2706 { "FM Radio", dbg_fm_radio },
2707 #endif
2708 #endif
2709 #if defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS)
2710 { "Write back EEPROM", dbg_write_eeprom },
2711 #endif
2712 #if CONFIG_USBOTG == USBOTG_ISP1583
2713 { "View ISP1583 info", dbg_isp1583 },
2714 #endif
2715 #if defined(CREATIVE_ZVx) && !defined(SIMULATOR)
2716 { "View PIC info", dbg_pic },
2717 #endif
2718 #ifdef ROCKBOX_HAS_LOGF
2719 {"Show Log File", logfdisplay },
2720 {"Dump Log File", logfdump },
2721 #endif
2722 #if defined(HAVE_USBSTACK)
2723 #if defined(ROCKBOX_HAS_LOGF) && defined(USB_ENABLE_SERIAL)
2724 {"USB Serial driver (logf)", toggle_usb_serial },
2725 #endif
2726 #endif /* HAVE_USBSTACK */
2727 #ifdef CPU_BOOST_LOGGING
2728 {"cpu_boost log",cpu_boost_log},
2729 #endif
2730 #if (defined(HAVE_WHEEL_ACCELERATION) && (CONFIG_KEYPAD==IPOD_4G_PAD) && !defined(SIMULATOR))
2731 {"Debug scrollwheel", dbg_scrollwheel },
2732 #endif
2734 static int menu_action_callback(int btn, struct gui_synclist *lists)
2736 int i;
2737 if (btn == ACTION_STD_OK)
2739 FOR_NB_SCREENS(i)
2740 viewportmanager_theme_enable(i, false, NULL);
2741 menuitems[gui_synclist_get_sel_pos(lists)].function();
2742 btn = ACTION_REDRAW;
2743 FOR_NB_SCREENS(i)
2744 viewportmanager_theme_undo(i, false);
2746 return btn;
2749 static const char* dbg_menu_getname(int item, void * data,
2750 char *buffer, size_t buffer_len)
2752 (void)data; (void)buffer; (void)buffer_len;
2753 return menuitems[item].desc;
2756 bool debug_menu(void)
2758 struct simplelist_info info;
2760 simplelist_info_init(&info, "Debug Menu", ARRAYLEN(menuitems), NULL);
2761 info.action_callback = menu_action_callback;
2762 info.get_name = dbg_menu_getname;
2763 return simplelist_show_list(&info);