Fix yellow.
[kugel-rb.git] / apps / debug_menu.c
bloba43dd0a768c5fc4f2bb864ce1d8ebd6d86689e9d
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 "eeprom_24cxx.h"
65 #if (CONFIG_STORAGE & STORAGE_MMC) || (CONFIG_STORAGE & STORAGE_SD)
66 #include "sdmmc.h"
67 #endif
68 #if (CONFIG_STORAGE & STORAGE_ATA)
69 #include "ata.h"
70 #endif
71 #if CONFIG_TUNER
72 #include "tuner.h"
73 #include "radio.h"
74 #endif
75 #endif
77 #ifdef HAVE_LCD_BITMAP
78 #include "scrollbar.h"
79 #include "peakmeter.h"
80 #endif
81 #include "logfdisp.h"
82 #if CONFIG_CODEC == SWCODEC
83 #include "pcmbuf.h"
84 #include "buffering.h"
85 #include "playback.h"
86 #if defined(HAVE_SPDIF_OUT) || defined(HAVE_SPDIF_IN)
87 #include "spdif.h"
88 #endif
89 #endif
90 #ifdef IRIVER_H300_SERIES
91 #include "pcf50606.h" /* for pcf50606_read */
92 #endif
93 #ifdef IAUDIO_X5
94 #include "ds2411.h"
95 #endif
96 #include "hwcompat.h"
97 #include "button.h"
98 #if CONFIG_RTC == RTC_PCF50605
99 #include "pcf50605.h"
100 #endif
101 #include "appevents.h"
102 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
103 #include "debug-target.h"
104 #endif
106 #if defined(SANSA_E200) || defined(SANSA_C200) || defined(PHILIPS_SA9200) \
107 || (CONFIG_CPU == AS3525 && defined(CONFIG_CHARGING)) \
108 || CONFIG_CPU == AS3525v2
109 #include "ascodec.h"
110 #include "as3514.h"
111 #endif
113 #ifdef IPOD_NANO2G
114 #include "pmu-target.h"
115 #endif
117 #ifdef HAVE_USBSTACK
118 #include "usb_core.h"
119 #endif
121 #if defined(IPOD_ACCESSORY_PROTOCOL)
122 #include "iap.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, freq_sum;
276 #ifndef CPU_MULTI_FREQUENCY
277 static unsigned int boost_ticks;
278 #endif
280 static void dbg_audio_task(void)
282 #ifdef CPUFREQ_NORMAL
283 #ifndef CPU_MULTI_FREQUENCY
284 if(FREQ > CPUFREQ_NORMAL)
285 boost_ticks++;
286 #endif
287 freq_sum += FREQ/1000000; /* in MHz */
288 #endif
289 ticks++;
292 static bool dbg_buffering_thread(void)
294 int button;
295 int line, i;
296 bool done = false;
297 size_t bufused;
298 size_t bufsize = pcmbuf_get_bufsize();
299 int pcmbufdescs = pcmbuf_descs();
300 struct buffering_debug d;
301 size_t filebuflen = audio_get_filebuflen();
302 /* This is a size_t, but call it a long so it puts a - when it's bad. */
304 #ifndef CPU_MULTI_FREQUENCY
305 boost_ticks = 0;
306 #endif
307 ticks = freq_sum = 0;
309 tick_add_task(dbg_audio_task);
311 FOR_NB_SCREENS(i)
312 screens[i].setfont(FONT_SYSFIXED);
314 while(!done)
316 button = get_action(CONTEXT_STD,HZ/5);
317 switch(button)
319 case ACTION_STD_NEXT:
320 audio_next();
321 break;
322 case ACTION_STD_PREV:
323 audio_prev();
324 break;
325 case ACTION_STD_CANCEL:
326 done = true;
327 break;
330 buffering_get_debugdata(&d);
331 bufused = bufsize - pcmbuf_free();
333 FOR_NB_SCREENS(i)
335 line = 0;
336 screens[i].clear_display();
339 screens[i].putsf(0, line++, "pcm: %6ld/%ld", (long) bufused, (long) bufsize);
341 gui_scrollbar_draw(&screens[i],0, line*8, screens[i].lcdwidth, 6,
342 bufsize, 0, bufused, HORIZONTAL);
343 line++;
345 screens[i].putsf(0, line++, "alloc: %6ld/%ld", audio_filebufused(),
346 (long) filebuflen);
348 #if LCD_HEIGHT > 80 || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_HEIGHT > 80)
349 if (screens[i].lcdheight > 80)
351 gui_scrollbar_draw(&screens[i],0, line*8, screens[i].lcdwidth, 6,
352 filebuflen, 0, audio_filebufused(), HORIZONTAL);
353 line++;
355 screens[i].putsf(0, line++, "real: %6ld/%ld", (long)d.buffered_data,
356 (long)filebuflen);
358 gui_scrollbar_draw(&screens[i],0, line*8, screens[i].lcdwidth, 6,
359 filebuflen, 0, (long)d.buffered_data, HORIZONTAL);
360 line++;
362 #endif
364 screens[i].putsf(0, line++, "usefl: %6ld/%ld", (long)(d.useful_data),
365 (long)filebuflen);
367 #if LCD_HEIGHT > 80 || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_HEIGHT > 80)
368 if (screens[i].lcdheight > 80)
370 gui_scrollbar_draw(&screens[i],0, line*8, screens[i].lcdwidth, 6,
371 filebuflen, 0, d.useful_data, HORIZONTAL);
372 line++;
374 #endif
376 screens[i].putsf(0, line++, "data_rem: %ld", (long)d.data_rem);
378 screens[i].putsf(0, line++, "track count: %2d", audio_track_count());
380 screens[i].putsf(0, line++, "handle count: %d", (int)d.num_handles);
382 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
383 screens[i].putsf(0, line++, "cpu freq: %3dMHz",
384 (int)((FREQ + 500000) / 1000000));
385 #endif
387 if (ticks > 0)
389 int avgclock = freq_sum * 10 / ticks; /* in 100 kHz */
390 #ifdef CPU_MULTI_FREQUENCY
391 int boostquota = (avgclock * 100 - CPUFREQ_NORMAL/1000) /
392 ((CPUFREQ_MAX - CPUFREQ_NORMAL) / 1000000); /* in 0.1 % */
393 #else
394 int boostquota = boost_ticks * 1000 / ticks; /* in 0.1 % */
395 #endif
396 screens[i].putsf(0, line++, "boost:%3d.%d%% (%d.%dMHz)",
397 boostquota/10, boostquota%10, avgclock/10, avgclock%10);
400 screens[i].putsf(0, line++, "pcmbufdesc: %2d/%2d",
401 pcmbuf_used_descs(), pcmbufdescs);
402 screens[i].putsf(0, line++, "watermark: %6d",
403 (int)(d.watermark));
405 screens[i].update();
409 tick_remove_task(dbg_audio_task);
411 FOR_NB_SCREENS(i)
412 screens[i].setfont(FONT_UI);
414 return false;
416 #endif /* CONFIG_CODEC */
417 #endif /* HAVE_LCD_BITMAP */
420 #if (CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE))
421 /* Tool function to read the flash manufacturer and type, if available.
422 Only chips which could be reprogrammed in system will return values.
423 (The mode switch addresses vary between flash manufacturers, hence addr1/2) */
424 /* In IRAM to avoid problems when running directly from Flash */
425 static bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
426 unsigned addr1, unsigned addr2)
427 ICODE_ATTR __attribute__((noinline));
428 static bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
429 unsigned addr1, unsigned addr2)
432 unsigned not_manu, not_id; /* read values before switching to ID mode */
433 unsigned manu, id; /* read values when in ID mode */
435 #if CONFIG_CPU == SH7034
436 volatile unsigned char* flash = (unsigned char*)0x2000000; /* flash mapping */
437 #elif defined(CPU_COLDFIRE)
438 volatile unsigned short* flash = (unsigned short*)0; /* flash mapping */
439 #endif
440 int old_level; /* saved interrupt level */
442 not_manu = flash[0]; /* read the normal content */
443 not_id = flash[1]; /* should be 'A' (0x41) and 'R' (0x52) from the "ARCH" marker */
445 /* disable interrupts, prevent any stray flash access */
446 old_level = disable_irq_save();
448 flash[addr1] = 0xAA; /* enter command mode */
449 flash[addr2] = 0x55;
450 flash[addr1] = 0x90; /* ID command */
451 /* Atmel wants 20ms pause here */
452 /* sleep(HZ/50); no sleeping possible while interrupts are disabled */
454 manu = flash[0]; /* read the IDs */
455 id = flash[1];
457 flash[0] = 0xF0; /* reset flash (back to normal read mode) */
458 /* Atmel wants 20ms pause here */
459 /* sleep(HZ/50); no sleeping possible while interrupts are disabled */
461 restore_irq(old_level); /* enable interrupts again */
463 /* I assume success if the obtained values are different from
464 the normal flash content. This is not perfectly bulletproof, they
465 could theoretically be the same by chance, causing us to fail. */
466 if (not_manu != manu || not_id != id) /* a value has changed */
468 *p_manufacturer = manu; /* return the results */
469 *p_device = id;
470 return true; /* success */
472 return false; /* fail */
474 #endif /* (CONFIG_CPU == SH7034 || CPU_COLDFIRE) */
476 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
477 #ifdef CPU_PP
478 static int perfcheck(void)
480 int result;
482 asm (
483 "mrs r2, CPSR \n"
484 "orr r0, r2, #0xc0 \n" /* disable IRQ and FIQ */
485 "msr CPSR_c, r0 \n"
486 "mov %[res], #0 \n"
487 "ldr r0, [%[timr]] \n"
488 "add r0, r0, %[tmo] \n"
489 "1: \n"
490 "add %[res], %[res], #1 \n"
491 "ldr r1, [%[timr]] \n"
492 "cmp r1, r0 \n"
493 "bmi 1b \n"
494 "msr CPSR_c, r2 \n" /* reset IRQ and FIQ state */
496 [res]"=&r"(result)
498 [timr]"r"(&USEC_TIMER),
499 [tmo]"r"(
500 #if CONFIG_CPU == PP5002
501 16000
502 #else /* PP5020/5022/5024 */
503 10226
504 #endif
507 "r0", "r1", "r2"
509 return result;
511 #endif
513 #ifdef HAVE_LCD_BITMAP
514 static bool dbg_hw_info(void)
516 #if CONFIG_CPU == SH7034
517 int bitmask = HW_MASK;
518 int rom_version = ROM_VERSION;
519 unsigned manu, id; /* flash IDs */
520 bool got_id; /* flag if we managed to get the flash IDs */
521 unsigned rom_crc = 0xffffffff; /* CRC32 of the boot ROM */
522 bool has_bootrom; /* flag for boot ROM present */
523 int oldmode; /* saved memory guard mode */
525 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
527 /* get flash ROM type */
528 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
529 if (!got_id)
530 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
532 /* check if the boot ROM area is a flash mirror */
533 has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0);
534 if (has_bootrom) /* if ROM and Flash different */
536 /* calculate CRC16 checksum of boot ROM */
537 rom_crc = crc_32((unsigned char*)0x0000, 64*1024, 0xffffffff);
540 system_memory_guard(oldmode); /* re-enable memory guard */
542 lcd_setfont(FONT_SYSFIXED);
543 lcd_clear_display();
545 lcd_puts(0, 0, "[Hardware info]");
547 lcd_putsf(0, 1, "ROM: %d.%02d", rom_version/100, rom_version%100);
549 lcd_putsf(0, 2, "Mask: 0x%04x", bitmask);
551 if (got_id)
552 lcd_putsf(0, 3, "Flash: M=%02x D=%02x", manu, id);
553 else
554 lcd_puts(0, 3, "Flash: M=?? D=??"); /* unknown, sorry */
556 if (has_bootrom)
558 if (rom_crc == 0x56DBA4EE) /* known Version 1 */
559 lcd_puts(0, 4, "Boot ROM: V1");
560 else
561 lcd_putsf(0, 4, "ROMcrc: 0x%08x", rom_crc);
563 else
565 lcd_puts(0, 4, "Boot ROM: none");
568 lcd_update();
570 while (!(action_userabort(TIMEOUT_BLOCK)));
572 #elif CONFIG_CPU == MCF5249 || CONFIG_CPU == MCF5250
573 unsigned manu, id; /* flash IDs */
574 int got_id; /* flag if we managed to get the flash IDs */
575 int oldmode; /* saved memory guard mode */
576 int line = 0;
578 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
580 /* get flash ROM type */
581 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
582 if (!got_id)
583 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
585 system_memory_guard(oldmode); /* re-enable memory guard */
587 lcd_setfont(FONT_SYSFIXED);
588 lcd_clear_display();
590 lcd_puts(0, line++, "[Hardware info]");
592 if (got_id)
593 lcd_putsf(0, line++, "Flash: M=%04x D=%04x", manu, id);
594 else
595 lcd_puts(0, line++, "Flash: M=???? D=????"); /* unknown, sorry */
597 #ifdef IAUDIO_X5
599 struct ds2411_id id;
601 lcd_puts(0, ++line, "Serial Number:");
603 got_id = ds2411_read_id(&id);
605 if (got_id == DS2411_OK)
607 lcd_putsf(0, ++line, " FC=%02x", (unsigned)id.family_code);
608 lcd_putsf(0, ++line, " ID=%02X %02X %02X %02X %02X %02X",
609 (unsigned)id.uid[0], (unsigned)id.uid[1], (unsigned)id.uid[2],
610 (unsigned)id.uid[3], (unsigned)id.uid[4], (unsigned)id.uid[5]);
611 lcd_putsf(0, ++line, " CRC=%02X", (unsigned)id.crc);
613 else
615 lcd_putsf(0, ++line, "READ ERR=%d", got_id);
618 #endif
620 lcd_update();
622 while (!(action_userabort(TIMEOUT_BLOCK)));
624 #elif defined(CPU_PP502x)
625 int line = 0;
626 char pp_version[] = { (PP_VER2 >> 24) & 0xff, (PP_VER2 >> 16) & 0xff,
627 (PP_VER2 >> 8) & 0xff, (PP_VER2) & 0xff,
628 (PP_VER1 >> 24) & 0xff, (PP_VER1 >> 16) & 0xff,
629 (PP_VER1 >> 8) & 0xff, (PP_VER1) & 0xff, '\0' };
631 lcd_setfont(FONT_SYSFIXED);
632 lcd_clear_display();
634 lcd_puts(0, line++, "[Hardware info]");
636 #ifdef IPOD_ARCH
637 lcd_putsf(0, line++, "HW rev: 0x%08lx", IPOD_HW_REVISION);
638 #endif
640 #ifdef IPOD_COLOR
641 extern int lcd_type; /* Defined in lcd-colornano.c */
643 lcd_putsf(0, line++, "LCD type: %d", lcd_type);
644 #endif
646 lcd_putsf(0, line++, "PP version: %s", pp_version);
648 lcd_putsf(0, line++, "Est. clock (kHz): %d", perfcheck());
650 lcd_update();
652 while (!(action_userabort(TIMEOUT_BLOCK)));
654 #elif CONFIG_CPU == PP5002
655 int line = 0;
656 char pp_version[] = { (PP_VER4 >> 8) & 0xff, PP_VER4 & 0xff,
657 (PP_VER3 >> 8) & 0xff, PP_VER3 & 0xff,
658 (PP_VER2 >> 8) & 0xff, PP_VER2 & 0xff,
659 (PP_VER1 >> 8) & 0xff, PP_VER1 & 0xff, '\0' };
662 lcd_setfont(FONT_SYSFIXED);
663 lcd_clear_display();
665 lcd_puts(0, line++, "[Hardware info]");
667 #ifdef IPOD_ARCH
668 lcd_putsf(0, line++, "HW rev: 0x%08lx", IPOD_HW_REVISION);
669 #endif
671 lcd_putsf(0, line++, "PP version: %s", pp_version);
673 lcd_putsf(0, line++, "Est. clock (kHz): %d", perfcheck());
675 lcd_update();
677 while (!(action_userabort(TIMEOUT_BLOCK)));
679 #else
680 /* Define this function in your target tree */
681 return __dbg_hw_info();
682 #endif /* CONFIG_CPU */
683 lcd_setfont(FONT_UI);
684 return false;
686 #else /* !HAVE_LCD_BITMAP */
687 static bool dbg_hw_info(void)
689 int button;
690 int currval = 0;
691 int rom_version = ROM_VERSION;
692 unsigned manu, id; /* flash IDs */
693 bool got_id; /* flag if we managed to get the flash IDs */
694 unsigned rom_crc = 0xffffffff; /* CRC32 of the boot ROM */
695 bool has_bootrom; /* flag for boot ROM present */
696 int oldmode; /* saved memory guard mode */
698 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
700 /* get flash ROM type */
701 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
702 if (!got_id)
703 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
705 /* check if the boot ROM area is a flash mirror */
706 has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0);
707 if (has_bootrom) /* if ROM and Flash different */
709 /* calculate CRC16 checksum of boot ROM */
710 rom_crc = crc_32((unsigned char*)0x0000, 64*1024, 0xffffffff);
713 system_memory_guard(oldmode); /* re-enable memory guard */
715 lcd_clear_display();
717 lcd_puts(0, 0, "[HW Info]");
718 while(1)
720 switch(currval)
722 case 0:
723 lcd_putsf(0, 1, "ROM: %d.%02d",
724 rom_version/100, rom_version%100);
725 break;
726 case 1:
727 if (got_id)
728 lcd_putsf(0, 1, "Flash:%02x,%02x", manu, id);
729 else
730 lcd_puts(0, 1, "Flash:??,??"); /* unknown, sorry */
731 break;
732 case 2:
733 if (has_bootrom)
735 if (rom_crc == 0x56DBA4EE) /* known Version 1 */
736 lcd_puts(0, 1, "BootROM: V1");
737 else if (rom_crc == 0x358099E8)
738 lcd_puts(0, 1, "BootROM: V2");
739 /* alternative boot ROM found in one single player so far */
740 else
741 lcd_putsf(0, 1, "R: %08x", rom_crc);
743 else
744 lcd_puts(0, 1, "BootROM: no");
747 lcd_update();
749 button = get_action(CONTEXT_SETTINGS,TIMEOUT_BLOCK);
751 switch(button)
753 case ACTION_STD_CANCEL:
754 return false;
756 case ACTION_SETTINGS_DEC:
757 currval--;
758 if(currval < 0)
759 currval = 2;
760 break;
762 case ACTION_SETTINGS_INC:
763 currval++;
764 if(currval > 2)
765 currval = 0;
766 break;
769 return false;
771 #endif /* !HAVE_LCD_BITMAP */
772 #endif /* PLATFORM_NATIVE */
774 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
775 static const char* dbg_partitions_getname(int selected_item, void *data,
776 char *buffer, size_t buffer_len)
778 (void)data;
779 int partition = selected_item/2;
780 struct partinfo* p = disk_partinfo(partition);
781 if (selected_item%2)
783 snprintf(buffer, buffer_len, " T:%x %ld MB", p->type, p->size / ( 2048 / ( SECTOR_SIZE / 512 )));
785 else
787 snprintf(buffer, buffer_len, "P%d: S:%lx", partition, p->start);
789 return buffer;
792 bool dbg_partitions(void)
794 struct simplelist_info info;
795 simplelist_info_init(&info, "Partition Info", 4, NULL);
796 info.selection_size = 2;
797 info.hide_selection = true;
798 info.scroll_all = true;
799 info.get_name = dbg_partitions_getname;
800 return simplelist_show_list(&info);
802 #endif /* PLATFORM_NATIVE */
804 #if defined(CPU_COLDFIRE) && defined(HAVE_SPDIF_OUT)
805 static bool dbg_spdif(void)
807 int line;
808 unsigned int control;
809 int x;
810 char *s;
811 int category;
812 int generation;
813 unsigned int interruptstat;
814 bool valnogood, symbolerr, parityerr;
815 bool done = false;
816 bool spdif_src_on;
817 int spdif_source = spdif_get_output_source(&spdif_src_on);
818 spdif_set_output_source(AUDIO_SRC_SPDIF IF_SPDIF_POWER_(, true));
820 lcd_clear_display();
821 lcd_setfont(FONT_SYSFIXED);
823 #ifdef HAVE_SPDIF_POWER
824 spdif_power_enable(true); /* We need SPDIF power for both sending & receiving */
825 #endif
827 while (!done)
829 line = 0;
831 control = EBU1RCVCCHANNEL1;
832 interruptstat = INTERRUPTSTAT;
833 INTERRUPTCLEAR = 0x03c00000;
835 valnogood = (interruptstat & 0x01000000)?true:false;
836 symbolerr = (interruptstat & 0x00800000)?true:false;
837 parityerr = (interruptstat & 0x00400000)?true:false;
839 lcd_putsf(0, line++, "Val: %s Sym: %s Par: %s",
840 valnogood?"--":"OK",
841 symbolerr?"--":"OK",
842 parityerr?"--":"OK");
844 lcd_putsf(0, line++, "Status word: %08x", (int)control);
846 line++;
848 x = control >> 31;
849 lcd_putsf(0, line++, "PRO: %d (%s)",
850 x, x?"Professional":"Consumer");
852 x = (control >> 30) & 1;
853 lcd_putsf(0, line++, "Audio: %d (%s)",
854 x, x?"Non-PCM":"PCM");
856 x = (control >> 29) & 1;
857 lcd_putsf(0, line++, "Copy: %d (%s)",
858 x, x?"Permitted":"Inhibited");
860 x = (control >> 27) & 7;
861 switch(x)
863 case 0:
864 s = "None";
865 break;
866 case 1:
867 s = "50/15us";
868 break;
869 default:
870 s = "Reserved";
871 break;
873 lcd_putsf(0, line++, "Preemphasis: %d (%s)", x, s);
875 x = (control >> 24) & 3;
876 lcd_putsf(0, line++, "Mode: %d", x);
878 category = (control >> 17) & 127;
879 switch(category)
881 case 0x00:
882 s = "General";
883 break;
884 case 0x40:
885 s = "Audio CD";
886 break;
887 default:
888 s = "Unknown";
890 lcd_putsf(0, line++, "Category: 0x%02x (%s)", category, s);
892 x = (control >> 16) & 1;
893 generation = x;
894 if(((category & 0x70) == 0x10) ||
895 ((category & 0x70) == 0x40) ||
896 ((category & 0x78) == 0x38))
898 generation = !generation;
900 lcd_putsf(0, line++, "Generation: %d (%s)",
901 x, generation?"Original":"No ind.");
903 x = (control >> 12) & 15;
904 lcd_putsf(0, line++, "Source: %d", x);
907 x = (control >> 8) & 15;
908 switch(x)
910 case 0:
911 s = "Unspecified";
912 break;
913 case 8:
914 s = "A (Left)";
915 break;
916 case 4:
917 s = "B (Right)";
918 break;
919 default:
920 s = "";
921 break;
923 lcd_putsf(0, line++, "Channel: %d (%s)", x, s);
925 x = (control >> 4) & 15;
926 switch(x)
928 case 0:
929 s = "44.1kHz";
930 break;
931 case 0x4:
932 s = "48kHz";
933 break;
934 case 0xc:
935 s = "32kHz";
936 break;
938 lcd_putsf(0, line++, "Frequency: %d (%s)", x, s);
940 x = (control >> 2) & 3;
941 lcd_putsf(0, line++, "Clock accuracy: %d", x);
942 line++;
944 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
945 lcd_putsf(0, line++, "Measured freq: %ldHz",
946 spdif_measure_frequency());
947 #endif
949 lcd_update();
951 if (action_userabort(HZ/10))
952 break;
955 spdif_set_output_source(spdif_source IF_SPDIF_POWER_(, spdif_src_on));
957 #ifdef HAVE_SPDIF_POWER
958 spdif_power_enable(global_settings.spdif_enable);
959 #endif
961 lcd_setfont(FONT_UI);
962 return false;
964 #endif /* CPU_COLDFIRE */
966 #if (CONFIG_RTC == RTC_PCF50605) && (CONFIG_PLATFORM & PLATFORM_NATIVE)
967 static bool dbg_pcf(void)
969 int line;
971 #ifdef HAVE_LCD_BITMAP
972 lcd_setfont(FONT_SYSFIXED);
973 #endif
974 lcd_clear_display();
976 while(1)
978 line = 0;
980 lcd_putsf(0, line++, "DCDC1: %02x", pcf50605_read(0x1b));
981 lcd_putsf(0, line++, "DCDC2: %02x", pcf50605_read(0x1c));
982 lcd_putsf(0, line++, "DCDC3: %02x", pcf50605_read(0x1d));
983 lcd_putsf(0, line++, "DCDC4: %02x", pcf50605_read(0x1e));
984 lcd_putsf(0, line++, "DCDEC1: %02x", pcf50605_read(0x1f));
985 lcd_putsf(0, line++, "DCDEC2: %02x", pcf50605_read(0x20));
986 lcd_putsf(0, line++, "DCUDC1: %02x", pcf50605_read(0x21));
987 lcd_putsf(0, line++, "DCUDC2: %02x", pcf50605_read(0x22));
988 lcd_putsf(0, line++, "IOREGC: %02x", pcf50605_read(0x23));
989 lcd_putsf(0, line++, "D1REGC: %02x", pcf50605_read(0x24));
990 lcd_putsf(0, line++, "D2REGC: %02x", pcf50605_read(0x25));
991 lcd_putsf(0, line++, "D3REGC: %02x", pcf50605_read(0x26));
992 lcd_putsf(0, line++, "LPREG1: %02x", pcf50605_read(0x27));
993 lcd_update();
994 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
996 lcd_setfont(FONT_UI);
997 return false;
1001 lcd_setfont(FONT_UI);
1002 return false;
1004 #endif
1006 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
1007 static bool dbg_cpufreq(void)
1009 int line;
1010 int button;
1012 #ifdef HAVE_LCD_BITMAP
1013 lcd_setfont(FONT_SYSFIXED);
1014 #endif
1015 lcd_clear_display();
1017 while(1)
1019 line = 0;
1021 lcd_putsf(0, line++, "Frequency: %ld", FREQ);
1022 lcd_putsf(0, line++, "boost_counter: %d", get_cpu_boost_counter());
1024 lcd_update();
1025 button = get_action(CONTEXT_STD,HZ/10);
1027 switch(button)
1029 case ACTION_STD_PREV:
1030 cpu_boost(true);
1031 break;
1033 case ACTION_STD_NEXT:
1034 cpu_boost(false);
1035 break;
1037 case ACTION_STD_OK:
1038 while (get_cpu_boost_counter() > 0)
1039 cpu_boost(false);
1040 set_cpu_frequency(CPUFREQ_DEFAULT);
1041 break;
1043 case ACTION_STD_CANCEL:
1044 lcd_setfont(FONT_UI);
1045 return false;
1048 lcd_setfont(FONT_UI);
1049 return false;
1051 #endif /* HAVE_ADJUSTABLE_CPU_FREQ */
1053 #if defined(HAVE_TSC2100) && (CONFIG_PLATFORM & PLATFORM_NATIVE)
1054 #include "tsc2100.h"
1055 static const char* tsc2100_debug_getname(int selected_item, void * data,
1056 char *buffer, size_t buffer_len)
1058 int *page = (int*)data;
1059 bool reserved = false;
1060 switch (*page)
1062 case 0:
1063 if ((selected_item > 0x0a) ||
1064 (selected_item == 0x04) ||
1065 (selected_item == 0x08))
1066 reserved = true;
1067 break;
1068 case 1:
1069 if ((selected_item > 0x05) ||
1070 (selected_item == 0x02))
1071 reserved = true;
1072 break;
1073 case 2:
1074 if (selected_item > 0x1e)
1075 reserved = true;
1076 break;
1078 if (reserved)
1079 snprintf(buffer, buffer_len, "%02x: RSVD", selected_item);
1080 else
1081 snprintf(buffer, buffer_len, "%02x: %04x", selected_item,
1082 tsc2100_readreg(*page, selected_item)&0xffff);
1083 return buffer;
1085 static int tsc2100debug_action_callback(int action, struct gui_synclist *lists)
1087 int *page = (int*)lists->data;
1088 if (action == ACTION_STD_OK)
1090 *page = (*page+1)%3;
1091 snprintf(lists->title, 32,
1092 "tsc2100 registers - Page %d", *page);
1093 return ACTION_REDRAW;
1095 return action;
1097 static bool tsc2100_debug(void)
1099 int page = 0;
1100 char title[32] = "tsc2100 registers - Page 0";
1101 struct simplelist_info info;
1102 simplelist_info_init(&info, title, 32, &page);
1103 info.timeout = HZ/100;
1104 info.get_name = tsc2100_debug_getname;
1105 info.action_callback= tsc2100debug_action_callback;
1106 return simplelist_show_list(&info);
1108 #endif
1109 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
1110 #ifdef HAVE_LCD_BITMAP
1112 * view_battery() shows a automatically scaled graph of the battery voltage
1113 * over time. Usable for estimating battery life / charging rate.
1114 * The power_history array is updated in power_thread of powermgmt.c.
1117 #define BAT_LAST_VAL MIN(LCD_WIDTH, POWER_HISTORY_LEN)
1118 #define BAT_YSPACE (LCD_HEIGHT - 20)
1121 static bool view_battery(void)
1123 int view = 0;
1124 int i, x, y, y1, y2, grid, graph;
1125 unsigned short maxv, minv;
1127 lcd_setfont(FONT_SYSFIXED);
1129 while(1)
1131 lcd_clear_display();
1132 switch (view) {
1133 case 0: /* voltage history graph */
1134 /* Find maximum and minimum voltage for scaling */
1135 minv = power_history[0];
1136 maxv = minv + 1;
1137 for (i = 1; i < BAT_LAST_VAL && power_history[i]; i++) {
1138 if (power_history[i] > maxv)
1139 maxv = power_history[i];
1140 if (power_history[i] < minv)
1141 minv = power_history[i];
1144 /* adjust grid scale */
1145 if ((maxv - minv) > 50)
1146 grid = 50;
1147 else
1148 grid = 5;
1150 /* print header */
1151 lcd_putsf(0, 0, "battery %d.%03dV", power_history[0] / 1000,
1152 power_history[0] % 1000);
1153 lcd_putsf(0, 1, "%d.%03d-%d.%03dV (%2dmV)",
1154 minv / 1000, minv % 1000, maxv / 1000, maxv % 1000,
1155 grid);
1157 i = 1;
1158 while ((y = (minv - (minv % grid)+i*grid)) < maxv)
1160 graph = ((y-minv)*BAT_YSPACE)/(maxv-minv);
1161 graph = LCD_HEIGHT-1 - graph;
1163 /* draw dotted horizontal grid line */
1164 for (x=0; x<LCD_WIDTH;x=x+2)
1165 lcd_drawpixel(x,graph);
1167 i++;
1170 x = 0;
1171 /* draw plot of power history
1172 * skip empty entries
1174 for (i = BAT_LAST_VAL - 1; i > 0; i--)
1176 if (power_history[i] && power_history[i-1])
1178 y1 = (power_history[i] - minv) * BAT_YSPACE /
1179 (maxv - minv);
1180 y1 = MIN(MAX(LCD_HEIGHT-1 - y1, 20),
1181 LCD_HEIGHT-1);
1182 y2 = (power_history[i-1] - minv) * BAT_YSPACE /
1183 (maxv - minv);
1184 y2 = MIN(MAX(LCD_HEIGHT-1 - y2, 20),
1185 LCD_HEIGHT-1);
1187 lcd_set_drawmode(DRMODE_SOLID);
1189 /* make line thicker */
1190 lcd_drawline(((x*LCD_WIDTH)/(BAT_LAST_VAL)),
1191 y1,
1192 (((x+1)*LCD_WIDTH)/(BAT_LAST_VAL)),
1193 y2);
1194 lcd_drawline(((x*LCD_WIDTH)/(BAT_LAST_VAL))+1,
1195 y1+1,
1196 (((x+1)*LCD_WIDTH)/(BAT_LAST_VAL))+1,
1197 y2+1);
1198 x++;
1201 break;
1203 case 1: /* status: */
1204 #if CONFIG_CHARGING >= CHARGING_MONITOR
1205 lcd_putsf(0, 0, "Pwr status: %s",
1206 charging_state() ? "charging" : "discharging");
1207 #else
1208 lcd_puts(0, 0, "Power status:");
1209 #endif
1210 battery_read_info(&y, NULL);
1211 lcd_putsf(0, 1, "Battery: %d.%03d V", y / 1000, y % 1000);
1212 #ifdef ADC_EXT_POWER
1213 y = (adc_read(ADC_EXT_POWER) * EXT_SCALE_FACTOR) / 1000;
1214 lcd_putsf(0, 2, "External: %d.%03d V", y / 1000, y % 1000);
1215 #endif
1216 #if CONFIG_CHARGING
1217 #if defined ARCHOS_RECORDER
1218 lcd_putsf(0, 3, "Chgr: %s %s",
1219 charger_inserted() ? "present" : "absent",
1220 charger_enabled() ? "on" : "off");
1221 lcd_putsf(0, 5, "short delta: %d", short_delta);
1222 lcd_putsf(0, 6, "long delta: %d", long_delta);
1223 lcd_puts(0, 7, power_message);
1224 lcd_putsf(0, 8, "USB Inserted: %s",
1225 usb_inserted() ? "yes" : "no");
1226 #elif defined IPOD_NANO || defined IPOD_VIDEO
1227 int usb_pwr = (GPIOL_INPUT_VAL & 0x10)?true:false;
1228 int ext_pwr = (GPIOL_INPUT_VAL & 0x08)?false:true;
1229 int dock = (GPIOA_INPUT_VAL & 0x10)?true:false;
1230 int charging = (GPIOB_INPUT_VAL & 0x01)?false:true;
1231 int headphone= (GPIOA_INPUT_VAL & 0x80)?true:false;
1233 lcd_putsf(0, 3, "USB pwr: %s",
1234 usb_pwr ? "present" : "absent");
1235 lcd_putsf(0, 4, "EXT pwr: %s",
1236 ext_pwr ? "present" : "absent");
1237 lcd_putsf(0, 5, "Battery: %s",
1238 charging ? "charging" : (usb_pwr||ext_pwr) ? "charged" : "discharging");
1239 lcd_putsf(0, 6, "Dock mode: %s",
1240 dock ? "enabled" : "disabled");
1241 lcd_putsf(0, 7, "Headphone: %s",
1242 headphone ? "connected" : "disconnected");
1243 #ifdef IPOD_VIDEO
1244 if(probed_ramsize == 64)
1245 x = (adc_read(ADC_4066_ISTAT) * 2400) / (1024 * 2);
1246 else
1247 x = (adc_read(ADC_4066_ISTAT) * 2400) / (1024 * 3);
1248 lcd_putsf(0, 8, "Ibat: %d mA", x);
1249 lcd_putsf(0, 9, "Vbat * Ibat: %d mW", x * y / 1000);
1250 #endif
1251 #elif defined TOSHIBA_GIGABEAT_S
1252 int line = 3;
1253 unsigned int st;
1255 static const unsigned char * const chrgstate_strings[] =
1257 "Disabled",
1258 "Error",
1259 "Discharging",
1260 "Precharge",
1261 "Constant Voltage",
1262 "Constant Current",
1263 "<unknown>",
1266 lcd_putsf(0, line++, "Charger: %s",
1267 charger_inserted() ? "present" : "absent");
1269 st = power_input_status() &
1270 (POWER_INPUT_CHARGER | POWER_INPUT_BATTERY);
1271 lcd_putsf(0, line++, "%s%s",
1272 (st & POWER_INPUT_MAIN_CHARGER) ? " Main" : "",
1273 (st & POWER_INPUT_USB_CHARGER) ? " USB" : "");
1275 y = ARRAYLEN(chrgstate_strings) - 1;
1277 switch (charge_state)
1279 case CHARGE_STATE_DISABLED: y--;
1280 case CHARGE_STATE_ERROR: y--;
1281 case DISCHARGING: y--;
1282 case TRICKLE: y--;
1283 case TOPOFF: y--;
1284 case CHARGING: y--;
1285 default:;
1288 lcd_putsf(0, line++, "State: %s", chrgstate_strings[y]);
1290 lcd_putsf(0, line++, "Battery Switch: %s",
1291 (st & POWER_INPUT_BATTERY) ? "On" : "Off");
1293 y = chrgraw_adc_voltage();
1294 lcd_putsf(0, line++, "CHRGRAW: %d.%03d V",
1295 y / 1000, y % 1000);
1297 y = application_supply_adc_voltage();
1298 lcd_putsf(0, line++, "BP : %d.%03d V",
1299 y / 1000, y % 1000);
1301 y = battery_adc_charge_current();
1302 if (y < 0) x = '-', y = -y;
1303 else x = ' ';
1304 lcd_putsf(0, line++, "CHRGISN:%c%d mA", x, y);
1306 y = cccv_regulator_dissipation();
1307 lcd_putsf(0, line++, "P CCCV : %d mW", y);
1309 y = battery_charge_current();
1310 if (y < 0) x = '-', y = -y;
1311 else x = ' ';
1312 lcd_putsf(0, line++, "I Charge:%c%d mA", x, y);
1314 y = battery_adc_temp();
1316 if (y != INT_MIN) {
1317 lcd_putsf(0, line++, "T Battery: %dC (%dF)", y,
1318 (9*y + 160) / 5);
1319 } else {
1320 /* Conversion disabled */
1321 lcd_puts(0, line++, "T Battery: ?");
1324 #elif defined(SANSA_E200) || defined(SANSA_C200) || CONFIG_CPU == AS3525 || \
1325 CONFIG_CPU == AS3525v2
1326 static const char * const chrgstate_strings[] =
1328 [CHARGE_STATE_DISABLED - CHARGE_STATE_DISABLED]= "Disabled",
1329 [CHARGE_STATE_ERROR - CHARGE_STATE_DISABLED] = "Error",
1330 [DISCHARGING - CHARGE_STATE_DISABLED] = "Discharging",
1331 [CHARGING - CHARGE_STATE_DISABLED] = "Charging",
1333 const char *str = NULL;
1335 lcd_putsf(0, 3, "Charger: %s",
1336 charger_inserted() ? "present" : "absent");
1338 y = charge_state - CHARGE_STATE_DISABLED;
1339 if ((unsigned)y < ARRAYLEN(chrgstate_strings))
1340 str = chrgstate_strings[y];
1342 lcd_putsf(0, 4, "State: %s",
1343 str ? str : "<unknown>");
1345 lcd_putsf(0, 5, "CHARGER: %02X", ascodec_read_charger());
1346 #elif defined(IPOD_NANO2G)
1347 y = pmu_read_battery_voltage();
1348 lcd_putsf(17, 1, "RAW: %d.%03d V", y / 1000, y % 1000);
1349 y = pmu_read_battery_current();
1350 lcd_putsf(0, 2, "Battery current: %d mA", y);
1351 lcd_putsf(0, 3, "PWRCON: %08x %08x", PWRCON, PWRCONEXT);
1352 lcd_putsf(0, 4, "CLKCON: %08x %03x %03x", CLKCON, CLKCON2, CLKCON3);
1353 lcd_putsf(0, 5, "PLL: %06x %06x %06x", PLL0PMS, PLL1PMS, PLL2PMS);
1354 x = pmu_read(0x1b) & 0xf;
1355 y = pmu_read(0x1a) * 25 + 625;
1356 lcd_putsf(0, 6, "AUTO: %x / %d mV", x, y);
1357 x = pmu_read(0x1f) & 0xf;
1358 y = pmu_read(0x1e) * 25 + 625;
1359 lcd_putsf(0, 7, "DOWN1: %x / %d mV", x, y);
1360 x = pmu_read(0x23) & 0xf;
1361 y = pmu_read(0x22) * 25 + 625;
1362 lcd_putsf(0, 8, "DOWN2: %x / %d mV", x, y);
1363 x = pmu_read(0x27) & 0xf;
1364 y = pmu_read(0x26) * 100 + 900;
1365 lcd_putsf(0, 9, "MEMLDO: %x / %d mV", x, y);
1366 for (i = 0; i < 6; i++)
1368 x = pmu_read(0x2e + (i << 1)) & 0xf;
1369 y = pmu_read(0x2d + (i << 1)) * 100 + 900;
1370 lcd_putsf(0, 10 + i, "LDO%d: %x / %d mV", i + 1, x, y);
1372 #else
1373 lcd_putsf(0, 3, "Charger: %s",
1374 charger_inserted() ? "present" : "absent");
1375 #endif /* target type */
1376 #endif /* CONFIG_CHARGING */
1377 break;
1379 case 2: /* voltage deltas: */
1380 lcd_puts(0, 0, "Voltage deltas:");
1382 for (i = 0; i <= 6; i++) {
1383 y = power_history[i] - power_history[i+1];
1384 lcd_putsf(0, i+1, "-%d min: %s%d.%03d V", i,
1385 (y < 0) ? "-" : "", ((y < 0) ? y * -1 : y) / 1000,
1386 ((y < 0) ? y * -1 : y ) % 1000);
1388 break;
1390 case 3: /* remaining time estimation: */
1392 #ifdef ARCHOS_RECORDER
1393 lcd_putsf(0, 0, "charge_state: %d", charge_state);
1395 lcd_putsf(0, 1, "Cycle time: %d m", powermgmt_last_cycle_startstop_min);
1397 lcd_putsf(0, 2, "Lvl@cyc st: %d%%", powermgmt_last_cycle_level);
1399 lcd_putsf(0, 3, "P=%2d I=%2d", pid_p, pid_i);
1401 lcd_putsf(0, 4, "Trickle sec: %d/60", trickle_sec);
1402 #endif /* ARCHOS_RECORDER */
1404 lcd_putsf(0, 5, "Last PwrHist: %d.%03dV",
1405 power_history[0] / 1000,
1406 power_history[0] % 1000);
1408 lcd_putsf(0, 6, "battery level: %d%%", battery_level());
1410 lcd_putsf(0, 7, "Est. remain: %d m", battery_time());
1411 break;
1414 lcd_update();
1416 switch(get_action(CONTEXT_STD,HZ/2))
1418 case ACTION_STD_PREV:
1419 if (view)
1420 view--;
1421 break;
1423 case ACTION_STD_NEXT:
1424 if (view < 3)
1425 view++;
1426 break;
1428 case ACTION_STD_CANCEL:
1429 lcd_setfont(FONT_UI);
1430 return false;
1433 lcd_setfont(FONT_UI);
1434 return false;
1437 #endif /* HAVE_LCD_BITMAP */
1438 #endif
1440 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
1441 #if (CONFIG_STORAGE & STORAGE_MMC) || (CONFIG_STORAGE & STORAGE_SD)
1443 #if (CONFIG_STORAGE & STORAGE_MMC)
1444 #define CARDTYPE "MMC"
1445 #elif (CONFIG_STORAGE & STORAGE_SD)
1446 #define CARDTYPE "microSD"
1447 #endif
1449 static int disk_callback(int btn, struct gui_synclist *lists)
1451 tCardInfo *card;
1452 int *cardnum = (int*)lists->data;
1453 unsigned char card_name[6];
1454 unsigned char pbuf[32];
1455 char *title = lists->title;
1456 static const unsigned char i_vmin[] = { 0, 1, 5, 10, 25, 35, 60, 100 };
1457 static const unsigned char i_vmax[] = { 1, 5, 10, 25, 35, 45, 80, 200 };
1458 static const unsigned char * const kbit_units[] = { "kBit/s", "MBit/s", "GBit/s" };
1459 static const unsigned char * const nsec_units[] = { "ns", "µs", "ms" };
1460 #if (CONFIG_STORAGE & STORAGE_MMC)
1461 static const char * const mmc_spec_vers[] = { "1.0-1.2", "1.4", "2.0-2.2",
1462 "3.1-3.31", "4.0" };
1463 #endif
1465 if ((btn == ACTION_STD_OK) || (btn == SYS_FS_CHANGED) || (btn == ACTION_REDRAW))
1467 #ifdef HAVE_HOTSWAP
1468 if (btn == ACTION_STD_OK)
1470 *cardnum ^= 0x1; /* change cards */
1472 #endif
1474 simplelist_set_line_count(0);
1476 card = card_get_info(*cardnum);
1478 if (card->initialized > 0)
1480 unsigned i;
1481 for (i=0; i<sizeof(card_name); i++)
1483 card_name[i] = card_extract_bits(card->cid, (103-8*i), 8);
1485 strlcpy(card_name, card_name, sizeof(card_name));
1486 simplelist_addline(SIMPLELIST_ADD_LINE,
1487 "%s Rev %d.%d", card_name,
1488 (int) card_extract_bits(card->cid, 63, 4),
1489 (int) card_extract_bits(card->cid, 59, 4));
1490 simplelist_addline(SIMPLELIST_ADD_LINE,
1491 "Prod: %d/%d",
1492 #if (CONFIG_STORAGE & STORAGE_SD)
1493 (int) card_extract_bits(card->cid, 11, 4),
1494 (int) card_extract_bits(card->cid, 19, 8) + 2000
1495 #elif (CONFIG_STORAGE & STORAGE_MMC)
1496 (int) card_extract_bits(card->cid, 15, 4),
1497 (int) card_extract_bits(card->cid, 11, 4) + 1997
1498 #endif
1500 simplelist_addline(SIMPLELIST_ADD_LINE,
1501 #if (CONFIG_STORAGE & STORAGE_SD)
1502 "Ser#: 0x%08lx",
1503 card_extract_bits(card->cid, 55, 32)
1504 #elif (CONFIG_STORAGE & STORAGE_MMC)
1505 "Ser#: 0x%04lx",
1506 card_extract_bits(card->cid, 47, 16)
1507 #endif
1510 simplelist_addline(SIMPLELIST_ADD_LINE, "M=%02x, "
1511 #if (CONFIG_STORAGE & STORAGE_SD)
1512 "O=%c%c",
1513 (int) card_extract_bits(card->cid, 127, 8),
1514 card_extract_bits(card->cid, 119, 8),
1515 card_extract_bits(card->cid, 111, 8)
1516 #elif (CONFIG_STORAGE & STORAGE_MMC)
1517 "O=%04x",
1518 (int) card_extract_bits(card->cid, 127, 8),
1519 (int) card_extract_bits(card->cid, 119, 16)
1520 #endif
1523 #if (CONFIG_STORAGE & STORAGE_MMC)
1524 int temp = card_extract_bits(card->csd, 125, 4);
1525 simplelist_addline(SIMPLELIST_ADD_LINE,
1526 "MMC v%s", temp < 5 ?
1527 mmc_spec_vers[temp] : "?.?");
1528 #endif
1529 simplelist_addline(SIMPLELIST_ADD_LINE,
1530 "Blocks: 0x%08lx", card->numblocks);
1531 output_dyn_value(pbuf, sizeof pbuf, card->speed / 1000,
1532 kbit_units, false);
1533 simplelist_addline(SIMPLELIST_ADD_LINE,
1534 "Speed: %s", pbuf);
1535 output_dyn_value(pbuf, sizeof pbuf, card->taac,
1536 nsec_units, false);
1537 simplelist_addline(SIMPLELIST_ADD_LINE,
1538 "Taac: %s", pbuf);
1539 simplelist_addline(SIMPLELIST_ADD_LINE,
1540 "Nsac: %d clk", card->nsac);
1541 simplelist_addline(SIMPLELIST_ADD_LINE,
1542 "R2W: *%d", card->r2w_factor);
1543 #if (CONFIG_STORAGE & STORAGE_SD)
1544 int csd_structure = card_extract_bits(card->csd, 127, 2);
1545 if (csd_structure == 0) /* CSD version 1.0 */
1546 #endif
1548 simplelist_addline(SIMPLELIST_ADD_LINE,
1549 "IRmax: %d..%d mA",
1550 i_vmin[card_extract_bits(card->csd, 61, 3)],
1551 i_vmax[card_extract_bits(card->csd, 58, 3)]);
1552 simplelist_addline(SIMPLELIST_ADD_LINE,
1553 "IWmax: %d..%d mA",
1554 i_vmin[card_extract_bits(card->csd, 55, 3)],
1555 i_vmax[card_extract_bits(card->csd, 52, 3)]);
1558 else if (card->initialized == 0)
1560 simplelist_addline(SIMPLELIST_ADD_LINE, "Not Found!");
1562 #if (CONFIG_STORAGE & STORAGE_SD)
1563 else /* card->initialized < 0 */
1565 simplelist_addline(SIMPLELIST_ADD_LINE, "Init Error! (%d)", card->initialized);
1567 #endif
1568 snprintf(title, 16, "[" CARDTYPE " %d]", *cardnum);
1569 gui_synclist_set_title(lists, title, Icon_NOICON);
1570 gui_synclist_set_nb_items(lists, simplelist_get_line_count());
1571 gui_synclist_select_item(lists, 0);
1572 btn = ACTION_REDRAW;
1574 return btn;
1576 #elif (CONFIG_STORAGE & STORAGE_ATA)
1577 static int disk_callback(int btn, struct gui_synclist *lists)
1579 (void)lists;
1580 int i;
1581 char buf[128];
1582 unsigned short* identify_info = ata_get_identify();
1583 bool timing_info_present = false;
1584 (void)btn;
1586 simplelist_set_line_count(0);
1588 for (i=0; i < 20; i++)
1589 ((unsigned short*)buf)[i]=htobe16(identify_info[i+27]);
1590 buf[40]=0;
1591 /* kill trailing space */
1592 for (i=39; i && buf[i]==' '; i--)
1593 buf[i] = 0;
1594 simplelist_addline(SIMPLELIST_ADD_LINE, "Model: %s", buf);
1595 for (i=0; i < 4; i++)
1596 ((unsigned short*)buf)[i]=htobe16(identify_info[i+23]);
1597 buf[8]=0;
1598 simplelist_addline(SIMPLELIST_ADD_LINE,
1599 "Firmware: %s", buf);
1600 snprintf(buf, sizeof buf, "%ld MB",
1601 ((unsigned long)identify_info[61] << 16 |
1602 (unsigned long)identify_info[60]) / 2048 );
1603 simplelist_addline(SIMPLELIST_ADD_LINE,
1604 "Size: %s", buf);
1605 unsigned long free;
1606 fat_size( IF_MV2(0,) NULL, &free );
1607 simplelist_addline(SIMPLELIST_ADD_LINE,
1608 "Free: %ld MB", free / 1024);
1609 simplelist_addline(SIMPLELIST_ADD_LINE,
1610 "Spinup time: %d ms", storage_spinup_time() * (1000/HZ));
1611 i = identify_info[83] & (1<<3);
1612 simplelist_addline(SIMPLELIST_ADD_LINE,
1613 "Power mgmt: %s", i ? "enabled" : "unsupported");
1614 i = identify_info[83] & (1<<9);
1615 simplelist_addline(SIMPLELIST_ADD_LINE,
1616 "Noise mgmt: %s", i ? "enabled" : "unsupported");
1617 i = identify_info[82] & (1<<6);
1618 simplelist_addline(SIMPLELIST_ADD_LINE,
1619 "Read-ahead: %s", i ? "enabled" : "unsupported");
1620 timing_info_present = identify_info[53] & (1<<1);
1621 if(timing_info_present) {
1622 char pio3[2], pio4[2];pio3[1] = 0;
1623 pio4[1] = 0;
1624 pio3[0] = (identify_info[64] & (1<<0)) ? '3' : 0;
1625 pio4[0] = (identify_info[64] & (1<<1)) ? '4' : 0;
1626 simplelist_addline(SIMPLELIST_ADD_LINE,
1627 "PIO modes: 0 1 2 %s %s", pio3, pio4);
1629 else {
1630 simplelist_addline(SIMPLELIST_ADD_LINE,
1631 "No PIO mode info");
1633 timing_info_present = identify_info[53] & (1<<1);
1634 if(timing_info_present) {
1635 simplelist_addline(SIMPLELIST_ADD_LINE,
1636 "Cycle times %dns/%dns",
1637 identify_info[67],
1638 identify_info[68] );
1639 } else {
1640 simplelist_addline(SIMPLELIST_ADD_LINE,
1641 "No timing info");
1643 int sector_size = 512;
1644 if((identify_info[106] & 0xe000) == 0x6000)
1645 sector_size *= BIT_N(identify_info[106] & 0x000f);
1646 simplelist_addline(SIMPLELIST_ADD_LINE,
1647 "Physical sector size: %d", sector_size);
1648 #ifdef HAVE_ATA_DMA
1649 if (identify_info[63] & (1<<0)) {
1650 char mdma0[2], mdma1[2], mdma2[2];
1651 mdma0[1] = mdma1[1] = mdma2[1] = 0;
1652 mdma0[0] = (identify_info[63] & (1<<0)) ? '0' : 0;
1653 mdma1[0] = (identify_info[63] & (1<<1)) ? '1' : 0;
1654 mdma2[0] = (identify_info[63] & (1<<2)) ? '2' : 0;
1655 simplelist_addline(SIMPLELIST_ADD_LINE,
1656 "MDMA modes: %s %s %s", mdma0, mdma1, mdma2);
1657 simplelist_addline(SIMPLELIST_ADD_LINE,
1658 "MDMA Cycle times %dns/%dns",
1659 identify_info[65],
1660 identify_info[66] );
1662 else {
1663 simplelist_addline(SIMPLELIST_ADD_LINE,
1664 "No MDMA mode info");
1666 if (identify_info[53] & (1<<2)) {
1667 char udma0[2], udma1[2], udma2[2], udma3[2], udma4[2], udma5[2], udma6[2];
1668 udma0[1] = udma1[1] = udma2[1] = udma3[1] = udma4[1] = udma5[1] = udma6[1] = 0;
1669 udma0[0] = (identify_info[88] & (1<<0)) ? '0' : 0;
1670 udma1[0] = (identify_info[88] & (1<<1)) ? '1' : 0;
1671 udma2[0] = (identify_info[88] & (1<<2)) ? '2' : 0;
1672 udma3[0] = (identify_info[88] & (1<<3)) ? '3' : 0;
1673 udma4[0] = (identify_info[88] & (1<<4)) ? '4' : 0;
1674 udma5[0] = (identify_info[88] & (1<<5)) ? '5' : 0;
1675 udma6[0] = (identify_info[88] & (1<<6)) ? '6' : 0;
1676 simplelist_addline(SIMPLELIST_ADD_LINE,
1677 "UDMA modes: %s %s %s %s %s %s %s", udma0, udma1, udma2,
1678 udma3, udma4, udma5, udma6);
1680 else {
1681 simplelist_addline(SIMPLELIST_ADD_LINE,
1682 "No UDMA mode info");
1684 #endif /* HAVE_ATA_DMA */
1685 timing_info_present = identify_info[53] & (1<<1);
1686 if(timing_info_present) {
1687 i = identify_info[49] & (1<<11);
1688 simplelist_addline(SIMPLELIST_ADD_LINE,
1689 "IORDY support: %s", i ? "yes" : "no");
1690 i = identify_info[49] & (1<<10);
1691 simplelist_addline(SIMPLELIST_ADD_LINE,
1692 "IORDY disable: %s", i ? "yes" : "no");
1693 } else {
1694 simplelist_addline(SIMPLELIST_ADD_LINE,
1695 "No timing info");
1697 simplelist_addline(SIMPLELIST_ADD_LINE,
1698 "Cluster size: %d bytes", fat_get_cluster_size(IF_MV(0)));
1699 #ifdef HAVE_ATA_DMA
1700 i = ata_get_dma_mode();
1701 if (i == 0) {
1702 simplelist_addline(SIMPLELIST_ADD_LINE,
1703 "DMA not enabled");
1704 } else {
1705 simplelist_addline(SIMPLELIST_ADD_LINE,
1706 "DMA mode: %s %c",
1707 (i & 0x40) ? "UDMA" : "MDMA",
1708 '0' + (i & 7));
1710 #endif /* HAVE_ATA_DMA */
1711 return btn;
1713 #else /* No SD, MMC or ATA */
1714 static int disk_callback(int btn, struct gui_synclist *lists)
1716 (void)btn;
1717 (void)lists;
1718 struct storage_info info;
1719 storage_get_info(0,&info);
1720 simplelist_addline(SIMPLELIST_ADD_LINE, "Vendor: %s", info.vendor);
1721 simplelist_addline(SIMPLELIST_ADD_LINE, "Model: %s", info.product);
1722 simplelist_addline(SIMPLELIST_ADD_LINE, "Firmware: %s", info.revision);
1723 simplelist_addline(SIMPLELIST_ADD_LINE,
1724 "Size: %ld MB", info.num_sectors*(info.sector_size/512)/2024);
1725 unsigned long free;
1726 fat_size( IF_MV2(0,) NULL, &free );
1727 simplelist_addline(SIMPLELIST_ADD_LINE,
1728 "Free: %ld MB", free / 1024);
1729 simplelist_addline(SIMPLELIST_ADD_LINE,
1730 "Cluster size: %d bytes", fat_get_cluster_size(IF_MV(0)));
1731 return btn;
1733 #endif
1735 #if (CONFIG_STORAGE & STORAGE_ATA)
1736 static bool dbg_identify_info(void)
1738 int fd = creat("/identify_info.bin", 0666);
1739 if(fd >= 0)
1741 #ifdef ROCKBOX_LITTLE_ENDIAN
1742 ecwrite(fd, ata_get_identify(), SECTOR_SIZE/2, "s", true);
1743 #else
1744 write(fd, ata_get_identify(), SECTOR_SIZE);
1745 #endif
1746 close(fd);
1748 return false;
1750 #endif
1752 static bool dbg_disk_info(void)
1754 struct simplelist_info info;
1755 simplelist_info_init(&info, "Disk Info", 1, NULL);
1756 #if (CONFIG_STORAGE & STORAGE_MMC) || (CONFIG_STORAGE & STORAGE_SD)
1757 char title[16];
1758 int card = 0;
1759 info.callback_data = (void*)&card;
1760 info.title = title;
1761 #endif
1762 info.action_callback = disk_callback;
1763 info.hide_selection = true;
1764 info.scroll_all = true;
1765 return simplelist_show_list(&info);
1767 #endif /* PLATFORM_NATIVE */
1769 #ifdef HAVE_DIRCACHE
1770 static int dircache_callback(int btn, struct gui_synclist *lists)
1772 (void)btn; (void)lists;
1773 simplelist_set_line_count(0);
1774 simplelist_addline(SIMPLELIST_ADD_LINE, "Cache initialized: %s",
1775 dircache_is_enabled() ? "Yes" : "No");
1776 simplelist_addline(SIMPLELIST_ADD_LINE, "Cache size: %d B",
1777 dircache_get_cache_size());
1778 simplelist_addline(SIMPLELIST_ADD_LINE, "Last size: %d B",
1779 global_status.dircache_size);
1780 simplelist_addline(SIMPLELIST_ADD_LINE, "Limit: %d B",
1781 DIRCACHE_LIMIT);
1782 simplelist_addline(SIMPLELIST_ADD_LINE, "Reserve: %d/%d B",
1783 dircache_get_reserve_used(), DIRCACHE_RESERVE);
1784 simplelist_addline(SIMPLELIST_ADD_LINE, "Scanning took: %d s",
1785 dircache_get_build_ticks() / HZ);
1786 simplelist_addline(SIMPLELIST_ADD_LINE, "Entry count: %d",
1787 dircache_get_entry_count());
1788 return btn;
1791 static bool dbg_dircache_info(void)
1793 struct simplelist_info info;
1794 simplelist_info_init(&info, "Dircache Info", 7, NULL);
1795 info.action_callback = dircache_callback;
1796 info.hide_selection = true;
1797 info.scroll_all = true;
1798 return simplelist_show_list(&info);
1801 #endif /* HAVE_DIRCACHE */
1803 #ifdef HAVE_TAGCACHE
1804 static int database_callback(int btn, struct gui_synclist *lists)
1806 (void)lists;
1807 struct tagcache_stat *stat = tagcache_get_stat();
1808 static bool synced = false;
1810 simplelist_set_line_count(0);
1812 simplelist_addline(SIMPLELIST_ADD_LINE, "Initialized: %s",
1813 stat->initialized ? "Yes" : "No");
1814 simplelist_addline(SIMPLELIST_ADD_LINE, "DB Ready: %s",
1815 stat->ready ? "Yes" : "No");
1816 simplelist_addline(SIMPLELIST_ADD_LINE, "RAM Cache: %s",
1817 stat->ramcache ? "Yes" : "No");
1818 simplelist_addline(SIMPLELIST_ADD_LINE, "RAM: %d/%d B",
1819 stat->ramcache_used, stat->ramcache_allocated);
1820 simplelist_addline(SIMPLELIST_ADD_LINE, "Progress: %d%% (%d entries)",
1821 stat->progress, stat->processed_entries);
1822 simplelist_addline(SIMPLELIST_ADD_LINE, "Curfile: %s",
1823 stat->curentry ? stat->curentry : "---");
1824 simplelist_addline(SIMPLELIST_ADD_LINE, "Commit step: %d",
1825 stat->commit_step);
1826 simplelist_addline(SIMPLELIST_ADD_LINE, "Commit delayed: %s",
1827 stat->commit_delayed ? "Yes" : "No");
1829 simplelist_addline(SIMPLELIST_ADD_LINE, "Queue length: %d",
1830 stat->queue_length);
1832 if (synced)
1834 synced = false;
1835 tagcache_screensync_event();
1838 if (!btn && stat->curentry)
1840 synced = true;
1841 return ACTION_REDRAW;
1844 if (btn == ACTION_STD_CANCEL)
1845 tagcache_screensync_enable(false);
1847 return btn;
1849 static bool dbg_tagcache_info(void)
1851 struct simplelist_info info;
1852 simplelist_info_init(&info, "Database Info", 8, NULL);
1853 info.action_callback = database_callback;
1854 info.hide_selection = true;
1855 info.scroll_all = true;
1857 /* Don't do nonblock here, must give enough processing time
1858 for tagcache thread. */
1859 /* info.timeout = TIMEOUT_NOBLOCK; */
1860 info.timeout = 1;
1861 tagcache_screensync_enable(true);
1862 return simplelist_show_list(&info);
1864 #endif
1866 #if CONFIG_CPU == SH7034
1867 static bool dbg_save_roms(void)
1869 int fd;
1870 int oldmode = system_memory_guard(MEMGUARD_NONE);
1872 fd = creat("/internal_rom_0000-FFFF.bin", 0666);
1873 if(fd >= 0)
1875 write(fd, (void *)0, 0x10000);
1876 close(fd);
1879 fd = creat("/internal_rom_2000000-203FFFF.bin", 0666);
1880 if(fd >= 0)
1882 write(fd, (void *)0x2000000, 0x40000);
1883 close(fd);
1886 system_memory_guard(oldmode);
1887 return false;
1889 #elif defined CPU_COLDFIRE
1890 static bool dbg_save_roms(void)
1892 int fd;
1893 int oldmode = system_memory_guard(MEMGUARD_NONE);
1895 #if defined(IRIVER_H100_SERIES)
1896 fd = creat("/internal_rom_000000-1FFFFF.bin", 0666);
1897 #elif defined(IRIVER_H300_SERIES)
1898 fd = creat("/internal_rom_000000-3FFFFF.bin", 0666);
1899 #elif defined(IAUDIO_X5) || defined(IAUDIO_M5) || defined(IAUDIO_M3)
1900 fd = creat("/internal_rom_000000-3FFFFF.bin", 0666);
1901 #elif defined(MPIO_HD200) || defined(MPIO_HD300)
1902 fd = creat("/internal_rom_000000-1FFFFF.bin", 0666);
1903 #endif
1904 if(fd >= 0)
1906 write(fd, (void *)0, FLASH_SIZE);
1907 close(fd);
1909 system_memory_guard(oldmode);
1911 #ifdef HAVE_EEPROM
1912 fd = creat("/internal_eeprom.bin", 0666);
1913 if (fd >= 0)
1915 int old_irq_level;
1916 char buf[EEPROM_SIZE];
1917 int err;
1919 old_irq_level = disable_irq_save();
1921 err = eeprom_24cxx_read(0, buf, sizeof buf);
1923 restore_irq(old_irq_level);
1925 if (err)
1926 splashf(HZ*3, "Eeprom read failure (%d)", err);
1927 else
1929 write(fd, buf, sizeof buf);
1932 close(fd);
1934 #endif
1936 return false;
1938 #elif defined(CPU_PP) && !(CONFIG_STORAGE & STORAGE_SD)
1939 static bool dbg_save_roms(void)
1941 int fd;
1943 fd = creat("/internal_rom_000000-0FFFFF.bin", 0666);
1944 if(fd >= 0)
1946 write(fd, (void *)0x20000000, FLASH_SIZE);
1947 close(fd);
1950 return false;
1952 #elif CONFIG_CPU == IMX31L
1953 static bool dbg_save_roms(void)
1955 int fd;
1957 fd = creat("/flash_rom_A0000000-A01FFFFF.bin", 0666);
1958 if (fd >= 0)
1960 write(fd, (void*)0xa0000000, FLASH_SIZE);
1961 close(fd);
1964 return false;
1966 #elif defined(CPU_TCC780X)
1967 static bool dbg_save_roms(void)
1969 int fd;
1971 fd = creat("/eeprom_E0000000-E0001FFF.bin", 0666);
1972 if (fd >= 0)
1974 write(fd, (void*)0xe0000000, 0x2000);
1975 close(fd);
1978 return false;
1980 #endif /* CPU */
1982 #ifndef SIMULATOR
1983 #if CONFIG_TUNER
1985 #ifdef CONFIG_TUNER_MULTI
1986 static int tuner_type = 0;
1987 #define IF_TUNER_TYPE(type) if(tuner_type==type)
1988 #else
1989 #define IF_TUNER_TYPE(type)
1990 #endif
1992 static int radio_callback(int btn, struct gui_synclist *lists)
1994 (void)lists;
1995 if (btn == ACTION_STD_CANCEL)
1996 return btn;
1997 simplelist_set_line_count(1);
1999 #if (CONFIG_TUNER & LV24020LP)
2000 simplelist_addline(SIMPLELIST_ADD_LINE,
2001 "CTRL_STAT: %02X", lv24020lp_get(LV24020LP_CTRL_STAT) );
2002 simplelist_addline(SIMPLELIST_ADD_LINE,
2003 "RADIO_STAT: %02X", lv24020lp_get(LV24020LP_REG_STAT) );
2004 simplelist_addline(SIMPLELIST_ADD_LINE,
2005 "MSS_FM: %d kHz", lv24020lp_get(LV24020LP_MSS_FM) );
2006 simplelist_addline(SIMPLELIST_ADD_LINE,
2007 "MSS_IF: %d Hz", lv24020lp_get(LV24020LP_MSS_IF) );
2008 simplelist_addline(SIMPLELIST_ADD_LINE,
2009 "MSS_SD: %d Hz", lv24020lp_get(LV24020LP_MSS_SD) );
2010 simplelist_addline(SIMPLELIST_ADD_LINE,
2011 "if_set: %d Hz", lv24020lp_get(LV24020LP_IF_SET) );
2012 simplelist_addline(SIMPLELIST_ADD_LINE,
2013 "sd_set: %d Hz", lv24020lp_get(LV24020LP_SD_SET) );
2014 #endif /* LV24020LP */
2015 #if (CONFIG_TUNER & S1A0903X01)
2016 simplelist_addline(SIMPLELIST_ADD_LINE,
2017 "Samsung regs: %08X", s1a0903x01_get(RADIO_ALL));
2018 /* This one doesn't return dynamic data atm */
2019 #endif /* S1A0903X01 */
2020 #if (CONFIG_TUNER & TEA5767)
2021 struct tea5767_dbg_info nfo;
2022 tea5767_dbg_info(&nfo);
2023 simplelist_addline(SIMPLELIST_ADD_LINE, "Philips regs:");
2024 simplelist_addline(SIMPLELIST_ADD_LINE,
2025 " Read: %02X %02X %02X %02X %02X",
2026 (unsigned)nfo.read_regs[0], (unsigned)nfo.read_regs[1],
2027 (unsigned)nfo.read_regs[2], (unsigned)nfo.read_regs[3],
2028 (unsigned)nfo.read_regs[4]);
2029 simplelist_addline(SIMPLELIST_ADD_LINE,
2030 " Write: %02X %02X %02X %02X %02X",
2031 (unsigned)nfo.write_regs[0], (unsigned)nfo.write_regs[1],
2032 (unsigned)nfo.write_regs[2], (unsigned)nfo.write_regs[3],
2033 (unsigned)nfo.write_regs[4]);
2034 #endif /* TEA5767 */
2035 #if (CONFIG_TUNER & SI4700)
2036 IF_TUNER_TYPE(SI4700)
2038 struct si4700_dbg_info nfo;
2039 int i;
2040 si4700_dbg_info(&nfo);
2041 simplelist_addline(SIMPLELIST_ADD_LINE, "SI4700 regs:");
2042 for (i = 0; i < 16; i += 4) {
2043 simplelist_addline(SIMPLELIST_ADD_LINE,"%02X: %04X %04X %04X %04X",
2044 i, nfo.regs[i], nfo.regs[i+1], nfo.regs[i+2], nfo.regs[i+3]);
2047 #endif /* SI4700 */
2048 #if (CONFIG_TUNER & RDA5802)
2049 IF_TUNER_TYPE(RDA5802)
2051 struct rda5802_dbg_info nfo;
2052 int i;
2053 rda5802_dbg_info(&nfo);
2054 simplelist_addline(SIMPLELIST_ADD_LINE, "RDA5802 regs:");
2055 for (i = 0; i < 16; i += 4) {
2056 simplelist_addline(SIMPLELIST_ADD_LINE,"%02X: %04X %04X %04X %04X",
2057 i, nfo.regs[i], nfo.regs[i+1], nfo.regs[i+2], nfo.regs[i+3]);
2060 #endif /* RDA55802 */
2061 return ACTION_REDRAW;
2063 static bool dbg_fm_radio(void)
2065 struct simplelist_info info;
2066 #ifdef CONFIG_TUNER_MULTI
2067 tuner_type = tuner_detect_type();
2068 #endif
2069 info.scroll_all = true;
2070 simplelist_info_init(&info, "FM Radio", 1, NULL);
2071 simplelist_set_line_count(0);
2072 simplelist_addline(SIMPLELIST_ADD_LINE, "HW detected: %s",
2073 radio_hardware_present() ? "yes" : "no");
2075 info.action_callback = radio_hardware_present()?radio_callback : NULL;
2076 info.hide_selection = true;
2077 return simplelist_show_list(&info);
2079 #endif /* CONFIG_TUNER */
2080 #endif /* !SIMULATOR */
2082 #ifdef HAVE_LCD_BITMAP
2083 extern bool do_screendump_instead_of_usb;
2085 static bool dbg_screendump(void)
2087 do_screendump_instead_of_usb = !do_screendump_instead_of_usb;
2088 splashf(HZ, "Screendump %s",
2089 do_screendump_instead_of_usb?"enabled":"disabled");
2090 return false;
2092 #endif /* HAVE_LCD_BITMAP */
2094 extern bool write_metadata_log;
2096 static bool dbg_metadatalog(void)
2098 write_metadata_log = !write_metadata_log;
2099 splashf(HZ, "Metadata log %s",
2100 write_metadata_log?"enabled":"disabled");
2101 return false;
2104 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
2105 static bool dbg_set_memory_guard(void)
2107 static const struct opt_items names[MAXMEMGUARD] = {
2108 { "None", -1 },
2109 { "Flash ROM writes", -1 },
2110 { "Zero area (all)", -1 }
2112 int mode = system_memory_guard(MEMGUARD_KEEP);
2114 set_option( "Catch mem accesses", &mode, INT, names, MAXMEMGUARD, NULL);
2115 system_memory_guard(mode);
2117 return false;
2119 #endif /* CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) */
2121 #if defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS)
2122 static bool dbg_write_eeprom(void)
2124 int fd;
2125 int rc;
2126 int old_irq_level;
2127 char buf[EEPROM_SIZE];
2128 int err;
2130 fd = open("/internal_eeprom.bin", O_RDONLY);
2132 if (fd >= 0)
2134 rc = read(fd, buf, EEPROM_SIZE);
2136 if(rc == EEPROM_SIZE)
2138 old_irq_level = disable_irq_save();
2140 err = eeprom_24cxx_write(0, buf, sizeof buf);
2141 if (err)
2142 splashf(HZ*3, "Eeprom write failure (%d)", err);
2143 else
2144 splash(HZ*3, "Eeprom written successfully");
2146 restore_irq(old_irq_level);
2148 else
2150 splashf(HZ*3, "File read error (%d)",rc);
2152 close(fd);
2154 else
2156 splash(HZ*3, "Failed to open 'internal_eeprom.bin'");
2159 return false;
2161 #endif /* defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS) */
2162 #ifdef CPU_BOOST_LOGGING
2163 static bool cpu_boost_log(void)
2165 int i = 0,j=0;
2166 int count = cpu_boost_log_getcount();
2167 int lines = LCD_HEIGHT/SYSFONT_HEIGHT;
2168 char *str;
2169 bool done;
2170 lcd_setfont(FONT_SYSFIXED);
2171 str = cpu_boost_log_getlog_first();
2172 while (i < count)
2174 lcd_clear_display();
2175 for(j=0; j<lines; j++,i++)
2177 if (!str)
2178 str = cpu_boost_log_getlog_next();
2179 if (str)
2181 if(strlen(str) > LCD_WIDTH/SYSFONT_WIDTH)
2182 lcd_puts_scroll(0, j, str);
2183 else
2184 lcd_puts(0, j,str);
2186 str = NULL;
2188 lcd_update();
2189 done = false;
2190 while (!done)
2192 switch(get_action(CONTEXT_STD,TIMEOUT_BLOCK))
2194 case ACTION_STD_OK:
2195 case ACTION_STD_PREV:
2196 case ACTION_STD_NEXT:
2197 done = true;
2198 break;
2199 case ACTION_STD_CANCEL:
2200 i = count;
2201 done = true;
2202 break;
2206 lcd_stop_scroll();
2207 get_action(CONTEXT_STD,TIMEOUT_BLOCK);
2208 lcd_setfont(FONT_UI);
2209 return false;
2211 #endif
2213 #if (defined(HAVE_WHEEL_ACCELERATION) && (CONFIG_KEYPAD==IPOD_4G_PAD) \
2214 && !defined(IPOD_MINI) && !defined(SIMULATOR))
2215 extern bool wheel_is_touched;
2216 extern int old_wheel_value;
2217 extern int new_wheel_value;
2218 extern int wheel_delta;
2219 extern unsigned int accumulated_wheel_delta;
2220 extern unsigned int wheel_velocity;
2222 static bool dbg_scrollwheel(void)
2224 unsigned int speed;
2226 lcd_setfont(FONT_SYSFIXED);
2228 while (1)
2230 if (action_userabort(HZ/10))
2231 break;
2233 lcd_clear_display();
2235 /* show internal variables of scrollwheel driver */
2236 lcd_putsf(0, 0, "wheel touched: %s", (wheel_is_touched) ? "true" : "false");
2237 lcd_putsf(0, 1, "new position: %2d", new_wheel_value);
2238 lcd_putsf(0, 2, "old position: %2d", old_wheel_value);
2239 lcd_putsf(0, 3, "wheel delta: %2d", wheel_delta);
2240 lcd_putsf(0, 4, "accumulated delta: %2d", accumulated_wheel_delta);
2241 lcd_putsf(0, 5, "velo [deg/s]: %4d", (int)wheel_velocity);
2243 /* show effective accelerated scrollspeed */
2244 speed = button_apply_acceleration( (1<<31)|(1<<24)|wheel_velocity);
2245 lcd_putsf(0, 6, "accel. speed: %4d", speed);
2247 lcd_update();
2249 lcd_setfont(FONT_UI);
2250 return false;
2252 #endif
2254 #if defined (HAVE_USBSTACK)
2256 #if defined(ROCKBOX_HAS_LOGF) && defined(USB_ENABLE_SERIAL)
2257 static bool toggle_usb_core_driver(int driver, char *msg)
2259 bool enabled = !usb_core_driver_enabled(driver);
2261 usb_core_enable_driver(driver,enabled);
2262 splashf(HZ, "%s %s", msg, enabled?"enabled":"disabled");
2264 return false;
2267 static bool toggle_usb_serial(void)
2269 return toggle_usb_core_driver(USB_DRIVER_SERIAL,"USB Serial");
2271 #endif
2273 #endif
2275 #if CONFIG_USBOTG == USBOTG_ISP1583
2276 extern int dbg_usb_num_items(void);
2277 extern const char* dbg_usb_item(int selected_item, void *data,
2278 char *buffer, size_t buffer_len);
2280 static int isp1583_action_callback(int action, struct gui_synclist *lists)
2282 (void)lists;
2283 if (action == ACTION_NONE)
2284 action = ACTION_REDRAW;
2285 return action;
2288 static bool dbg_isp1583(void)
2290 struct simplelist_info isp1583;
2291 isp1583.scroll_all = true;
2292 simplelist_info_init(&isp1583, "ISP1583", dbg_usb_num_items(), NULL);
2293 isp1583.timeout = HZ/100;
2294 isp1583.hide_selection = true;
2295 isp1583.get_name = dbg_usb_item;
2296 isp1583.action_callback = isp1583_action_callback;
2297 return simplelist_show_list(&isp1583);
2299 #endif
2301 #if defined(CREATIVE_ZVx) && !defined(SIMULATOR)
2302 extern int pic_dbg_num_items(void);
2303 extern const char* pic_dbg_item(int selected_item, void *data,
2304 char *buffer, size_t buffer_len);
2306 static int pic_action_callback(int action, struct gui_synclist *lists)
2308 (void)lists;
2309 if (action == ACTION_NONE)
2310 action = ACTION_REDRAW;
2311 return action;
2314 static bool dbg_pic(void)
2316 struct simplelist_info pic;
2317 pic.scroll_all = true;
2318 simplelist_info_init(&pic, "PIC", pic_dbg_num_items(), NULL);
2319 pic.timeout = HZ/100;
2320 pic.hide_selection = true;
2321 pic.get_name = pic_dbg_item;
2322 pic.action_callback = pic_action_callback;
2323 return simplelist_show_list(&pic);
2325 #endif
2328 /****** The menu *********/
2329 struct the_menu_item {
2330 unsigned char *desc; /* string or ID */
2331 bool (*function) (void); /* return true if USB was connected */
2333 static const struct the_menu_item menuitems[] = {
2334 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || \
2335 (defined(CPU_PP) && !(CONFIG_STORAGE & STORAGE_SD)) || \
2336 CONFIG_CPU == IMX31L || defined(CPU_TCC780X)
2337 { "Dump ROM contents", dbg_save_roms },
2338 #endif
2339 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || defined(CPU_PP) \
2340 || CONFIG_CPU == S3C2440 || CONFIG_CPU == IMX31L || CONFIG_CPU == AS3525 \
2341 || CONFIG_CPU == DM320 || defined(CPU_S5L870X) || CONFIG_CPU == AS3525v2
2342 { "View I/O ports", dbg_ports },
2343 #endif
2344 #if (CONFIG_RTC == RTC_PCF50605) && (CONFIG_PLATFORM & PLATFORM_NATIVE)
2345 { "View PCF registers", dbg_pcf },
2346 #endif
2347 #if defined(HAVE_TSC2100) && (CONFIG_PLATFORM & PLATFORM_NATIVE)
2348 { "TSC2100 debug", tsc2100_debug },
2349 #endif
2350 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
2351 { "CPU frequency", dbg_cpufreq },
2352 #endif
2353 #if CONFIG_CPU == IMX31L
2354 { "DVFS/DPTC", __dbg_dvfs_dptc },
2355 #endif
2356 #if defined(IRIVER_H100_SERIES) && !defined(SIMULATOR)
2357 { "S/PDIF analyzer", dbg_spdif },
2358 #endif
2359 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
2360 { "Catch mem accesses", dbg_set_memory_guard },
2361 #endif
2362 { "View OS stacks", dbg_os },
2363 #ifdef HAVE_LCD_BITMAP
2364 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
2365 { "View battery", view_battery },
2366 #endif
2367 { "Screendump", dbg_screendump },
2368 #endif
2369 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
2370 { "View HW info", dbg_hw_info },
2371 #endif
2372 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
2373 { "View partitions", dbg_partitions },
2374 #endif
2375 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
2376 { "View disk info", dbg_disk_info },
2377 #if (CONFIG_STORAGE & STORAGE_ATA)
2378 { "Dump ATA identify info", dbg_identify_info},
2379 #endif
2380 #endif
2381 { "Metadata log", dbg_metadatalog },
2382 #ifdef HAVE_DIRCACHE
2383 { "View dircache info", dbg_dircache_info },
2384 #endif
2385 #ifdef HAVE_TAGCACHE
2386 { "View database info", dbg_tagcache_info },
2387 #endif
2388 #ifdef HAVE_LCD_BITMAP
2389 #if CONFIG_CODEC == SWCODEC
2390 { "View buffering thread", dbg_buffering_thread },
2391 #elif !defined(SIMULATOR)
2392 { "View audio thread", dbg_audio_thread },
2393 #endif
2394 #ifdef PM_DEBUG
2395 { "pm histogram", peak_meter_histogram},
2396 #endif /* PM_DEBUG */
2397 #endif /* HAVE_LCD_BITMAP */
2398 #ifndef SIMULATOR
2399 #if CONFIG_TUNER
2400 { "FM Radio", dbg_fm_radio },
2401 #endif
2402 #endif
2403 #if defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS)
2404 { "Write back EEPROM", dbg_write_eeprom },
2405 #endif
2406 #if CONFIG_USBOTG == USBOTG_ISP1583
2407 { "View ISP1583 info", dbg_isp1583 },
2408 #endif
2409 #if defined(CREATIVE_ZVx) && !defined(SIMULATOR)
2410 { "View PIC info", dbg_pic },
2411 #endif
2412 #ifdef ROCKBOX_HAS_LOGF
2413 {"Show Log File", logfdisplay },
2414 {"Dump Log File", logfdump },
2415 #endif
2416 #if defined(HAVE_USBSTACK)
2417 #if defined(ROCKBOX_HAS_LOGF) && defined(USB_ENABLE_SERIAL)
2418 {"USB Serial driver (logf)", toggle_usb_serial },
2419 #endif
2420 #endif /* HAVE_USBSTACK */
2421 #ifdef CPU_BOOST_LOGGING
2422 {"cpu_boost log",cpu_boost_log},
2423 #endif
2424 #if (defined(HAVE_WHEEL_ACCELERATION) && (CONFIG_KEYPAD==IPOD_4G_PAD) \
2425 && !defined(IPOD_MINI) && !defined(SIMULATOR))
2426 {"Debug scrollwheel", dbg_scrollwheel },
2427 #endif
2429 static int menu_action_callback(int btn, struct gui_synclist *lists)
2431 int i;
2432 if (btn == ACTION_STD_OK)
2434 FOR_NB_SCREENS(i)
2435 viewportmanager_theme_enable(i, false, NULL);
2436 menuitems[gui_synclist_get_sel_pos(lists)].function();
2437 btn = ACTION_REDRAW;
2438 FOR_NB_SCREENS(i)
2439 viewportmanager_theme_undo(i, false);
2441 return btn;
2444 static const char* dbg_menu_getname(int item, void * data,
2445 char *buffer, size_t buffer_len)
2447 (void)data; (void)buffer; (void)buffer_len;
2448 return menuitems[item].desc;
2451 bool debug_menu(void)
2453 struct simplelist_info info;
2455 simplelist_info_init(&info, "Debug Menu", ARRAYLEN(menuitems), NULL);
2456 info.action_callback = menu_action_callback;
2457 info.get_name = dbg_menu_getname;
2458 return simplelist_show_list(&info);