move dbg_ports() from apps/menu_debug.c to target tree. FS#11712 by me.
[kugel-rb.git] / apps / debug_menu.c
blob631f027017c9a34456f376b954bea13e0305adba
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 #include "debug-target.h"
104 #if defined(SANSA_E200) || defined(SANSA_C200) || defined(PHILIPS_SA9200) \
105 || (CONFIG_CPU == AS3525 && defined(CONFIG_CHARGING)) \
106 || CONFIG_CPU == AS3525v2
107 #include "ascodec.h"
108 #include "as3514.h"
109 #endif
111 #ifdef IPOD_NANO2G
112 #include "pmu-target.h"
113 #endif
115 #ifdef HAVE_USBSTACK
116 #include "usb_core.h"
117 #endif
119 #if defined(IPOD_ACCESSORY_PROTOCOL)
120 #include "iap.h"
121 #endif
123 /*---------------------------------------------------*/
124 /* SPECIAL DEBUG STUFF */
125 /*---------------------------------------------------*/
126 extern struct thread_entry threads[MAXTHREADS];
128 static char thread_status_char(unsigned status)
130 static const char thread_status_chars[THREAD_NUM_STATES+1] =
132 [0 ... THREAD_NUM_STATES] = '?',
133 [STATE_RUNNING] = 'R',
134 [STATE_BLOCKED] = 'B',
135 [STATE_SLEEPING] = 'S',
136 [STATE_BLOCKED_W_TMO] = 'T',
137 [STATE_FROZEN] = 'F',
138 [STATE_KILLED] = 'K',
141 if (status > THREAD_NUM_STATES)
142 status = THREAD_NUM_STATES;
144 return thread_status_chars[status];
147 static const char* threads_getname(int selected_item, void *data,
148 char *buffer, size_t buffer_len)
150 (void)data;
151 struct thread_entry *thread;
152 char name[32];
154 #if NUM_CORES > 1
155 if (selected_item < (int)NUM_CORES)
157 snprintf(buffer, buffer_len, "Idle (%d): %2d%%", selected_item,
158 idle_stack_usage(selected_item));
159 return buffer;
162 selected_item -= NUM_CORES;
163 #endif
165 thread = &threads[selected_item];
167 if (thread->state == STATE_KILLED)
169 snprintf(buffer, buffer_len, "%2d: ---", selected_item);
170 return buffer;
173 thread_get_name(name, 32, thread);
175 snprintf(buffer, buffer_len,
176 "%2d: " IF_COP("(%d) ") "%c%c " IF_PRIO("%d %d ") "%2d%% %s",
177 selected_item,
178 IF_COP(thread->core,)
179 #ifdef HAVE_SCHEDULER_BOOSTCTRL
180 (thread->cpu_boost) ? '+' :
181 #endif
182 ((thread->state == STATE_RUNNING) ? '*' : ' '),
183 thread_status_char(thread->state),
184 IF_PRIO(thread->base_priority, thread->priority, )
185 thread_stack_usage(thread), name);
187 return buffer;
190 static int dbg_threads_action_callback(int action, struct gui_synclist *lists)
192 (void)lists;
193 #ifdef ROCKBOX_HAS_LOGF
194 if (action == ACTION_STD_OK)
196 int selpos = gui_synclist_get_sel_pos(lists);
197 #if NUM_CORES > 1
198 if (selpos >= NUM_CORES)
199 remove_thread(threads[selpos - NUM_CORES].id);
200 #else
201 remove_thread(threads[selpos].id);
202 #endif
203 return ACTION_REDRAW;
205 #endif /* ROCKBOX_HAS_LOGF */
206 if (action == ACTION_NONE)
207 action = ACTION_REDRAW;
208 return action;
210 /* Test code!!! */
211 static bool dbg_os(void)
213 struct simplelist_info info;
214 simplelist_info_init(&info, IF_COP("Core and ") "Stack usage:",
215 #if NUM_CORES == 1
216 MAXTHREADS,
217 #else
218 MAXTHREADS+NUM_CORES,
219 #endif
220 NULL);
221 #ifndef ROCKBOX_HAS_LOGF
222 info.hide_selection = true;
223 info.scroll_all = true;
224 #endif
225 info.action_callback = dbg_threads_action_callback;
226 info.get_name = threads_getname;
227 return simplelist_show_list(&info);
230 #ifdef HAVE_LCD_BITMAP
231 #if CONFIG_CODEC != SWCODEC
232 #ifndef SIMULATOR
233 static bool dbg_audio_thread(void)
235 struct audio_debug d;
237 lcd_setfont(FONT_SYSFIXED);
239 while(1)
241 if (action_userabort(HZ/5))
242 return false;
244 audio_get_debugdata(&d);
246 lcd_clear_display();
248 lcd_putsf(0, 0, "read: %x", d.audiobuf_read);
249 lcd_putsf(0, 1, "write: %x", d.audiobuf_write);
250 lcd_putsf(0, 2, "swap: %x", d.audiobuf_swapwrite);
251 lcd_putsf(0, 3, "playing: %d", d.playing);
252 lcd_putsf(0, 4, "playable: %x", d.playable_space);
253 lcd_putsf(0, 5, "unswapped: %x", d.unswapped_space);
255 /* Playable space left */
256 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, 6*8, 112, 4, d.audiobuflen, 0,
257 d.playable_space, HORIZONTAL);
259 /* Show the watermark limit */
260 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, 6*8+4, 112, 4, d.audiobuflen, 0,
261 d.low_watermark_level, HORIZONTAL);
263 lcd_putsf(0, 7, "wm: %x - %x",
264 d.low_watermark_level, d.lowest_watermark_level);
266 lcd_update();
268 lcd_setfont(FONT_UI);
269 return false;
271 #endif /* !SIMULATOR */
272 #else /* CONFIG_CODEC == SWCODEC */
273 static unsigned int ticks, boost_ticks, freq_sum;
275 static void dbg_audio_task(void)
277 #ifdef CPUFREQ_NORMAL
278 if(FREQ > CPUFREQ_NORMAL)
279 boost_ticks++;
280 freq_sum += FREQ/1000000; /* in MHz */
281 #endif
282 ticks++;
285 static bool dbg_buffering_thread(void)
287 int button;
288 int line, i;
289 bool done = false;
290 size_t bufused;
291 size_t bufsize = pcmbuf_get_bufsize();
292 int pcmbufdescs = pcmbuf_descs();
293 struct buffering_debug d;
294 size_t filebuflen = audio_get_filebuflen();
295 /* This is a size_t, but call it a long so it puts a - when it's bad. */
297 ticks = boost_ticks = freq_sum = 0;
299 tick_add_task(dbg_audio_task);
301 FOR_NB_SCREENS(i)
302 screens[i].setfont(FONT_SYSFIXED);
304 while(!done)
306 button = get_action(CONTEXT_STD,HZ/5);
307 switch(button)
309 case ACTION_STD_NEXT:
310 audio_next();
311 break;
312 case ACTION_STD_PREV:
313 audio_prev();
314 break;
315 case ACTION_STD_CANCEL:
316 done = true;
317 break;
320 buffering_get_debugdata(&d);
321 bufused = bufsize - pcmbuf_free();
323 FOR_NB_SCREENS(i)
325 line = 0;
326 screens[i].clear_display();
329 screens[i].putsf(0, line++, "pcm: %6ld/%ld", (long) bufused, (long) bufsize);
331 gui_scrollbar_draw(&screens[i],0, line*8, screens[i].lcdwidth, 6,
332 bufsize, 0, bufused, HORIZONTAL);
333 line++;
335 screens[i].putsf(0, line++, "alloc: %6ld/%ld", audio_filebufused(),
336 (long) filebuflen);
338 #if LCD_HEIGHT > 80 || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_HEIGHT > 80)
339 if (screens[i].lcdheight > 80)
341 gui_scrollbar_draw(&screens[i],0, line*8, screens[i].lcdwidth, 6,
342 filebuflen, 0, audio_filebufused(), HORIZONTAL);
343 line++;
345 screens[i].putsf(0, line++, "real: %6ld/%ld", (long)d.buffered_data,
346 (long)filebuflen);
348 gui_scrollbar_draw(&screens[i],0, line*8, screens[i].lcdwidth, 6,
349 filebuflen, 0, (long)d.buffered_data, HORIZONTAL);
350 line++;
352 #endif
354 screens[i].putsf(0, line++, "usefl: %6ld/%ld", (long)(d.useful_data),
355 (long)filebuflen);
357 #if LCD_HEIGHT > 80 || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_HEIGHT > 80)
358 if (screens[i].lcdheight > 80)
360 gui_scrollbar_draw(&screens[i],0, line*8, screens[i].lcdwidth, 6,
361 filebuflen, 0, d.useful_data, HORIZONTAL);
362 line++;
364 #endif
366 screens[i].putsf(0, line++, "data_rem: %ld", (long)d.data_rem);
368 screens[i].putsf(0, line++, "track count: %2d", audio_track_count());
370 screens[i].putsf(0, line++, "handle count: %d", (int)d.num_handles);
372 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
373 screens[i].putsf(0, line++, "cpu freq: %3dMHz",
374 (int)((FREQ + 500000) / 1000000));
375 #endif
377 if (ticks > 0)
379 int boostquota = boost_ticks * 1000 / ticks; /* in 0.1 % */
380 int avgclock = freq_sum * 10 / ticks; /* in 100 kHz */
381 screens[i].putsf(0, line++, "boost:%3d.%d%% (%d.%dMHz)",
382 boostquota/10, boostquota%10, avgclock/10, avgclock%10);
385 screens[i].putsf(0, line++, "pcmbufdesc: %2d/%2d",
386 pcmbuf_used_descs(), pcmbufdescs);
387 screens[i].putsf(0, line++, "watermark: %6d",
388 (int)(d.watermark));
390 screens[i].update();
394 tick_remove_task(dbg_audio_task);
396 FOR_NB_SCREENS(i)
397 screens[i].setfont(FONT_UI);
399 return false;
401 #endif /* CONFIG_CODEC */
402 #endif /* HAVE_LCD_BITMAP */
405 #if (CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE))
406 /* Tool function to read the flash manufacturer and type, if available.
407 Only chips which could be reprogrammed in system will return values.
408 (The mode switch addresses vary between flash manufacturers, hence addr1/2) */
409 /* In IRAM to avoid problems when running directly from Flash */
410 static bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
411 unsigned addr1, unsigned addr2)
412 ICODE_ATTR __attribute__((noinline));
413 static bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
414 unsigned addr1, unsigned addr2)
417 unsigned not_manu, not_id; /* read values before switching to ID mode */
418 unsigned manu, id; /* read values when in ID mode */
420 #if CONFIG_CPU == SH7034
421 volatile unsigned char* flash = (unsigned char*)0x2000000; /* flash mapping */
422 #elif defined(CPU_COLDFIRE)
423 volatile unsigned short* flash = (unsigned short*)0; /* flash mapping */
424 #endif
425 int old_level; /* saved interrupt level */
427 not_manu = flash[0]; /* read the normal content */
428 not_id = flash[1]; /* should be 'A' (0x41) and 'R' (0x52) from the "ARCH" marker */
430 /* disable interrupts, prevent any stray flash access */
431 old_level = disable_irq_save();
433 flash[addr1] = 0xAA; /* enter command mode */
434 flash[addr2] = 0x55;
435 flash[addr1] = 0x90; /* ID command */
436 /* Atmel wants 20ms pause here */
437 /* sleep(HZ/50); no sleeping possible while interrupts are disabled */
439 manu = flash[0]; /* read the IDs */
440 id = flash[1];
442 flash[0] = 0xF0; /* reset flash (back to normal read mode) */
443 /* Atmel wants 20ms pause here */
444 /* sleep(HZ/50); no sleeping possible while interrupts are disabled */
446 restore_irq(old_level); /* enable interrupts again */
448 /* I assume success if the obtained values are different from
449 the normal flash content. This is not perfectly bulletproof, they
450 could theoretically be the same by chance, causing us to fail. */
451 if (not_manu != manu || not_id != id) /* a value has changed */
453 *p_manufacturer = manu; /* return the results */
454 *p_device = id;
455 return true; /* success */
457 return false; /* fail */
459 #endif /* (CONFIG_CPU == SH7034 || CPU_COLDFIRE) */
461 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
462 #ifdef CPU_PP
463 static int perfcheck(void)
465 int result;
467 asm (
468 "mrs r2, CPSR \n"
469 "orr r0, r2, #0xc0 \n" /* disable IRQ and FIQ */
470 "msr CPSR_c, r0 \n"
471 "mov %[res], #0 \n"
472 "ldr r0, [%[timr]] \n"
473 "add r0, r0, %[tmo] \n"
474 "1: \n"
475 "add %[res], %[res], #1 \n"
476 "ldr r1, [%[timr]] \n"
477 "cmp r1, r0 \n"
478 "bmi 1b \n"
479 "msr CPSR_c, r2 \n" /* reset IRQ and FIQ state */
481 [res]"=&r"(result)
483 [timr]"r"(&USEC_TIMER),
484 [tmo]"r"(
485 #if CONFIG_CPU == PP5002
486 16000
487 #else /* PP5020/5022/5024 */
488 10226
489 #endif
492 "r0", "r1", "r2"
494 return result;
496 #endif
498 #ifdef HAVE_LCD_BITMAP
499 static bool dbg_hw_info(void)
501 #if CONFIG_CPU == SH7034
502 int bitmask = HW_MASK;
503 int rom_version = ROM_VERSION;
504 unsigned manu, id; /* flash IDs */
505 bool got_id; /* flag if we managed to get the flash IDs */
506 unsigned rom_crc = 0xffffffff; /* CRC32 of the boot ROM */
507 bool has_bootrom; /* flag for boot ROM present */
508 int oldmode; /* saved memory guard mode */
510 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
512 /* get flash ROM type */
513 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
514 if (!got_id)
515 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
517 /* check if the boot ROM area is a flash mirror */
518 has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0);
519 if (has_bootrom) /* if ROM and Flash different */
521 /* calculate CRC16 checksum of boot ROM */
522 rom_crc = crc_32((unsigned char*)0x0000, 64*1024, 0xffffffff);
525 system_memory_guard(oldmode); /* re-enable memory guard */
527 lcd_setfont(FONT_SYSFIXED);
528 lcd_clear_display();
530 lcd_puts(0, 0, "[Hardware info]");
532 lcd_putsf(0, 1, "ROM: %d.%02d", rom_version/100, rom_version%100);
534 lcd_putsf(0, 2, "Mask: 0x%04x", bitmask);
536 if (got_id)
537 lcd_putsf(0, 3, "Flash: M=%02x D=%02x", manu, id);
538 else
539 lcd_puts(0, 3, "Flash: M=?? D=??"); /* unknown, sorry */
541 if (has_bootrom)
543 if (rom_crc == 0x56DBA4EE) /* known Version 1 */
544 lcd_puts(0, 4, "Boot ROM: V1");
545 else
546 lcd_putsf(0, 4, "ROMcrc: 0x%08x", rom_crc);
548 else
550 lcd_puts(0, 4, "Boot ROM: none");
553 lcd_update();
555 while (!(action_userabort(TIMEOUT_BLOCK)));
557 #elif CONFIG_CPU == MCF5249 || CONFIG_CPU == MCF5250
558 unsigned manu, id; /* flash IDs */
559 int got_id; /* flag if we managed to get the flash IDs */
560 int oldmode; /* saved memory guard mode */
561 int line = 0;
563 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
565 /* get flash ROM type */
566 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
567 if (!got_id)
568 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
570 system_memory_guard(oldmode); /* re-enable memory guard */
572 lcd_setfont(FONT_SYSFIXED);
573 lcd_clear_display();
575 lcd_puts(0, line++, "[Hardware info]");
577 if (got_id)
578 lcd_putsf(0, line++, "Flash: M=%04x D=%04x", manu, id);
579 else
580 lcd_puts(0, line++, "Flash: M=???? D=????"); /* unknown, sorry */
582 #ifdef IAUDIO_X5
584 struct ds2411_id id;
586 lcd_puts(0, ++line, "Serial Number:");
588 got_id = ds2411_read_id(&id);
590 if (got_id == DS2411_OK)
592 lcd_putsf(0, ++line, " FC=%02x", (unsigned)id.family_code);
593 lcd_putsf(0, ++line, " ID=%02X %02X %02X %02X %02X %02X",
594 (unsigned)id.uid[0], (unsigned)id.uid[1], (unsigned)id.uid[2],
595 (unsigned)id.uid[3], (unsigned)id.uid[4], (unsigned)id.uid[5]);
596 lcd_putsf(0, ++line, " CRC=%02X", (unsigned)id.crc);
598 else
600 lcd_putsf(0, ++line, "READ ERR=%d", got_id);
603 #endif
605 lcd_update();
607 while (!(action_userabort(TIMEOUT_BLOCK)));
609 #elif defined(CPU_PP502x)
610 int line = 0;
611 char pp_version[] = { (PP_VER2 >> 24) & 0xff, (PP_VER2 >> 16) & 0xff,
612 (PP_VER2 >> 8) & 0xff, (PP_VER2) & 0xff,
613 (PP_VER1 >> 24) & 0xff, (PP_VER1 >> 16) & 0xff,
614 (PP_VER1 >> 8) & 0xff, (PP_VER1) & 0xff, '\0' };
616 lcd_setfont(FONT_SYSFIXED);
617 lcd_clear_display();
619 lcd_puts(0, line++, "[Hardware info]");
621 #ifdef IPOD_ARCH
622 lcd_putsf(0, line++, "HW rev: 0x%08lx", IPOD_HW_REVISION);
623 #endif
625 #ifdef IPOD_COLOR
626 extern int lcd_type; /* Defined in lcd-colornano.c */
628 lcd_putsf(0, line++, "LCD type: %d", lcd_type);
629 #endif
631 lcd_putsf(0, line++, "PP version: %s", pp_version);
633 lcd_putsf(0, line++, "Est. clock (kHz): %d", perfcheck());
635 lcd_update();
637 while (!(action_userabort(TIMEOUT_BLOCK)));
639 #elif CONFIG_CPU == PP5002
640 int line = 0;
641 char pp_version[] = { (PP_VER4 >> 8) & 0xff, PP_VER4 & 0xff,
642 (PP_VER3 >> 8) & 0xff, PP_VER3 & 0xff,
643 (PP_VER2 >> 8) & 0xff, PP_VER2 & 0xff,
644 (PP_VER1 >> 8) & 0xff, PP_VER1 & 0xff, '\0' };
647 lcd_setfont(FONT_SYSFIXED);
648 lcd_clear_display();
650 lcd_puts(0, line++, "[Hardware info]");
652 #ifdef IPOD_ARCH
653 lcd_putsf(0, line++, "HW rev: 0x%08lx", IPOD_HW_REVISION);
654 #endif
656 lcd_putsf(0, line++, "PP version: %s", pp_version);
658 lcd_putsf(0, line++, "Est. clock (kHz): %d", perfcheck());
660 lcd_update();
662 while (!(action_userabort(TIMEOUT_BLOCK)));
664 #else
665 /* Define this function in your target tree */
666 return __dbg_hw_info();
667 #endif /* CONFIG_CPU */
668 lcd_setfont(FONT_UI);
669 return false;
671 #else /* !HAVE_LCD_BITMAP */
672 static bool dbg_hw_info(void)
674 int button;
675 int currval = 0;
676 int rom_version = ROM_VERSION;
677 unsigned manu, id; /* flash IDs */
678 bool got_id; /* flag if we managed to get the flash IDs */
679 unsigned rom_crc = 0xffffffff; /* CRC32 of the boot ROM */
680 bool has_bootrom; /* flag for boot ROM present */
681 int oldmode; /* saved memory guard mode */
683 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
685 /* get flash ROM type */
686 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
687 if (!got_id)
688 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
690 /* check if the boot ROM area is a flash mirror */
691 has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0);
692 if (has_bootrom) /* if ROM and Flash different */
694 /* calculate CRC16 checksum of boot ROM */
695 rom_crc = crc_32((unsigned char*)0x0000, 64*1024, 0xffffffff);
698 system_memory_guard(oldmode); /* re-enable memory guard */
700 lcd_clear_display();
702 lcd_puts(0, 0, "[HW Info]");
703 while(1)
705 switch(currval)
707 case 0:
708 lcd_putsf(0, 1, "ROM: %d.%02d",
709 rom_version/100, rom_version%100);
710 break;
711 case 1:
712 if (got_id)
713 lcd_putsf(0, 1, "Flash:%02x,%02x", manu, id);
714 else
715 lcd_puts(0, 1, "Flash:??,??"); /* unknown, sorry */
716 break;
717 case 2:
718 if (has_bootrom)
720 if (rom_crc == 0x56DBA4EE) /* known Version 1 */
721 lcd_puts(0, 1, "BootROM: V1");
722 else if (rom_crc == 0x358099E8)
723 lcd_puts(0, 1, "BootROM: V2");
724 /* alternative boot ROM found in one single player so far */
725 else
726 lcd_putsf(0, 1, "R: %08x", rom_crc);
728 else
729 lcd_puts(0, 1, "BootROM: no");
732 lcd_update();
734 button = get_action(CONTEXT_SETTINGS,TIMEOUT_BLOCK);
736 switch(button)
738 case ACTION_STD_CANCEL:
739 return false;
741 case ACTION_SETTINGS_DEC:
742 currval--;
743 if(currval < 0)
744 currval = 2;
745 break;
747 case ACTION_SETTINGS_INC:
748 currval++;
749 if(currval > 2)
750 currval = 0;
751 break;
754 return false;
756 #endif /* !HAVE_LCD_BITMAP */
757 #endif /* PLATFORM_NATIVE */
759 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
760 static const char* dbg_partitions_getname(int selected_item, void *data,
761 char *buffer, size_t buffer_len)
763 (void)data;
764 int partition = selected_item/2;
765 struct partinfo* p = disk_partinfo(partition);
766 if (selected_item%2)
768 snprintf(buffer, buffer_len, " T:%x %ld MB", p->type, p->size / ( 2048 / ( SECTOR_SIZE / 512 )));
770 else
772 snprintf(buffer, buffer_len, "P%d: S:%lx", partition, p->start);
774 return buffer;
777 bool dbg_partitions(void)
779 struct simplelist_info info;
780 simplelist_info_init(&info, "Partition Info", 4, NULL);
781 info.selection_size = 2;
782 info.hide_selection = true;
783 info.scroll_all = true;
784 info.get_name = dbg_partitions_getname;
785 return simplelist_show_list(&info);
787 #endif /* PLATFORM_NATIVE */
789 #if defined(CPU_COLDFIRE) && defined(HAVE_SPDIF_OUT)
790 static bool dbg_spdif(void)
792 int line;
793 unsigned int control;
794 int x;
795 char *s;
796 int category;
797 int generation;
798 unsigned int interruptstat;
799 bool valnogood, symbolerr, parityerr;
800 bool done = false;
801 bool spdif_src_on;
802 int spdif_source = spdif_get_output_source(&spdif_src_on);
803 spdif_set_output_source(AUDIO_SRC_SPDIF IF_SPDIF_POWER_(, true));
805 lcd_clear_display();
806 lcd_setfont(FONT_SYSFIXED);
808 #ifdef HAVE_SPDIF_POWER
809 spdif_power_enable(true); /* We need SPDIF power for both sending & receiving */
810 #endif
812 while (!done)
814 line = 0;
816 control = EBU1RCVCCHANNEL1;
817 interruptstat = INTERRUPTSTAT;
818 INTERRUPTCLEAR = 0x03c00000;
820 valnogood = (interruptstat & 0x01000000)?true:false;
821 symbolerr = (interruptstat & 0x00800000)?true:false;
822 parityerr = (interruptstat & 0x00400000)?true:false;
824 lcd_putsf(0, line++, "Val: %s Sym: %s Par: %s",
825 valnogood?"--":"OK",
826 symbolerr?"--":"OK",
827 parityerr?"--":"OK");
829 lcd_putsf(0, line++, "Status word: %08x", (int)control);
831 line++;
833 x = control >> 31;
834 lcd_putsf(0, line++, "PRO: %d (%s)",
835 x, x?"Professional":"Consumer");
837 x = (control >> 30) & 1;
838 lcd_putsf(0, line++, "Audio: %d (%s)",
839 x, x?"Non-PCM":"PCM");
841 x = (control >> 29) & 1;
842 lcd_putsf(0, line++, "Copy: %d (%s)",
843 x, x?"Permitted":"Inhibited");
845 x = (control >> 27) & 7;
846 switch(x)
848 case 0:
849 s = "None";
850 break;
851 case 1:
852 s = "50/15us";
853 break;
854 default:
855 s = "Reserved";
856 break;
858 lcd_putsf(0, line++, "Preemphasis: %d (%s)", x, s);
860 x = (control >> 24) & 3;
861 lcd_putsf(0, line++, "Mode: %d", x);
863 category = (control >> 17) & 127;
864 switch(category)
866 case 0x00:
867 s = "General";
868 break;
869 case 0x40:
870 s = "Audio CD";
871 break;
872 default:
873 s = "Unknown";
875 lcd_putsf(0, line++, "Category: 0x%02x (%s)", category, s);
877 x = (control >> 16) & 1;
878 generation = x;
879 if(((category & 0x70) == 0x10) ||
880 ((category & 0x70) == 0x40) ||
881 ((category & 0x78) == 0x38))
883 generation = !generation;
885 lcd_putsf(0, line++, "Generation: %d (%s)",
886 x, generation?"Original":"No ind.");
888 x = (control >> 12) & 15;
889 lcd_putsf(0, line++, "Source: %d", x);
892 x = (control >> 8) & 15;
893 switch(x)
895 case 0:
896 s = "Unspecified";
897 break;
898 case 8:
899 s = "A (Left)";
900 break;
901 case 4:
902 s = "B (Right)";
903 break;
904 default:
905 s = "";
906 break;
908 lcd_putsf(0, line++, "Channel: %d (%s)", x, s);
910 x = (control >> 4) & 15;
911 switch(x)
913 case 0:
914 s = "44.1kHz";
915 break;
916 case 0x4:
917 s = "48kHz";
918 break;
919 case 0xc:
920 s = "32kHz";
921 break;
923 lcd_putsf(0, line++, "Frequency: %d (%s)", x, s);
925 x = (control >> 2) & 3;
926 lcd_putsf(0, line++, "Clock accuracy: %d", x);
927 line++;
929 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
930 lcd_putsf(0, line++, "Measured freq: %ldHz",
931 spdif_measure_frequency());
932 #endif
934 lcd_update();
936 if (action_userabort(HZ/10))
937 break;
940 spdif_set_output_source(spdif_source IF_SPDIF_POWER_(, spdif_src_on));
942 #ifdef HAVE_SPDIF_POWER
943 spdif_power_enable(global_settings.spdif_enable);
944 #endif
946 lcd_setfont(FONT_UI);
947 return false;
949 #endif /* CPU_COLDFIRE */
951 #if (CONFIG_RTC == RTC_PCF50605) && (CONFIG_PLATFORM & PLATFORM_NATIVE)
952 static bool dbg_pcf(void)
954 int line;
956 #ifdef HAVE_LCD_BITMAP
957 lcd_setfont(FONT_SYSFIXED);
958 #endif
959 lcd_clear_display();
961 while(1)
963 line = 0;
965 lcd_putsf(0, line++, "DCDC1: %02x", pcf50605_read(0x1b));
966 lcd_putsf(0, line++, "DCDC2: %02x", pcf50605_read(0x1c));
967 lcd_putsf(0, line++, "DCDC3: %02x", pcf50605_read(0x1d));
968 lcd_putsf(0, line++, "DCDC4: %02x", pcf50605_read(0x1e));
969 lcd_putsf(0, line++, "DCDEC1: %02x", pcf50605_read(0x1f));
970 lcd_putsf(0, line++, "DCDEC2: %02x", pcf50605_read(0x20));
971 lcd_putsf(0, line++, "DCUDC1: %02x", pcf50605_read(0x21));
972 lcd_putsf(0, line++, "DCUDC2: %02x", pcf50605_read(0x22));
973 lcd_putsf(0, line++, "IOREGC: %02x", pcf50605_read(0x23));
974 lcd_putsf(0, line++, "D1REGC: %02x", pcf50605_read(0x24));
975 lcd_putsf(0, line++, "D2REGC: %02x", pcf50605_read(0x25));
976 lcd_putsf(0, line++, "D3REGC: %02x", pcf50605_read(0x26));
977 lcd_putsf(0, line++, "LPREG1: %02x", pcf50605_read(0x27));
978 lcd_update();
979 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
981 lcd_setfont(FONT_UI);
982 return false;
986 lcd_setfont(FONT_UI);
987 return false;
989 #endif
991 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
992 static bool dbg_cpufreq(void)
994 int line;
995 int button;
997 #ifdef HAVE_LCD_BITMAP
998 lcd_setfont(FONT_SYSFIXED);
999 #endif
1000 lcd_clear_display();
1002 while(1)
1004 line = 0;
1006 lcd_putsf(0, line++, "Frequency: %ld", FREQ);
1007 lcd_putsf(0, line++, "boost_counter: %d", get_cpu_boost_counter());
1009 lcd_update();
1010 button = get_action(CONTEXT_STD,HZ/10);
1012 switch(button)
1014 case ACTION_STD_PREV:
1015 cpu_boost(true);
1016 break;
1018 case ACTION_STD_NEXT:
1019 cpu_boost(false);
1020 break;
1022 case ACTION_STD_OK:
1023 while (get_cpu_boost_counter() > 0)
1024 cpu_boost(false);
1025 set_cpu_frequency(CPUFREQ_DEFAULT);
1026 break;
1028 case ACTION_STD_CANCEL:
1029 lcd_setfont(FONT_UI);
1030 return false;
1033 lcd_setfont(FONT_UI);
1034 return false;
1036 #endif /* HAVE_ADJUSTABLE_CPU_FREQ */
1038 #if defined(HAVE_TSC2100) && (CONFIG_PLATFORM & PLATFORM_NATIVE)
1039 #include "tsc2100.h"
1040 static char *itob(int n, int len)
1042 static char binary[64];
1043 int i,j;
1044 for (i=1, j=0;i<=len;i++)
1046 binary[j++] = n&(1<<(len-i))?'1':'0';
1047 if (i%4 == 0)
1048 binary[j++] = ' ';
1050 binary[j] = '\0';
1051 return binary;
1054 static const char* tsc2100_debug_getname(int selected_item, void * data,
1055 char *buffer, size_t buffer_len)
1057 int *page = (int*)data;
1058 bool reserved = false;
1059 switch (*page)
1061 case 0:
1062 if ((selected_item > 0x0a) ||
1063 (selected_item == 0x04) ||
1064 (selected_item == 0x08))
1065 reserved = true;
1066 break;
1067 case 1:
1068 if ((selected_item > 0x05) ||
1069 (selected_item == 0x02))
1070 reserved = true;
1071 break;
1072 case 2:
1073 if (selected_item > 0x1e)
1074 reserved = true;
1075 break;
1077 if (reserved)
1078 snprintf(buffer, buffer_len, "%02x: RESERVED", selected_item);
1079 else
1080 snprintf(buffer, buffer_len, "%02x: %s", selected_item,
1081 itob(tsc2100_readreg(*page, selected_item)&0xffff,16));
1082 return buffer;
1084 static int tsc2100debug_action_callback(int action, struct gui_synclist *lists)
1086 int *page = (int*)lists->data;
1087 if (action == ACTION_STD_OK)
1089 *page = (*page+1)%3;
1090 snprintf(lists->title, 32,
1091 "tsc2100 registers - Page %d", *page);
1092 return ACTION_REDRAW;
1094 return action;
1096 static bool tsc2100_debug(void)
1098 int page = 0;
1099 char title[32] = "tsc2100 registers - Page 0";
1100 struct simplelist_info info;
1101 simplelist_info_init(&info, title, 32, &page);
1102 info.timeout = HZ/100;
1103 info.get_name = tsc2100_debug_getname;
1104 info.action_callback= tsc2100debug_action_callback;
1105 return simplelist_show_list(&info);
1107 #endif
1108 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
1109 #ifdef HAVE_LCD_BITMAP
1111 * view_battery() shows a automatically scaled graph of the battery voltage
1112 * over time. Usable for estimating battery life / charging rate.
1113 * The power_history array is updated in power_thread of powermgmt.c.
1116 #define BAT_LAST_VAL MIN(LCD_WIDTH, POWER_HISTORY_LEN)
1117 #define BAT_YSPACE (LCD_HEIGHT - 20)
1120 static bool view_battery(void)
1122 int view = 0;
1123 int i, x, y, y1, y2, grid, graph;
1124 unsigned short maxv, minv;
1126 lcd_setfont(FONT_SYSFIXED);
1128 while(1)
1130 lcd_clear_display();
1131 switch (view) {
1132 case 0: /* voltage history graph */
1133 /* Find maximum and minimum voltage for scaling */
1134 minv = power_history[0];
1135 maxv = minv + 1;
1136 for (i = 1; i < BAT_LAST_VAL && power_history[i]; i++) {
1137 if (power_history[i] > maxv)
1138 maxv = power_history[i];
1139 if (power_history[i] < minv)
1140 minv = power_history[i];
1143 /* adjust grid scale */
1144 if ((maxv - minv) > 50)
1145 grid = 50;
1146 else
1147 grid = 5;
1149 /* print header */
1150 lcd_putsf(0, 0, "battery %d.%03dV", power_history[0] / 1000,
1151 power_history[0] % 1000);
1152 lcd_putsf(0, 1, "%d.%03d-%d.%03dV (%2dmV)",
1153 minv / 1000, minv % 1000, maxv / 1000, maxv % 1000,
1154 grid);
1156 i = 1;
1157 while ((y = (minv - (minv % grid)+i*grid)) < maxv)
1159 graph = ((y-minv)*BAT_YSPACE)/(maxv-minv);
1160 graph = LCD_HEIGHT-1 - graph;
1162 /* draw dotted horizontal grid line */
1163 for (x=0; x<LCD_WIDTH;x=x+2)
1164 lcd_drawpixel(x,graph);
1166 i++;
1169 x = 0;
1170 /* draw plot of power history
1171 * skip empty entries
1173 for (i = BAT_LAST_VAL - 1; i > 0; i--)
1175 if (power_history[i] && power_history[i-1])
1177 y1 = (power_history[i] - minv) * BAT_YSPACE /
1178 (maxv - minv);
1179 y1 = MIN(MAX(LCD_HEIGHT-1 - y1, 20),
1180 LCD_HEIGHT-1);
1181 y2 = (power_history[i-1] - minv) * BAT_YSPACE /
1182 (maxv - minv);
1183 y2 = MIN(MAX(LCD_HEIGHT-1 - y2, 20),
1184 LCD_HEIGHT-1);
1186 lcd_set_drawmode(DRMODE_SOLID);
1188 /* make line thicker */
1189 lcd_drawline(((x*LCD_WIDTH)/(BAT_LAST_VAL)),
1190 y1,
1191 (((x+1)*LCD_WIDTH)/(BAT_LAST_VAL)),
1192 y2);
1193 lcd_drawline(((x*LCD_WIDTH)/(BAT_LAST_VAL))+1,
1194 y1+1,
1195 (((x+1)*LCD_WIDTH)/(BAT_LAST_VAL))+1,
1196 y2+1);
1197 x++;
1200 break;
1202 case 1: /* status: */
1203 #if CONFIG_CHARGING >= CHARGING_MONITOR
1204 lcd_putsf(0, 0, "Pwr status: %s",
1205 charging_state() ? "charging" : "discharging");
1206 #else
1207 lcd_puts(0, 0, "Power status:");
1208 #endif
1209 battery_read_info(&y, NULL);
1210 lcd_putsf(0, 1, "Battery: %d.%03d V", y / 1000, y % 1000);
1211 #ifdef ADC_EXT_POWER
1212 y = (adc_read(ADC_EXT_POWER) * EXT_SCALE_FACTOR) / 1000;
1213 lcd_putsf(0, 2, "External: %d.%03d V", y / 1000, y % 1000);
1214 #endif
1215 #if CONFIG_CHARGING
1216 #if defined ARCHOS_RECORDER
1217 lcd_putsf(0, 3, "Chgr: %s %s",
1218 charger_inserted() ? "present" : "absent",
1219 charger_enabled() ? "on" : "off");
1220 lcd_putsf(0, 5, "short delta: %d", short_delta);
1221 lcd_putsf(0, 6, "long delta: %d", long_delta);
1222 lcd_puts(0, 7, power_message);
1223 lcd_putsf(0, 8, "USB Inserted: %s",
1224 usb_inserted() ? "yes" : "no");
1225 #elif defined IPOD_NANO || defined IPOD_VIDEO
1226 int usb_pwr = (GPIOL_INPUT_VAL & 0x10)?true:false;
1227 int ext_pwr = (GPIOL_INPUT_VAL & 0x08)?false:true;
1228 int dock = (GPIOA_INPUT_VAL & 0x10)?true:false;
1229 int charging = (GPIOB_INPUT_VAL & 0x01)?false:true;
1230 int headphone= (GPIOA_INPUT_VAL & 0x80)?true:false;
1232 lcd_putsf(0, 3, "USB pwr: %s",
1233 usb_pwr ? "present" : "absent");
1234 lcd_putsf(0, 4, "EXT pwr: %s",
1235 ext_pwr ? "present" : "absent");
1236 lcd_putsf(0, 5, "Battery: %s",
1237 charging ? "charging" : (usb_pwr||ext_pwr) ? "charged" : "discharging");
1238 lcd_putsf(0, 6, "Dock mode: %s",
1239 dock ? "enabled" : "disabled");
1240 lcd_putsf(0, 7, "Headphone: %s",
1241 headphone ? "connected" : "disconnected");
1242 #ifdef IPOD_VIDEO
1243 if(probed_ramsize == 64)
1244 x = (adc_read(ADC_4066_ISTAT) * 2400) / (1024 * 2);
1245 else
1246 x = (adc_read(ADC_4066_ISTAT) * 2400) / (1024 * 3);
1247 lcd_putsf(0, 8, "Ibat: %d mA", x);
1248 lcd_putsf(0, 9, "Vbat * Ibat: %d mW", x * y / 1000);
1249 #endif
1250 #elif defined TOSHIBA_GIGABEAT_S
1251 int line = 3;
1252 unsigned int st;
1254 static const unsigned char * const chrgstate_strings[] =
1256 "Disabled",
1257 "Error",
1258 "Discharging",
1259 "Precharge",
1260 "Constant Voltage",
1261 "Constant Current",
1262 "<unknown>",
1265 lcd_putsf(0, line++, "Charger: %s",
1266 charger_inserted() ? "present" : "absent");
1268 st = power_input_status() &
1269 (POWER_INPUT_CHARGER | POWER_INPUT_BATTERY);
1270 lcd_putsf(0, line++, "%s%s",
1271 (st & POWER_INPUT_MAIN_CHARGER) ? " Main" : "",
1272 (st & POWER_INPUT_USB_CHARGER) ? " USB" : "");
1274 y = ARRAYLEN(chrgstate_strings) - 1;
1276 switch (charge_state)
1278 case CHARGE_STATE_DISABLED: y--;
1279 case CHARGE_STATE_ERROR: y--;
1280 case DISCHARGING: y--;
1281 case TRICKLE: y--;
1282 case TOPOFF: y--;
1283 case CHARGING: y--;
1284 default:;
1287 lcd_putsf(0, line++, "State: %s", chrgstate_strings[y]);
1289 lcd_putsf(0, line++, "Battery Switch: %s",
1290 (st & POWER_INPUT_BATTERY) ? "On" : "Off");
1292 y = chrgraw_adc_voltage();
1293 lcd_putsf(0, line++, "CHRGRAW: %d.%03d V",
1294 y / 1000, y % 1000);
1296 y = application_supply_adc_voltage();
1297 lcd_putsf(0, line++, "BP : %d.%03d V",
1298 y / 1000, y % 1000);
1300 y = battery_adc_charge_current();
1301 if (y < 0) x = '-', y = -y;
1302 else x = ' ';
1303 lcd_putsf(0, line++, "CHRGISN:%c%d mA", x, y);
1305 y = cccv_regulator_dissipation();
1306 lcd_putsf(0, line++, "P CCCV : %d mW", y);
1308 y = battery_charge_current();
1309 if (y < 0) x = '-', y = -y;
1310 else x = ' ';
1311 lcd_putsf(0, line++, "I Charge:%c%d mA", x, y);
1313 y = battery_adc_temp();
1315 if (y != INT_MIN) {
1316 lcd_putsf(0, line++, "T Battery: %dC (%dF)", y,
1317 (9*y + 160) / 5);
1318 } else {
1319 /* Conversion disabled */
1320 lcd_puts(0, line++, "T Battery: ?");
1323 #elif defined(SANSA_E200) || defined(SANSA_C200) || CONFIG_CPU == AS3525 || \
1324 CONFIG_CPU == AS3525v2
1325 static const char * const chrgstate_strings[] =
1327 [CHARGE_STATE_DISABLED - CHARGE_STATE_DISABLED]= "Disabled",
1328 [CHARGE_STATE_ERROR - CHARGE_STATE_DISABLED] = "Error",
1329 [DISCHARGING - CHARGE_STATE_DISABLED] = "Discharging",
1330 [CHARGING - CHARGE_STATE_DISABLED] = "Charging",
1332 const char *str = NULL;
1334 lcd_putsf(0, 3, "Charger: %s",
1335 charger_inserted() ? "present" : "absent");
1337 y = charge_state - CHARGE_STATE_DISABLED;
1338 if ((unsigned)y < ARRAYLEN(chrgstate_strings))
1339 str = chrgstate_strings[y];
1341 lcd_putsf(0, 4, "State: %s",
1342 str ? str : "<unknown>");
1344 lcd_putsf(0, 5, "CHARGER: %02X", ascodec_read_charger());
1345 #elif defined(IPOD_NANO2G)
1346 y = pmu_read_battery_voltage();
1347 lcd_putsf(17, 1, "RAW: %d.%03d V", y / 1000, y % 1000);
1348 y = pmu_read_battery_current();
1349 lcd_putsf(0, 2, "Battery current: %d mA", y);
1350 lcd_putsf(0, 3, "PWRCON: %8x", PWRCON);
1351 lcd_putsf(0, 4, "PWRCONEXT: %8x", PWRCONEXT);
1352 x = pmu_read(0x1b) & 0xf;
1353 y = pmu_read(0x1a) * 25 + 625;
1354 lcd_putsf(0, 5, "AUTO: %x / %d mV", x, y);
1355 x = pmu_read(0x1f) & 0xf;
1356 y = pmu_read(0x1e) * 25 + 625;
1357 lcd_putsf(0, 6, "DOWN1: %x / %d mV", x, y);
1358 x = pmu_read(0x23) & 0xf;
1359 y = pmu_read(0x22) * 25 + 625;
1360 lcd_putsf(0, 7, "DOWN2: %x / %d mV", x, y);
1361 x = pmu_read(0x27) & 0xf;
1362 y = pmu_read(0x26) * 100 + 900;
1363 lcd_putsf(0, 8, "MEMLDO: %x / %d mV", x, y);
1364 for (i = 0; i < 6; i++)
1366 x = pmu_read(0x2e + (i << 1)) & 0xf;
1367 y = pmu_read(0x2d + (i << 1)) * 100 + 900;
1368 lcd_putsf(0, 9 + i, "LDO%d: %x / %d mV", i + 1, x, y);
1370 lcd_putsf(0, 15, "CLKCON: %8x", CLKCON);
1371 lcd_putsf(17, 15, "PLL0: %6x", PLL0PMS);
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 simplelist_addline(SIMPLELIST_ADD_LINE,
1544 "IRmax: %d..%d mA",
1545 i_vmin[card_extract_bits(card->csd, 61, 3)],
1546 i_vmax[card_extract_bits(card->csd, 58, 3)]);
1547 simplelist_addline(SIMPLELIST_ADD_LINE,
1548 "IWmax: %d..%d mA",
1549 i_vmin[card_extract_bits(card->csd, 55, 3)],
1550 i_vmax[card_extract_bits(card->csd, 52, 3)]);
1552 else if (card->initialized == 0)
1554 simplelist_addline(SIMPLELIST_ADD_LINE, "Not Found!");
1556 #if (CONFIG_STORAGE & STORAGE_SD)
1557 else /* card->initialized < 0 */
1559 simplelist_addline(SIMPLELIST_ADD_LINE, "Init Error! (%d)", card->initialized);
1561 #endif
1562 snprintf(title, 16, "[" CARDTYPE " %d]", *cardnum);
1563 gui_synclist_set_title(lists, title, Icon_NOICON);
1564 gui_synclist_set_nb_items(lists, simplelist_get_line_count());
1565 gui_synclist_select_item(lists, 0);
1566 btn = ACTION_REDRAW;
1568 return btn;
1570 #elif (CONFIG_STORAGE & STORAGE_ATA)
1571 static int disk_callback(int btn, struct gui_synclist *lists)
1573 (void)lists;
1574 int i;
1575 char buf[128];
1576 unsigned short* identify_info = ata_get_identify();
1577 bool timing_info_present = false;
1578 (void)btn;
1580 simplelist_set_line_count(0);
1582 for (i=0; i < 20; i++)
1583 ((unsigned short*)buf)[i]=htobe16(identify_info[i+27]);
1584 buf[40]=0;
1585 /* kill trailing space */
1586 for (i=39; i && buf[i]==' '; i--)
1587 buf[i] = 0;
1588 simplelist_addline(SIMPLELIST_ADD_LINE, "Model: %s", buf);
1589 for (i=0; i < 4; i++)
1590 ((unsigned short*)buf)[i]=htobe16(identify_info[i+23]);
1591 buf[8]=0;
1592 simplelist_addline(SIMPLELIST_ADD_LINE,
1593 "Firmware: %s", buf);
1594 snprintf(buf, sizeof buf, "%ld MB",
1595 ((unsigned long)identify_info[61] << 16 |
1596 (unsigned long)identify_info[60]) / 2048 );
1597 simplelist_addline(SIMPLELIST_ADD_LINE,
1598 "Size: %s", buf);
1599 unsigned long free;
1600 fat_size( IF_MV2(0,) NULL, &free );
1601 simplelist_addline(SIMPLELIST_ADD_LINE,
1602 "Free: %ld MB", free / 1024);
1603 simplelist_addline(SIMPLELIST_ADD_LINE,
1604 "Spinup time: %d ms", storage_spinup_time() * (1000/HZ));
1605 i = identify_info[83] & (1<<3);
1606 simplelist_addline(SIMPLELIST_ADD_LINE,
1607 "Power mgmt: %s", i ? "enabled" : "unsupported");
1608 i = identify_info[83] & (1<<9);
1609 simplelist_addline(SIMPLELIST_ADD_LINE,
1610 "Noise mgmt: %s", i ? "enabled" : "unsupported");
1611 i = identify_info[82] & (1<<6);
1612 simplelist_addline(SIMPLELIST_ADD_LINE,
1613 "Read-ahead: %s", i ? "enabled" : "unsupported");
1614 timing_info_present = identify_info[53] & (1<<1);
1615 if(timing_info_present) {
1616 char pio3[2], pio4[2];pio3[1] = 0;
1617 pio4[1] = 0;
1618 pio3[0] = (identify_info[64] & (1<<0)) ? '3' : 0;
1619 pio4[0] = (identify_info[64] & (1<<1)) ? '4' : 0;
1620 simplelist_addline(SIMPLELIST_ADD_LINE,
1621 "PIO modes: 0 1 2 %s %s", pio3, pio4);
1623 else {
1624 simplelist_addline(SIMPLELIST_ADD_LINE,
1625 "No PIO mode info");
1627 timing_info_present = identify_info[53] & (1<<1);
1628 if(timing_info_present) {
1629 simplelist_addline(SIMPLELIST_ADD_LINE,
1630 "Cycle times %dns/%dns",
1631 identify_info[67],
1632 identify_info[68] );
1633 } else {
1634 simplelist_addline(SIMPLELIST_ADD_LINE,
1635 "No timing info");
1637 int sector_size = 512;
1638 if((identify_info[106] & 0xe000) == 0x6000)
1639 sector_size *= BIT_N(identify_info[106] & 0x000f);
1640 simplelist_addline(SIMPLELIST_ADD_LINE,
1641 "Physical sector size: %d", sector_size);
1642 #ifdef HAVE_ATA_DMA
1643 if (identify_info[63] & (1<<0)) {
1644 char mdma0[2], mdma1[2], mdma2[2];
1645 mdma0[1] = mdma1[1] = mdma2[1] = 0;
1646 mdma0[0] = (identify_info[63] & (1<<0)) ? '0' : 0;
1647 mdma1[0] = (identify_info[63] & (1<<1)) ? '1' : 0;
1648 mdma2[0] = (identify_info[63] & (1<<2)) ? '2' : 0;
1649 simplelist_addline(SIMPLELIST_ADD_LINE,
1650 "MDMA modes: %s %s %s", mdma0, mdma1, mdma2);
1651 simplelist_addline(SIMPLELIST_ADD_LINE,
1652 "MDMA Cycle times %dns/%dns",
1653 identify_info[65],
1654 identify_info[66] );
1656 else {
1657 simplelist_addline(SIMPLELIST_ADD_LINE,
1658 "No MDMA mode info");
1660 if (identify_info[53] & (1<<2)) {
1661 char udma0[2], udma1[2], udma2[2], udma3[2], udma4[2], udma5[2], udma6[2];
1662 udma0[1] = udma1[1] = udma2[1] = udma3[1] = udma4[1] = udma5[1] = udma6[1] = 0;
1663 udma0[0] = (identify_info[88] & (1<<0)) ? '0' : 0;
1664 udma1[0] = (identify_info[88] & (1<<1)) ? '1' : 0;
1665 udma2[0] = (identify_info[88] & (1<<2)) ? '2' : 0;
1666 udma3[0] = (identify_info[88] & (1<<3)) ? '3' : 0;
1667 udma4[0] = (identify_info[88] & (1<<4)) ? '4' : 0;
1668 udma5[0] = (identify_info[88] & (1<<5)) ? '5' : 0;
1669 udma6[0] = (identify_info[88] & (1<<6)) ? '6' : 0;
1670 simplelist_addline(SIMPLELIST_ADD_LINE,
1671 "UDMA modes: %s %s %s %s %s %s %s", udma0, udma1, udma2,
1672 udma3, udma4, udma5, udma6);
1674 else {
1675 simplelist_addline(SIMPLELIST_ADD_LINE,
1676 "No UDMA mode info");
1678 #endif /* HAVE_ATA_DMA */
1679 timing_info_present = identify_info[53] & (1<<1);
1680 if(timing_info_present) {
1681 i = identify_info[49] & (1<<11);
1682 simplelist_addline(SIMPLELIST_ADD_LINE,
1683 "IORDY support: %s", i ? "yes" : "no");
1684 i = identify_info[49] & (1<<10);
1685 simplelist_addline(SIMPLELIST_ADD_LINE,
1686 "IORDY disable: %s", i ? "yes" : "no");
1687 } else {
1688 simplelist_addline(SIMPLELIST_ADD_LINE,
1689 "No timing info");
1691 simplelist_addline(SIMPLELIST_ADD_LINE,
1692 "Cluster size: %d bytes", fat_get_cluster_size(IF_MV(0)));
1693 #ifdef HAVE_ATA_DMA
1694 i = ata_get_dma_mode();
1695 if (i == 0) {
1696 simplelist_addline(SIMPLELIST_ADD_LINE,
1697 "DMA not enabled");
1698 } else {
1699 simplelist_addline(SIMPLELIST_ADD_LINE,
1700 "DMA mode: %s %c",
1701 (i & 0x40) ? "UDMA" : "MDMA",
1702 '0' + (i & 7));
1704 #endif /* HAVE_ATA_DMA */
1705 return btn;
1707 #else /* No SD, MMC or ATA */
1708 static int disk_callback(int btn, struct gui_synclist *lists)
1710 (void)btn;
1711 (void)lists;
1712 struct storage_info info;
1713 storage_get_info(0,&info);
1714 simplelist_addline(SIMPLELIST_ADD_LINE, "Vendor: %s", info.vendor);
1715 simplelist_addline(SIMPLELIST_ADD_LINE, "Model: %s", info.product);
1716 simplelist_addline(SIMPLELIST_ADD_LINE, "Firmware: %s", info.revision);
1717 simplelist_addline(SIMPLELIST_ADD_LINE,
1718 "Size: %ld MB", info.num_sectors*(info.sector_size/512)/2024);
1719 unsigned long free;
1720 fat_size( IF_MV2(0,) NULL, &free );
1721 simplelist_addline(SIMPLELIST_ADD_LINE,
1722 "Free: %ld MB", free / 1024);
1723 simplelist_addline(SIMPLELIST_ADD_LINE,
1724 "Cluster size: %d bytes", fat_get_cluster_size(IF_MV(0)));
1725 return btn;
1727 #endif
1729 #if (CONFIG_STORAGE & STORAGE_ATA)
1730 static bool dbg_identify_info(void)
1732 int fd = creat("/identify_info.bin", 0666);
1733 if(fd >= 0)
1735 #ifdef ROCKBOX_LITTLE_ENDIAN
1736 ecwrite(fd, ata_get_identify(), SECTOR_SIZE/2, "s", true);
1737 #else
1738 write(fd, ata_get_identify(), SECTOR_SIZE);
1739 #endif
1740 close(fd);
1742 return false;
1744 #endif
1746 static bool dbg_disk_info(void)
1748 struct simplelist_info info;
1749 simplelist_info_init(&info, "Disk Info", 1, NULL);
1750 #if (CONFIG_STORAGE & STORAGE_MMC) || (CONFIG_STORAGE & STORAGE_SD)
1751 char title[16];
1752 int card = 0;
1753 info.callback_data = (void*)&card;
1754 info.title = title;
1755 #endif
1756 info.action_callback = disk_callback;
1757 info.hide_selection = true;
1758 info.scroll_all = true;
1759 return simplelist_show_list(&info);
1761 #endif /* PLATFORM_NATIVE */
1763 #ifdef HAVE_DIRCACHE
1764 static int dircache_callback(int btn, struct gui_synclist *lists)
1766 (void)btn; (void)lists;
1767 simplelist_set_line_count(0);
1768 simplelist_addline(SIMPLELIST_ADD_LINE, "Cache initialized: %s",
1769 dircache_is_enabled() ? "Yes" : "No");
1770 simplelist_addline(SIMPLELIST_ADD_LINE, "Cache size: %d B",
1771 dircache_get_cache_size());
1772 simplelist_addline(SIMPLELIST_ADD_LINE, "Last size: %d B",
1773 global_status.dircache_size);
1774 simplelist_addline(SIMPLELIST_ADD_LINE, "Limit: %d B",
1775 DIRCACHE_LIMIT);
1776 simplelist_addline(SIMPLELIST_ADD_LINE, "Reserve: %d/%d B",
1777 dircache_get_reserve_used(), DIRCACHE_RESERVE);
1778 simplelist_addline(SIMPLELIST_ADD_LINE, "Scanning took: %d s",
1779 dircache_get_build_ticks() / HZ);
1780 simplelist_addline(SIMPLELIST_ADD_LINE, "Entry count: %d",
1781 dircache_get_entry_count());
1782 return btn;
1785 static bool dbg_dircache_info(void)
1787 struct simplelist_info info;
1788 simplelist_info_init(&info, "Dircache Info", 7, NULL);
1789 info.action_callback = dircache_callback;
1790 info.hide_selection = true;
1791 info.scroll_all = true;
1792 return simplelist_show_list(&info);
1795 #endif /* HAVE_DIRCACHE */
1797 #ifdef HAVE_TAGCACHE
1798 static int database_callback(int btn, struct gui_synclist *lists)
1800 (void)lists;
1801 struct tagcache_stat *stat = tagcache_get_stat();
1802 static bool synced = false;
1804 simplelist_set_line_count(0);
1806 simplelist_addline(SIMPLELIST_ADD_LINE, "Initialized: %s",
1807 stat->initialized ? "Yes" : "No");
1808 simplelist_addline(SIMPLELIST_ADD_LINE, "DB Ready: %s",
1809 stat->ready ? "Yes" : "No");
1810 simplelist_addline(SIMPLELIST_ADD_LINE, "RAM Cache: %s",
1811 stat->ramcache ? "Yes" : "No");
1812 simplelist_addline(SIMPLELIST_ADD_LINE, "RAM: %d/%d B",
1813 stat->ramcache_used, stat->ramcache_allocated);
1814 simplelist_addline(SIMPLELIST_ADD_LINE, "Progress: %d%% (%d entries)",
1815 stat->progress, stat->processed_entries);
1816 simplelist_addline(SIMPLELIST_ADD_LINE, "Curfile: %s",
1817 stat->curentry ? stat->curentry : "---");
1818 simplelist_addline(SIMPLELIST_ADD_LINE, "Commit step: %d",
1819 stat->commit_step);
1820 simplelist_addline(SIMPLELIST_ADD_LINE, "Commit delayed: %s",
1821 stat->commit_delayed ? "Yes" : "No");
1823 simplelist_addline(SIMPLELIST_ADD_LINE, "Queue length: %d",
1824 stat->queue_length);
1826 if (synced)
1828 synced = false;
1829 tagcache_screensync_event();
1832 if (!btn && stat->curentry)
1834 synced = true;
1835 return ACTION_REDRAW;
1838 if (btn == ACTION_STD_CANCEL)
1839 tagcache_screensync_enable(false);
1841 return btn;
1843 static bool dbg_tagcache_info(void)
1845 struct simplelist_info info;
1846 simplelist_info_init(&info, "Database Info", 8, NULL);
1847 info.action_callback = database_callback;
1848 info.hide_selection = true;
1849 info.scroll_all = true;
1851 /* Don't do nonblock here, must give enough processing time
1852 for tagcache thread. */
1853 /* info.timeout = TIMEOUT_NOBLOCK; */
1854 info.timeout = 1;
1855 tagcache_screensync_enable(true);
1856 return simplelist_show_list(&info);
1858 #endif
1860 #if CONFIG_CPU == SH7034
1861 static bool dbg_save_roms(void)
1863 int fd;
1864 int oldmode = system_memory_guard(MEMGUARD_NONE);
1866 fd = creat("/internal_rom_0000-FFFF.bin", 0666);
1867 if(fd >= 0)
1869 write(fd, (void *)0, 0x10000);
1870 close(fd);
1873 fd = creat("/internal_rom_2000000-203FFFF.bin", 0666);
1874 if(fd >= 0)
1876 write(fd, (void *)0x2000000, 0x40000);
1877 close(fd);
1880 system_memory_guard(oldmode);
1881 return false;
1883 #elif defined CPU_COLDFIRE
1884 static bool dbg_save_roms(void)
1886 int fd;
1887 int oldmode = system_memory_guard(MEMGUARD_NONE);
1889 #if defined(IRIVER_H100_SERIES)
1890 fd = creat("/internal_rom_000000-1FFFFF.bin", 0666);
1891 #elif defined(IRIVER_H300_SERIES)
1892 fd = creat("/internal_rom_000000-3FFFFF.bin", 0666);
1893 #elif defined(IAUDIO_X5) || defined(IAUDIO_M5) || defined(IAUDIO_M3)
1894 fd = creat("/internal_rom_000000-3FFFFF.bin", 0666);
1895 #elif defined(MPIO_HD200)
1896 fd = creat("/internal_rom_000000-1FFFFF.bin", 0666);
1897 #endif
1898 if(fd >= 0)
1900 write(fd, (void *)0, FLASH_SIZE);
1901 close(fd);
1903 system_memory_guard(oldmode);
1905 #ifdef HAVE_EEPROM
1906 fd = creat("/internal_eeprom.bin", 0666);
1907 if (fd >= 0)
1909 int old_irq_level;
1910 char buf[EEPROM_SIZE];
1911 int err;
1913 old_irq_level = disable_irq_save();
1915 err = eeprom_24cxx_read(0, buf, sizeof buf);
1917 restore_irq(old_irq_level);
1919 if (err)
1920 splashf(HZ*3, "Eeprom read failure (%d)", err);
1921 else
1923 write(fd, buf, sizeof buf);
1926 close(fd);
1928 #endif
1930 return false;
1932 #elif defined(CPU_PP) && !(CONFIG_STORAGE & STORAGE_SD)
1933 static bool dbg_save_roms(void)
1935 int fd;
1937 fd = creat("/internal_rom_000000-0FFFFF.bin", 0666);
1938 if(fd >= 0)
1940 write(fd, (void *)0x20000000, FLASH_SIZE);
1941 close(fd);
1944 return false;
1946 #elif CONFIG_CPU == IMX31L
1947 static bool dbg_save_roms(void)
1949 int fd;
1951 fd = creat("/flash_rom_A0000000-A01FFFFF.bin", 0666);
1952 if (fd >= 0)
1954 write(fd, (void*)0xa0000000, FLASH_SIZE);
1955 close(fd);
1958 return false;
1960 #elif defined(CPU_TCC780X)
1961 static bool dbg_save_roms(void)
1963 int fd;
1965 fd = creat("/eeprom_E0000000-E0001FFF.bin", 0666);
1966 if (fd >= 0)
1968 write(fd, (void*)0xe0000000, 0x2000);
1969 close(fd);
1972 return false;
1974 #endif /* CPU */
1976 #ifndef SIMULATOR
1977 #if CONFIG_TUNER
1979 #ifdef CONFIG_TUNER_MULTI
1980 static int tuner_type = 0;
1981 #define IF_TUNER_TYPE(type) if(tuner_type==type)
1982 #else
1983 #define IF_TUNER_TYPE(type)
1984 #endif
1986 static int radio_callback(int btn, struct gui_synclist *lists)
1988 (void)lists;
1989 if (btn == ACTION_STD_CANCEL)
1990 return btn;
1991 simplelist_set_line_count(1);
1993 #if (CONFIG_TUNER & LV24020LP)
1994 simplelist_addline(SIMPLELIST_ADD_LINE,
1995 "CTRL_STAT: %02X", lv24020lp_get(LV24020LP_CTRL_STAT) );
1996 simplelist_addline(SIMPLELIST_ADD_LINE,
1997 "RADIO_STAT: %02X", lv24020lp_get(LV24020LP_REG_STAT) );
1998 simplelist_addline(SIMPLELIST_ADD_LINE,
1999 "MSS_FM: %d kHz", lv24020lp_get(LV24020LP_MSS_FM) );
2000 simplelist_addline(SIMPLELIST_ADD_LINE,
2001 "MSS_IF: %d Hz", lv24020lp_get(LV24020LP_MSS_IF) );
2002 simplelist_addline(SIMPLELIST_ADD_LINE,
2003 "MSS_SD: %d Hz", lv24020lp_get(LV24020LP_MSS_SD) );
2004 simplelist_addline(SIMPLELIST_ADD_LINE,
2005 "if_set: %d Hz", lv24020lp_get(LV24020LP_IF_SET) );
2006 simplelist_addline(SIMPLELIST_ADD_LINE,
2007 "sd_set: %d Hz", lv24020lp_get(LV24020LP_SD_SET) );
2008 #endif /* LV24020LP */
2009 #if (CONFIG_TUNER & S1A0903X01)
2010 simplelist_addline(SIMPLELIST_ADD_LINE,
2011 "Samsung regs: %08X", s1a0903x01_get(RADIO_ALL));
2012 /* This one doesn't return dynamic data atm */
2013 #endif /* S1A0903X01 */
2014 #if (CONFIG_TUNER & TEA5767)
2015 struct tea5767_dbg_info nfo;
2016 tea5767_dbg_info(&nfo);
2017 simplelist_addline(SIMPLELIST_ADD_LINE, "Philips regs:");
2018 simplelist_addline(SIMPLELIST_ADD_LINE,
2019 " Read: %02X %02X %02X %02X %02X",
2020 (unsigned)nfo.read_regs[0], (unsigned)nfo.read_regs[1],
2021 (unsigned)nfo.read_regs[2], (unsigned)nfo.read_regs[3],
2022 (unsigned)nfo.read_regs[4]);
2023 simplelist_addline(SIMPLELIST_ADD_LINE,
2024 " Write: %02X %02X %02X %02X %02X",
2025 (unsigned)nfo.write_regs[0], (unsigned)nfo.write_regs[1],
2026 (unsigned)nfo.write_regs[2], (unsigned)nfo.write_regs[3],
2027 (unsigned)nfo.write_regs[4]);
2028 #endif /* TEA5767 */
2029 #if (CONFIG_TUNER & SI4700)
2030 IF_TUNER_TYPE(SI4700)
2032 struct si4700_dbg_info nfo;
2033 int i;
2034 si4700_dbg_info(&nfo);
2035 simplelist_addline(SIMPLELIST_ADD_LINE, "SI4700 regs:");
2036 for (i = 0; i < 16; i += 4) {
2037 simplelist_addline(SIMPLELIST_ADD_LINE,"%02X: %04X %04X %04X %04X",
2038 i, nfo.regs[i], nfo.regs[i+1], nfo.regs[i+2], nfo.regs[i+3]);
2041 #endif /* SI4700 */
2042 #if (CONFIG_TUNER & RDA5802)
2043 IF_TUNER_TYPE(RDA5802)
2045 struct rda5802_dbg_info nfo;
2046 int i;
2047 rda5802_dbg_info(&nfo);
2048 simplelist_addline(SIMPLELIST_ADD_LINE, "RDA5802 regs:");
2049 for (i = 0; i < 16; i += 4) {
2050 simplelist_addline(SIMPLELIST_ADD_LINE,"%02X: %04X %04X %04X %04X",
2051 i, nfo.regs[i], nfo.regs[i+1], nfo.regs[i+2], nfo.regs[i+3]);
2054 #endif /* RDA55802 */
2055 return ACTION_REDRAW;
2057 static bool dbg_fm_radio(void)
2059 struct simplelist_info info;
2060 #ifdef CONFIG_TUNER_MULTI
2061 tuner_type = tuner_detect_type();
2062 #endif
2063 info.scroll_all = true;
2064 simplelist_info_init(&info, "FM Radio", 1, NULL);
2065 simplelist_set_line_count(0);
2066 simplelist_addline(SIMPLELIST_ADD_LINE, "HW detected: %s",
2067 radio_hardware_present() ? "yes" : "no");
2069 info.action_callback = radio_hardware_present()?radio_callback : NULL;
2070 info.hide_selection = true;
2071 return simplelist_show_list(&info);
2073 #endif /* CONFIG_TUNER */
2074 #endif /* !SIMULATOR */
2076 #ifdef HAVE_LCD_BITMAP
2077 extern bool do_screendump_instead_of_usb;
2079 static bool dbg_screendump(void)
2081 do_screendump_instead_of_usb = !do_screendump_instead_of_usb;
2082 splashf(HZ, "Screendump %s",
2083 do_screendump_instead_of_usb?"enabled":"disabled");
2084 return false;
2086 #endif /* HAVE_LCD_BITMAP */
2088 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
2089 static bool dbg_set_memory_guard(void)
2091 static const struct opt_items names[MAXMEMGUARD] = {
2092 { "None", -1 },
2093 { "Flash ROM writes", -1 },
2094 { "Zero area (all)", -1 }
2096 int mode = system_memory_guard(MEMGUARD_KEEP);
2098 set_option( "Catch mem accesses", &mode, INT, names, MAXMEMGUARD, NULL);
2099 system_memory_guard(mode);
2101 return false;
2103 #endif /* CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) */
2105 #if defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS)
2106 static bool dbg_write_eeprom(void)
2108 int fd;
2109 int rc;
2110 int old_irq_level;
2111 char buf[EEPROM_SIZE];
2112 int err;
2114 fd = open("/internal_eeprom.bin", O_RDONLY);
2116 if (fd >= 0)
2118 rc = read(fd, buf, EEPROM_SIZE);
2120 if(rc == EEPROM_SIZE)
2122 old_irq_level = disable_irq_save();
2124 err = eeprom_24cxx_write(0, buf, sizeof buf);
2125 if (err)
2126 splashf(HZ*3, "Eeprom write failure (%d)", err);
2127 else
2128 splash(HZ*3, "Eeprom written successfully");
2130 restore_irq(old_irq_level);
2132 else
2134 splashf(HZ*3, "File read error (%d)",rc);
2136 close(fd);
2138 else
2140 splash(HZ*3, "Failed to open 'internal_eeprom.bin'");
2143 return false;
2145 #endif /* defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS) */
2146 #ifdef CPU_BOOST_LOGGING
2147 static bool cpu_boost_log(void)
2149 int i = 0,j=0;
2150 int count = cpu_boost_log_getcount();
2151 int lines = LCD_HEIGHT/SYSFONT_HEIGHT;
2152 char *str;
2153 bool done;
2154 lcd_setfont(FONT_SYSFIXED);
2155 str = cpu_boost_log_getlog_first();
2156 while (i < count)
2158 lcd_clear_display();
2159 for(j=0; j<lines; j++,i++)
2161 if (!str)
2162 str = cpu_boost_log_getlog_next();
2163 if (str)
2165 if(strlen(str) > LCD_WIDTH/SYSFONT_WIDTH)
2166 lcd_puts_scroll(0, j, str);
2167 else
2168 lcd_puts(0, j,str);
2170 str = NULL;
2172 lcd_update();
2173 done = false;
2174 while (!done)
2176 switch(get_action(CONTEXT_STD,TIMEOUT_BLOCK))
2178 case ACTION_STD_OK:
2179 case ACTION_STD_PREV:
2180 case ACTION_STD_NEXT:
2181 done = true;
2182 break;
2183 case ACTION_STD_CANCEL:
2184 i = count;
2185 done = true;
2186 break;
2190 lcd_stop_scroll();
2191 get_action(CONTEXT_STD,TIMEOUT_BLOCK);
2192 lcd_setfont(FONT_UI);
2193 return false;
2195 #endif
2197 #if (defined(HAVE_WHEEL_ACCELERATION) && (CONFIG_KEYPAD==IPOD_4G_PAD) \
2198 && !defined(IPOD_MINI) && !defined(SIMULATOR))
2199 extern bool wheel_is_touched;
2200 extern int old_wheel_value;
2201 extern int new_wheel_value;
2202 extern int wheel_delta;
2203 extern unsigned int accumulated_wheel_delta;
2204 extern unsigned int wheel_velocity;
2206 static bool dbg_scrollwheel(void)
2208 unsigned int speed;
2210 lcd_setfont(FONT_SYSFIXED);
2212 while (1)
2214 if (action_userabort(HZ/10))
2215 break;
2217 lcd_clear_display();
2219 /* show internal variables of scrollwheel driver */
2220 lcd_putsf(0, 0, "wheel touched: %s", (wheel_is_touched) ? "true" : "false");
2221 lcd_putsf(0, 1, "new position: %2d", new_wheel_value);
2222 lcd_putsf(0, 2, "old position: %2d", old_wheel_value);
2223 lcd_putsf(0, 3, "wheel delta: %2d", wheel_delta);
2224 lcd_putsf(0, 4, "accumulated delta: %2d", accumulated_wheel_delta);
2225 lcd_putsf(0, 5, "velo [deg/s]: %4d", (int)wheel_velocity);
2227 /* show effective accelerated scrollspeed */
2228 speed = button_apply_acceleration( (1<<31)|(1<<24)|wheel_velocity);
2229 lcd_putsf(0, 6, "accel. speed: %4d", speed);
2231 lcd_update();
2233 lcd_setfont(FONT_UI);
2234 return false;
2236 #endif
2238 #if defined (HAVE_USBSTACK)
2240 #if defined(ROCKBOX_HAS_LOGF) && defined(USB_ENABLE_SERIAL)
2241 static bool toggle_usb_core_driver(int driver, char *msg)
2243 bool enabled = !usb_core_driver_enabled(driver);
2245 usb_core_enable_driver(driver,enabled);
2246 splashf(HZ, "%s %s", msg, enabled?"enabled":"disabled");
2248 return false;
2251 static bool toggle_usb_serial(void)
2253 return toggle_usb_core_driver(USB_DRIVER_SERIAL,"USB Serial");
2255 #endif
2257 #endif
2259 #if CONFIG_USBOTG == USBOTG_ISP1583
2260 extern int dbg_usb_num_items(void);
2261 extern const char* dbg_usb_item(int selected_item, void *data,
2262 char *buffer, size_t buffer_len);
2264 static int isp1583_action_callback(int action, struct gui_synclist *lists)
2266 (void)lists;
2267 if (action == ACTION_NONE)
2268 action = ACTION_REDRAW;
2269 return action;
2272 static bool dbg_isp1583(void)
2274 struct simplelist_info isp1583;
2275 isp1583.scroll_all = true;
2276 simplelist_info_init(&isp1583, "ISP1583", dbg_usb_num_items(), NULL);
2277 isp1583.timeout = HZ/100;
2278 isp1583.hide_selection = true;
2279 isp1583.get_name = dbg_usb_item;
2280 isp1583.action_callback = isp1583_action_callback;
2281 return simplelist_show_list(&isp1583);
2283 #endif
2285 #if defined(CREATIVE_ZVx) && !defined(SIMULATOR)
2286 extern int pic_dbg_num_items(void);
2287 extern const char* pic_dbg_item(int selected_item, void *data,
2288 char *buffer, size_t buffer_len);
2290 static int pic_action_callback(int action, struct gui_synclist *lists)
2292 (void)lists;
2293 if (action == ACTION_NONE)
2294 action = ACTION_REDRAW;
2295 return action;
2298 static bool dbg_pic(void)
2300 struct simplelist_info pic;
2301 pic.scroll_all = true;
2302 simplelist_info_init(&pic, "PIC", pic_dbg_num_items(), NULL);
2303 pic.timeout = HZ/100;
2304 pic.hide_selection = true;
2305 pic.get_name = pic_dbg_item;
2306 pic.action_callback = pic_action_callback;
2307 return simplelist_show_list(&pic);
2309 #endif
2312 /****** The menu *********/
2313 struct the_menu_item {
2314 unsigned char *desc; /* string or ID */
2315 bool (*function) (void); /* return true if USB was connected */
2317 static const struct the_menu_item menuitems[] = {
2318 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || \
2319 (defined(CPU_PP) && !(CONFIG_STORAGE & STORAGE_SD)) || \
2320 CONFIG_CPU == IMX31L || defined(CPU_TCC780X)
2321 { "Dump ROM contents", dbg_save_roms },
2322 #endif
2323 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || defined(CPU_PP) \
2324 || CONFIG_CPU == S3C2440 || CONFIG_CPU == IMX31L || CONFIG_CPU == AS3525 \
2325 || CONFIG_CPU == DM320 || defined(CPU_S5L870X) || CONFIG_CPU == AS3525v2
2326 { "View I/O ports", dbg_ports },
2327 #endif
2328 #if (CONFIG_RTC == RTC_PCF50605) && (CONFIG_PLATFORM & PLATFORM_NATIVE)
2329 { "View PCF registers", dbg_pcf },
2330 #endif
2331 #if defined(HAVE_TSC2100) && (CONFIG_PLATFORM & PLATFORM_NATIVE)
2332 { "TSC2100 debug", tsc2100_debug },
2333 #endif
2334 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
2335 { "CPU frequency", dbg_cpufreq },
2336 #endif
2337 #if defined(IRIVER_H100_SERIES) && !defined(SIMULATOR)
2338 { "S/PDIF analyzer", dbg_spdif },
2339 #endif
2340 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
2341 { "Catch mem accesses", dbg_set_memory_guard },
2342 #endif
2343 { "View OS stacks", dbg_os },
2344 #ifdef HAVE_LCD_BITMAP
2345 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
2346 { "View battery", view_battery },
2347 #endif
2348 { "Screendump", dbg_screendump },
2349 #endif
2350 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
2351 { "View HW info", dbg_hw_info },
2352 #endif
2353 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
2354 { "View partitions", dbg_partitions },
2355 #endif
2356 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
2357 { "View disk info", dbg_disk_info },
2358 #if (CONFIG_STORAGE & STORAGE_ATA)
2359 { "Dump ATA identify info", dbg_identify_info},
2360 #endif
2361 #endif
2362 #ifdef HAVE_DIRCACHE
2363 { "View dircache info", dbg_dircache_info },
2364 #endif
2365 #ifdef HAVE_TAGCACHE
2366 { "View database info", dbg_tagcache_info },
2367 #endif
2368 #ifdef HAVE_LCD_BITMAP
2369 #if CONFIG_CODEC == SWCODEC
2370 { "View buffering thread", dbg_buffering_thread },
2371 #elif !defined(SIMULATOR)
2372 { "View audio thread", dbg_audio_thread },
2373 #endif
2374 #ifdef PM_DEBUG
2375 { "pm histogram", peak_meter_histogram},
2376 #endif /* PM_DEBUG */
2377 #endif /* HAVE_LCD_BITMAP */
2378 #ifndef SIMULATOR
2379 #if CONFIG_TUNER
2380 { "FM Radio", dbg_fm_radio },
2381 #endif
2382 #endif
2383 #if defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS)
2384 { "Write back EEPROM", dbg_write_eeprom },
2385 #endif
2386 #if CONFIG_USBOTG == USBOTG_ISP1583
2387 { "View ISP1583 info", dbg_isp1583 },
2388 #endif
2389 #if defined(CREATIVE_ZVx) && !defined(SIMULATOR)
2390 { "View PIC info", dbg_pic },
2391 #endif
2392 #ifdef ROCKBOX_HAS_LOGF
2393 {"Show Log File", logfdisplay },
2394 {"Dump Log File", logfdump },
2395 #endif
2396 #if defined(HAVE_USBSTACK)
2397 #if defined(ROCKBOX_HAS_LOGF) && defined(USB_ENABLE_SERIAL)
2398 {"USB Serial driver (logf)", toggle_usb_serial },
2399 #endif
2400 #endif /* HAVE_USBSTACK */
2401 #ifdef CPU_BOOST_LOGGING
2402 {"cpu_boost log",cpu_boost_log},
2403 #endif
2404 #if (defined(HAVE_WHEEL_ACCELERATION) && (CONFIG_KEYPAD==IPOD_4G_PAD) \
2405 && !defined(IPOD_MINI) && !defined(SIMULATOR))
2406 {"Debug scrollwheel", dbg_scrollwheel },
2407 #endif
2409 static int menu_action_callback(int btn, struct gui_synclist *lists)
2411 int i;
2412 if (btn == ACTION_STD_OK)
2414 FOR_NB_SCREENS(i)
2415 viewportmanager_theme_enable(i, false, NULL);
2416 menuitems[gui_synclist_get_sel_pos(lists)].function();
2417 btn = ACTION_REDRAW;
2418 FOR_NB_SCREENS(i)
2419 viewportmanager_theme_undo(i, false);
2421 return btn;
2424 static const char* dbg_menu_getname(int item, void * data,
2425 char *buffer, size_t buffer_len)
2427 (void)data; (void)buffer; (void)buffer_len;
2428 return menuitems[item].desc;
2431 bool debug_menu(void)
2433 struct simplelist_info info;
2435 simplelist_info_init(&info, "Debug Menu", ARRAYLEN(menuitems), NULL);
2436 info.action_callback = menu_action_callback;
2437 info.get_name = dbg_menu_getname;
2438 return simplelist_show_list(&info);