skin_engine: struct gui_skin can be static
[maemo-rb.git] / apps / debug_menu.c
blob94076bf64d81ff5cb6a35ab55338646712ff7763
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 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
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 "sdmmc.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 #if defined(IPOD_ACCESSORY_PROTOCOL)
126 #include "iap.h"
127 #endif
129 /*---------------------------------------------------*/
130 /* SPECIAL DEBUG STUFF */
131 /*---------------------------------------------------*/
132 extern struct thread_entry threads[MAXTHREADS];
134 static char thread_status_char(unsigned status)
136 static const char thread_status_chars[THREAD_NUM_STATES+1] =
138 [0 ... THREAD_NUM_STATES] = '?',
139 [STATE_RUNNING] = 'R',
140 [STATE_BLOCKED] = 'B',
141 [STATE_SLEEPING] = 'S',
142 [STATE_BLOCKED_W_TMO] = 'T',
143 [STATE_FROZEN] = 'F',
144 [STATE_KILLED] = 'K',
147 if (status > THREAD_NUM_STATES)
148 status = THREAD_NUM_STATES;
150 return thread_status_chars[status];
153 static const char* threads_getname(int selected_item, void *data,
154 char *buffer, size_t buffer_len)
156 (void)data;
157 struct thread_entry *thread;
158 char name[32];
160 #if NUM_CORES > 1
161 if (selected_item < (int)NUM_CORES)
163 snprintf(buffer, buffer_len, "Idle (%d): %2d%%", selected_item,
164 idle_stack_usage(selected_item));
165 return buffer;
168 selected_item -= NUM_CORES;
169 #endif
171 thread = &threads[selected_item];
173 if (thread->state == STATE_KILLED)
175 snprintf(buffer, buffer_len, "%2d: ---", selected_item);
176 return buffer;
179 thread_get_name(name, 32, thread);
181 snprintf(buffer, buffer_len,
182 "%2d: " IF_COP("(%d) ") "%c%c " IF_PRIO("%d %d ") "%2d%% %s",
183 selected_item,
184 IF_COP(thread->core,)
185 #ifdef HAVE_SCHEDULER_BOOSTCTRL
186 (thread->cpu_boost) ? '+' :
187 #endif
188 ((thread->state == STATE_RUNNING) ? '*' : ' '),
189 thread_status_char(thread->state),
190 IF_PRIO(thread->base_priority, thread->priority, )
191 thread_stack_usage(thread), name);
193 return buffer;
196 static int dbg_threads_action_callback(int action, struct gui_synclist *lists)
198 (void)lists;
199 #ifdef ROCKBOX_HAS_LOGF
200 if (action == ACTION_STD_OK)
202 int selpos = gui_synclist_get_sel_pos(lists);
203 #if NUM_CORES > 1
204 if (selpos >= NUM_CORES)
205 remove_thread(threads[selpos - NUM_CORES].id);
206 #else
207 remove_thread(threads[selpos].id);
208 #endif
209 return ACTION_REDRAW;
211 #endif /* ROCKBOX_HAS_LOGF */
212 if (action == ACTION_NONE)
213 action = ACTION_REDRAW;
214 return action;
216 /* Test code!!! */
217 static bool dbg_os(void)
219 struct simplelist_info info;
220 simplelist_info_init(&info, IF_COP("Core and ") "Stack usage:",
221 #if NUM_CORES == 1
222 MAXTHREADS,
223 #else
224 MAXTHREADS+NUM_CORES,
225 #endif
226 NULL);
227 #ifndef ROCKBOX_HAS_LOGF
228 info.hide_selection = true;
229 info.scroll_all = true;
230 #endif
231 info.action_callback = dbg_threads_action_callback;
232 info.get_name = threads_getname;
233 return simplelist_show_list(&info);
236 #ifdef HAVE_LCD_BITMAP
237 #if CONFIG_CODEC != SWCODEC
238 #ifndef SIMULATOR
239 static bool dbg_audio_thread(void)
241 struct audio_debug d;
243 lcd_setfont(FONT_SYSFIXED);
245 while(1)
247 if (action_userabort(HZ/5))
248 return false;
250 audio_get_debugdata(&d);
252 lcd_clear_display();
254 lcd_putsf(0, 0, "read: %x", d.audiobuf_read);
255 lcd_putsf(0, 1, "write: %x", d.audiobuf_write);
256 lcd_putsf(0, 2, "swap: %x", d.audiobuf_swapwrite);
257 lcd_putsf(0, 3, "playing: %d", d.playing);
258 lcd_putsf(0, 4, "playable: %x", d.playable_space);
259 lcd_putsf(0, 5, "unswapped: %x", d.unswapped_space);
261 /* Playable space left */
262 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, 6*8, 112, 4, d.audiobuflen, 0,
263 d.playable_space, HORIZONTAL);
265 /* Show the watermark limit */
266 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, 6*8+4, 112, 4, d.audiobuflen, 0,
267 d.low_watermark_level, HORIZONTAL);
269 lcd_putsf(0, 7, "wm: %x - %x",
270 d.low_watermark_level, d.lowest_watermark_level);
272 lcd_update();
274 lcd_setfont(FONT_UI);
275 return false;
277 #endif /* !SIMULATOR */
278 #else /* CONFIG_CODEC == SWCODEC */
279 static unsigned int ticks, boost_ticks, freq_sum;
281 static void dbg_audio_task(void)
283 #ifdef CPUFREQ_NORMAL
284 if(FREQ > CPUFREQ_NORMAL)
285 boost_ticks++;
286 freq_sum += FREQ/1000000; /* in MHz */
287 #endif
288 ticks++;
291 static bool dbg_buffering_thread(void)
293 int button;
294 int line, i;
295 bool done = false;
296 size_t bufused;
297 size_t bufsize = pcmbuf_get_bufsize();
298 int pcmbufdescs = pcmbuf_descs();
299 struct buffering_debug d;
300 size_t filebuflen = audio_get_filebuflen();
301 /* This is a size_t, but call it a long so it puts a - when it's bad. */
303 ticks = boost_ticks = freq_sum = 0;
305 tick_add_task(dbg_audio_task);
307 FOR_NB_SCREENS(i)
308 screens[i].setfont(FONT_SYSFIXED);
310 while(!done)
312 button = get_action(CONTEXT_STD,HZ/5);
313 switch(button)
315 case ACTION_STD_NEXT:
316 audio_next();
317 break;
318 case ACTION_STD_PREV:
319 audio_prev();
320 break;
321 case ACTION_STD_CANCEL:
322 done = true;
323 break;
326 buffering_get_debugdata(&d);
327 bufused = bufsize - pcmbuf_free();
329 FOR_NB_SCREENS(i)
331 line = 0;
332 screens[i].clear_display();
335 screens[i].putsf(0, line++, "pcm: %6ld/%ld", (long) bufused, (long) bufsize);
337 gui_scrollbar_draw(&screens[i],0, line*8, screens[i].lcdwidth, 6,
338 bufsize, 0, bufused, HORIZONTAL);
339 line++;
341 screens[i].putsf(0, line++, "alloc: %6ld/%ld", audio_filebufused(),
342 (long) filebuflen);
344 #if LCD_HEIGHT > 80 || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_HEIGHT > 80)
345 if (screens[i].lcdheight > 80)
347 gui_scrollbar_draw(&screens[i],0, line*8, screens[i].lcdwidth, 6,
348 filebuflen, 0, audio_filebufused(), HORIZONTAL);
349 line++;
351 screens[i].putsf(0, line++, "real: %6ld/%ld", (long)d.buffered_data,
352 (long)filebuflen);
354 gui_scrollbar_draw(&screens[i],0, line*8, screens[i].lcdwidth, 6,
355 filebuflen, 0, (long)d.buffered_data, HORIZONTAL);
356 line++;
358 #endif
360 screens[i].putsf(0, line++, "usefl: %6ld/%ld", (long)(d.useful_data),
361 (long)filebuflen);
363 #if LCD_HEIGHT > 80 || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_HEIGHT > 80)
364 if (screens[i].lcdheight > 80)
366 gui_scrollbar_draw(&screens[i],0, line*8, screens[i].lcdwidth, 6,
367 filebuflen, 0, d.useful_data, HORIZONTAL);
368 line++;
370 #endif
372 screens[i].putsf(0, line++, "data_rem: %ld", (long)d.data_rem);
374 screens[i].putsf(0, line++, "track count: %2d", audio_track_count());
376 screens[i].putsf(0, line++, "handle count: %d", (int)d.num_handles);
378 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
379 screens[i].putsf(0, line++, "cpu freq: %3dMHz",
380 (int)((FREQ + 500000) / 1000000));
381 #endif
383 if (ticks > 0)
385 int boostquota = boost_ticks * 1000 / ticks; /* in 0.1 % */
386 int avgclock = freq_sum * 10 / ticks; /* in 100 kHz */
387 screens[i].putsf(0, line++, "boost:%3d.%d%% (%d.%dMHz)",
388 boostquota/10, boostquota%10, avgclock/10, avgclock%10);
391 screens[i].putsf(0, line++, "pcmbufdesc: %2d/%2d",
392 pcmbuf_used_descs(), pcmbufdescs);
393 screens[i].putsf(0, line++, "watermark: %6d",
394 (int)(d.watermark));
396 screens[i].update();
400 tick_remove_task(dbg_audio_task);
402 FOR_NB_SCREENS(i)
403 screens[i].setfont(FONT_UI);
405 return false;
407 #endif /* CONFIG_CODEC */
408 #endif /* HAVE_LCD_BITMAP */
411 #if (CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE))
412 /* Tool function to read the flash manufacturer and type, if available.
413 Only chips which could be reprogrammed in system will return values.
414 (The mode switch addresses vary between flash manufacturers, hence addr1/2) */
415 /* In IRAM to avoid problems when running directly from Flash */
416 static bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
417 unsigned addr1, unsigned addr2)
418 ICODE_ATTR __attribute__((noinline));
419 static bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
420 unsigned addr1, unsigned addr2)
423 unsigned not_manu, not_id; /* read values before switching to ID mode */
424 unsigned manu, id; /* read values when in ID mode */
426 #if CONFIG_CPU == SH7034
427 volatile unsigned char* flash = (unsigned char*)0x2000000; /* flash mapping */
428 #elif defined(CPU_COLDFIRE)
429 volatile unsigned short* flash = (unsigned short*)0; /* flash mapping */
430 #endif
431 int old_level; /* saved interrupt level */
433 not_manu = flash[0]; /* read the normal content */
434 not_id = flash[1]; /* should be 'A' (0x41) and 'R' (0x52) from the "ARCH" marker */
436 /* disable interrupts, prevent any stray flash access */
437 old_level = disable_irq_save();
439 flash[addr1] = 0xAA; /* enter command mode */
440 flash[addr2] = 0x55;
441 flash[addr1] = 0x90; /* ID command */
442 /* Atmel wants 20ms pause here */
443 /* sleep(HZ/50); no sleeping possible while interrupts are disabled */
445 manu = flash[0]; /* read the IDs */
446 id = flash[1];
448 flash[0] = 0xF0; /* reset flash (back to normal read mode) */
449 /* Atmel wants 20ms pause here */
450 /* sleep(HZ/50); no sleeping possible while interrupts are disabled */
452 restore_irq(old_level); /* enable interrupts again */
454 /* I assume success if the obtained values are different from
455 the normal flash content. This is not perfectly bulletproof, they
456 could theoretically be the same by chance, causing us to fail. */
457 if (not_manu != manu || not_id != id) /* a value has changed */
459 *p_manufacturer = manu; /* return the results */
460 *p_device = id;
461 return true; /* success */
463 return false; /* fail */
465 #endif /* (CONFIG_CPU == SH7034 || CPU_COLDFIRE) */
467 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
468 #ifdef CPU_PP
469 static int perfcheck(void)
471 int result;
473 asm (
474 "mrs r2, CPSR \n"
475 "orr r0, r2, #0xc0 \n" /* disable IRQ and FIQ */
476 "msr CPSR_c, r0 \n"
477 "mov %[res], #0 \n"
478 "ldr r0, [%[timr]] \n"
479 "add r0, r0, %[tmo] \n"
480 "1: \n"
481 "add %[res], %[res], #1 \n"
482 "ldr r1, [%[timr]] \n"
483 "cmp r1, r0 \n"
484 "bmi 1b \n"
485 "msr CPSR_c, r2 \n" /* reset IRQ and FIQ state */
487 [res]"=&r"(result)
489 [timr]"r"(&USEC_TIMER),
490 [tmo]"r"(
491 #if CONFIG_CPU == PP5002
492 16000
493 #else /* PP5020/5022/5024 */
494 10226
495 #endif
498 "r0", "r1", "r2"
500 return result;
502 #endif
504 #ifdef HAVE_LCD_BITMAP
505 static bool dbg_hw_info(void)
507 #if CONFIG_CPU == SH7034
508 int bitmask = HW_MASK;
509 int rom_version = ROM_VERSION;
510 unsigned manu, id; /* flash IDs */
511 bool got_id; /* flag if we managed to get the flash IDs */
512 unsigned rom_crc = 0xffffffff; /* CRC32 of the boot ROM */
513 bool has_bootrom; /* flag for boot ROM present */
514 int oldmode; /* saved memory guard mode */
516 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
518 /* get flash ROM type */
519 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
520 if (!got_id)
521 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
523 /* check if the boot ROM area is a flash mirror */
524 has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0);
525 if (has_bootrom) /* if ROM and Flash different */
527 /* calculate CRC16 checksum of boot ROM */
528 rom_crc = crc_32((unsigned char*)0x0000, 64*1024, 0xffffffff);
531 system_memory_guard(oldmode); /* re-enable memory guard */
533 lcd_setfont(FONT_SYSFIXED);
534 lcd_clear_display();
536 lcd_puts(0, 0, "[Hardware info]");
538 lcd_putsf(0, 1, "ROM: %d.%02d", rom_version/100, rom_version%100);
540 lcd_putsf(0, 2, "Mask: 0x%04x", bitmask);
542 if (got_id)
543 lcd_putsf(0, 3, "Flash: M=%02x D=%02x", manu, id);
544 else
545 lcd_puts(0, 3, "Flash: M=?? D=??"); /* unknown, sorry */
547 if (has_bootrom)
549 if (rom_crc == 0x56DBA4EE) /* known Version 1 */
550 lcd_puts(0, 4, "Boot ROM: V1");
551 else
552 lcd_putsf(0, 4, "ROMcrc: 0x%08x", rom_crc);
554 else
556 lcd_puts(0, 4, "Boot ROM: none");
559 lcd_update();
561 while (!(action_userabort(TIMEOUT_BLOCK)));
563 #elif CONFIG_CPU == MCF5249 || CONFIG_CPU == MCF5250
564 unsigned manu, id; /* flash IDs */
565 int got_id; /* flag if we managed to get the flash IDs */
566 int oldmode; /* saved memory guard mode */
567 int line = 0;
569 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
571 /* get flash ROM type */
572 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
573 if (!got_id)
574 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
576 system_memory_guard(oldmode); /* re-enable memory guard */
578 lcd_setfont(FONT_SYSFIXED);
579 lcd_clear_display();
581 lcd_puts(0, line++, "[Hardware info]");
583 if (got_id)
584 lcd_putsf(0, line++, "Flash: M=%04x D=%04x", manu, id);
585 else
586 lcd_puts(0, line++, "Flash: M=???? D=????"); /* unknown, sorry */
588 #ifdef IAUDIO_X5
590 struct ds2411_id id;
592 lcd_puts(0, ++line, "Serial Number:");
594 got_id = ds2411_read_id(&id);
596 if (got_id == DS2411_OK)
598 lcd_putsf(0, ++line, " FC=%02x", (unsigned)id.family_code);
599 lcd_putsf(0, ++line, " ID=%02X %02X %02X %02X %02X %02X",
600 (unsigned)id.uid[0], (unsigned)id.uid[1], (unsigned)id.uid[2],
601 (unsigned)id.uid[3], (unsigned)id.uid[4], (unsigned)id.uid[5]);
602 lcd_putsf(0, ++line, " CRC=%02X", (unsigned)id.crc);
604 else
606 lcd_putsf(0, ++line, "READ ERR=%d", got_id);
609 #endif
611 lcd_update();
613 while (!(action_userabort(TIMEOUT_BLOCK)));
615 #elif defined(CPU_PP502x)
616 int line = 0;
617 char pp_version[] = { (PP_VER2 >> 24) & 0xff, (PP_VER2 >> 16) & 0xff,
618 (PP_VER2 >> 8) & 0xff, (PP_VER2) & 0xff,
619 (PP_VER1 >> 24) & 0xff, (PP_VER1 >> 16) & 0xff,
620 (PP_VER1 >> 8) & 0xff, (PP_VER1) & 0xff, '\0' };
622 lcd_setfont(FONT_SYSFIXED);
623 lcd_clear_display();
625 lcd_puts(0, line++, "[Hardware info]");
627 #ifdef IPOD_ARCH
628 lcd_putsf(0, line++, "HW rev: 0x%08lx", IPOD_HW_REVISION);
629 #endif
631 #ifdef IPOD_COLOR
632 extern int lcd_type; /* Defined in lcd-colornano.c */
634 lcd_putsf(0, line++, "LCD type: %d", lcd_type);
635 #endif
637 lcd_putsf(0, line++, "PP version: %s", pp_version);
639 lcd_putsf(0, line++, "Est. clock (kHz): %d", perfcheck());
641 lcd_update();
643 while (!(action_userabort(TIMEOUT_BLOCK)));
645 #elif CONFIG_CPU == PP5002
646 int line = 0;
647 char pp_version[] = { (PP_VER4 >> 8) & 0xff, PP_VER4 & 0xff,
648 (PP_VER3 >> 8) & 0xff, PP_VER3 & 0xff,
649 (PP_VER2 >> 8) & 0xff, PP_VER2 & 0xff,
650 (PP_VER1 >> 8) & 0xff, PP_VER1 & 0xff, '\0' };
653 lcd_setfont(FONT_SYSFIXED);
654 lcd_clear_display();
656 lcd_puts(0, line++, "[Hardware info]");
658 #ifdef IPOD_ARCH
659 lcd_putsf(0, line++, "HW rev: 0x%08lx", IPOD_HW_REVISION);
660 #endif
662 lcd_putsf(0, line++, "PP version: %s", pp_version);
664 lcd_putsf(0, line++, "Est. clock (kHz): %d", perfcheck());
666 lcd_update();
668 while (!(action_userabort(TIMEOUT_BLOCK)));
670 #else
671 /* Define this function in your target tree */
672 return __dbg_hw_info();
673 #endif /* CONFIG_CPU */
674 lcd_setfont(FONT_UI);
675 return false;
677 #else /* !HAVE_LCD_BITMAP */
678 static bool dbg_hw_info(void)
680 int button;
681 int currval = 0;
682 int rom_version = ROM_VERSION;
683 unsigned manu, id; /* flash IDs */
684 bool got_id; /* flag if we managed to get the flash IDs */
685 unsigned rom_crc = 0xffffffff; /* CRC32 of the boot ROM */
686 bool has_bootrom; /* flag for boot ROM present */
687 int oldmode; /* saved memory guard mode */
689 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
691 /* get flash ROM type */
692 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
693 if (!got_id)
694 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
696 /* check if the boot ROM area is a flash mirror */
697 has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0);
698 if (has_bootrom) /* if ROM and Flash different */
700 /* calculate CRC16 checksum of boot ROM */
701 rom_crc = crc_32((unsigned char*)0x0000, 64*1024, 0xffffffff);
704 system_memory_guard(oldmode); /* re-enable memory guard */
706 lcd_clear_display();
708 lcd_puts(0, 0, "[HW Info]");
709 while(1)
711 switch(currval)
713 case 0:
714 lcd_putsf(0, 1, "ROM: %d.%02d",
715 rom_version/100, rom_version%100);
716 break;
717 case 1:
718 if (got_id)
719 lcd_putsf(0, 1, "Flash:%02x,%02x", manu, id);
720 else
721 lcd_puts(0, 1, "Flash:??,??"); /* unknown, sorry */
722 break;
723 case 2:
724 if (has_bootrom)
726 if (rom_crc == 0x56DBA4EE) /* known Version 1 */
727 lcd_puts(0, 1, "BootROM: V1");
728 else if (rom_crc == 0x358099E8)
729 lcd_puts(0, 1, "BootROM: V2");
730 /* alternative boot ROM found in one single player so far */
731 else
732 lcd_putsf(0, 1, "R: %08x", rom_crc);
734 else
735 lcd_puts(0, 1, "BootROM: no");
738 lcd_update();
740 button = get_action(CONTEXT_SETTINGS,TIMEOUT_BLOCK);
742 switch(button)
744 case ACTION_STD_CANCEL:
745 return false;
747 case ACTION_SETTINGS_DEC:
748 currval--;
749 if(currval < 0)
750 currval = 2;
751 break;
753 case ACTION_SETTINGS_INC:
754 currval++;
755 if(currval > 2)
756 currval = 0;
757 break;
760 return false;
762 #endif /* !HAVE_LCD_BITMAP */
763 #endif /* PLATFORM_NATIVE */
765 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
766 static const char* dbg_partitions_getname(int selected_item, void *data,
767 char *buffer, size_t buffer_len)
769 (void)data;
770 int partition = selected_item/2;
771 struct partinfo* p = disk_partinfo(partition);
772 if (selected_item%2)
774 snprintf(buffer, buffer_len, " T:%x %ld MB", p->type, p->size / ( 2048 / ( SECTOR_SIZE / 512 )));
776 else
778 snprintf(buffer, buffer_len, "P%d: S:%lx", partition, p->start);
780 return buffer;
783 bool dbg_partitions(void)
785 struct simplelist_info info;
786 simplelist_info_init(&info, "Partition Info", 4, NULL);
787 info.selection_size = 2;
788 info.hide_selection = true;
789 info.scroll_all = true;
790 info.get_name = dbg_partitions_getname;
791 return simplelist_show_list(&info);
793 #endif /* PLATFORM_NATIVE */
795 #if defined(CPU_COLDFIRE) && defined(HAVE_SPDIF_OUT)
796 static bool dbg_spdif(void)
798 int line;
799 unsigned int control;
800 int x;
801 char *s;
802 int category;
803 int generation;
804 unsigned int interruptstat;
805 bool valnogood, symbolerr, parityerr;
806 bool done = false;
807 bool spdif_src_on;
808 int spdif_source = spdif_get_output_source(&spdif_src_on);
809 spdif_set_output_source(AUDIO_SRC_SPDIF IF_SPDIF_POWER_(, true));
811 lcd_clear_display();
812 lcd_setfont(FONT_SYSFIXED);
814 #ifdef HAVE_SPDIF_POWER
815 spdif_power_enable(true); /* We need SPDIF power for both sending & receiving */
816 #endif
818 while (!done)
820 line = 0;
822 control = EBU1RCVCCHANNEL1;
823 interruptstat = INTERRUPTSTAT;
824 INTERRUPTCLEAR = 0x03c00000;
826 valnogood = (interruptstat & 0x01000000)?true:false;
827 symbolerr = (interruptstat & 0x00800000)?true:false;
828 parityerr = (interruptstat & 0x00400000)?true:false;
830 lcd_putsf(0, line++, "Val: %s Sym: %s Par: %s",
831 valnogood?"--":"OK",
832 symbolerr?"--":"OK",
833 parityerr?"--":"OK");
835 lcd_putsf(0, line++, "Status word: %08x", (int)control);
837 line++;
839 x = control >> 31;
840 lcd_putsf(0, line++, "PRO: %d (%s)",
841 x, x?"Professional":"Consumer");
843 x = (control >> 30) & 1;
844 lcd_putsf(0, line++, "Audio: %d (%s)",
845 x, x?"Non-PCM":"PCM");
847 x = (control >> 29) & 1;
848 lcd_putsf(0, line++, "Copy: %d (%s)",
849 x, x?"Permitted":"Inhibited");
851 x = (control >> 27) & 7;
852 switch(x)
854 case 0:
855 s = "None";
856 break;
857 case 1:
858 s = "50/15us";
859 break;
860 default:
861 s = "Reserved";
862 break;
864 lcd_putsf(0, line++, "Preemphasis: %d (%s)", x, s);
866 x = (control >> 24) & 3;
867 lcd_putsf(0, line++, "Mode: %d", x);
869 category = (control >> 17) & 127;
870 switch(category)
872 case 0x00:
873 s = "General";
874 break;
875 case 0x40:
876 s = "Audio CD";
877 break;
878 default:
879 s = "Unknown";
881 lcd_putsf(0, line++, "Category: 0x%02x (%s)", category, s);
883 x = (control >> 16) & 1;
884 generation = x;
885 if(((category & 0x70) == 0x10) ||
886 ((category & 0x70) == 0x40) ||
887 ((category & 0x78) == 0x38))
889 generation = !generation;
891 lcd_putsf(0, line++, "Generation: %d (%s)",
892 x, generation?"Original":"No ind.");
894 x = (control >> 12) & 15;
895 lcd_putsf(0, line++, "Source: %d", x);
898 x = (control >> 8) & 15;
899 switch(x)
901 case 0:
902 s = "Unspecified";
903 break;
904 case 8:
905 s = "A (Left)";
906 break;
907 case 4:
908 s = "B (Right)";
909 break;
910 default:
911 s = "";
912 break;
914 lcd_putsf(0, line++, "Channel: %d (%s)", x, s);
916 x = (control >> 4) & 15;
917 switch(x)
919 case 0:
920 s = "44.1kHz";
921 break;
922 case 0x4:
923 s = "48kHz";
924 break;
925 case 0xc:
926 s = "32kHz";
927 break;
929 lcd_putsf(0, line++, "Frequency: %d (%s)", x, s);
931 x = (control >> 2) & 3;
932 lcd_putsf(0, line++, "Clock accuracy: %d", x);
933 line++;
935 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
936 lcd_putsf(0, line++, "Measured freq: %ldHz",
937 spdif_measure_frequency());
938 #endif
940 lcd_update();
942 if (action_userabort(HZ/10))
943 break;
946 spdif_set_output_source(spdif_source IF_SPDIF_POWER_(, spdif_src_on));
948 #ifdef HAVE_SPDIF_POWER
949 spdif_power_enable(global_settings.spdif_enable);
950 #endif
952 lcd_setfont(FONT_UI);
953 return false;
955 #endif /* CPU_COLDFIRE */
957 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
958 #ifdef HAVE_LCD_BITMAP
959 /* button definitions */
960 #if (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
961 (CONFIG_KEYPAD == IRIVER_H300_PAD)
962 # define DEBUG_CANCEL BUTTON_OFF
964 #elif CONFIG_KEYPAD == RECORDER_PAD
965 # define DEBUG_CANCEL BUTTON_OFF
967 #elif CONFIG_KEYPAD == ONDIO_PAD
968 # define DEBUG_CANCEL BUTTON_MENU
970 #elif (CONFIG_KEYPAD == IPOD_1G2G_PAD) || \
971 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
972 (CONFIG_KEYPAD == IPOD_4G_PAD)
973 # define DEBUG_CANCEL BUTTON_MENU
975 #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
976 # define DEBUG_CANCEL BUTTON_PLAY
978 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
979 # define DEBUG_CANCEL BUTTON_REC
981 #elif (CONFIG_KEYPAD == IAUDIO_M3_PAD)
982 # define DEBUG_CANCEL BUTTON_RC_REC
984 #elif (CONFIG_KEYPAD == IRIVER_H10_PAD)
985 # define DEBUG_CANCEL BUTTON_REW
987 #elif (CONFIG_KEYPAD == MROBE100_PAD)
988 # define DEBUG_CANCEL BUTTON_MENU
990 #elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \
991 (CONFIG_KEYPAD == SANSA_C200_PAD) || \
992 (CONFIG_KEYPAD == SANSA_FUZE_PAD)
993 # define DEBUG_CANCEL BUTTON_LEFT
995 /* This is temporary until the SA9200 touchpad works */
996 #elif (CONFIG_KEYPAD == PHILIPS_SA9200_PAD) || \
997 (CONFIG_KEYPAD == PHILIPS_HDD1630_PAD) || \
998 (CONFIG_KEYPAD == PHILIPS_HDD6330_PAD)
999 # define DEBUG_CANCEL BUTTON_POWER
1001 #elif (CONFIG_KEYPAD == SAMSUNG_YH_PAD)
1002 # define DEBUG_CANCEL BUTTON_PLAY
1004 #elif (CONFIG_KEYPAD == PBELL_VIBE500_PAD)
1005 # define DEBUG_CANCEL BUTTON_CANCEL
1007 #elif (CONFIG_KEYPAD == MPIO_HD200_PAD)
1008 # define DEBUG_CANCEL BUTTON_REC
1010 #endif /* key definitions */
1012 /* Test code!!! */
1013 bool dbg_ports(void)
1015 #if CONFIG_CPU == SH7034
1016 int adc_battery_voltage, adc_battery_level;
1018 lcd_setfont(FONT_SYSFIXED);
1019 lcd_clear_display();
1021 while(1)
1023 lcd_putsf(0, 0, "PADR: %04x", (unsigned short)PADR);
1024 lcd_putsf(0, 1, "PBDR: %04x", (unsigned short)PBDR);
1026 lcd_putsf(0, 2, "AN0: %03x AN4: %03x", adc_read(0), adc_read(4));
1027 lcd_putsf(0, 3, "AN1: %03x AN5: %03x", adc_read(1), adc_read(5));
1028 lcd_putsf(0, 4, "AN2: %03x AN6: %03x", adc_read(2), adc_read(6));
1029 lcd_putsf(0, 5, "AN3: %03x AN7: %03x", adc_read(3), adc_read(7));
1031 battery_read_info(&adc_battery_voltage, &adc_battery_level);
1032 lcd_putsf(0, 6, "Batt: %d.%03dV %d%% ", adc_battery_voltage / 1000,
1033 adc_battery_voltage % 1000, adc_battery_level);
1035 lcd_update();
1036 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1038 lcd_setfont(FONT_UI);
1039 return false;
1042 #elif defined(CPU_COLDFIRE)
1043 unsigned int gpio_out;
1044 unsigned int gpio1_out;
1045 unsigned int gpio_read;
1046 unsigned int gpio1_read;
1047 unsigned int gpio_function;
1048 unsigned int gpio1_function;
1049 unsigned int gpio_enable;
1050 unsigned int gpio1_enable;
1051 int adc_buttons, adc_remote;
1052 int adc_battery_voltage, adc_battery_level;
1053 int line;
1055 lcd_clear_display();
1056 lcd_setfont(FONT_SYSFIXED);
1058 while(1)
1060 line = 0;
1061 gpio_read = GPIO_READ;
1062 gpio1_read = GPIO1_READ;
1063 gpio_out = GPIO_OUT;
1064 gpio1_out = GPIO1_OUT;
1065 gpio_function = GPIO_FUNCTION;
1066 gpio1_function = GPIO1_FUNCTION;
1067 gpio_enable = GPIO_ENABLE;
1068 gpio1_enable = GPIO1_ENABLE;
1070 lcd_putsf(0, line++, "GPIO_READ: %08x", gpio_read);
1071 lcd_putsf(0, line++, "GPIO_OUT: %08x", gpio_out);
1072 lcd_putsf(0, line++, "GPIO_FUNC: %08x", gpio_function);
1073 lcd_putsf(0, line++, "GPIO_ENA: %08x", gpio_enable);
1075 lcd_putsf(0, line++, "GPIO1_READ: %08x", gpio1_read);
1076 lcd_putsf(0, line++, "GPIO1_OUT: %08x", gpio1_out);
1077 lcd_putsf(0, line++, "GPIO1_FUNC: %08x", gpio1_function);
1078 lcd_putsf(0, line++, "GPIO1_ENA: %08x", gpio1_enable);
1080 adc_buttons = adc_read(ADC_BUTTONS);
1081 adc_remote = adc_read(ADC_REMOTE);
1082 battery_read_info(&adc_battery_voltage, &adc_battery_level);
1083 #if defined(IAUDIO_X5) || defined(IAUDIO_M5) || defined(IRIVER_H300_SERIES)
1084 lcd_putsf(0, line++, "ADC_BUTTONS (%c): %02x",
1085 button_scan_enabled() ? '+' : '-', adc_buttons);
1086 #else
1087 lcd_putsf(0, line++, "ADC_BUTTONS: %02x", adc_buttons);
1088 #endif
1089 #if defined(IAUDIO_X5) || defined(IAUDIO_M5)
1090 lcd_putsf(0, line++, "ADC_REMOTE (%c): %02x",
1091 remote_detect() ? '+' : '-', adc_remote);
1092 #else
1093 lcd_putsf(0, line++, "ADC_REMOTE: %02x", adc_remote);
1094 #endif
1095 #if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES)
1096 lcd_putsf(0, line++, "ADC_REMOTEDETECT: %02x",
1097 adc_read(ADC_REMOTEDETECT));
1098 #endif
1100 lcd_putsf(0, line++, "Batt: %d.%03dV %d%% ", adc_battery_voltage / 1000,
1101 adc_battery_voltage % 1000, adc_battery_level);
1103 #if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES)
1104 lcd_putsf(0, line++, "remotetype: %d", remote_type());
1105 #endif
1107 lcd_update();
1108 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1110 lcd_setfont(FONT_UI);
1111 return false;
1115 #elif defined(CPU_PP502x)
1116 int line;
1118 lcd_clear_display();
1119 lcd_setfont(FONT_SYSFIXED);
1121 while(1)
1123 line = 0;
1124 #if (LCD_HEIGHT >= 176) /* Only for displays with appropriate height. */
1125 lcd_puts(0, line++, "GPIO ENABLE: GPIO OUTPUT ENABLE:");
1126 lcd_putsf(0, line++, "A: %02x E: %02x I: %02x A: %02x E: %02x I: %02x",
1127 (unsigned int)GPIOA_ENABLE,
1128 (unsigned int)GPIOE_ENABLE,
1129 (unsigned int)GPIOI_ENABLE,
1130 (unsigned int)GPIOA_OUTPUT_EN,
1131 (unsigned int)GPIOE_OUTPUT_EN,
1132 (unsigned int)GPIOI_OUTPUT_EN);
1133 lcd_putsf(0, line++, "B: %02x F: %02x J: %02x B: %02x F: %02x J: %02x",
1134 (unsigned int)GPIOB_ENABLE,
1135 (unsigned int)GPIOF_ENABLE,
1136 (unsigned int)GPIOJ_ENABLE,
1137 (unsigned int)GPIOB_OUTPUT_EN,
1138 (unsigned int)GPIOF_OUTPUT_EN,
1139 (unsigned int)GPIOJ_OUTPUT_EN);
1140 lcd_putsf(0, line++, "C: %02x G: %02x K: %02x C: %02x G: %02x K: %02x",
1141 (unsigned int)GPIOC_ENABLE,
1142 (unsigned int)GPIOG_ENABLE,
1143 (unsigned int)GPIOK_ENABLE,
1144 (unsigned int)GPIOC_OUTPUT_EN,
1145 (unsigned int)GPIOG_OUTPUT_EN,
1146 (unsigned int)GPIOK_OUTPUT_EN);
1147 lcd_putsf(0, line++, "D: %02x H: %02x L: %02x D: %02x H: %02x L: %02x",
1148 (unsigned int)GPIOD_ENABLE,
1149 (unsigned int)GPIOH_ENABLE,
1150 (unsigned int)GPIOL_ENABLE,
1151 (unsigned int)GPIOD_OUTPUT_EN,
1152 (unsigned int)GPIOH_OUTPUT_EN,
1153 (unsigned int)GPIOL_OUTPUT_EN);
1154 line++;
1155 #endif
1156 lcd_puts(0, line++, "GPIO INPUT VAL:");
1157 lcd_putsf(0, line++, "A: %02x E: %02x I: %02x",
1158 (unsigned int)GPIOA_INPUT_VAL,
1159 (unsigned int)GPIOE_INPUT_VAL,
1160 (unsigned int)GPIOI_INPUT_VAL);
1161 lcd_putsf(0, line++, "B: %02x F: %02x J: %02x",
1162 (unsigned int)GPIOB_INPUT_VAL,
1163 (unsigned int)GPIOF_INPUT_VAL,
1164 (unsigned int)GPIOJ_INPUT_VAL);
1165 lcd_putsf(0, line++, "C: %02x G: %02x K: %02x",
1166 (unsigned int)GPIOC_INPUT_VAL,
1167 (unsigned int)GPIOG_INPUT_VAL,
1168 (unsigned int)GPIOK_INPUT_VAL);
1169 lcd_putsf(0, line++, "D: %02x H: %02x L: %02x",
1170 (unsigned int)GPIOD_INPUT_VAL,
1171 (unsigned int)GPIOH_INPUT_VAL,
1172 (unsigned int)GPIOL_INPUT_VAL);
1173 line++;
1174 lcd_putsf(0, line++, "GPO32_VAL: %08lx", GPO32_VAL);
1175 lcd_putsf(0, line++, "GPO32_EN: %08lx", GPO32_ENABLE);
1176 lcd_putsf(0, line++, "DEV_EN: %08lx", DEV_EN);
1177 lcd_putsf(0, line++, "DEV_EN2: %08lx", DEV_EN2);
1178 lcd_putsf(0, line++, "DEV_EN3: %08lx", inl(0x60006044)); /* to be verified */
1179 lcd_putsf(0, line++, "DEV_INIT1: %08lx", DEV_INIT1);
1180 lcd_putsf(0, line++, "DEV_INIT2: %08lx", DEV_INIT2);
1181 #ifdef ADC_ACCESSORY
1182 lcd_putsf(0, line++, "ACCESSORY: %d", adc_read(ADC_ACCESSORY));
1183 #endif
1184 #ifdef IPOD_VIDEO
1185 lcd_putsf(0, line++, "4066_ISTAT: %d", adc_read(ADC_4066_ISTAT));
1186 #endif
1188 #if defined(IPOD_ACCESSORY_PROTOCOL)
1189 const unsigned char *serbuf = iap_get_serbuf();
1190 lcd_putsf(0, line++, "IAP PACKET: %02x %02x %02x %02x %02x %02x %02x %02x",
1191 serbuf[0], serbuf[1], serbuf[2], serbuf[3], serbuf[4], serbuf[5],
1192 serbuf[6], serbuf[7]);
1193 #endif
1195 #if defined(IRIVER_H10) || defined(IRIVER_H10_5GB)
1196 line++;
1197 lcd_putsf(0, line++, "BATT: %03x UNK1: %03x",
1198 adc_read(ADC_BATTERY), adc_read(ADC_UNKNOWN_1));
1199 lcd_putsf(0, line++, "REM: %03x PAD: %03x",
1200 adc_read(ADC_REMOTE), adc_read(ADC_SCROLLPAD));
1201 #elif defined(PHILIPS_HDD1630) || defined(PHILIPS_HDD6330)
1202 line++;
1203 lcd_putsf(0, line++, "BATT: %03x UNK1: %03x",
1204 adc_read(ADC_BATTERY), adc_read(ADC_UNKNOWN_1));
1205 #elif defined(SANSA_E200) || defined(PHILIPS_SA9200)
1206 lcd_putsf(0, line++, "ADC_BVDD: %4d", adc_read(ADC_BVDD));
1207 lcd_putsf(0, line++, "ADC_RTCSUP: %4d", adc_read(ADC_RTCSUP));
1208 lcd_putsf(0, line++, "ADC_UVDD: %4d", adc_read(ADC_UVDD));
1209 lcd_putsf(0, line++, "ADC_CHG_IN: %4d", adc_read(ADC_CHG_IN));
1210 lcd_putsf(0, line++, "ADC_CVDD: %4d", adc_read(ADC_CVDD));
1211 lcd_putsf(0, line++, "ADC_BATTEMP: %4d", adc_read(ADC_BATTEMP));
1212 lcd_putsf(0, line++, "ADC_MICSUP1: %4d", adc_read(ADC_MICSUP1));
1213 lcd_putsf(0, line++, "ADC_MICSUP2: %4d", adc_read(ADC_MICSUP2));
1214 lcd_putsf(0, line++, "ADC_VBE1: %4d", adc_read(ADC_VBE1));
1215 lcd_putsf(0, line++, "ADC_VBE2: %4d", adc_read(ADC_VBE2));
1216 lcd_putsf(0, line++, "ADC_I_MICSUP1:%4d", adc_read(ADC_I_MICSUP1));
1217 #if !defined(PHILIPS_SA9200)
1218 lcd_putsf(0, line++, "ADC_I_MICSUP2:%4d", adc_read(ADC_I_MICSUP2));
1219 lcd_putsf(0, line++, "ADC_VBAT: %4d", adc_read(ADC_VBAT));
1220 #endif
1221 #endif
1222 lcd_update();
1223 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1225 lcd_setfont(FONT_UI);
1226 return false;
1230 #elif CONFIG_CPU == PP5002
1231 int line;
1233 lcd_clear_display();
1234 lcd_setfont(FONT_SYSFIXED);
1236 while(1)
1238 line = 0;
1239 lcd_putsf(0, line++, "GPIO_A: %02x GPIO_B: %02x",
1240 (unsigned int)GPIOA_INPUT_VAL, (unsigned int)GPIOB_INPUT_VAL);
1241 lcd_putsf(0, line++, "GPIO_C: %02x GPIO_D: %02x",
1242 (unsigned int)GPIOC_INPUT_VAL, (unsigned int)GPIOD_INPUT_VAL);
1244 lcd_putsf(0, line++, "DEV_EN: %08lx", DEV_EN);
1245 lcd_putsf(0, line++, "CLOCK_ENABLE: %08lx", CLOCK_ENABLE);
1246 lcd_putsf(0, line++, "CLOCK_SOURCE: %08lx", CLOCK_SOURCE);
1247 lcd_putsf(0, line++, "PLL_CONTROL: %08lx", PLL_CONTROL);
1248 lcd_putsf(0, line++, "PLL_DIV: %08lx", PLL_DIV);
1249 lcd_putsf(0, line++, "PLL_MULT: %08lx", PLL_MULT);
1250 lcd_putsf(0, line++, "TIMING1_CTL: %08lx", TIMING1_CTL);
1251 lcd_putsf(0, line++, "TIMING2_CTL: %08lx", TIMING2_CTL);
1253 lcd_update();
1254 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1256 lcd_setfont(FONT_UI);
1257 return false;
1260 lcd_setfont(FONT_UI);
1261 #else
1262 return __dbg_ports();
1263 #endif /* CPU */
1264 return false;
1266 #else /* !HAVE_LCD_BITMAP */
1267 bool dbg_ports(void)
1269 int button;
1270 int adc_battery_voltage;
1271 int currval = 0;
1273 lcd_clear_display();
1275 while(1)
1277 if (currval == 0) {
1278 lcd_putsf(0, 0, "PADR: %04x", (unsigned short)PADR);
1279 } else if (currval == 1) {
1280 lcd_putsf(0, 0, "PBDR: %04x", (unsigned short)PBDR);
1281 } else {
1282 int idx = currval - 2; /* idx < 7 */
1283 lcd_putsf(0, 0, "AN%d: %03x", idx, adc_read(idx));
1286 battery_read_info(&adc_battery_voltage, NULL);
1287 lcd_putsf(0, 1, "Batt: %d.%03dV", adc_battery_voltage / 1000,
1288 adc_battery_voltage % 1000);
1289 lcd_update();
1291 button = get_action(CONTEXT_SETTINGS,HZ/5);
1293 switch(button)
1295 case ACTION_STD_CANCEL:
1296 return false;
1298 case ACTION_SETTINGS_DEC:
1299 currval--;
1300 if(currval < 0)
1301 currval = 9;
1302 break;
1304 case ACTION_SETTINGS_INC:
1305 currval++;
1306 if(currval > 9)
1307 currval = 0;
1308 break;
1311 return false;
1313 #endif /* !HAVE_LCD_BITMAP */
1314 #endif /* PLATFORM_NATIVE */
1316 #if (CONFIG_RTC == RTC_PCF50605) && (CONFIG_PLATFORM & PLATFORM_NATIVE)
1317 static bool dbg_pcf(void)
1319 int line;
1321 #ifdef HAVE_LCD_BITMAP
1322 lcd_setfont(FONT_SYSFIXED);
1323 #endif
1324 lcd_clear_display();
1326 while(1)
1328 line = 0;
1330 lcd_putsf(0, line++, "DCDC1: %02x", pcf50605_read(0x1b));
1331 lcd_putsf(0, line++, "DCDC2: %02x", pcf50605_read(0x1c));
1332 lcd_putsf(0, line++, "DCDC3: %02x", pcf50605_read(0x1d));
1333 lcd_putsf(0, line++, "DCDC4: %02x", pcf50605_read(0x1e));
1334 lcd_putsf(0, line++, "DCDEC1: %02x", pcf50605_read(0x1f));
1335 lcd_putsf(0, line++, "DCDEC2: %02x", pcf50605_read(0x20));
1336 lcd_putsf(0, line++, "DCUDC1: %02x", pcf50605_read(0x21));
1337 lcd_putsf(0, line++, "DCUDC2: %02x", pcf50605_read(0x22));
1338 lcd_putsf(0, line++, "IOREGC: %02x", pcf50605_read(0x23));
1339 lcd_putsf(0, line++, "D1REGC: %02x", pcf50605_read(0x24));
1340 lcd_putsf(0, line++, "D2REGC: %02x", pcf50605_read(0x25));
1341 lcd_putsf(0, line++, "D3REGC: %02x", pcf50605_read(0x26));
1342 lcd_putsf(0, line++, "LPREG1: %02x", pcf50605_read(0x27));
1343 lcd_update();
1344 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1346 lcd_setfont(FONT_UI);
1347 return false;
1351 lcd_setfont(FONT_UI);
1352 return false;
1354 #endif
1356 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
1357 static bool dbg_cpufreq(void)
1359 int line;
1360 int button;
1362 #ifdef HAVE_LCD_BITMAP
1363 lcd_setfont(FONT_SYSFIXED);
1364 #endif
1365 lcd_clear_display();
1367 while(1)
1369 line = 0;
1371 lcd_putsf(0, line++, "Frequency: %ld", FREQ);
1372 lcd_putsf(0, line++, "boost_counter: %d", get_cpu_boost_counter());
1374 lcd_update();
1375 button = get_action(CONTEXT_STD,HZ/10);
1377 switch(button)
1379 case ACTION_STD_PREV:
1380 cpu_boost(true);
1381 break;
1383 case ACTION_STD_NEXT:
1384 cpu_boost(false);
1385 break;
1387 case ACTION_STD_OK:
1388 while (get_cpu_boost_counter() > 0)
1389 cpu_boost(false);
1390 set_cpu_frequency(CPUFREQ_DEFAULT);
1391 break;
1393 case ACTION_STD_CANCEL:
1394 lcd_setfont(FONT_UI);
1395 return false;
1398 lcd_setfont(FONT_UI);
1399 return false;
1401 #endif /* HAVE_ADJUSTABLE_CPU_FREQ */
1403 #if defined(HAVE_TSC2100) && (CONFIG_PLATFORM & PLATFORM_NATIVE)
1404 #include "tsc2100.h"
1405 static char *itob(int n, int len)
1407 static char binary[64];
1408 int i,j;
1409 for (i=1, j=0;i<=len;i++)
1411 binary[j++] = n&(1<<(len-i))?'1':'0';
1412 if (i%4 == 0)
1413 binary[j++] = ' ';
1415 binary[j] = '\0';
1416 return binary;
1419 static const char* tsc2100_debug_getname(int selected_item, void * data,
1420 char *buffer, size_t buffer_len)
1422 int *page = (int*)data;
1423 bool reserved = false;
1424 switch (*page)
1426 case 0:
1427 if ((selected_item > 0x0a) ||
1428 (selected_item == 0x04) ||
1429 (selected_item == 0x08))
1430 reserved = true;
1431 break;
1432 case 1:
1433 if ((selected_item > 0x05) ||
1434 (selected_item == 0x02))
1435 reserved = true;
1436 break;
1437 case 2:
1438 if (selected_item > 0x1e)
1439 reserved = true;
1440 break;
1442 if (reserved)
1443 snprintf(buffer, buffer_len, "%02x: RESERVED", selected_item);
1444 else
1445 snprintf(buffer, buffer_len, "%02x: %s", selected_item,
1446 itob(tsc2100_readreg(*page, selected_item)&0xffff,16));
1447 return buffer;
1449 static int tsc2100debug_action_callback(int action, struct gui_synclist *lists)
1451 int *page = (int*)lists->data;
1452 if (action == ACTION_STD_OK)
1454 *page = (*page+1)%3;
1455 snprintf(lists->title, 32,
1456 "tsc2100 registers - Page %d", *page);
1457 return ACTION_REDRAW;
1459 return action;
1461 static bool tsc2100_debug(void)
1463 int page = 0;
1464 char title[32] = "tsc2100 registers - Page 0";
1465 struct simplelist_info info;
1466 simplelist_info_init(&info, title, 32, &page);
1467 info.timeout = HZ/100;
1468 info.get_name = tsc2100_debug_getname;
1469 info.action_callback= tsc2100debug_action_callback;
1470 return simplelist_show_list(&info);
1472 #endif
1473 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
1474 #ifdef HAVE_LCD_BITMAP
1476 * view_battery() shows a automatically scaled graph of the battery voltage
1477 * over time. Usable for estimating battery life / charging rate.
1478 * The power_history array is updated in power_thread of powermgmt.c.
1481 #define BAT_LAST_VAL MIN(LCD_WIDTH, POWER_HISTORY_LEN)
1482 #define BAT_YSPACE (LCD_HEIGHT - 20)
1485 static bool view_battery(void)
1487 int view = 0;
1488 int i, x, y, y1, y2, grid, graph;
1489 unsigned short maxv, minv;
1491 lcd_setfont(FONT_SYSFIXED);
1493 while(1)
1495 lcd_clear_display();
1496 switch (view) {
1497 case 0: /* voltage history graph */
1498 /* Find maximum and minimum voltage for scaling */
1499 minv = power_history[0];
1500 maxv = minv + 1;
1501 for (i = 1; i < BAT_LAST_VAL && power_history[i]; i++) {
1502 if (power_history[i] > maxv)
1503 maxv = power_history[i];
1504 if (power_history[i] < minv)
1505 minv = power_history[i];
1508 /* adjust grid scale */
1509 if ((maxv - minv) > 50)
1510 grid = 50;
1511 else
1512 grid = 5;
1514 /* print header */
1515 lcd_putsf(0, 0, "battery %d.%03dV", power_history[0] / 1000,
1516 power_history[0] % 1000);
1517 lcd_putsf(0, 1, "%d.%03d-%d.%03dV (%2dmV)",
1518 minv / 1000, minv % 1000, maxv / 1000, maxv % 1000,
1519 grid);
1521 i = 1;
1522 while ((y = (minv - (minv % grid)+i*grid)) < maxv)
1524 graph = ((y-minv)*BAT_YSPACE)/(maxv-minv);
1525 graph = LCD_HEIGHT-1 - graph;
1527 /* draw dotted horizontal grid line */
1528 for (x=0; x<LCD_WIDTH;x=x+2)
1529 lcd_drawpixel(x,graph);
1531 i++;
1534 x = 0;
1535 /* draw plot of power history
1536 * skip empty entries
1538 for (i = BAT_LAST_VAL - 1; i > 0; i--)
1540 if (power_history[i] && power_history[i-1])
1542 y1 = (power_history[i] - minv) * BAT_YSPACE /
1543 (maxv - minv);
1544 y1 = MIN(MAX(LCD_HEIGHT-1 - y1, 20),
1545 LCD_HEIGHT-1);
1546 y2 = (power_history[i-1] - minv) * BAT_YSPACE /
1547 (maxv - minv);
1548 y2 = MIN(MAX(LCD_HEIGHT-1 - y2, 20),
1549 LCD_HEIGHT-1);
1551 lcd_set_drawmode(DRMODE_SOLID);
1553 /* make line thicker */
1554 lcd_drawline(((x*LCD_WIDTH)/(BAT_LAST_VAL)),
1555 y1,
1556 (((x+1)*LCD_WIDTH)/(BAT_LAST_VAL)),
1557 y2);
1558 lcd_drawline(((x*LCD_WIDTH)/(BAT_LAST_VAL))+1,
1559 y1+1,
1560 (((x+1)*LCD_WIDTH)/(BAT_LAST_VAL))+1,
1561 y2+1);
1562 x++;
1565 break;
1567 case 1: /* status: */
1568 #if CONFIG_CHARGING >= CHARGING_MONITOR
1569 lcd_putsf(0, 0, "Pwr status: %s",
1570 charging_state() ? "charging" : "discharging");
1571 #else
1572 lcd_puts(0, 0, "Power status:");
1573 #endif
1574 battery_read_info(&y, NULL);
1575 lcd_putsf(0, 1, "Battery: %d.%03d V", y / 1000, y % 1000);
1576 #ifdef ADC_EXT_POWER
1577 y = (adc_read(ADC_EXT_POWER) * EXT_SCALE_FACTOR) / 1000;
1578 lcd_putsf(0, 2, "External: %d.%03d V", y / 1000, y % 1000);
1579 #endif
1580 #if CONFIG_CHARGING
1581 #if defined ARCHOS_RECORDER
1582 lcd_putsf(0, 3, "Chgr: %s %s",
1583 charger_inserted() ? "present" : "absent",
1584 charger_enabled() ? "on" : "off");
1585 lcd_putsf(0, 5, "short delta: %d", short_delta);
1586 lcd_putsf(0, 6, "long delta: %d", long_delta);
1587 lcd_puts(0, 7, power_message);
1588 lcd_putsf(0, 8, "USB Inserted: %s",
1589 usb_inserted() ? "yes" : "no");
1590 #elif defined IPOD_NANO || defined IPOD_VIDEO
1591 int usb_pwr = (GPIOL_INPUT_VAL & 0x10)?true:false;
1592 int ext_pwr = (GPIOL_INPUT_VAL & 0x08)?false:true;
1593 int dock = (GPIOA_INPUT_VAL & 0x10)?true:false;
1594 int charging = (GPIOB_INPUT_VAL & 0x01)?false:true;
1595 int headphone= (GPIOA_INPUT_VAL & 0x80)?true:false;
1597 lcd_putsf(0, 3, "USB pwr: %s",
1598 usb_pwr ? "present" : "absent");
1599 lcd_putsf(0, 4, "EXT pwr: %s",
1600 ext_pwr ? "present" : "absent");
1601 lcd_putsf(0, 5, "Battery: %s",
1602 charging ? "charging" : (usb_pwr||ext_pwr) ? "charged" : "discharging");
1603 lcd_putsf(0, 6, "Dock mode: %s",
1604 dock ? "enabled" : "disabled");
1605 lcd_putsf(0, 7, "Headphone: %s",
1606 headphone ? "connected" : "disconnected");
1607 #ifdef IPOD_VIDEO
1608 if(probed_ramsize == 64)
1609 x = (adc_read(ADC_4066_ISTAT) * 2400) / (1024 * 2);
1610 else
1611 x = (adc_read(ADC_4066_ISTAT) * 2400) / (1024 * 3);
1612 lcd_putsf(0, 8, "Ibat: %d mA", x);
1613 lcd_putsf(0, 9, "Vbat * Ibat: %d mW", x * y / 1000);
1614 #endif
1615 #elif defined TOSHIBA_GIGABEAT_S
1616 int line = 3;
1617 unsigned int st;
1619 static const unsigned char * const chrgstate_strings[] =
1621 "Disabled",
1622 "Error",
1623 "Discharging",
1624 "Precharge",
1625 "Constant Voltage",
1626 "Constant Current",
1627 "<unknown>",
1630 lcd_putsf(0, line++, "Charger: %s",
1631 charger_inserted() ? "present" : "absent");
1633 st = power_input_status() &
1634 (POWER_INPUT_CHARGER | POWER_INPUT_BATTERY);
1635 lcd_putsf(0, line++, "%s%s",
1636 (st & POWER_INPUT_MAIN_CHARGER) ? " Main" : "",
1637 (st & POWER_INPUT_USB_CHARGER) ? " USB" : "");
1639 y = ARRAYLEN(chrgstate_strings) - 1;
1641 switch (charge_state)
1643 case CHARGE_STATE_DISABLED: y--;
1644 case CHARGE_STATE_ERROR: y--;
1645 case DISCHARGING: y--;
1646 case TRICKLE: y--;
1647 case TOPOFF: y--;
1648 case CHARGING: y--;
1649 default:;
1652 lcd_putsf(0, line++, "State: %s", chrgstate_strings[y]);
1654 lcd_putsf(0, line++, "Battery Switch: %s",
1655 (st & POWER_INPUT_BATTERY) ? "On" : "Off");
1657 y = chrgraw_adc_voltage();
1658 lcd_putsf(0, line++, "CHRGRAW: %d.%03d V",
1659 y / 1000, y % 1000);
1661 y = application_supply_adc_voltage();
1662 lcd_putsf(0, line++, "BP : %d.%03d V",
1663 y / 1000, y % 1000);
1665 y = battery_adc_charge_current();
1666 if (y < 0) x = '-', y = -y;
1667 else x = ' ';
1668 lcd_putsf(0, line++, "CHRGISN:%c%d mA", x, y);
1670 y = cccv_regulator_dissipation();
1671 lcd_putsf(0, line++, "P CCCV : %d mW", y);
1673 y = battery_charge_current();
1674 if (y < 0) x = '-', y = -y;
1675 else x = ' ';
1676 lcd_putsf(0, line++, "I Charge:%c%d mA", x, y);
1678 y = battery_adc_temp();
1680 if (y != INT_MIN) {
1681 lcd_putsf(0, line++, "T Battery: %dC (%dF)", y,
1682 (9*y + 160) / 5);
1683 } else {
1684 /* Conversion disabled */
1685 lcd_puts(0, line++, "T Battery: ?");
1688 #elif defined(SANSA_E200) || defined(SANSA_C200) || CONFIG_CPU == AS3525 || \
1689 CONFIG_CPU == AS3525v2
1690 static const char * const chrgstate_strings[] =
1692 [CHARGE_STATE_DISABLED - CHARGE_STATE_DISABLED]= "Disabled",
1693 [CHARGE_STATE_ERROR - CHARGE_STATE_DISABLED] = "Error",
1694 [DISCHARGING - CHARGE_STATE_DISABLED] = "Discharging",
1695 [CHARGING - CHARGE_STATE_DISABLED] = "Charging",
1697 const char *str = NULL;
1699 lcd_putsf(0, 3, "Charger: %s",
1700 charger_inserted() ? "present" : "absent");
1702 y = charge_state - CHARGE_STATE_DISABLED;
1703 if ((unsigned)y < ARRAYLEN(chrgstate_strings))
1704 str = chrgstate_strings[y];
1706 lcd_putsf(0, 4, "State: %s",
1707 str ? str : "<unknown>");
1709 lcd_putsf(0, 5, "CHARGER: %02X", ascodec_read_charger());
1710 #elif defined(IPOD_NANO2G)
1711 y = pmu_read_battery_voltage();
1712 lcd_putsf(17, 1, "RAW: %d.%03d V", y / 1000, y % 1000);
1713 y = pmu_read_battery_current();
1714 lcd_putsf(0, 2, "Battery current: %d mA", y);
1715 lcd_putsf(0, 3, "PWRCON: %8x", PWRCON);
1716 lcd_putsf(0, 4, "PWRCONEXT: %8x", PWRCONEXT);
1717 x = pmu_read(0x1b) & 0xf;
1718 y = pmu_read(0x1a) * 25 + 625;
1719 lcd_putsf(0, 5, "AUTO: %x / %d mV", x, y);
1720 x = pmu_read(0x1f) & 0xf;
1721 y = pmu_read(0x1e) * 25 + 625;
1722 lcd_putsf(0, 6, "DOWN1: %x / %d mV", x, y);
1723 x = pmu_read(0x23) & 0xf;
1724 y = pmu_read(0x22) * 25 + 625;
1725 lcd_putsf(0, 7, "DOWN2: %x / %d mV", x, y);
1726 x = pmu_read(0x27) & 0xf;
1727 y = pmu_read(0x26) * 100 + 900;
1728 lcd_putsf(0, 8, "MEMLDO: %x / %d mV", x, y);
1729 for (i = 0; i < 6; i++)
1731 x = pmu_read(0x2e + (i << 1)) & 0xf;
1732 y = pmu_read(0x2d + (i << 1)) * 100 + 900;
1733 lcd_putsf(0, 9 + i, "LDO%d: %x / %d mV", i + 1, x, y);
1735 lcd_putsf(0, 15, "CLKCON: %8x", CLKCON);
1736 lcd_putsf(17, 15, "PLL0: %6x", PLL0PMS);
1737 #else
1738 lcd_putsf(0, 3, "Charger: %s",
1739 charger_inserted() ? "present" : "absent");
1740 #endif /* target type */
1741 #endif /* CONFIG_CHARGING */
1742 break;
1744 case 2: /* voltage deltas: */
1745 lcd_puts(0, 0, "Voltage deltas:");
1747 for (i = 0; i <= 6; i++) {
1748 y = power_history[i] - power_history[i+1];
1749 lcd_putsf(0, i+1, "-%d min: %s%d.%03d V", i,
1750 (y < 0) ? "-" : "", ((y < 0) ? y * -1 : y) / 1000,
1751 ((y < 0) ? y * -1 : y ) % 1000);
1753 break;
1755 case 3: /* remaining time estimation: */
1757 #ifdef ARCHOS_RECORDER
1758 lcd_putsf(0, 0, "charge_state: %d", charge_state);
1760 lcd_putsf(0, 1, "Cycle time: %d m", powermgmt_last_cycle_startstop_min);
1762 lcd_putsf(0, 2, "Lvl@cyc st: %d%%", powermgmt_last_cycle_level);
1764 lcd_putsf(0, 3, "P=%2d I=%2d", pid_p, pid_i);
1766 lcd_putsf(0, 4, "Trickle sec: %d/60", trickle_sec);
1767 #endif /* ARCHOS_RECORDER */
1769 lcd_putsf(0, 5, "Last PwrHist: %d.%03dV",
1770 power_history[0] / 1000,
1771 power_history[0] % 1000);
1773 lcd_putsf(0, 6, "battery level: %d%%", battery_level());
1775 lcd_putsf(0, 7, "Est. remain: %d m", battery_time());
1776 break;
1779 lcd_update();
1781 switch(get_action(CONTEXT_STD,HZ/2))
1783 case ACTION_STD_PREV:
1784 if (view)
1785 view--;
1786 break;
1788 case ACTION_STD_NEXT:
1789 if (view < 3)
1790 view++;
1791 break;
1793 case ACTION_STD_CANCEL:
1794 lcd_setfont(FONT_UI);
1795 return false;
1798 lcd_setfont(FONT_UI);
1799 return false;
1802 #endif /* HAVE_LCD_BITMAP */
1803 #endif
1805 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
1806 #if (CONFIG_STORAGE & STORAGE_MMC) || (CONFIG_STORAGE & STORAGE_SD)
1808 #if (CONFIG_STORAGE & STORAGE_MMC)
1809 #define CARDTYPE "MMC"
1810 #elif (CONFIG_STORAGE & STORAGE_SD)
1811 #define CARDTYPE "microSD"
1812 #endif
1814 static int disk_callback(int btn, struct gui_synclist *lists)
1816 tCardInfo *card;
1817 int *cardnum = (int*)lists->data;
1818 unsigned char card_name[6];
1819 unsigned char pbuf[32];
1820 char *title = lists->title;
1821 static const unsigned char i_vmin[] = { 0, 1, 5, 10, 25, 35, 60, 100 };
1822 static const unsigned char i_vmax[] = { 1, 5, 10, 25, 35, 45, 80, 200 };
1823 static const unsigned char * const kbit_units[] = { "kBit/s", "MBit/s", "GBit/s" };
1824 static const unsigned char * const nsec_units[] = { "ns", "µs", "ms" };
1825 #if (CONFIG_STORAGE & STORAGE_MMC)
1826 static const char * const mmc_spec_vers[] = { "1.0-1.2", "1.4", "2.0-2.2",
1827 "3.1-3.31", "4.0" };
1828 #endif
1830 if ((btn == ACTION_STD_OK) || (btn == SYS_FS_CHANGED) || (btn == ACTION_REDRAW))
1832 #ifdef HAVE_HOTSWAP
1833 if (btn == ACTION_STD_OK)
1835 *cardnum ^= 0x1; /* change cards */
1837 #endif
1839 simplelist_set_line_count(0);
1841 card = card_get_info(*cardnum);
1843 if (card->initialized > 0)
1845 unsigned i;
1846 for (i=0; i<sizeof(card_name); i++)
1848 card_name[i] = card_extract_bits(card->cid, (103-8*i), 8);
1850 strlcpy(card_name, card_name, sizeof(card_name));
1851 simplelist_addline(SIMPLELIST_ADD_LINE,
1852 "%s Rev %d.%d", card_name,
1853 (int) card_extract_bits(card->cid, 63, 4),
1854 (int) card_extract_bits(card->cid, 59, 4));
1855 simplelist_addline(SIMPLELIST_ADD_LINE,
1856 "Prod: %d/%d",
1857 #if (CONFIG_STORAGE & STORAGE_SD)
1858 (int) card_extract_bits(card->cid, 11, 4),
1859 (int) card_extract_bits(card->cid, 19, 8) + 2000
1860 #elif (CONFIG_STORAGE & STORAGE_MMC)
1861 (int) card_extract_bits(card->cid, 15, 4),
1862 (int) card_extract_bits(card->cid, 11, 4) + 1997
1863 #endif
1865 simplelist_addline(SIMPLELIST_ADD_LINE,
1866 #if (CONFIG_STORAGE & STORAGE_SD)
1867 "Ser#: 0x%08lx",
1868 card_extract_bits(card->cid, 55, 32)
1869 #elif (CONFIG_STORAGE & STORAGE_MMC)
1870 "Ser#: 0x%04lx",
1871 card_extract_bits(card->cid, 47, 16)
1872 #endif
1875 simplelist_addline(SIMPLELIST_ADD_LINE, "M=%02x, "
1876 #if (CONFIG_STORAGE & STORAGE_SD)
1877 "O=%c%c",
1878 (int) card_extract_bits(card->cid, 127, 8),
1879 card_extract_bits(card->cid, 119, 8),
1880 card_extract_bits(card->cid, 111, 8)
1881 #elif (CONFIG_STORAGE & STORAGE_MMC)
1882 "O=%04x",
1883 (int) card_extract_bits(card->cid, 127, 8),
1884 (int) card_extract_bits(card->cid, 119, 16)
1885 #endif
1888 #if (CONFIG_STORAGE & STORAGE_MMC)
1889 int temp = card_extract_bits(card->csd, 125, 4);
1890 simplelist_addline(SIMPLELIST_ADD_LINE,
1891 "MMC v%s", temp < 5 ?
1892 mmc_spec_vers[temp] : "?.?");
1893 #endif
1894 simplelist_addline(SIMPLELIST_ADD_LINE,
1895 "Blocks: 0x%08lx", card->numblocks);
1896 output_dyn_value(pbuf, sizeof pbuf, card->speed / 1000,
1897 kbit_units, false);
1898 simplelist_addline(SIMPLELIST_ADD_LINE,
1899 "Speed: %s", pbuf);
1900 output_dyn_value(pbuf, sizeof pbuf, card->taac,
1901 nsec_units, false);
1902 simplelist_addline(SIMPLELIST_ADD_LINE,
1903 "Taac: %s", pbuf);
1904 simplelist_addline(SIMPLELIST_ADD_LINE,
1905 "Nsac: %d clk", card->nsac);
1906 simplelist_addline(SIMPLELIST_ADD_LINE,
1907 "R2W: *%d", card->r2w_factor);
1908 simplelist_addline(SIMPLELIST_ADD_LINE,
1909 "IRmax: %d..%d mA",
1910 i_vmin[card_extract_bits(card->csd, 61, 3)],
1911 i_vmax[card_extract_bits(card->csd, 58, 3)]);
1912 simplelist_addline(SIMPLELIST_ADD_LINE,
1913 "IWmax: %d..%d mA",
1914 i_vmin[card_extract_bits(card->csd, 55, 3)],
1915 i_vmax[card_extract_bits(card->csd, 52, 3)]);
1917 else if (card->initialized == 0)
1919 simplelist_addline(SIMPLELIST_ADD_LINE, "Not Found!");
1921 #if (CONFIG_STORAGE & STORAGE_SD)
1922 else /* card->initialized < 0 */
1924 simplelist_addline(SIMPLELIST_ADD_LINE, "Init Error! (%d)", card->initialized);
1926 #endif
1927 snprintf(title, 16, "[" CARDTYPE " %d]", *cardnum);
1928 gui_synclist_set_title(lists, title, Icon_NOICON);
1929 gui_synclist_set_nb_items(lists, simplelist_get_line_count());
1930 gui_synclist_select_item(lists, 0);
1931 btn = ACTION_REDRAW;
1933 return btn;
1935 #elif (CONFIG_STORAGE & STORAGE_ATA)
1936 static int disk_callback(int btn, struct gui_synclist *lists)
1938 (void)lists;
1939 int i;
1940 char buf[128];
1941 unsigned short* identify_info = ata_get_identify();
1942 bool timing_info_present = false;
1943 (void)btn;
1945 simplelist_set_line_count(0);
1947 for (i=0; i < 20; i++)
1948 ((unsigned short*)buf)[i]=htobe16(identify_info[i+27]);
1949 buf[40]=0;
1950 /* kill trailing space */
1951 for (i=39; i && buf[i]==' '; i--)
1952 buf[i] = 0;
1953 simplelist_addline(SIMPLELIST_ADD_LINE, "Model: %s", buf);
1954 for (i=0; i < 4; i++)
1955 ((unsigned short*)buf)[i]=htobe16(identify_info[i+23]);
1956 buf[8]=0;
1957 simplelist_addline(SIMPLELIST_ADD_LINE,
1958 "Firmware: %s", buf);
1959 snprintf(buf, sizeof buf, "%ld MB",
1960 ((unsigned long)identify_info[61] << 16 |
1961 (unsigned long)identify_info[60]) / 2048 );
1962 simplelist_addline(SIMPLELIST_ADD_LINE,
1963 "Size: %s", buf);
1964 unsigned long free;
1965 fat_size( IF_MV2(0,) NULL, &free );
1966 simplelist_addline(SIMPLELIST_ADD_LINE,
1967 "Free: %ld MB", free / 1024);
1968 simplelist_addline(SIMPLELIST_ADD_LINE,
1969 "Spinup time: %d ms", storage_spinup_time() * (1000/HZ));
1970 i = identify_info[83] & (1<<3);
1971 simplelist_addline(SIMPLELIST_ADD_LINE,
1972 "Power mgmt: %s", i ? "enabled" : "unsupported");
1973 i = identify_info[83] & (1<<9);
1974 simplelist_addline(SIMPLELIST_ADD_LINE,
1975 "Noise mgmt: %s", i ? "enabled" : "unsupported");
1976 i = identify_info[82] & (1<<6);
1977 simplelist_addline(SIMPLELIST_ADD_LINE,
1978 "Read-ahead: %s", i ? "enabled" : "unsupported");
1979 timing_info_present = identify_info[53] & (1<<1);
1980 if(timing_info_present) {
1981 char pio3[2], pio4[2];pio3[1] = 0;
1982 pio4[1] = 0;
1983 pio3[0] = (identify_info[64] & (1<<0)) ? '3' : 0;
1984 pio4[0] = (identify_info[64] & (1<<1)) ? '4' : 0;
1985 simplelist_addline(SIMPLELIST_ADD_LINE,
1986 "PIO modes: 0 1 2 %s %s", pio3, pio4);
1988 else {
1989 simplelist_addline(SIMPLELIST_ADD_LINE,
1990 "No PIO mode info");
1992 timing_info_present = identify_info[53] & (1<<1);
1993 if(timing_info_present) {
1994 simplelist_addline(SIMPLELIST_ADD_LINE,
1995 "Cycle times %dns/%dns",
1996 identify_info[67],
1997 identify_info[68] );
1998 } else {
1999 simplelist_addline(SIMPLELIST_ADD_LINE,
2000 "No timing info");
2002 int sector_size = 512;
2003 if((identify_info[106] & 0xe000) == 0x6000)
2004 sector_size *= BIT_N(identify_info[106] & 0x000f);
2005 simplelist_addline(SIMPLELIST_ADD_LINE,
2006 "Physical sector size: %d", sector_size);
2007 #ifdef HAVE_ATA_DMA
2008 if (identify_info[63] & (1<<0)) {
2009 char mdma0[2], mdma1[2], mdma2[2];
2010 mdma0[1] = mdma1[1] = mdma2[1] = 0;
2011 mdma0[0] = (identify_info[63] & (1<<0)) ? '0' : 0;
2012 mdma1[0] = (identify_info[63] & (1<<1)) ? '1' : 0;
2013 mdma2[0] = (identify_info[63] & (1<<2)) ? '2' : 0;
2014 simplelist_addline(SIMPLELIST_ADD_LINE,
2015 "MDMA modes: %s %s %s", mdma0, mdma1, mdma2);
2016 simplelist_addline(SIMPLELIST_ADD_LINE,
2017 "MDMA Cycle times %dns/%dns",
2018 identify_info[65],
2019 identify_info[66] );
2021 else {
2022 simplelist_addline(SIMPLELIST_ADD_LINE,
2023 "No MDMA mode info");
2025 if (identify_info[53] & (1<<2)) {
2026 char udma0[2], udma1[2], udma2[2], udma3[2], udma4[2], udma5[2], udma6[2];
2027 udma0[1] = udma1[1] = udma2[1] = udma3[1] = udma4[1] = udma5[1] = udma6[1] = 0;
2028 udma0[0] = (identify_info[88] & (1<<0)) ? '0' : 0;
2029 udma1[0] = (identify_info[88] & (1<<1)) ? '1' : 0;
2030 udma2[0] = (identify_info[88] & (1<<2)) ? '2' : 0;
2031 udma3[0] = (identify_info[88] & (1<<3)) ? '3' : 0;
2032 udma4[0] = (identify_info[88] & (1<<4)) ? '4' : 0;
2033 udma5[0] = (identify_info[88] & (1<<5)) ? '5' : 0;
2034 udma6[0] = (identify_info[88] & (1<<6)) ? '6' : 0;
2035 simplelist_addline(SIMPLELIST_ADD_LINE,
2036 "UDMA modes: %s %s %s %s %s %s %s", udma0, udma1, udma2,
2037 udma3, udma4, udma5, udma6);
2039 else {
2040 simplelist_addline(SIMPLELIST_ADD_LINE,
2041 "No UDMA mode info");
2043 #endif /* HAVE_ATA_DMA */
2044 timing_info_present = identify_info[53] & (1<<1);
2045 if(timing_info_present) {
2046 i = identify_info[49] & (1<<11);
2047 simplelist_addline(SIMPLELIST_ADD_LINE,
2048 "IORDY support: %s", i ? "yes" : "no");
2049 i = identify_info[49] & (1<<10);
2050 simplelist_addline(SIMPLELIST_ADD_LINE,
2051 "IORDY disable: %s", i ? "yes" : "no");
2052 } else {
2053 simplelist_addline(SIMPLELIST_ADD_LINE,
2054 "No timing info");
2056 simplelist_addline(SIMPLELIST_ADD_LINE,
2057 "Cluster size: %d bytes", fat_get_cluster_size(IF_MV(0)));
2058 #ifdef HAVE_ATA_DMA
2059 i = ata_get_dma_mode();
2060 if (i == 0) {
2061 simplelist_addline(SIMPLELIST_ADD_LINE,
2062 "DMA not enabled");
2063 } else {
2064 simplelist_addline(SIMPLELIST_ADD_LINE,
2065 "DMA mode: %s %c",
2066 (i & 0x40) ? "UDMA" : "MDMA",
2067 '0' + (i & 7));
2069 #endif /* HAVE_ATA_DMA */
2070 return btn;
2072 #else /* No SD, MMC or ATA */
2073 static int disk_callback(int btn, struct gui_synclist *lists)
2075 (void)btn;
2076 (void)lists;
2077 struct storage_info info;
2078 storage_get_info(0,&info);
2079 simplelist_addline(SIMPLELIST_ADD_LINE, "Vendor: %s", info.vendor);
2080 simplelist_addline(SIMPLELIST_ADD_LINE, "Model: %s", info.product);
2081 simplelist_addline(SIMPLELIST_ADD_LINE, "Firmware: %s", info.revision);
2082 simplelist_addline(SIMPLELIST_ADD_LINE,
2083 "Size: %ld MB", info.num_sectors*(info.sector_size/512)/2024);
2084 unsigned long free;
2085 fat_size( IF_MV2(0,) NULL, &free );
2086 simplelist_addline(SIMPLELIST_ADD_LINE,
2087 "Free: %ld MB", free / 1024);
2088 simplelist_addline(SIMPLELIST_ADD_LINE,
2089 "Cluster size: %d bytes", fat_get_cluster_size(IF_MV(0)));
2090 return btn;
2092 #endif
2094 #if (CONFIG_STORAGE & STORAGE_ATA)
2095 static bool dbg_identify_info(void)
2097 int fd = creat("/identify_info.bin", 0666);
2098 if(fd >= 0)
2100 #ifdef ROCKBOX_LITTLE_ENDIAN
2101 ecwrite(fd, ata_get_identify(), SECTOR_SIZE/2, "s", true);
2102 #else
2103 write(fd, ata_get_identify(), SECTOR_SIZE);
2104 #endif
2105 close(fd);
2107 return false;
2109 #endif
2111 static bool dbg_disk_info(void)
2113 struct simplelist_info info;
2114 simplelist_info_init(&info, "Disk Info", 1, NULL);
2115 #if (CONFIG_STORAGE & STORAGE_MMC) || (CONFIG_STORAGE & STORAGE_SD)
2116 char title[16];
2117 int card = 0;
2118 info.callback_data = (void*)&card;
2119 info.title = title;
2120 #endif
2121 info.action_callback = disk_callback;
2122 info.hide_selection = true;
2123 info.scroll_all = true;
2124 return simplelist_show_list(&info);
2126 #endif /* PLATFORM_NATIVE */
2128 #ifdef HAVE_DIRCACHE
2129 static int dircache_callback(int btn, struct gui_synclist *lists)
2131 (void)btn; (void)lists;
2132 simplelist_set_line_count(0);
2133 simplelist_addline(SIMPLELIST_ADD_LINE, "Cache initialized: %s",
2134 dircache_is_enabled() ? "Yes" : "No");
2135 simplelist_addline(SIMPLELIST_ADD_LINE, "Cache size: %d B",
2136 dircache_get_cache_size());
2137 simplelist_addline(SIMPLELIST_ADD_LINE, "Last size: %d B",
2138 global_status.dircache_size);
2139 simplelist_addline(SIMPLELIST_ADD_LINE, "Limit: %d B",
2140 DIRCACHE_LIMIT);
2141 simplelist_addline(SIMPLELIST_ADD_LINE, "Reserve: %d/%d B",
2142 dircache_get_reserve_used(), DIRCACHE_RESERVE);
2143 simplelist_addline(SIMPLELIST_ADD_LINE, "Scanning took: %d s",
2144 dircache_get_build_ticks() / HZ);
2145 simplelist_addline(SIMPLELIST_ADD_LINE, "Entry count: %d",
2146 dircache_get_entry_count());
2147 return btn;
2150 static bool dbg_dircache_info(void)
2152 struct simplelist_info info;
2153 simplelist_info_init(&info, "Dircache Info", 7, NULL);
2154 info.action_callback = dircache_callback;
2155 info.hide_selection = true;
2156 info.scroll_all = true;
2157 return simplelist_show_list(&info);
2160 #endif /* HAVE_DIRCACHE */
2162 #ifdef HAVE_TAGCACHE
2163 static int database_callback(int btn, struct gui_synclist *lists)
2165 (void)lists;
2166 struct tagcache_stat *stat = tagcache_get_stat();
2167 static bool synced = false;
2169 simplelist_set_line_count(0);
2171 simplelist_addline(SIMPLELIST_ADD_LINE, "Initialized: %s",
2172 stat->initialized ? "Yes" : "No");
2173 simplelist_addline(SIMPLELIST_ADD_LINE, "DB Ready: %s",
2174 stat->ready ? "Yes" : "No");
2175 simplelist_addline(SIMPLELIST_ADD_LINE, "RAM Cache: %s",
2176 stat->ramcache ? "Yes" : "No");
2177 simplelist_addline(SIMPLELIST_ADD_LINE, "RAM: %d/%d B",
2178 stat->ramcache_used, stat->ramcache_allocated);
2179 simplelist_addline(SIMPLELIST_ADD_LINE, "Progress: %d%% (%d entries)",
2180 stat->progress, stat->processed_entries);
2181 simplelist_addline(SIMPLELIST_ADD_LINE, "Curfile: %s",
2182 stat->curentry ? stat->curentry : "---");
2183 simplelist_addline(SIMPLELIST_ADD_LINE, "Commit step: %d",
2184 stat->commit_step);
2185 simplelist_addline(SIMPLELIST_ADD_LINE, "Commit delayed: %s",
2186 stat->commit_delayed ? "Yes" : "No");
2188 simplelist_addline(SIMPLELIST_ADD_LINE, "Queue length: %d",
2189 stat->queue_length);
2191 if (synced)
2193 synced = false;
2194 tagcache_screensync_event();
2197 if (!btn && stat->curentry)
2199 synced = true;
2200 return ACTION_REDRAW;
2203 if (btn == ACTION_STD_CANCEL)
2204 tagcache_screensync_enable(false);
2206 return btn;
2208 static bool dbg_tagcache_info(void)
2210 struct simplelist_info info;
2211 simplelist_info_init(&info, "Database Info", 8, NULL);
2212 info.action_callback = database_callback;
2213 info.hide_selection = true;
2214 info.scroll_all = true;
2216 /* Don't do nonblock here, must give enough processing time
2217 for tagcache thread. */
2218 /* info.timeout = TIMEOUT_NOBLOCK; */
2219 info.timeout = 1;
2220 tagcache_screensync_enable(true);
2221 return simplelist_show_list(&info);
2223 #endif
2225 #if CONFIG_CPU == SH7034
2226 static bool dbg_save_roms(void)
2228 int fd;
2229 int oldmode = system_memory_guard(MEMGUARD_NONE);
2231 fd = creat("/internal_rom_0000-FFFF.bin", 0666);
2232 if(fd >= 0)
2234 write(fd, (void *)0, 0x10000);
2235 close(fd);
2238 fd = creat("/internal_rom_2000000-203FFFF.bin", 0666);
2239 if(fd >= 0)
2241 write(fd, (void *)0x2000000, 0x40000);
2242 close(fd);
2245 system_memory_guard(oldmode);
2246 return false;
2248 #elif defined CPU_COLDFIRE
2249 static bool dbg_save_roms(void)
2251 int fd;
2252 int oldmode = system_memory_guard(MEMGUARD_NONE);
2254 #if defined(IRIVER_H100_SERIES)
2255 fd = creat("/internal_rom_000000-1FFFFF.bin", 0666);
2256 #elif defined(IRIVER_H300_SERIES)
2257 fd = creat("/internal_rom_000000-3FFFFF.bin", 0666);
2258 #elif defined(IAUDIO_X5) || defined(IAUDIO_M5) || defined(IAUDIO_M3)
2259 fd = creat("/internal_rom_000000-3FFFFF.bin", 0666);
2260 #elif defined(MPIO_HD200)
2261 fd = creat("/internal_rom_000000-1FFFFF.bin", 0666);
2262 #endif
2263 if(fd >= 0)
2265 write(fd, (void *)0, FLASH_SIZE);
2266 close(fd);
2268 system_memory_guard(oldmode);
2270 #ifdef HAVE_EEPROM
2271 fd = creat("/internal_eeprom.bin", 0666);
2272 if (fd >= 0)
2274 int old_irq_level;
2275 char buf[EEPROM_SIZE];
2276 int err;
2278 old_irq_level = disable_irq_save();
2280 err = eeprom_24cxx_read(0, buf, sizeof buf);
2282 restore_irq(old_irq_level);
2284 if (err)
2285 splashf(HZ*3, "Eeprom read failure (%d)", err);
2286 else
2288 write(fd, buf, sizeof buf);
2291 close(fd);
2293 #endif
2295 return false;
2297 #elif defined(CPU_PP) && !(CONFIG_STORAGE & STORAGE_SD)
2298 static bool dbg_save_roms(void)
2300 int fd;
2302 fd = creat("/internal_rom_000000-0FFFFF.bin", 0666);
2303 if(fd >= 0)
2305 write(fd, (void *)0x20000000, FLASH_SIZE);
2306 close(fd);
2309 return false;
2311 #elif CONFIG_CPU == IMX31L
2312 static bool dbg_save_roms(void)
2314 int fd;
2316 fd = creat("/flash_rom_A0000000-A01FFFFF.bin", 0666);
2317 if (fd >= 0)
2319 write(fd, (void*)0xa0000000, FLASH_SIZE);
2320 close(fd);
2323 return false;
2325 #elif defined(CPU_TCC780X)
2326 static bool dbg_save_roms(void)
2328 int fd;
2330 fd = creat("/eeprom_E0000000-E0001FFF.bin", 0666);
2331 if (fd >= 0)
2333 write(fd, (void*)0xe0000000, 0x2000);
2334 close(fd);
2337 return false;
2339 #endif /* CPU */
2341 #ifndef SIMULATOR
2342 #if CONFIG_TUNER
2344 #ifdef CONFIG_TUNER_MULTI
2345 static int tuner_type = 0;
2346 #define IF_TUNER_TYPE(type) if(tuner_type==type)
2347 #else
2348 #define IF_TUNER_TYPE(type)
2349 #endif
2351 static int radio_callback(int btn, struct gui_synclist *lists)
2353 (void)lists;
2354 if (btn == ACTION_STD_CANCEL)
2355 return btn;
2356 simplelist_set_line_count(1);
2358 #if (CONFIG_TUNER & LV24020LP)
2359 simplelist_addline(SIMPLELIST_ADD_LINE,
2360 "CTRL_STAT: %02X", lv24020lp_get(LV24020LP_CTRL_STAT) );
2361 simplelist_addline(SIMPLELIST_ADD_LINE,
2362 "RADIO_STAT: %02X", lv24020lp_get(LV24020LP_REG_STAT) );
2363 simplelist_addline(SIMPLELIST_ADD_LINE,
2364 "MSS_FM: %d kHz", lv24020lp_get(LV24020LP_MSS_FM) );
2365 simplelist_addline(SIMPLELIST_ADD_LINE,
2366 "MSS_IF: %d Hz", lv24020lp_get(LV24020LP_MSS_IF) );
2367 simplelist_addline(SIMPLELIST_ADD_LINE,
2368 "MSS_SD: %d Hz", lv24020lp_get(LV24020LP_MSS_SD) );
2369 simplelist_addline(SIMPLELIST_ADD_LINE,
2370 "if_set: %d Hz", lv24020lp_get(LV24020LP_IF_SET) );
2371 simplelist_addline(SIMPLELIST_ADD_LINE,
2372 "sd_set: %d Hz", lv24020lp_get(LV24020LP_SD_SET) );
2373 #endif /* LV24020LP */
2374 #if (CONFIG_TUNER & S1A0903X01)
2375 simplelist_addline(SIMPLELIST_ADD_LINE,
2376 "Samsung regs: %08X", s1a0903x01_get(RADIO_ALL));
2377 /* This one doesn't return dynamic data atm */
2378 #endif /* S1A0903X01 */
2379 #if (CONFIG_TUNER & TEA5767)
2380 struct tea5767_dbg_info nfo;
2381 tea5767_dbg_info(&nfo);
2382 simplelist_addline(SIMPLELIST_ADD_LINE, "Philips regs:");
2383 simplelist_addline(SIMPLELIST_ADD_LINE,
2384 " Read: %02X %02X %02X %02X %02X",
2385 (unsigned)nfo.read_regs[0], (unsigned)nfo.read_regs[1],
2386 (unsigned)nfo.read_regs[2], (unsigned)nfo.read_regs[3],
2387 (unsigned)nfo.read_regs[4]);
2388 simplelist_addline(SIMPLELIST_ADD_LINE,
2389 " Write: %02X %02X %02X %02X %02X",
2390 (unsigned)nfo.write_regs[0], (unsigned)nfo.write_regs[1],
2391 (unsigned)nfo.write_regs[2], (unsigned)nfo.write_regs[3],
2392 (unsigned)nfo.write_regs[4]);
2393 #endif /* TEA5767 */
2394 #if (CONFIG_TUNER & SI4700)
2395 IF_TUNER_TYPE(SI4700)
2397 struct si4700_dbg_info nfo;
2398 int i;
2399 si4700_dbg_info(&nfo);
2400 simplelist_addline(SIMPLELIST_ADD_LINE, "SI4700 regs:");
2401 for (i = 0; i < 16; i += 4) {
2402 simplelist_addline(SIMPLELIST_ADD_LINE,"%02X: %04X %04X %04X %04X",
2403 i, nfo.regs[i], nfo.regs[i+1], nfo.regs[i+2], nfo.regs[i+3]);
2406 #endif /* SI4700 */
2407 #if (CONFIG_TUNER & RDA5802)
2408 IF_TUNER_TYPE(RDA5802)
2410 struct rda5802_dbg_info nfo;
2411 int i;
2412 rda5802_dbg_info(&nfo);
2413 simplelist_addline(SIMPLELIST_ADD_LINE, "RDA5802 regs:");
2414 for (i = 0; i < 16; i += 4) {
2415 simplelist_addline(SIMPLELIST_ADD_LINE,"%02X: %04X %04X %04X %04X",
2416 i, nfo.regs[i], nfo.regs[i+1], nfo.regs[i+2], nfo.regs[i+3]);
2419 #endif /* RDA55802 */
2420 return ACTION_REDRAW;
2422 static bool dbg_fm_radio(void)
2424 struct simplelist_info info;
2425 #ifdef CONFIG_TUNER_MULTI
2426 tuner_type = tuner_detect_type();
2427 #endif
2428 info.scroll_all = true;
2429 simplelist_info_init(&info, "FM Radio", 1, NULL);
2430 simplelist_set_line_count(0);
2431 simplelist_addline(SIMPLELIST_ADD_LINE, "HW detected: %s",
2432 radio_hardware_present() ? "yes" : "no");
2434 info.action_callback = radio_hardware_present()?radio_callback : NULL;
2435 info.hide_selection = true;
2436 return simplelist_show_list(&info);
2438 #endif /* CONFIG_TUNER */
2439 #endif /* !SIMULATOR */
2441 #ifdef HAVE_LCD_BITMAP
2442 extern bool do_screendump_instead_of_usb;
2444 static bool dbg_screendump(void)
2446 do_screendump_instead_of_usb = !do_screendump_instead_of_usb;
2447 splashf(HZ, "Screendump %s",
2448 do_screendump_instead_of_usb?"enabled":"disabled");
2449 return false;
2451 #endif /* HAVE_LCD_BITMAP */
2453 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
2454 static bool dbg_set_memory_guard(void)
2456 static const struct opt_items names[MAXMEMGUARD] = {
2457 { "None", -1 },
2458 { "Flash ROM writes", -1 },
2459 { "Zero area (all)", -1 }
2461 int mode = system_memory_guard(MEMGUARD_KEEP);
2463 set_option( "Catch mem accesses", &mode, INT, names, MAXMEMGUARD, NULL);
2464 system_memory_guard(mode);
2466 return false;
2468 #endif /* CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) */
2470 #if defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS)
2471 static bool dbg_write_eeprom(void)
2473 int fd;
2474 int rc;
2475 int old_irq_level;
2476 char buf[EEPROM_SIZE];
2477 int err;
2479 fd = open("/internal_eeprom.bin", O_RDONLY);
2481 if (fd >= 0)
2483 rc = read(fd, buf, EEPROM_SIZE);
2485 if(rc == EEPROM_SIZE)
2487 old_irq_level = disable_irq_save();
2489 err = eeprom_24cxx_write(0, buf, sizeof buf);
2490 if (err)
2491 splashf(HZ*3, "Eeprom write failure (%d)", err);
2492 else
2493 splash(HZ*3, "Eeprom written successfully");
2495 restore_irq(old_irq_level);
2497 else
2499 splashf(HZ*3, "File read error (%d)",rc);
2501 close(fd);
2503 else
2505 splash(HZ*3, "Failed to open 'internal_eeprom.bin'");
2508 return false;
2510 #endif /* defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS) */
2511 #ifdef CPU_BOOST_LOGGING
2512 static bool cpu_boost_log(void)
2514 int i = 0,j=0;
2515 int count = cpu_boost_log_getcount();
2516 int lines = LCD_HEIGHT/SYSFONT_HEIGHT;
2517 char *str;
2518 bool done;
2519 lcd_setfont(FONT_SYSFIXED);
2520 str = cpu_boost_log_getlog_first();
2521 while (i < count)
2523 lcd_clear_display();
2524 for(j=0; j<lines; j++,i++)
2526 if (!str)
2527 str = cpu_boost_log_getlog_next();
2528 if (str)
2530 if(strlen(str) > LCD_WIDTH/SYSFONT_WIDTH)
2531 lcd_puts_scroll(0, j, str);
2532 else
2533 lcd_puts(0, j,str);
2535 str = NULL;
2537 lcd_update();
2538 done = false;
2539 while (!done)
2541 switch(get_action(CONTEXT_STD,TIMEOUT_BLOCK))
2543 case ACTION_STD_OK:
2544 case ACTION_STD_PREV:
2545 case ACTION_STD_NEXT:
2546 done = true;
2547 break;
2548 case ACTION_STD_CANCEL:
2549 i = count;
2550 done = true;
2551 break;
2555 lcd_stop_scroll();
2556 get_action(CONTEXT_STD,TIMEOUT_BLOCK);
2557 lcd_setfont(FONT_UI);
2558 return false;
2560 #endif
2562 #if (defined(HAVE_WHEEL_ACCELERATION) && (CONFIG_KEYPAD==IPOD_4G_PAD) \
2563 && !defined(IPOD_MINI) && !defined(SIMULATOR))
2564 extern bool wheel_is_touched;
2565 extern int old_wheel_value;
2566 extern int new_wheel_value;
2567 extern int wheel_delta;
2568 extern unsigned int accumulated_wheel_delta;
2569 extern unsigned int wheel_velocity;
2571 static bool dbg_scrollwheel(void)
2573 unsigned int speed;
2575 lcd_setfont(FONT_SYSFIXED);
2577 while (1)
2579 if (action_userabort(HZ/10))
2580 break;
2582 lcd_clear_display();
2584 /* show internal variables of scrollwheel driver */
2585 lcd_putsf(0, 0, "wheel touched: %s", (wheel_is_touched) ? "true" : "false");
2586 lcd_putsf(0, 1, "new position: %2d", new_wheel_value);
2587 lcd_putsf(0, 2, "old position: %2d", old_wheel_value);
2588 lcd_putsf(0, 3, "wheel delta: %2d", wheel_delta);
2589 lcd_putsf(0, 4, "accumulated delta: %2d", accumulated_wheel_delta);
2590 lcd_putsf(0, 5, "velo [deg/s]: %4d", (int)wheel_velocity);
2592 /* show effective accelerated scrollspeed */
2593 speed = button_apply_acceleration( (1<<31)|(1<<24)|wheel_velocity);
2594 lcd_putsf(0, 6, "accel. speed: %4d", speed);
2596 lcd_update();
2598 lcd_setfont(FONT_UI);
2599 return false;
2601 #endif
2603 #if defined (HAVE_USBSTACK)
2605 #if defined(ROCKBOX_HAS_LOGF) && defined(USB_ENABLE_SERIAL)
2606 static bool toggle_usb_core_driver(int driver, char *msg)
2608 bool enabled = !usb_core_driver_enabled(driver);
2610 usb_core_enable_driver(driver,enabled);
2611 splashf(HZ, "%s %s", msg, enabled?"enabled":"disabled");
2613 return false;
2616 static bool toggle_usb_serial(void)
2618 return toggle_usb_core_driver(USB_DRIVER_SERIAL,"USB Serial");
2620 #endif
2622 #endif
2624 #if CONFIG_USBOTG == USBOTG_ISP1583
2625 extern int dbg_usb_num_items(void);
2626 extern const char* dbg_usb_item(int selected_item, void *data,
2627 char *buffer, size_t buffer_len);
2629 static int isp1583_action_callback(int action, struct gui_synclist *lists)
2631 (void)lists;
2632 if (action == ACTION_NONE)
2633 action = ACTION_REDRAW;
2634 return action;
2637 static bool dbg_isp1583(void)
2639 struct simplelist_info isp1583;
2640 isp1583.scroll_all = true;
2641 simplelist_info_init(&isp1583, "ISP1583", dbg_usb_num_items(), NULL);
2642 isp1583.timeout = HZ/100;
2643 isp1583.hide_selection = true;
2644 isp1583.get_name = dbg_usb_item;
2645 isp1583.action_callback = isp1583_action_callback;
2646 return simplelist_show_list(&isp1583);
2648 #endif
2650 #if defined(CREATIVE_ZVx) && !defined(SIMULATOR)
2651 extern int pic_dbg_num_items(void);
2652 extern const char* pic_dbg_item(int selected_item, void *data,
2653 char *buffer, size_t buffer_len);
2655 static int pic_action_callback(int action, struct gui_synclist *lists)
2657 (void)lists;
2658 if (action == ACTION_NONE)
2659 action = ACTION_REDRAW;
2660 return action;
2663 static bool dbg_pic(void)
2665 struct simplelist_info pic;
2666 pic.scroll_all = true;
2667 simplelist_info_init(&pic, "PIC", pic_dbg_num_items(), NULL);
2668 pic.timeout = HZ/100;
2669 pic.hide_selection = true;
2670 pic.get_name = pic_dbg_item;
2671 pic.action_callback = pic_action_callback;
2672 return simplelist_show_list(&pic);
2674 #endif
2677 /****** The menu *********/
2678 struct the_menu_item {
2679 unsigned char *desc; /* string or ID */
2680 bool (*function) (void); /* return true if USB was connected */
2682 static const struct the_menu_item menuitems[] = {
2683 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || \
2684 (defined(CPU_PP) && !(CONFIG_STORAGE & STORAGE_SD)) || \
2685 CONFIG_CPU == IMX31L || defined(CPU_TCC780X)
2686 { "Dump ROM contents", dbg_save_roms },
2687 #endif
2688 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || defined(CPU_PP) \
2689 || CONFIG_CPU == S3C2440 || CONFIG_CPU == IMX31L || CONFIG_CPU == AS3525 \
2690 || CONFIG_CPU == DM320 || defined(CPU_S5L870X) || CONFIG_CPU == AS3525v2
2691 { "View I/O ports", dbg_ports },
2692 #endif
2693 #if (CONFIG_RTC == RTC_PCF50605) && (CONFIG_PLATFORM & PLATFORM_NATIVE)
2694 { "View PCF registers", dbg_pcf },
2695 #endif
2696 #if defined(HAVE_TSC2100) && (CONFIG_PLATFORM & PLATFORM_NATIVE)
2697 { "TSC2100 debug", tsc2100_debug },
2698 #endif
2699 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
2700 { "CPU frequency", dbg_cpufreq },
2701 #endif
2702 #if defined(IRIVER_H100_SERIES) && !defined(SIMULATOR)
2703 { "S/PDIF analyzer", dbg_spdif },
2704 #endif
2705 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
2706 { "Catch mem accesses", dbg_set_memory_guard },
2707 #endif
2708 { "View OS stacks", dbg_os },
2709 #ifdef HAVE_LCD_BITMAP
2710 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
2711 { "View battery", view_battery },
2712 #endif
2713 { "Screendump", dbg_screendump },
2714 #endif
2715 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
2716 { "View HW info", dbg_hw_info },
2717 #endif
2718 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
2719 { "View partitions", dbg_partitions },
2720 #endif
2721 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
2722 { "View disk info", dbg_disk_info },
2723 #if (CONFIG_STORAGE & STORAGE_ATA)
2724 { "Dump ATA identify info", dbg_identify_info},
2725 #endif
2726 #endif
2727 #ifdef HAVE_DIRCACHE
2728 { "View dircache info", dbg_dircache_info },
2729 #endif
2730 #ifdef HAVE_TAGCACHE
2731 { "View database info", dbg_tagcache_info },
2732 #endif
2733 #ifdef HAVE_LCD_BITMAP
2734 #if CONFIG_CODEC == SWCODEC
2735 { "View buffering thread", dbg_buffering_thread },
2736 #elif !defined(SIMULATOR)
2737 { "View audio thread", dbg_audio_thread },
2738 #endif
2739 #ifdef PM_DEBUG
2740 { "pm histogram", peak_meter_histogram},
2741 #endif /* PM_DEBUG */
2742 #endif /* HAVE_LCD_BITMAP */
2743 #ifndef SIMULATOR
2744 #if CONFIG_TUNER
2745 { "FM Radio", dbg_fm_radio },
2746 #endif
2747 #endif
2748 #if defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS)
2749 { "Write back EEPROM", dbg_write_eeprom },
2750 #endif
2751 #if CONFIG_USBOTG == USBOTG_ISP1583
2752 { "View ISP1583 info", dbg_isp1583 },
2753 #endif
2754 #if defined(CREATIVE_ZVx) && !defined(SIMULATOR)
2755 { "View PIC info", dbg_pic },
2756 #endif
2757 #ifdef ROCKBOX_HAS_LOGF
2758 {"Show Log File", logfdisplay },
2759 {"Dump Log File", logfdump },
2760 #endif
2761 #if defined(HAVE_USBSTACK)
2762 #if defined(ROCKBOX_HAS_LOGF) && defined(USB_ENABLE_SERIAL)
2763 {"USB Serial driver (logf)", toggle_usb_serial },
2764 #endif
2765 #endif /* HAVE_USBSTACK */
2766 #ifdef CPU_BOOST_LOGGING
2767 {"cpu_boost log",cpu_boost_log},
2768 #endif
2769 #if (defined(HAVE_WHEEL_ACCELERATION) && (CONFIG_KEYPAD==IPOD_4G_PAD) \
2770 && !defined(IPOD_MINI) && !defined(SIMULATOR))
2771 {"Debug scrollwheel", dbg_scrollwheel },
2772 #endif
2774 static int menu_action_callback(int btn, struct gui_synclist *lists)
2776 int i;
2777 if (btn == ACTION_STD_OK)
2779 FOR_NB_SCREENS(i)
2780 viewportmanager_theme_enable(i, false, NULL);
2781 menuitems[gui_synclist_get_sel_pos(lists)].function();
2782 btn = ACTION_REDRAW;
2783 FOR_NB_SCREENS(i)
2784 viewportmanager_theme_undo(i, false);
2786 return btn;
2789 static const char* dbg_menu_getname(int item, void * data,
2790 char *buffer, size_t buffer_len)
2792 (void)data; (void)buffer; (void)buffer_len;
2793 return menuitems[item].desc;
2796 bool debug_menu(void)
2798 struct simplelist_info info;
2800 simplelist_info_init(&info, "Debug Menu", ARRAYLEN(menuitems), NULL);
2801 info.action_callback = menu_action_callback;
2802 info.get_name = dbg_menu_getname;
2803 return simplelist_show_list(&info);