Initial 800x480 cabbiev2 port, based on 480x800x16 one
[kugel-rb.git] / apps / debug_menu.c
blob968355f51845c016cda161b5eade71aa9df0071b
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, boost_ticks, freq_sum;
277 static void dbg_audio_task(void)
279 #ifdef CPUFREQ_NORMAL
280 if(FREQ > CPUFREQ_NORMAL)
281 boost_ticks++;
282 freq_sum += FREQ/1000000; /* in MHz */
283 #endif
284 ticks++;
287 static bool dbg_buffering_thread(void)
289 int button;
290 int line, i;
291 bool done = false;
292 size_t bufused;
293 size_t bufsize = pcmbuf_get_bufsize();
294 int pcmbufdescs = pcmbuf_descs();
295 struct buffering_debug d;
296 size_t filebuflen = audio_get_filebuflen();
297 /* This is a size_t, but call it a long so it puts a - when it's bad. */
299 ticks = boost_ticks = freq_sum = 0;
301 tick_add_task(dbg_audio_task);
303 FOR_NB_SCREENS(i)
304 screens[i].setfont(FONT_SYSFIXED);
306 while(!done)
308 button = get_action(CONTEXT_STD,HZ/5);
309 switch(button)
311 case ACTION_STD_NEXT:
312 audio_next();
313 break;
314 case ACTION_STD_PREV:
315 audio_prev();
316 break;
317 case ACTION_STD_CANCEL:
318 done = true;
319 break;
322 buffering_get_debugdata(&d);
323 bufused = bufsize - pcmbuf_free();
325 FOR_NB_SCREENS(i)
327 line = 0;
328 screens[i].clear_display();
331 screens[i].putsf(0, line++, "pcm: %6ld/%ld", (long) bufused, (long) bufsize);
333 gui_scrollbar_draw(&screens[i],0, line*8, screens[i].lcdwidth, 6,
334 bufsize, 0, bufused, HORIZONTAL);
335 line++;
337 screens[i].putsf(0, line++, "alloc: %6ld/%ld", audio_filebufused(),
338 (long) filebuflen);
340 #if LCD_HEIGHT > 80 || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_HEIGHT > 80)
341 if (screens[i].lcdheight > 80)
343 gui_scrollbar_draw(&screens[i],0, line*8, screens[i].lcdwidth, 6,
344 filebuflen, 0, audio_filebufused(), HORIZONTAL);
345 line++;
347 screens[i].putsf(0, line++, "real: %6ld/%ld", (long)d.buffered_data,
348 (long)filebuflen);
350 gui_scrollbar_draw(&screens[i],0, line*8, screens[i].lcdwidth, 6,
351 filebuflen, 0, (long)d.buffered_data, HORIZONTAL);
352 line++;
354 #endif
356 screens[i].putsf(0, line++, "usefl: %6ld/%ld", (long)(d.useful_data),
357 (long)filebuflen);
359 #if LCD_HEIGHT > 80 || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_HEIGHT > 80)
360 if (screens[i].lcdheight > 80)
362 gui_scrollbar_draw(&screens[i],0, line*8, screens[i].lcdwidth, 6,
363 filebuflen, 0, d.useful_data, HORIZONTAL);
364 line++;
366 #endif
368 screens[i].putsf(0, line++, "data_rem: %ld", (long)d.data_rem);
370 screens[i].putsf(0, line++, "track count: %2d", audio_track_count());
372 screens[i].putsf(0, line++, "handle count: %d", (int)d.num_handles);
374 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
375 screens[i].putsf(0, line++, "cpu freq: %3dMHz",
376 (int)((FREQ + 500000) / 1000000));
377 #endif
379 if (ticks > 0)
381 int boostquota = boost_ticks * 1000 / ticks; /* in 0.1 % */
382 int avgclock = freq_sum * 10 / ticks; /* in 100 kHz */
383 screens[i].putsf(0, line++, "boost:%3d.%d%% (%d.%dMHz)",
384 boostquota/10, boostquota%10, avgclock/10, avgclock%10);
387 screens[i].putsf(0, line++, "pcmbufdesc: %2d/%2d",
388 pcmbuf_used_descs(), pcmbufdescs);
389 screens[i].putsf(0, line++, "watermark: %6d",
390 (int)(d.watermark));
392 screens[i].update();
396 tick_remove_task(dbg_audio_task);
398 FOR_NB_SCREENS(i)
399 screens[i].setfont(FONT_UI);
401 return false;
403 #endif /* CONFIG_CODEC */
404 #endif /* HAVE_LCD_BITMAP */
407 #if (CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE))
408 /* Tool function to read the flash manufacturer and type, if available.
409 Only chips which could be reprogrammed in system will return values.
410 (The mode switch addresses vary between flash manufacturers, hence addr1/2) */
411 /* In IRAM to avoid problems when running directly from Flash */
412 static bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
413 unsigned addr1, unsigned addr2)
414 ICODE_ATTR __attribute__((noinline));
415 static bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
416 unsigned addr1, unsigned addr2)
419 unsigned not_manu, not_id; /* read values before switching to ID mode */
420 unsigned manu, id; /* read values when in ID mode */
422 #if CONFIG_CPU == SH7034
423 volatile unsigned char* flash = (unsigned char*)0x2000000; /* flash mapping */
424 #elif defined(CPU_COLDFIRE)
425 volatile unsigned short* flash = (unsigned short*)0; /* flash mapping */
426 #endif
427 int old_level; /* saved interrupt level */
429 not_manu = flash[0]; /* read the normal content */
430 not_id = flash[1]; /* should be 'A' (0x41) and 'R' (0x52) from the "ARCH" marker */
432 /* disable interrupts, prevent any stray flash access */
433 old_level = disable_irq_save();
435 flash[addr1] = 0xAA; /* enter command mode */
436 flash[addr2] = 0x55;
437 flash[addr1] = 0x90; /* ID command */
438 /* Atmel wants 20ms pause here */
439 /* sleep(HZ/50); no sleeping possible while interrupts are disabled */
441 manu = flash[0]; /* read the IDs */
442 id = flash[1];
444 flash[0] = 0xF0; /* reset flash (back to normal read mode) */
445 /* Atmel wants 20ms pause here */
446 /* sleep(HZ/50); no sleeping possible while interrupts are disabled */
448 restore_irq(old_level); /* enable interrupts again */
450 /* I assume success if the obtained values are different from
451 the normal flash content. This is not perfectly bulletproof, they
452 could theoretically be the same by chance, causing us to fail. */
453 if (not_manu != manu || not_id != id) /* a value has changed */
455 *p_manufacturer = manu; /* return the results */
456 *p_device = id;
457 return true; /* success */
459 return false; /* fail */
461 #endif /* (CONFIG_CPU == SH7034 || CPU_COLDFIRE) */
463 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
464 #ifdef CPU_PP
465 static int perfcheck(void)
467 int result;
469 asm (
470 "mrs r2, CPSR \n"
471 "orr r0, r2, #0xc0 \n" /* disable IRQ and FIQ */
472 "msr CPSR_c, r0 \n"
473 "mov %[res], #0 \n"
474 "ldr r0, [%[timr]] \n"
475 "add r0, r0, %[tmo] \n"
476 "1: \n"
477 "add %[res], %[res], #1 \n"
478 "ldr r1, [%[timr]] \n"
479 "cmp r1, r0 \n"
480 "bmi 1b \n"
481 "msr CPSR_c, r2 \n" /* reset IRQ and FIQ state */
483 [res]"=&r"(result)
485 [timr]"r"(&USEC_TIMER),
486 [tmo]"r"(
487 #if CONFIG_CPU == PP5002
488 16000
489 #else /* PP5020/5022/5024 */
490 10226
491 #endif
494 "r0", "r1", "r2"
496 return result;
498 #endif
500 #ifdef HAVE_LCD_BITMAP
501 static bool dbg_hw_info(void)
503 #if CONFIG_CPU == SH7034
504 int bitmask = HW_MASK;
505 int rom_version = ROM_VERSION;
506 unsigned manu, id; /* flash IDs */
507 bool got_id; /* flag if we managed to get the flash IDs */
508 unsigned rom_crc = 0xffffffff; /* CRC32 of the boot ROM */
509 bool has_bootrom; /* flag for boot ROM present */
510 int oldmode; /* saved memory guard mode */
512 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
514 /* get flash ROM type */
515 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
516 if (!got_id)
517 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
519 /* check if the boot ROM area is a flash mirror */
520 has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0);
521 if (has_bootrom) /* if ROM and Flash different */
523 /* calculate CRC16 checksum of boot ROM */
524 rom_crc = crc_32((unsigned char*)0x0000, 64*1024, 0xffffffff);
527 system_memory_guard(oldmode); /* re-enable memory guard */
529 lcd_setfont(FONT_SYSFIXED);
530 lcd_clear_display();
532 lcd_puts(0, 0, "[Hardware info]");
534 lcd_putsf(0, 1, "ROM: %d.%02d", rom_version/100, rom_version%100);
536 lcd_putsf(0, 2, "Mask: 0x%04x", bitmask);
538 if (got_id)
539 lcd_putsf(0, 3, "Flash: M=%02x D=%02x", manu, id);
540 else
541 lcd_puts(0, 3, "Flash: M=?? D=??"); /* unknown, sorry */
543 if (has_bootrom)
545 if (rom_crc == 0x56DBA4EE) /* known Version 1 */
546 lcd_puts(0, 4, "Boot ROM: V1");
547 else
548 lcd_putsf(0, 4, "ROMcrc: 0x%08x", rom_crc);
550 else
552 lcd_puts(0, 4, "Boot ROM: none");
555 lcd_update();
557 while (!(action_userabort(TIMEOUT_BLOCK)));
559 #elif CONFIG_CPU == MCF5249 || CONFIG_CPU == MCF5250
560 unsigned manu, id; /* flash IDs */
561 int got_id; /* flag if we managed to get the flash IDs */
562 int oldmode; /* saved memory guard mode */
563 int line = 0;
565 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
567 /* get flash ROM type */
568 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
569 if (!got_id)
570 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
572 system_memory_guard(oldmode); /* re-enable memory guard */
574 lcd_setfont(FONT_SYSFIXED);
575 lcd_clear_display();
577 lcd_puts(0, line++, "[Hardware info]");
579 if (got_id)
580 lcd_putsf(0, line++, "Flash: M=%04x D=%04x", manu, id);
581 else
582 lcd_puts(0, line++, "Flash: M=???? D=????"); /* unknown, sorry */
584 #ifdef IAUDIO_X5
586 struct ds2411_id id;
588 lcd_puts(0, ++line, "Serial Number:");
590 got_id = ds2411_read_id(&id);
592 if (got_id == DS2411_OK)
594 lcd_putsf(0, ++line, " FC=%02x", (unsigned)id.family_code);
595 lcd_putsf(0, ++line, " ID=%02X %02X %02X %02X %02X %02X",
596 (unsigned)id.uid[0], (unsigned)id.uid[1], (unsigned)id.uid[2],
597 (unsigned)id.uid[3], (unsigned)id.uid[4], (unsigned)id.uid[5]);
598 lcd_putsf(0, ++line, " CRC=%02X", (unsigned)id.crc);
600 else
602 lcd_putsf(0, ++line, "READ ERR=%d", got_id);
605 #endif
607 lcd_update();
609 while (!(action_userabort(TIMEOUT_BLOCK)));
611 #elif defined(CPU_PP502x)
612 int line = 0;
613 char pp_version[] = { (PP_VER2 >> 24) & 0xff, (PP_VER2 >> 16) & 0xff,
614 (PP_VER2 >> 8) & 0xff, (PP_VER2) & 0xff,
615 (PP_VER1 >> 24) & 0xff, (PP_VER1 >> 16) & 0xff,
616 (PP_VER1 >> 8) & 0xff, (PP_VER1) & 0xff, '\0' };
618 lcd_setfont(FONT_SYSFIXED);
619 lcd_clear_display();
621 lcd_puts(0, line++, "[Hardware info]");
623 #ifdef IPOD_ARCH
624 lcd_putsf(0, line++, "HW rev: 0x%08lx", IPOD_HW_REVISION);
625 #endif
627 #ifdef IPOD_COLOR
628 extern int lcd_type; /* Defined in lcd-colornano.c */
630 lcd_putsf(0, line++, "LCD type: %d", lcd_type);
631 #endif
633 lcd_putsf(0, line++, "PP version: %s", pp_version);
635 lcd_putsf(0, line++, "Est. clock (kHz): %d", perfcheck());
637 lcd_update();
639 while (!(action_userabort(TIMEOUT_BLOCK)));
641 #elif CONFIG_CPU == PP5002
642 int line = 0;
643 char pp_version[] = { (PP_VER4 >> 8) & 0xff, PP_VER4 & 0xff,
644 (PP_VER3 >> 8) & 0xff, PP_VER3 & 0xff,
645 (PP_VER2 >> 8) & 0xff, PP_VER2 & 0xff,
646 (PP_VER1 >> 8) & 0xff, PP_VER1 & 0xff, '\0' };
649 lcd_setfont(FONT_SYSFIXED);
650 lcd_clear_display();
652 lcd_puts(0, line++, "[Hardware info]");
654 #ifdef IPOD_ARCH
655 lcd_putsf(0, line++, "HW rev: 0x%08lx", IPOD_HW_REVISION);
656 #endif
658 lcd_putsf(0, line++, "PP version: %s", pp_version);
660 lcd_putsf(0, line++, "Est. clock (kHz): %d", perfcheck());
662 lcd_update();
664 while (!(action_userabort(TIMEOUT_BLOCK)));
666 #else
667 /* Define this function in your target tree */
668 return __dbg_hw_info();
669 #endif /* CONFIG_CPU */
670 lcd_setfont(FONT_UI);
671 return false;
673 #else /* !HAVE_LCD_BITMAP */
674 static bool dbg_hw_info(void)
676 int button;
677 int currval = 0;
678 int rom_version = ROM_VERSION;
679 unsigned manu, id; /* flash IDs */
680 bool got_id; /* flag if we managed to get the flash IDs */
681 unsigned rom_crc = 0xffffffff; /* CRC32 of the boot ROM */
682 bool has_bootrom; /* flag for boot ROM present */
683 int oldmode; /* saved memory guard mode */
685 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
687 /* get flash ROM type */
688 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
689 if (!got_id)
690 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
692 /* check if the boot ROM area is a flash mirror */
693 has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0);
694 if (has_bootrom) /* if ROM and Flash different */
696 /* calculate CRC16 checksum of boot ROM */
697 rom_crc = crc_32((unsigned char*)0x0000, 64*1024, 0xffffffff);
700 system_memory_guard(oldmode); /* re-enable memory guard */
702 lcd_clear_display();
704 lcd_puts(0, 0, "[HW Info]");
705 while(1)
707 switch(currval)
709 case 0:
710 lcd_putsf(0, 1, "ROM: %d.%02d",
711 rom_version/100, rom_version%100);
712 break;
713 case 1:
714 if (got_id)
715 lcd_putsf(0, 1, "Flash:%02x,%02x", manu, id);
716 else
717 lcd_puts(0, 1, "Flash:??,??"); /* unknown, sorry */
718 break;
719 case 2:
720 if (has_bootrom)
722 if (rom_crc == 0x56DBA4EE) /* known Version 1 */
723 lcd_puts(0, 1, "BootROM: V1");
724 else if (rom_crc == 0x358099E8)
725 lcd_puts(0, 1, "BootROM: V2");
726 /* alternative boot ROM found in one single player so far */
727 else
728 lcd_putsf(0, 1, "R: %08x", rom_crc);
730 else
731 lcd_puts(0, 1, "BootROM: no");
734 lcd_update();
736 button = get_action(CONTEXT_SETTINGS,TIMEOUT_BLOCK);
738 switch(button)
740 case ACTION_STD_CANCEL:
741 return false;
743 case ACTION_SETTINGS_DEC:
744 currval--;
745 if(currval < 0)
746 currval = 2;
747 break;
749 case ACTION_SETTINGS_INC:
750 currval++;
751 if(currval > 2)
752 currval = 0;
753 break;
756 return false;
758 #endif /* !HAVE_LCD_BITMAP */
759 #endif /* PLATFORM_NATIVE */
761 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
762 static const char* dbg_partitions_getname(int selected_item, void *data,
763 char *buffer, size_t buffer_len)
765 (void)data;
766 int partition = selected_item/2;
767 struct partinfo* p = disk_partinfo(partition);
768 if (selected_item%2)
770 snprintf(buffer, buffer_len, " T:%x %ld MB", p->type, p->size / ( 2048 / ( SECTOR_SIZE / 512 )));
772 else
774 snprintf(buffer, buffer_len, "P%d: S:%lx", partition, p->start);
776 return buffer;
779 bool dbg_partitions(void)
781 struct simplelist_info info;
782 simplelist_info_init(&info, "Partition Info", 4, NULL);
783 info.selection_size = 2;
784 info.hide_selection = true;
785 info.scroll_all = true;
786 info.get_name = dbg_partitions_getname;
787 return simplelist_show_list(&info);
789 #endif /* PLATFORM_NATIVE */
791 #if defined(CPU_COLDFIRE) && defined(HAVE_SPDIF_OUT)
792 static bool dbg_spdif(void)
794 int line;
795 unsigned int control;
796 int x;
797 char *s;
798 int category;
799 int generation;
800 unsigned int interruptstat;
801 bool valnogood, symbolerr, parityerr;
802 bool done = false;
803 bool spdif_src_on;
804 int spdif_source = spdif_get_output_source(&spdif_src_on);
805 spdif_set_output_source(AUDIO_SRC_SPDIF IF_SPDIF_POWER_(, true));
807 lcd_clear_display();
808 lcd_setfont(FONT_SYSFIXED);
810 #ifdef HAVE_SPDIF_POWER
811 spdif_power_enable(true); /* We need SPDIF power for both sending & receiving */
812 #endif
814 while (!done)
816 line = 0;
818 control = EBU1RCVCCHANNEL1;
819 interruptstat = INTERRUPTSTAT;
820 INTERRUPTCLEAR = 0x03c00000;
822 valnogood = (interruptstat & 0x01000000)?true:false;
823 symbolerr = (interruptstat & 0x00800000)?true:false;
824 parityerr = (interruptstat & 0x00400000)?true:false;
826 lcd_putsf(0, line++, "Val: %s Sym: %s Par: %s",
827 valnogood?"--":"OK",
828 symbolerr?"--":"OK",
829 parityerr?"--":"OK");
831 lcd_putsf(0, line++, "Status word: %08x", (int)control);
833 line++;
835 x = control >> 31;
836 lcd_putsf(0, line++, "PRO: %d (%s)",
837 x, x?"Professional":"Consumer");
839 x = (control >> 30) & 1;
840 lcd_putsf(0, line++, "Audio: %d (%s)",
841 x, x?"Non-PCM":"PCM");
843 x = (control >> 29) & 1;
844 lcd_putsf(0, line++, "Copy: %d (%s)",
845 x, x?"Permitted":"Inhibited");
847 x = (control >> 27) & 7;
848 switch(x)
850 case 0:
851 s = "None";
852 break;
853 case 1:
854 s = "50/15us";
855 break;
856 default:
857 s = "Reserved";
858 break;
860 lcd_putsf(0, line++, "Preemphasis: %d (%s)", x, s);
862 x = (control >> 24) & 3;
863 lcd_putsf(0, line++, "Mode: %d", x);
865 category = (control >> 17) & 127;
866 switch(category)
868 case 0x00:
869 s = "General";
870 break;
871 case 0x40:
872 s = "Audio CD";
873 break;
874 default:
875 s = "Unknown";
877 lcd_putsf(0, line++, "Category: 0x%02x (%s)", category, s);
879 x = (control >> 16) & 1;
880 generation = x;
881 if(((category & 0x70) == 0x10) ||
882 ((category & 0x70) == 0x40) ||
883 ((category & 0x78) == 0x38))
885 generation = !generation;
887 lcd_putsf(0, line++, "Generation: %d (%s)",
888 x, generation?"Original":"No ind.");
890 x = (control >> 12) & 15;
891 lcd_putsf(0, line++, "Source: %d", x);
894 x = (control >> 8) & 15;
895 switch(x)
897 case 0:
898 s = "Unspecified";
899 break;
900 case 8:
901 s = "A (Left)";
902 break;
903 case 4:
904 s = "B (Right)";
905 break;
906 default:
907 s = "";
908 break;
910 lcd_putsf(0, line++, "Channel: %d (%s)", x, s);
912 x = (control >> 4) & 15;
913 switch(x)
915 case 0:
916 s = "44.1kHz";
917 break;
918 case 0x4:
919 s = "48kHz";
920 break;
921 case 0xc:
922 s = "32kHz";
923 break;
925 lcd_putsf(0, line++, "Frequency: %d (%s)", x, s);
927 x = (control >> 2) & 3;
928 lcd_putsf(0, line++, "Clock accuracy: %d", x);
929 line++;
931 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
932 lcd_putsf(0, line++, "Measured freq: %ldHz",
933 spdif_measure_frequency());
934 #endif
936 lcd_update();
938 if (action_userabort(HZ/10))
939 break;
942 spdif_set_output_source(spdif_source IF_SPDIF_POWER_(, spdif_src_on));
944 #ifdef HAVE_SPDIF_POWER
945 spdif_power_enable(global_settings.spdif_enable);
946 #endif
948 lcd_setfont(FONT_UI);
949 return false;
951 #endif /* CPU_COLDFIRE */
953 #if (CONFIG_RTC == RTC_PCF50605) && (CONFIG_PLATFORM & PLATFORM_NATIVE)
954 static bool dbg_pcf(void)
956 int line;
958 #ifdef HAVE_LCD_BITMAP
959 lcd_setfont(FONT_SYSFIXED);
960 #endif
961 lcd_clear_display();
963 while(1)
965 line = 0;
967 lcd_putsf(0, line++, "DCDC1: %02x", pcf50605_read(0x1b));
968 lcd_putsf(0, line++, "DCDC2: %02x", pcf50605_read(0x1c));
969 lcd_putsf(0, line++, "DCDC3: %02x", pcf50605_read(0x1d));
970 lcd_putsf(0, line++, "DCDC4: %02x", pcf50605_read(0x1e));
971 lcd_putsf(0, line++, "DCDEC1: %02x", pcf50605_read(0x1f));
972 lcd_putsf(0, line++, "DCDEC2: %02x", pcf50605_read(0x20));
973 lcd_putsf(0, line++, "DCUDC1: %02x", pcf50605_read(0x21));
974 lcd_putsf(0, line++, "DCUDC2: %02x", pcf50605_read(0x22));
975 lcd_putsf(0, line++, "IOREGC: %02x", pcf50605_read(0x23));
976 lcd_putsf(0, line++, "D1REGC: %02x", pcf50605_read(0x24));
977 lcd_putsf(0, line++, "D2REGC: %02x", pcf50605_read(0x25));
978 lcd_putsf(0, line++, "D3REGC: %02x", pcf50605_read(0x26));
979 lcd_putsf(0, line++, "LPREG1: %02x", pcf50605_read(0x27));
980 lcd_update();
981 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
983 lcd_setfont(FONT_UI);
984 return false;
988 lcd_setfont(FONT_UI);
989 return false;
991 #endif
993 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
994 static bool dbg_cpufreq(void)
996 int line;
997 int button;
999 #ifdef HAVE_LCD_BITMAP
1000 lcd_setfont(FONT_SYSFIXED);
1001 #endif
1002 lcd_clear_display();
1004 while(1)
1006 line = 0;
1008 lcd_putsf(0, line++, "Frequency: %ld", FREQ);
1009 lcd_putsf(0, line++, "boost_counter: %d", get_cpu_boost_counter());
1011 lcd_update();
1012 button = get_action(CONTEXT_STD,HZ/10);
1014 switch(button)
1016 case ACTION_STD_PREV:
1017 cpu_boost(true);
1018 break;
1020 case ACTION_STD_NEXT:
1021 cpu_boost(false);
1022 break;
1024 case ACTION_STD_OK:
1025 while (get_cpu_boost_counter() > 0)
1026 cpu_boost(false);
1027 set_cpu_frequency(CPUFREQ_DEFAULT);
1028 break;
1030 case ACTION_STD_CANCEL:
1031 lcd_setfont(FONT_UI);
1032 return false;
1035 lcd_setfont(FONT_UI);
1036 return false;
1038 #endif /* HAVE_ADJUSTABLE_CPU_FREQ */
1040 #if defined(HAVE_TSC2100) && (CONFIG_PLATFORM & PLATFORM_NATIVE)
1041 #include "tsc2100.h"
1042 static char *itob(int n, int len)
1044 static char binary[64];
1045 int i,j;
1046 for (i=1, j=0;i<=len;i++)
1048 binary[j++] = n&(1<<(len-i))?'1':'0';
1049 if (i%4 == 0)
1050 binary[j++] = ' ';
1052 binary[j] = '\0';
1053 return binary;
1056 static const char* tsc2100_debug_getname(int selected_item, void * data,
1057 char *buffer, size_t buffer_len)
1059 int *page = (int*)data;
1060 bool reserved = false;
1061 switch (*page)
1063 case 0:
1064 if ((selected_item > 0x0a) ||
1065 (selected_item == 0x04) ||
1066 (selected_item == 0x08))
1067 reserved = true;
1068 break;
1069 case 1:
1070 if ((selected_item > 0x05) ||
1071 (selected_item == 0x02))
1072 reserved = true;
1073 break;
1074 case 2:
1075 if (selected_item > 0x1e)
1076 reserved = true;
1077 break;
1079 if (reserved)
1080 snprintf(buffer, buffer_len, "%02x: RESERVED", selected_item);
1081 else
1082 snprintf(buffer, buffer_len, "%02x: %s", selected_item,
1083 itob(tsc2100_readreg(*page, selected_item)&0xffff,16));
1084 return buffer;
1086 static int tsc2100debug_action_callback(int action, struct gui_synclist *lists)
1088 int *page = (int*)lists->data;
1089 if (action == ACTION_STD_OK)
1091 *page = (*page+1)%3;
1092 snprintf(lists->title, 32,
1093 "tsc2100 registers - Page %d", *page);
1094 return ACTION_REDRAW;
1096 return action;
1098 static bool tsc2100_debug(void)
1100 int page = 0;
1101 char title[32] = "tsc2100 registers - Page 0";
1102 struct simplelist_info info;
1103 simplelist_info_init(&info, title, 32, &page);
1104 info.timeout = HZ/100;
1105 info.get_name = tsc2100_debug_getname;
1106 info.action_callback= tsc2100debug_action_callback;
1107 return simplelist_show_list(&info);
1109 #endif
1110 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
1111 #ifdef HAVE_LCD_BITMAP
1113 * view_battery() shows a automatically scaled graph of the battery voltage
1114 * over time. Usable for estimating battery life / charging rate.
1115 * The power_history array is updated in power_thread of powermgmt.c.
1118 #define BAT_LAST_VAL MIN(LCD_WIDTH, POWER_HISTORY_LEN)
1119 #define BAT_YSPACE (LCD_HEIGHT - 20)
1122 static bool view_battery(void)
1124 int view = 0;
1125 int i, x, y, y1, y2, grid, graph;
1126 unsigned short maxv, minv;
1128 lcd_setfont(FONT_SYSFIXED);
1130 while(1)
1132 lcd_clear_display();
1133 switch (view) {
1134 case 0: /* voltage history graph */
1135 /* Find maximum and minimum voltage for scaling */
1136 minv = power_history[0];
1137 maxv = minv + 1;
1138 for (i = 1; i < BAT_LAST_VAL && power_history[i]; i++) {
1139 if (power_history[i] > maxv)
1140 maxv = power_history[i];
1141 if (power_history[i] < minv)
1142 minv = power_history[i];
1145 /* adjust grid scale */
1146 if ((maxv - minv) > 50)
1147 grid = 50;
1148 else
1149 grid = 5;
1151 /* print header */
1152 lcd_putsf(0, 0, "battery %d.%03dV", power_history[0] / 1000,
1153 power_history[0] % 1000);
1154 lcd_putsf(0, 1, "%d.%03d-%d.%03dV (%2dmV)",
1155 minv / 1000, minv % 1000, maxv / 1000, maxv % 1000,
1156 grid);
1158 i = 1;
1159 while ((y = (minv - (minv % grid)+i*grid)) < maxv)
1161 graph = ((y-minv)*BAT_YSPACE)/(maxv-minv);
1162 graph = LCD_HEIGHT-1 - graph;
1164 /* draw dotted horizontal grid line */
1165 for (x=0; x<LCD_WIDTH;x=x+2)
1166 lcd_drawpixel(x,graph);
1168 i++;
1171 x = 0;
1172 /* draw plot of power history
1173 * skip empty entries
1175 for (i = BAT_LAST_VAL - 1; i > 0; i--)
1177 if (power_history[i] && power_history[i-1])
1179 y1 = (power_history[i] - minv) * BAT_YSPACE /
1180 (maxv - minv);
1181 y1 = MIN(MAX(LCD_HEIGHT-1 - y1, 20),
1182 LCD_HEIGHT-1);
1183 y2 = (power_history[i-1] - minv) * BAT_YSPACE /
1184 (maxv - minv);
1185 y2 = MIN(MAX(LCD_HEIGHT-1 - y2, 20),
1186 LCD_HEIGHT-1);
1188 lcd_set_drawmode(DRMODE_SOLID);
1190 /* make line thicker */
1191 lcd_drawline(((x*LCD_WIDTH)/(BAT_LAST_VAL)),
1192 y1,
1193 (((x+1)*LCD_WIDTH)/(BAT_LAST_VAL)),
1194 y2);
1195 lcd_drawline(((x*LCD_WIDTH)/(BAT_LAST_VAL))+1,
1196 y1+1,
1197 (((x+1)*LCD_WIDTH)/(BAT_LAST_VAL))+1,
1198 y2+1);
1199 x++;
1202 break;
1204 case 1: /* status: */
1205 #if CONFIG_CHARGING >= CHARGING_MONITOR
1206 lcd_putsf(0, 0, "Pwr status: %s",
1207 charging_state() ? "charging" : "discharging");
1208 #else
1209 lcd_puts(0, 0, "Power status:");
1210 #endif
1211 battery_read_info(&y, NULL);
1212 lcd_putsf(0, 1, "Battery: %d.%03d V", y / 1000, y % 1000);
1213 #ifdef ADC_EXT_POWER
1214 y = (adc_read(ADC_EXT_POWER) * EXT_SCALE_FACTOR) / 1000;
1215 lcd_putsf(0, 2, "External: %d.%03d V", y / 1000, y % 1000);
1216 #endif
1217 #if CONFIG_CHARGING
1218 #if defined ARCHOS_RECORDER
1219 lcd_putsf(0, 3, "Chgr: %s %s",
1220 charger_inserted() ? "present" : "absent",
1221 charger_enabled() ? "on" : "off");
1222 lcd_putsf(0, 5, "short delta: %d", short_delta);
1223 lcd_putsf(0, 6, "long delta: %d", long_delta);
1224 lcd_puts(0, 7, power_message);
1225 lcd_putsf(0, 8, "USB Inserted: %s",
1226 usb_inserted() ? "yes" : "no");
1227 #elif defined IPOD_NANO || defined IPOD_VIDEO
1228 int usb_pwr = (GPIOL_INPUT_VAL & 0x10)?true:false;
1229 int ext_pwr = (GPIOL_INPUT_VAL & 0x08)?false:true;
1230 int dock = (GPIOA_INPUT_VAL & 0x10)?true:false;
1231 int charging = (GPIOB_INPUT_VAL & 0x01)?false:true;
1232 int headphone= (GPIOA_INPUT_VAL & 0x80)?true:false;
1234 lcd_putsf(0, 3, "USB pwr: %s",
1235 usb_pwr ? "present" : "absent");
1236 lcd_putsf(0, 4, "EXT pwr: %s",
1237 ext_pwr ? "present" : "absent");
1238 lcd_putsf(0, 5, "Battery: %s",
1239 charging ? "charging" : (usb_pwr||ext_pwr) ? "charged" : "discharging");
1240 lcd_putsf(0, 6, "Dock mode: %s",
1241 dock ? "enabled" : "disabled");
1242 lcd_putsf(0, 7, "Headphone: %s",
1243 headphone ? "connected" : "disconnected");
1244 #ifdef IPOD_VIDEO
1245 if(probed_ramsize == 64)
1246 x = (adc_read(ADC_4066_ISTAT) * 2400) / (1024 * 2);
1247 else
1248 x = (adc_read(ADC_4066_ISTAT) * 2400) / (1024 * 3);
1249 lcd_putsf(0, 8, "Ibat: %d mA", x);
1250 lcd_putsf(0, 9, "Vbat * Ibat: %d mW", x * y / 1000);
1251 #endif
1252 #elif defined TOSHIBA_GIGABEAT_S
1253 int line = 3;
1254 unsigned int st;
1256 static const unsigned char * const chrgstate_strings[] =
1258 "Disabled",
1259 "Error",
1260 "Discharging",
1261 "Precharge",
1262 "Constant Voltage",
1263 "Constant Current",
1264 "<unknown>",
1267 lcd_putsf(0, line++, "Charger: %s",
1268 charger_inserted() ? "present" : "absent");
1270 st = power_input_status() &
1271 (POWER_INPUT_CHARGER | POWER_INPUT_BATTERY);
1272 lcd_putsf(0, line++, "%s%s",
1273 (st & POWER_INPUT_MAIN_CHARGER) ? " Main" : "",
1274 (st & POWER_INPUT_USB_CHARGER) ? " USB" : "");
1276 y = ARRAYLEN(chrgstate_strings) - 1;
1278 switch (charge_state)
1280 case CHARGE_STATE_DISABLED: y--;
1281 case CHARGE_STATE_ERROR: y--;
1282 case DISCHARGING: y--;
1283 case TRICKLE: y--;
1284 case TOPOFF: y--;
1285 case CHARGING: y--;
1286 default:;
1289 lcd_putsf(0, line++, "State: %s", chrgstate_strings[y]);
1291 lcd_putsf(0, line++, "Battery Switch: %s",
1292 (st & POWER_INPUT_BATTERY) ? "On" : "Off");
1294 y = chrgraw_adc_voltage();
1295 lcd_putsf(0, line++, "CHRGRAW: %d.%03d V",
1296 y / 1000, y % 1000);
1298 y = application_supply_adc_voltage();
1299 lcd_putsf(0, line++, "BP : %d.%03d V",
1300 y / 1000, y % 1000);
1302 y = battery_adc_charge_current();
1303 if (y < 0) x = '-', y = -y;
1304 else x = ' ';
1305 lcd_putsf(0, line++, "CHRGISN:%c%d mA", x, y);
1307 y = cccv_regulator_dissipation();
1308 lcd_putsf(0, line++, "P CCCV : %d mW", y);
1310 y = battery_charge_current();
1311 if (y < 0) x = '-', y = -y;
1312 else x = ' ';
1313 lcd_putsf(0, line++, "I Charge:%c%d mA", x, y);
1315 y = battery_adc_temp();
1317 if (y != INT_MIN) {
1318 lcd_putsf(0, line++, "T Battery: %dC (%dF)", y,
1319 (9*y + 160) / 5);
1320 } else {
1321 /* Conversion disabled */
1322 lcd_puts(0, line++, "T Battery: ?");
1325 #elif defined(SANSA_E200) || defined(SANSA_C200) || CONFIG_CPU == AS3525 || \
1326 CONFIG_CPU == AS3525v2
1327 static const char * const chrgstate_strings[] =
1329 [CHARGE_STATE_DISABLED - CHARGE_STATE_DISABLED]= "Disabled",
1330 [CHARGE_STATE_ERROR - CHARGE_STATE_DISABLED] = "Error",
1331 [DISCHARGING - CHARGE_STATE_DISABLED] = "Discharging",
1332 [CHARGING - CHARGE_STATE_DISABLED] = "Charging",
1334 const char *str = NULL;
1336 lcd_putsf(0, 3, "Charger: %s",
1337 charger_inserted() ? "present" : "absent");
1339 y = charge_state - CHARGE_STATE_DISABLED;
1340 if ((unsigned)y < ARRAYLEN(chrgstate_strings))
1341 str = chrgstate_strings[y];
1343 lcd_putsf(0, 4, "State: %s",
1344 str ? str : "<unknown>");
1346 lcd_putsf(0, 5, "CHARGER: %02X", ascodec_read_charger());
1347 #elif defined(IPOD_NANO2G)
1348 y = pmu_read_battery_voltage();
1349 lcd_putsf(17, 1, "RAW: %d.%03d V", y / 1000, y % 1000);
1350 y = pmu_read_battery_current();
1351 lcd_putsf(0, 2, "Battery current: %d mA", y);
1352 lcd_putsf(0, 3, "PWRCON: %08x %08x", PWRCON, PWRCONEXT);
1353 lcd_putsf(0, 4, "CLKCON: %08x %03x %03x", CLKCON, CLKCON2, CLKCON3);
1354 lcd_putsf(0, 5, "PLL: %06x %06x %06x", PLL0PMS, PLL1PMS, PLL2PMS);
1355 x = pmu_read(0x1b) & 0xf;
1356 y = pmu_read(0x1a) * 25 + 625;
1357 lcd_putsf(0, 6, "AUTO: %x / %d mV", x, y);
1358 x = pmu_read(0x1f) & 0xf;
1359 y = pmu_read(0x1e) * 25 + 625;
1360 lcd_putsf(0, 7, "DOWN1: %x / %d mV", x, y);
1361 x = pmu_read(0x23) & 0xf;
1362 y = pmu_read(0x22) * 25 + 625;
1363 lcd_putsf(0, 8, "DOWN2: %x / %d mV", x, y);
1364 x = pmu_read(0x27) & 0xf;
1365 y = pmu_read(0x26) * 100 + 900;
1366 lcd_putsf(0, 9, "MEMLDO: %x / %d mV", x, y);
1367 for (i = 0; i < 6; i++)
1369 x = pmu_read(0x2e + (i << 1)) & 0xf;
1370 y = pmu_read(0x2d + (i << 1)) * 100 + 900;
1371 lcd_putsf(0, 10 + i, "LDO%d: %x / %d mV", i + 1, x, y);
1373 #else
1374 lcd_putsf(0, 3, "Charger: %s",
1375 charger_inserted() ? "present" : "absent");
1376 #endif /* target type */
1377 #endif /* CONFIG_CHARGING */
1378 break;
1380 case 2: /* voltage deltas: */
1381 lcd_puts(0, 0, "Voltage deltas:");
1383 for (i = 0; i <= 6; i++) {
1384 y = power_history[i] - power_history[i+1];
1385 lcd_putsf(0, i+1, "-%d min: %s%d.%03d V", i,
1386 (y < 0) ? "-" : "", ((y < 0) ? y * -1 : y) / 1000,
1387 ((y < 0) ? y * -1 : y ) % 1000);
1389 break;
1391 case 3: /* remaining time estimation: */
1393 #ifdef ARCHOS_RECORDER
1394 lcd_putsf(0, 0, "charge_state: %d", charge_state);
1396 lcd_putsf(0, 1, "Cycle time: %d m", powermgmt_last_cycle_startstop_min);
1398 lcd_putsf(0, 2, "Lvl@cyc st: %d%%", powermgmt_last_cycle_level);
1400 lcd_putsf(0, 3, "P=%2d I=%2d", pid_p, pid_i);
1402 lcd_putsf(0, 4, "Trickle sec: %d/60", trickle_sec);
1403 #endif /* ARCHOS_RECORDER */
1405 lcd_putsf(0, 5, "Last PwrHist: %d.%03dV",
1406 power_history[0] / 1000,
1407 power_history[0] % 1000);
1409 lcd_putsf(0, 6, "battery level: %d%%", battery_level());
1411 lcd_putsf(0, 7, "Est. remain: %d m", battery_time());
1412 break;
1415 lcd_update();
1417 switch(get_action(CONTEXT_STD,HZ/2))
1419 case ACTION_STD_PREV:
1420 if (view)
1421 view--;
1422 break;
1424 case ACTION_STD_NEXT:
1425 if (view < 3)
1426 view++;
1427 break;
1429 case ACTION_STD_CANCEL:
1430 lcd_setfont(FONT_UI);
1431 return false;
1434 lcd_setfont(FONT_UI);
1435 return false;
1438 #endif /* HAVE_LCD_BITMAP */
1439 #endif
1441 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
1442 #if (CONFIG_STORAGE & STORAGE_MMC) || (CONFIG_STORAGE & STORAGE_SD)
1444 #if (CONFIG_STORAGE & STORAGE_MMC)
1445 #define CARDTYPE "MMC"
1446 #elif (CONFIG_STORAGE & STORAGE_SD)
1447 #define CARDTYPE "microSD"
1448 #endif
1450 static int disk_callback(int btn, struct gui_synclist *lists)
1452 tCardInfo *card;
1453 int *cardnum = (int*)lists->data;
1454 unsigned char card_name[6];
1455 unsigned char pbuf[32];
1456 char *title = lists->title;
1457 static const unsigned char i_vmin[] = { 0, 1, 5, 10, 25, 35, 60, 100 };
1458 static const unsigned char i_vmax[] = { 1, 5, 10, 25, 35, 45, 80, 200 };
1459 static const unsigned char * const kbit_units[] = { "kBit/s", "MBit/s", "GBit/s" };
1460 static const unsigned char * const nsec_units[] = { "ns", "µs", "ms" };
1461 #if (CONFIG_STORAGE & STORAGE_MMC)
1462 static const char * const mmc_spec_vers[] = { "1.0-1.2", "1.4", "2.0-2.2",
1463 "3.1-3.31", "4.0" };
1464 #endif
1466 if ((btn == ACTION_STD_OK) || (btn == SYS_FS_CHANGED) || (btn == ACTION_REDRAW))
1468 #ifdef HAVE_HOTSWAP
1469 if (btn == ACTION_STD_OK)
1471 *cardnum ^= 0x1; /* change cards */
1473 #endif
1475 simplelist_set_line_count(0);
1477 card = card_get_info(*cardnum);
1479 if (card->initialized > 0)
1481 unsigned i;
1482 for (i=0; i<sizeof(card_name); i++)
1484 card_name[i] = card_extract_bits(card->cid, (103-8*i), 8);
1486 strlcpy(card_name, card_name, sizeof(card_name));
1487 simplelist_addline(SIMPLELIST_ADD_LINE,
1488 "%s Rev %d.%d", card_name,
1489 (int) card_extract_bits(card->cid, 63, 4),
1490 (int) card_extract_bits(card->cid, 59, 4));
1491 simplelist_addline(SIMPLELIST_ADD_LINE,
1492 "Prod: %d/%d",
1493 #if (CONFIG_STORAGE & STORAGE_SD)
1494 (int) card_extract_bits(card->cid, 11, 4),
1495 (int) card_extract_bits(card->cid, 19, 8) + 2000
1496 #elif (CONFIG_STORAGE & STORAGE_MMC)
1497 (int) card_extract_bits(card->cid, 15, 4),
1498 (int) card_extract_bits(card->cid, 11, 4) + 1997
1499 #endif
1501 simplelist_addline(SIMPLELIST_ADD_LINE,
1502 #if (CONFIG_STORAGE & STORAGE_SD)
1503 "Ser#: 0x%08lx",
1504 card_extract_bits(card->cid, 55, 32)
1505 #elif (CONFIG_STORAGE & STORAGE_MMC)
1506 "Ser#: 0x%04lx",
1507 card_extract_bits(card->cid, 47, 16)
1508 #endif
1511 simplelist_addline(SIMPLELIST_ADD_LINE, "M=%02x, "
1512 #if (CONFIG_STORAGE & STORAGE_SD)
1513 "O=%c%c",
1514 (int) card_extract_bits(card->cid, 127, 8),
1515 card_extract_bits(card->cid, 119, 8),
1516 card_extract_bits(card->cid, 111, 8)
1517 #elif (CONFIG_STORAGE & STORAGE_MMC)
1518 "O=%04x",
1519 (int) card_extract_bits(card->cid, 127, 8),
1520 (int) card_extract_bits(card->cid, 119, 16)
1521 #endif
1524 #if (CONFIG_STORAGE & STORAGE_MMC)
1525 int temp = card_extract_bits(card->csd, 125, 4);
1526 simplelist_addline(SIMPLELIST_ADD_LINE,
1527 "MMC v%s", temp < 5 ?
1528 mmc_spec_vers[temp] : "?.?");
1529 #endif
1530 simplelist_addline(SIMPLELIST_ADD_LINE,
1531 "Blocks: 0x%08lx", card->numblocks);
1532 output_dyn_value(pbuf, sizeof pbuf, card->speed / 1000,
1533 kbit_units, false);
1534 simplelist_addline(SIMPLELIST_ADD_LINE,
1535 "Speed: %s", pbuf);
1536 output_dyn_value(pbuf, sizeof pbuf, card->taac,
1537 nsec_units, false);
1538 simplelist_addline(SIMPLELIST_ADD_LINE,
1539 "Taac: %s", pbuf);
1540 simplelist_addline(SIMPLELIST_ADD_LINE,
1541 "Nsac: %d clk", card->nsac);
1542 simplelist_addline(SIMPLELIST_ADD_LINE,
1543 "R2W: *%d", card->r2w_factor);
1544 simplelist_addline(SIMPLELIST_ADD_LINE,
1545 "IRmax: %d..%d mA",
1546 i_vmin[card_extract_bits(card->csd, 61, 3)],
1547 i_vmax[card_extract_bits(card->csd, 58, 3)]);
1548 simplelist_addline(SIMPLELIST_ADD_LINE,
1549 "IWmax: %d..%d mA",
1550 i_vmin[card_extract_bits(card->csd, 55, 3)],
1551 i_vmax[card_extract_bits(card->csd, 52, 3)]);
1553 else if (card->initialized == 0)
1555 simplelist_addline(SIMPLELIST_ADD_LINE, "Not Found!");
1557 #if (CONFIG_STORAGE & STORAGE_SD)
1558 else /* card->initialized < 0 */
1560 simplelist_addline(SIMPLELIST_ADD_LINE, "Init Error! (%d)", card->initialized);
1562 #endif
1563 snprintf(title, 16, "[" CARDTYPE " %d]", *cardnum);
1564 gui_synclist_set_title(lists, title, Icon_NOICON);
1565 gui_synclist_set_nb_items(lists, simplelist_get_line_count());
1566 gui_synclist_select_item(lists, 0);
1567 btn = ACTION_REDRAW;
1569 return btn;
1571 #elif (CONFIG_STORAGE & STORAGE_ATA)
1572 static int disk_callback(int btn, struct gui_synclist *lists)
1574 (void)lists;
1575 int i;
1576 char buf[128];
1577 unsigned short* identify_info = ata_get_identify();
1578 bool timing_info_present = false;
1579 (void)btn;
1581 simplelist_set_line_count(0);
1583 for (i=0; i < 20; i++)
1584 ((unsigned short*)buf)[i]=htobe16(identify_info[i+27]);
1585 buf[40]=0;
1586 /* kill trailing space */
1587 for (i=39; i && buf[i]==' '; i--)
1588 buf[i] = 0;
1589 simplelist_addline(SIMPLELIST_ADD_LINE, "Model: %s", buf);
1590 for (i=0; i < 4; i++)
1591 ((unsigned short*)buf)[i]=htobe16(identify_info[i+23]);
1592 buf[8]=0;
1593 simplelist_addline(SIMPLELIST_ADD_LINE,
1594 "Firmware: %s", buf);
1595 snprintf(buf, sizeof buf, "%ld MB",
1596 ((unsigned long)identify_info[61] << 16 |
1597 (unsigned long)identify_info[60]) / 2048 );
1598 simplelist_addline(SIMPLELIST_ADD_LINE,
1599 "Size: %s", buf);
1600 unsigned long free;
1601 fat_size( IF_MV2(0,) NULL, &free );
1602 simplelist_addline(SIMPLELIST_ADD_LINE,
1603 "Free: %ld MB", free / 1024);
1604 simplelist_addline(SIMPLELIST_ADD_LINE,
1605 "Spinup time: %d ms", storage_spinup_time() * (1000/HZ));
1606 i = identify_info[83] & (1<<3);
1607 simplelist_addline(SIMPLELIST_ADD_LINE,
1608 "Power mgmt: %s", i ? "enabled" : "unsupported");
1609 i = identify_info[83] & (1<<9);
1610 simplelist_addline(SIMPLELIST_ADD_LINE,
1611 "Noise mgmt: %s", i ? "enabled" : "unsupported");
1612 i = identify_info[82] & (1<<6);
1613 simplelist_addline(SIMPLELIST_ADD_LINE,
1614 "Read-ahead: %s", i ? "enabled" : "unsupported");
1615 timing_info_present = identify_info[53] & (1<<1);
1616 if(timing_info_present) {
1617 char pio3[2], pio4[2];pio3[1] = 0;
1618 pio4[1] = 0;
1619 pio3[0] = (identify_info[64] & (1<<0)) ? '3' : 0;
1620 pio4[0] = (identify_info[64] & (1<<1)) ? '4' : 0;
1621 simplelist_addline(SIMPLELIST_ADD_LINE,
1622 "PIO modes: 0 1 2 %s %s", pio3, pio4);
1624 else {
1625 simplelist_addline(SIMPLELIST_ADD_LINE,
1626 "No PIO mode info");
1628 timing_info_present = identify_info[53] & (1<<1);
1629 if(timing_info_present) {
1630 simplelist_addline(SIMPLELIST_ADD_LINE,
1631 "Cycle times %dns/%dns",
1632 identify_info[67],
1633 identify_info[68] );
1634 } else {
1635 simplelist_addline(SIMPLELIST_ADD_LINE,
1636 "No timing info");
1638 int sector_size = 512;
1639 if((identify_info[106] & 0xe000) == 0x6000)
1640 sector_size *= BIT_N(identify_info[106] & 0x000f);
1641 simplelist_addline(SIMPLELIST_ADD_LINE,
1642 "Physical sector size: %d", sector_size);
1643 #ifdef HAVE_ATA_DMA
1644 if (identify_info[63] & (1<<0)) {
1645 char mdma0[2], mdma1[2], mdma2[2];
1646 mdma0[1] = mdma1[1] = mdma2[1] = 0;
1647 mdma0[0] = (identify_info[63] & (1<<0)) ? '0' : 0;
1648 mdma1[0] = (identify_info[63] & (1<<1)) ? '1' : 0;
1649 mdma2[0] = (identify_info[63] & (1<<2)) ? '2' : 0;
1650 simplelist_addline(SIMPLELIST_ADD_LINE,
1651 "MDMA modes: %s %s %s", mdma0, mdma1, mdma2);
1652 simplelist_addline(SIMPLELIST_ADD_LINE,
1653 "MDMA Cycle times %dns/%dns",
1654 identify_info[65],
1655 identify_info[66] );
1657 else {
1658 simplelist_addline(SIMPLELIST_ADD_LINE,
1659 "No MDMA mode info");
1661 if (identify_info[53] & (1<<2)) {
1662 char udma0[2], udma1[2], udma2[2], udma3[2], udma4[2], udma5[2], udma6[2];
1663 udma0[1] = udma1[1] = udma2[1] = udma3[1] = udma4[1] = udma5[1] = udma6[1] = 0;
1664 udma0[0] = (identify_info[88] & (1<<0)) ? '0' : 0;
1665 udma1[0] = (identify_info[88] & (1<<1)) ? '1' : 0;
1666 udma2[0] = (identify_info[88] & (1<<2)) ? '2' : 0;
1667 udma3[0] = (identify_info[88] & (1<<3)) ? '3' : 0;
1668 udma4[0] = (identify_info[88] & (1<<4)) ? '4' : 0;
1669 udma5[0] = (identify_info[88] & (1<<5)) ? '5' : 0;
1670 udma6[0] = (identify_info[88] & (1<<6)) ? '6' : 0;
1671 simplelist_addline(SIMPLELIST_ADD_LINE,
1672 "UDMA modes: %s %s %s %s %s %s %s", udma0, udma1, udma2,
1673 udma3, udma4, udma5, udma6);
1675 else {
1676 simplelist_addline(SIMPLELIST_ADD_LINE,
1677 "No UDMA mode info");
1679 #endif /* HAVE_ATA_DMA */
1680 timing_info_present = identify_info[53] & (1<<1);
1681 if(timing_info_present) {
1682 i = identify_info[49] & (1<<11);
1683 simplelist_addline(SIMPLELIST_ADD_LINE,
1684 "IORDY support: %s", i ? "yes" : "no");
1685 i = identify_info[49] & (1<<10);
1686 simplelist_addline(SIMPLELIST_ADD_LINE,
1687 "IORDY disable: %s", i ? "yes" : "no");
1688 } else {
1689 simplelist_addline(SIMPLELIST_ADD_LINE,
1690 "No timing info");
1692 simplelist_addline(SIMPLELIST_ADD_LINE,
1693 "Cluster size: %d bytes", fat_get_cluster_size(IF_MV(0)));
1694 #ifdef HAVE_ATA_DMA
1695 i = ata_get_dma_mode();
1696 if (i == 0) {
1697 simplelist_addline(SIMPLELIST_ADD_LINE,
1698 "DMA not enabled");
1699 } else {
1700 simplelist_addline(SIMPLELIST_ADD_LINE,
1701 "DMA mode: %s %c",
1702 (i & 0x40) ? "UDMA" : "MDMA",
1703 '0' + (i & 7));
1705 #endif /* HAVE_ATA_DMA */
1706 return btn;
1708 #else /* No SD, MMC or ATA */
1709 static int disk_callback(int btn, struct gui_synclist *lists)
1711 (void)btn;
1712 (void)lists;
1713 struct storage_info info;
1714 storage_get_info(0,&info);
1715 simplelist_addline(SIMPLELIST_ADD_LINE, "Vendor: %s", info.vendor);
1716 simplelist_addline(SIMPLELIST_ADD_LINE, "Model: %s", info.product);
1717 simplelist_addline(SIMPLELIST_ADD_LINE, "Firmware: %s", info.revision);
1718 simplelist_addline(SIMPLELIST_ADD_LINE,
1719 "Size: %ld MB", info.num_sectors*(info.sector_size/512)/2024);
1720 unsigned long free;
1721 fat_size( IF_MV2(0,) NULL, &free );
1722 simplelist_addline(SIMPLELIST_ADD_LINE,
1723 "Free: %ld MB", free / 1024);
1724 simplelist_addline(SIMPLELIST_ADD_LINE,
1725 "Cluster size: %d bytes", fat_get_cluster_size(IF_MV(0)));
1726 return btn;
1728 #endif
1730 #if (CONFIG_STORAGE & STORAGE_ATA)
1731 static bool dbg_identify_info(void)
1733 int fd = creat("/identify_info.bin", 0666);
1734 if(fd >= 0)
1736 #ifdef ROCKBOX_LITTLE_ENDIAN
1737 ecwrite(fd, ata_get_identify(), SECTOR_SIZE/2, "s", true);
1738 #else
1739 write(fd, ata_get_identify(), SECTOR_SIZE);
1740 #endif
1741 close(fd);
1743 return false;
1745 #endif
1747 static bool dbg_disk_info(void)
1749 struct simplelist_info info;
1750 simplelist_info_init(&info, "Disk Info", 1, NULL);
1751 #if (CONFIG_STORAGE & STORAGE_MMC) || (CONFIG_STORAGE & STORAGE_SD)
1752 char title[16];
1753 int card = 0;
1754 info.callback_data = (void*)&card;
1755 info.title = title;
1756 #endif
1757 info.action_callback = disk_callback;
1758 info.hide_selection = true;
1759 info.scroll_all = true;
1760 return simplelist_show_list(&info);
1762 #endif /* PLATFORM_NATIVE */
1764 #ifdef HAVE_DIRCACHE
1765 static int dircache_callback(int btn, struct gui_synclist *lists)
1767 (void)btn; (void)lists;
1768 simplelist_set_line_count(0);
1769 simplelist_addline(SIMPLELIST_ADD_LINE, "Cache initialized: %s",
1770 dircache_is_enabled() ? "Yes" : "No");
1771 simplelist_addline(SIMPLELIST_ADD_LINE, "Cache size: %d B",
1772 dircache_get_cache_size());
1773 simplelist_addline(SIMPLELIST_ADD_LINE, "Last size: %d B",
1774 global_status.dircache_size);
1775 simplelist_addline(SIMPLELIST_ADD_LINE, "Limit: %d B",
1776 DIRCACHE_LIMIT);
1777 simplelist_addline(SIMPLELIST_ADD_LINE, "Reserve: %d/%d B",
1778 dircache_get_reserve_used(), DIRCACHE_RESERVE);
1779 simplelist_addline(SIMPLELIST_ADD_LINE, "Scanning took: %d s",
1780 dircache_get_build_ticks() / HZ);
1781 simplelist_addline(SIMPLELIST_ADD_LINE, "Entry count: %d",
1782 dircache_get_entry_count());
1783 return btn;
1786 static bool dbg_dircache_info(void)
1788 struct simplelist_info info;
1789 simplelist_info_init(&info, "Dircache Info", 7, NULL);
1790 info.action_callback = dircache_callback;
1791 info.hide_selection = true;
1792 info.scroll_all = true;
1793 return simplelist_show_list(&info);
1796 #endif /* HAVE_DIRCACHE */
1798 #ifdef HAVE_TAGCACHE
1799 static int database_callback(int btn, struct gui_synclist *lists)
1801 (void)lists;
1802 struct tagcache_stat *stat = tagcache_get_stat();
1803 static bool synced = false;
1805 simplelist_set_line_count(0);
1807 simplelist_addline(SIMPLELIST_ADD_LINE, "Initialized: %s",
1808 stat->initialized ? "Yes" : "No");
1809 simplelist_addline(SIMPLELIST_ADD_LINE, "DB Ready: %s",
1810 stat->ready ? "Yes" : "No");
1811 simplelist_addline(SIMPLELIST_ADD_LINE, "RAM Cache: %s",
1812 stat->ramcache ? "Yes" : "No");
1813 simplelist_addline(SIMPLELIST_ADD_LINE, "RAM: %d/%d B",
1814 stat->ramcache_used, stat->ramcache_allocated);
1815 simplelist_addline(SIMPLELIST_ADD_LINE, "Progress: %d%% (%d entries)",
1816 stat->progress, stat->processed_entries);
1817 simplelist_addline(SIMPLELIST_ADD_LINE, "Curfile: %s",
1818 stat->curentry ? stat->curentry : "---");
1819 simplelist_addline(SIMPLELIST_ADD_LINE, "Commit step: %d",
1820 stat->commit_step);
1821 simplelist_addline(SIMPLELIST_ADD_LINE, "Commit delayed: %s",
1822 stat->commit_delayed ? "Yes" : "No");
1824 simplelist_addline(SIMPLELIST_ADD_LINE, "Queue length: %d",
1825 stat->queue_length);
1827 if (synced)
1829 synced = false;
1830 tagcache_screensync_event();
1833 if (!btn && stat->curentry)
1835 synced = true;
1836 return ACTION_REDRAW;
1839 if (btn == ACTION_STD_CANCEL)
1840 tagcache_screensync_enable(false);
1842 return btn;
1844 static bool dbg_tagcache_info(void)
1846 struct simplelist_info info;
1847 simplelist_info_init(&info, "Database Info", 8, NULL);
1848 info.action_callback = database_callback;
1849 info.hide_selection = true;
1850 info.scroll_all = true;
1852 /* Don't do nonblock here, must give enough processing time
1853 for tagcache thread. */
1854 /* info.timeout = TIMEOUT_NOBLOCK; */
1855 info.timeout = 1;
1856 tagcache_screensync_enable(true);
1857 return simplelist_show_list(&info);
1859 #endif
1861 #if CONFIG_CPU == SH7034
1862 static bool dbg_save_roms(void)
1864 int fd;
1865 int oldmode = system_memory_guard(MEMGUARD_NONE);
1867 fd = creat("/internal_rom_0000-FFFF.bin", 0666);
1868 if(fd >= 0)
1870 write(fd, (void *)0, 0x10000);
1871 close(fd);
1874 fd = creat("/internal_rom_2000000-203FFFF.bin", 0666);
1875 if(fd >= 0)
1877 write(fd, (void *)0x2000000, 0x40000);
1878 close(fd);
1881 system_memory_guard(oldmode);
1882 return false;
1884 #elif defined CPU_COLDFIRE
1885 static bool dbg_save_roms(void)
1887 int fd;
1888 int oldmode = system_memory_guard(MEMGUARD_NONE);
1890 #if defined(IRIVER_H100_SERIES)
1891 fd = creat("/internal_rom_000000-1FFFFF.bin", 0666);
1892 #elif defined(IRIVER_H300_SERIES)
1893 fd = creat("/internal_rom_000000-3FFFFF.bin", 0666);
1894 #elif defined(IAUDIO_X5) || defined(IAUDIO_M5) || defined(IAUDIO_M3)
1895 fd = creat("/internal_rom_000000-3FFFFF.bin", 0666);
1896 #elif defined(MPIO_HD200) || defined(MPIO_HD300)
1897 fd = creat("/internal_rom_000000-1FFFFF.bin", 0666);
1898 #endif
1899 if(fd >= 0)
1901 write(fd, (void *)0, FLASH_SIZE);
1902 close(fd);
1904 system_memory_guard(oldmode);
1906 #ifdef HAVE_EEPROM
1907 fd = creat("/internal_eeprom.bin", 0666);
1908 if (fd >= 0)
1910 int old_irq_level;
1911 char buf[EEPROM_SIZE];
1912 int err;
1914 old_irq_level = disable_irq_save();
1916 err = eeprom_24cxx_read(0, buf, sizeof buf);
1918 restore_irq(old_irq_level);
1920 if (err)
1921 splashf(HZ*3, "Eeprom read failure (%d)", err);
1922 else
1924 write(fd, buf, sizeof buf);
1927 close(fd);
1929 #endif
1931 return false;
1933 #elif defined(CPU_PP) && !(CONFIG_STORAGE & STORAGE_SD)
1934 static bool dbg_save_roms(void)
1936 int fd;
1938 fd = creat("/internal_rom_000000-0FFFFF.bin", 0666);
1939 if(fd >= 0)
1941 write(fd, (void *)0x20000000, FLASH_SIZE);
1942 close(fd);
1945 return false;
1947 #elif CONFIG_CPU == IMX31L
1948 static bool dbg_save_roms(void)
1950 int fd;
1952 fd = creat("/flash_rom_A0000000-A01FFFFF.bin", 0666);
1953 if (fd >= 0)
1955 write(fd, (void*)0xa0000000, FLASH_SIZE);
1956 close(fd);
1959 return false;
1961 #elif defined(CPU_TCC780X)
1962 static bool dbg_save_roms(void)
1964 int fd;
1966 fd = creat("/eeprom_E0000000-E0001FFF.bin", 0666);
1967 if (fd >= 0)
1969 write(fd, (void*)0xe0000000, 0x2000);
1970 close(fd);
1973 return false;
1975 #endif /* CPU */
1977 #ifndef SIMULATOR
1978 #if CONFIG_TUNER
1980 #ifdef CONFIG_TUNER_MULTI
1981 static int tuner_type = 0;
1982 #define IF_TUNER_TYPE(type) if(tuner_type==type)
1983 #else
1984 #define IF_TUNER_TYPE(type)
1985 #endif
1987 static int radio_callback(int btn, struct gui_synclist *lists)
1989 (void)lists;
1990 if (btn == ACTION_STD_CANCEL)
1991 return btn;
1992 simplelist_set_line_count(1);
1994 #if (CONFIG_TUNER & LV24020LP)
1995 simplelist_addline(SIMPLELIST_ADD_LINE,
1996 "CTRL_STAT: %02X", lv24020lp_get(LV24020LP_CTRL_STAT) );
1997 simplelist_addline(SIMPLELIST_ADD_LINE,
1998 "RADIO_STAT: %02X", lv24020lp_get(LV24020LP_REG_STAT) );
1999 simplelist_addline(SIMPLELIST_ADD_LINE,
2000 "MSS_FM: %d kHz", lv24020lp_get(LV24020LP_MSS_FM) );
2001 simplelist_addline(SIMPLELIST_ADD_LINE,
2002 "MSS_IF: %d Hz", lv24020lp_get(LV24020LP_MSS_IF) );
2003 simplelist_addline(SIMPLELIST_ADD_LINE,
2004 "MSS_SD: %d Hz", lv24020lp_get(LV24020LP_MSS_SD) );
2005 simplelist_addline(SIMPLELIST_ADD_LINE,
2006 "if_set: %d Hz", lv24020lp_get(LV24020LP_IF_SET) );
2007 simplelist_addline(SIMPLELIST_ADD_LINE,
2008 "sd_set: %d Hz", lv24020lp_get(LV24020LP_SD_SET) );
2009 #endif /* LV24020LP */
2010 #if (CONFIG_TUNER & S1A0903X01)
2011 simplelist_addline(SIMPLELIST_ADD_LINE,
2012 "Samsung regs: %08X", s1a0903x01_get(RADIO_ALL));
2013 /* This one doesn't return dynamic data atm */
2014 #endif /* S1A0903X01 */
2015 #if (CONFIG_TUNER & TEA5767)
2016 struct tea5767_dbg_info nfo;
2017 tea5767_dbg_info(&nfo);
2018 simplelist_addline(SIMPLELIST_ADD_LINE, "Philips regs:");
2019 simplelist_addline(SIMPLELIST_ADD_LINE,
2020 " Read: %02X %02X %02X %02X %02X",
2021 (unsigned)nfo.read_regs[0], (unsigned)nfo.read_regs[1],
2022 (unsigned)nfo.read_regs[2], (unsigned)nfo.read_regs[3],
2023 (unsigned)nfo.read_regs[4]);
2024 simplelist_addline(SIMPLELIST_ADD_LINE,
2025 " Write: %02X %02X %02X %02X %02X",
2026 (unsigned)nfo.write_regs[0], (unsigned)nfo.write_regs[1],
2027 (unsigned)nfo.write_regs[2], (unsigned)nfo.write_regs[3],
2028 (unsigned)nfo.write_regs[4]);
2029 #endif /* TEA5767 */
2030 #if (CONFIG_TUNER & SI4700)
2031 IF_TUNER_TYPE(SI4700)
2033 struct si4700_dbg_info nfo;
2034 int i;
2035 si4700_dbg_info(&nfo);
2036 simplelist_addline(SIMPLELIST_ADD_LINE, "SI4700 regs:");
2037 for (i = 0; i < 16; i += 4) {
2038 simplelist_addline(SIMPLELIST_ADD_LINE,"%02X: %04X %04X %04X %04X",
2039 i, nfo.regs[i], nfo.regs[i+1], nfo.regs[i+2], nfo.regs[i+3]);
2042 #endif /* SI4700 */
2043 #if (CONFIG_TUNER & RDA5802)
2044 IF_TUNER_TYPE(RDA5802)
2046 struct rda5802_dbg_info nfo;
2047 int i;
2048 rda5802_dbg_info(&nfo);
2049 simplelist_addline(SIMPLELIST_ADD_LINE, "RDA5802 regs:");
2050 for (i = 0; i < 16; i += 4) {
2051 simplelist_addline(SIMPLELIST_ADD_LINE,"%02X: %04X %04X %04X %04X",
2052 i, nfo.regs[i], nfo.regs[i+1], nfo.regs[i+2], nfo.regs[i+3]);
2055 #endif /* RDA55802 */
2056 return ACTION_REDRAW;
2058 static bool dbg_fm_radio(void)
2060 struct simplelist_info info;
2061 #ifdef CONFIG_TUNER_MULTI
2062 tuner_type = tuner_detect_type();
2063 #endif
2064 info.scroll_all = true;
2065 simplelist_info_init(&info, "FM Radio", 1, NULL);
2066 simplelist_set_line_count(0);
2067 simplelist_addline(SIMPLELIST_ADD_LINE, "HW detected: %s",
2068 radio_hardware_present() ? "yes" : "no");
2070 info.action_callback = radio_hardware_present()?radio_callback : NULL;
2071 info.hide_selection = true;
2072 return simplelist_show_list(&info);
2074 #endif /* CONFIG_TUNER */
2075 #endif /* !SIMULATOR */
2077 #ifdef HAVE_LCD_BITMAP
2078 extern bool do_screendump_instead_of_usb;
2080 static bool dbg_screendump(void)
2082 do_screendump_instead_of_usb = !do_screendump_instead_of_usb;
2083 splashf(HZ, "Screendump %s",
2084 do_screendump_instead_of_usb?"enabled":"disabled");
2085 return false;
2087 #endif /* HAVE_LCD_BITMAP */
2089 extern bool write_metadata_log;
2091 static bool dbg_metadatalog(void)
2093 write_metadata_log = !write_metadata_log;
2094 splashf(HZ, "Metadata log %s",
2095 write_metadata_log?"enabled":"disabled");
2096 return false;
2099 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
2100 static bool dbg_set_memory_guard(void)
2102 static const struct opt_items names[MAXMEMGUARD] = {
2103 { "None", -1 },
2104 { "Flash ROM writes", -1 },
2105 { "Zero area (all)", -1 }
2107 int mode = system_memory_guard(MEMGUARD_KEEP);
2109 set_option( "Catch mem accesses", &mode, INT, names, MAXMEMGUARD, NULL);
2110 system_memory_guard(mode);
2112 return false;
2114 #endif /* CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) */
2116 #if defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS)
2117 static bool dbg_write_eeprom(void)
2119 int fd;
2120 int rc;
2121 int old_irq_level;
2122 char buf[EEPROM_SIZE];
2123 int err;
2125 fd = open("/internal_eeprom.bin", O_RDONLY);
2127 if (fd >= 0)
2129 rc = read(fd, buf, EEPROM_SIZE);
2131 if(rc == EEPROM_SIZE)
2133 old_irq_level = disable_irq_save();
2135 err = eeprom_24cxx_write(0, buf, sizeof buf);
2136 if (err)
2137 splashf(HZ*3, "Eeprom write failure (%d)", err);
2138 else
2139 splash(HZ*3, "Eeprom written successfully");
2141 restore_irq(old_irq_level);
2143 else
2145 splashf(HZ*3, "File read error (%d)",rc);
2147 close(fd);
2149 else
2151 splash(HZ*3, "Failed to open 'internal_eeprom.bin'");
2154 return false;
2156 #endif /* defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS) */
2157 #ifdef CPU_BOOST_LOGGING
2158 static bool cpu_boost_log(void)
2160 int i = 0,j=0;
2161 int count = cpu_boost_log_getcount();
2162 int lines = LCD_HEIGHT/SYSFONT_HEIGHT;
2163 char *str;
2164 bool done;
2165 lcd_setfont(FONT_SYSFIXED);
2166 str = cpu_boost_log_getlog_first();
2167 while (i < count)
2169 lcd_clear_display();
2170 for(j=0; j<lines; j++,i++)
2172 if (!str)
2173 str = cpu_boost_log_getlog_next();
2174 if (str)
2176 if(strlen(str) > LCD_WIDTH/SYSFONT_WIDTH)
2177 lcd_puts_scroll(0, j, str);
2178 else
2179 lcd_puts(0, j,str);
2181 str = NULL;
2183 lcd_update();
2184 done = false;
2185 while (!done)
2187 switch(get_action(CONTEXT_STD,TIMEOUT_BLOCK))
2189 case ACTION_STD_OK:
2190 case ACTION_STD_PREV:
2191 case ACTION_STD_NEXT:
2192 done = true;
2193 break;
2194 case ACTION_STD_CANCEL:
2195 i = count;
2196 done = true;
2197 break;
2201 lcd_stop_scroll();
2202 get_action(CONTEXT_STD,TIMEOUT_BLOCK);
2203 lcd_setfont(FONT_UI);
2204 return false;
2206 #endif
2208 #if (defined(HAVE_WHEEL_ACCELERATION) && (CONFIG_KEYPAD==IPOD_4G_PAD) \
2209 && !defined(IPOD_MINI) && !defined(SIMULATOR))
2210 extern bool wheel_is_touched;
2211 extern int old_wheel_value;
2212 extern int new_wheel_value;
2213 extern int wheel_delta;
2214 extern unsigned int accumulated_wheel_delta;
2215 extern unsigned int wheel_velocity;
2217 static bool dbg_scrollwheel(void)
2219 unsigned int speed;
2221 lcd_setfont(FONT_SYSFIXED);
2223 while (1)
2225 if (action_userabort(HZ/10))
2226 break;
2228 lcd_clear_display();
2230 /* show internal variables of scrollwheel driver */
2231 lcd_putsf(0, 0, "wheel touched: %s", (wheel_is_touched) ? "true" : "false");
2232 lcd_putsf(0, 1, "new position: %2d", new_wheel_value);
2233 lcd_putsf(0, 2, "old position: %2d", old_wheel_value);
2234 lcd_putsf(0, 3, "wheel delta: %2d", wheel_delta);
2235 lcd_putsf(0, 4, "accumulated delta: %2d", accumulated_wheel_delta);
2236 lcd_putsf(0, 5, "velo [deg/s]: %4d", (int)wheel_velocity);
2238 /* show effective accelerated scrollspeed */
2239 speed = button_apply_acceleration( (1<<31)|(1<<24)|wheel_velocity);
2240 lcd_putsf(0, 6, "accel. speed: %4d", speed);
2242 lcd_update();
2244 lcd_setfont(FONT_UI);
2245 return false;
2247 #endif
2249 #if defined (HAVE_USBSTACK)
2251 #if defined(ROCKBOX_HAS_LOGF) && defined(USB_ENABLE_SERIAL)
2252 static bool toggle_usb_core_driver(int driver, char *msg)
2254 bool enabled = !usb_core_driver_enabled(driver);
2256 usb_core_enable_driver(driver,enabled);
2257 splashf(HZ, "%s %s", msg, enabled?"enabled":"disabled");
2259 return false;
2262 static bool toggle_usb_serial(void)
2264 return toggle_usb_core_driver(USB_DRIVER_SERIAL,"USB Serial");
2266 #endif
2268 #endif
2270 #if CONFIG_USBOTG == USBOTG_ISP1583
2271 extern int dbg_usb_num_items(void);
2272 extern const char* dbg_usb_item(int selected_item, void *data,
2273 char *buffer, size_t buffer_len);
2275 static int isp1583_action_callback(int action, struct gui_synclist *lists)
2277 (void)lists;
2278 if (action == ACTION_NONE)
2279 action = ACTION_REDRAW;
2280 return action;
2283 static bool dbg_isp1583(void)
2285 struct simplelist_info isp1583;
2286 isp1583.scroll_all = true;
2287 simplelist_info_init(&isp1583, "ISP1583", dbg_usb_num_items(), NULL);
2288 isp1583.timeout = HZ/100;
2289 isp1583.hide_selection = true;
2290 isp1583.get_name = dbg_usb_item;
2291 isp1583.action_callback = isp1583_action_callback;
2292 return simplelist_show_list(&isp1583);
2294 #endif
2296 #if defined(CREATIVE_ZVx) && !defined(SIMULATOR)
2297 extern int pic_dbg_num_items(void);
2298 extern const char* pic_dbg_item(int selected_item, void *data,
2299 char *buffer, size_t buffer_len);
2301 static int pic_action_callback(int action, struct gui_synclist *lists)
2303 (void)lists;
2304 if (action == ACTION_NONE)
2305 action = ACTION_REDRAW;
2306 return action;
2309 static bool dbg_pic(void)
2311 struct simplelist_info pic;
2312 pic.scroll_all = true;
2313 simplelist_info_init(&pic, "PIC", pic_dbg_num_items(), NULL);
2314 pic.timeout = HZ/100;
2315 pic.hide_selection = true;
2316 pic.get_name = pic_dbg_item;
2317 pic.action_callback = pic_action_callback;
2318 return simplelist_show_list(&pic);
2320 #endif
2323 /****** The menu *********/
2324 struct the_menu_item {
2325 unsigned char *desc; /* string or ID */
2326 bool (*function) (void); /* return true if USB was connected */
2328 static const struct the_menu_item menuitems[] = {
2329 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || \
2330 (defined(CPU_PP) && !(CONFIG_STORAGE & STORAGE_SD)) || \
2331 CONFIG_CPU == IMX31L || defined(CPU_TCC780X)
2332 { "Dump ROM contents", dbg_save_roms },
2333 #endif
2334 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || defined(CPU_PP) \
2335 || CONFIG_CPU == S3C2440 || CONFIG_CPU == IMX31L || CONFIG_CPU == AS3525 \
2336 || CONFIG_CPU == DM320 || defined(CPU_S5L870X) || CONFIG_CPU == AS3525v2
2337 { "View I/O ports", dbg_ports },
2338 #endif
2339 #if (CONFIG_RTC == RTC_PCF50605) && (CONFIG_PLATFORM & PLATFORM_NATIVE)
2340 { "View PCF registers", dbg_pcf },
2341 #endif
2342 #if defined(HAVE_TSC2100) && (CONFIG_PLATFORM & PLATFORM_NATIVE)
2343 { "TSC2100 debug", tsc2100_debug },
2344 #endif
2345 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
2346 { "CPU frequency", dbg_cpufreq },
2347 #endif
2348 #if defined(IRIVER_H100_SERIES) && !defined(SIMULATOR)
2349 { "S/PDIF analyzer", dbg_spdif },
2350 #endif
2351 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
2352 { "Catch mem accesses", dbg_set_memory_guard },
2353 #endif
2354 { "View OS stacks", dbg_os },
2355 #ifdef HAVE_LCD_BITMAP
2356 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
2357 { "View battery", view_battery },
2358 #endif
2359 { "Screendump", dbg_screendump },
2360 #endif
2361 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
2362 { "View HW info", dbg_hw_info },
2363 #endif
2364 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
2365 { "View partitions", dbg_partitions },
2366 #endif
2367 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
2368 { "View disk info", dbg_disk_info },
2369 #if (CONFIG_STORAGE & STORAGE_ATA)
2370 { "Dump ATA identify info", dbg_identify_info},
2371 #endif
2372 #endif
2373 { "Metadata log", dbg_metadatalog },
2374 #ifdef HAVE_DIRCACHE
2375 { "View dircache info", dbg_dircache_info },
2376 #endif
2377 #ifdef HAVE_TAGCACHE
2378 { "View database info", dbg_tagcache_info },
2379 #endif
2380 #ifdef HAVE_LCD_BITMAP
2381 #if CONFIG_CODEC == SWCODEC
2382 { "View buffering thread", dbg_buffering_thread },
2383 #elif !defined(SIMULATOR)
2384 { "View audio thread", dbg_audio_thread },
2385 #endif
2386 #ifdef PM_DEBUG
2387 { "pm histogram", peak_meter_histogram},
2388 #endif /* PM_DEBUG */
2389 #endif /* HAVE_LCD_BITMAP */
2390 #ifndef SIMULATOR
2391 #if CONFIG_TUNER
2392 { "FM Radio", dbg_fm_radio },
2393 #endif
2394 #endif
2395 #if defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS)
2396 { "Write back EEPROM", dbg_write_eeprom },
2397 #endif
2398 #if CONFIG_USBOTG == USBOTG_ISP1583
2399 { "View ISP1583 info", dbg_isp1583 },
2400 #endif
2401 #if defined(CREATIVE_ZVx) && !defined(SIMULATOR)
2402 { "View PIC info", dbg_pic },
2403 #endif
2404 #ifdef ROCKBOX_HAS_LOGF
2405 {"Show Log File", logfdisplay },
2406 {"Dump Log File", logfdump },
2407 #endif
2408 #if defined(HAVE_USBSTACK)
2409 #if defined(ROCKBOX_HAS_LOGF) && defined(USB_ENABLE_SERIAL)
2410 {"USB Serial driver (logf)", toggle_usb_serial },
2411 #endif
2412 #endif /* HAVE_USBSTACK */
2413 #ifdef CPU_BOOST_LOGGING
2414 {"cpu_boost log",cpu_boost_log},
2415 #endif
2416 #if (defined(HAVE_WHEEL_ACCELERATION) && (CONFIG_KEYPAD==IPOD_4G_PAD) \
2417 && !defined(IPOD_MINI) && !defined(SIMULATOR))
2418 {"Debug scrollwheel", dbg_scrollwheel },
2419 #endif
2421 static int menu_action_callback(int btn, struct gui_synclist *lists)
2423 int i;
2424 if (btn == ACTION_STD_OK)
2426 FOR_NB_SCREENS(i)
2427 viewportmanager_theme_enable(i, false, NULL);
2428 menuitems[gui_synclist_get_sel_pos(lists)].function();
2429 btn = ACTION_REDRAW;
2430 FOR_NB_SCREENS(i)
2431 viewportmanager_theme_undo(i, false);
2433 return btn;
2436 static const char* dbg_menu_getname(int item, void * data,
2437 char *buffer, size_t buffer_len)
2439 (void)data; (void)buffer; (void)buffer_len;
2440 return menuitems[item].desc;
2443 bool debug_menu(void)
2445 struct simplelist_info info;
2447 simplelist_info_init(&info, "Debug Menu", ARRAYLEN(menuitems), NULL);
2448 info.action_callback = menu_action_callback;
2449 info.get_name = dbg_menu_getname;
2450 return simplelist_show_list(&info);