Update the discussion of themeing in the manual, and put a note in the wps tags appen...
[kugel-rb.git] / apps / debug_menu.c
blobe8104f74dc9aab4d8fead28beb975c79b2a97d41
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2002 Heikki Hannikainen
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
22 #include "config.h"
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <stdbool.h>
26 #include <string.h>
27 #include "lcd.h"
28 #include "menu.h"
29 #include "debug_menu.h"
30 #include "kernel.h"
31 #include "structec.h"
32 #include "action.h"
33 #include "debug.h"
34 #include "thread.h"
35 #include "powermgmt.h"
36 #include "system.h"
37 #include "font.h"
38 #include "audio.h"
39 #include "mp3_playback.h"
40 #include "settings.h"
41 #include "list.h"
42 #include "statusbar.h"
43 #include "dir.h"
44 #include "panic.h"
45 #include "screens.h"
46 #include "misc.h"
47 #include "splash.h"
48 #include "dircache.h"
49 #include "viewport.h"
50 #ifdef HAVE_TAGCACHE
51 #include "tagcache.h"
52 #endif
53 #include "lcd-remote.h"
54 #include "crc32.h"
55 #include "logf.h"
56 #ifndef SIMULATOR
57 #include "disk.h"
58 #include "adc.h"
59 #include "power.h"
60 #include "usb.h"
61 #include "rtc.h"
62 #include "storage.h"
63 #include "fat.h"
64 #include "mas.h"
65 #include "eeprom_24cxx.h"
66 #if (CONFIG_STORAGE & STORAGE_MMC) || (CONFIG_STORAGE & STORAGE_SD)
67 #include "hotswap.h"
68 #endif
69 #if (CONFIG_STORAGE & STORAGE_ATA)
70 #include "ata.h"
71 #endif
72 #if CONFIG_TUNER
73 #include "tuner.h"
74 #include "radio.h"
75 #endif
76 #endif
78 #ifdef HAVE_LCD_BITMAP
79 #include "scrollbar.h"
80 #include "peakmeter.h"
81 #endif
82 #include "logfdisp.h"
83 #if CONFIG_CODEC == SWCODEC
84 #include "pcmbuf.h"
85 #include "buffering.h"
86 #include "playback.h"
87 #if defined(HAVE_SPDIF_OUT) || defined(HAVE_SPDIF_IN)
88 #include "spdif.h"
89 #endif
90 #endif
91 #ifdef IRIVER_H300_SERIES
92 #include "pcf50606.h" /* for pcf50606_read */
93 #endif
94 #ifdef IAUDIO_X5
95 #include "ds2411.h"
96 #endif
97 #include "hwcompat.h"
98 #include "button.h"
99 #if CONFIG_RTC == RTC_PCF50605
100 #include "pcf50605.h"
101 #endif
102 #include "appevents.h"
104 #if CONFIG_CPU == DM320 || CONFIG_CPU == S3C2440 || CONFIG_CPU == TCC7801 \
105 || CONFIG_CPU == IMX31L || CONFIG_CPU == AS3525 || CONFIG_CPU == JZ4732 \
106 || defined(CPU_S5L870X) || CONFIG_CPU == AS3525v2
107 #include "debug-target.h"
108 #endif
110 #if defined(SANSA_E200) || defined(SANSA_C200) || defined(PHILIPS_SA9200) \
111 || defined(SANSA_CLIP) || defined(SANSA_FUZE) || defined(SANSA_C200V2)
112 #include "ascodec.h"
113 #include "as3514.h"
114 #endif
116 #ifdef IPOD_NANO2G
117 #include "pmu-target.h"
118 #endif
120 #ifdef HAVE_USBSTACK
121 #include "usb_core.h"
122 #endif
124 /*---------------------------------------------------*/
125 /* SPECIAL DEBUG STUFF */
126 /*---------------------------------------------------*/
127 extern struct thread_entry threads[MAXTHREADS];
129 static char thread_status_char(unsigned status)
131 static const char thread_status_chars[THREAD_NUM_STATES+1] =
133 [0 ... THREAD_NUM_STATES] = '?',
134 [STATE_RUNNING] = 'R',
135 [STATE_BLOCKED] = 'B',
136 [STATE_SLEEPING] = 'S',
137 [STATE_BLOCKED_W_TMO] = 'T',
138 [STATE_FROZEN] = 'F',
139 [STATE_KILLED] = 'K',
142 if (status > THREAD_NUM_STATES)
143 status = THREAD_NUM_STATES;
145 return thread_status_chars[status];
148 static const char* threads_getname(int selected_item, void *data,
149 char *buffer, size_t buffer_len)
151 (void)data;
152 struct thread_entry *thread;
153 char name[32];
155 #if NUM_CORES > 1
156 if (selected_item < (int)NUM_CORES)
158 snprintf(buffer, buffer_len, "Idle (%d): %2d%%", selected_item,
159 idle_stack_usage(selected_item));
160 return buffer;
163 selected_item -= NUM_CORES;
164 #endif
166 thread = &threads[selected_item];
168 if (thread->state == STATE_KILLED)
170 snprintf(buffer, buffer_len, "%2d: ---", selected_item);
171 return buffer;
174 thread_get_name(name, 32, thread);
176 snprintf(buffer, buffer_len,
177 "%2d: " IF_COP("(%d) ") "%c%c " IF_PRIO("%d %d ") "%2d%% %s",
178 selected_item,
179 IF_COP(thread->core,)
180 #ifdef HAVE_SCHEDULER_BOOSTCTRL
181 (thread->cpu_boost) ? '+' :
182 #endif
183 ((thread->state == STATE_RUNNING) ? '*' : ' '),
184 thread_status_char(thread->state),
185 IF_PRIO(thread->base_priority, thread->priority, )
186 thread_stack_usage(thread), name);
188 return buffer;
191 static int dbg_threads_action_callback(int action, struct gui_synclist *lists)
193 (void)lists;
194 #ifdef ROCKBOX_HAS_LOGF
195 if (action == ACTION_STD_OK)
197 int selpos = gui_synclist_get_sel_pos(lists);
198 #if NUM_CORES > 1
199 if (selpos >= NUM_CORES)
200 remove_thread(threads[selpos - NUM_CORES].id);
201 #else
202 remove_thread(threads[selpos].id);
203 #endif
204 return ACTION_REDRAW;
206 #endif /* ROCKBOX_HAS_LOGF */
207 if (action == ACTION_NONE)
208 action = ACTION_REDRAW;
209 return action;
211 /* Test code!!! */
212 static bool dbg_os(void)
214 struct simplelist_info info;
215 simplelist_info_init(&info, IF_COP("Core and ") "Stack usage:",
216 #if NUM_CORES == 1
217 MAXTHREADS,
218 #else
219 MAXTHREADS+NUM_CORES,
220 #endif
221 NULL);
222 #ifndef ROCKBOX_HAS_LOGF
223 info.hide_selection = true;
224 info.scroll_all = true;
225 #endif
226 info.action_callback = dbg_threads_action_callback;
227 info.get_name = threads_getname;
228 return simplelist_show_list(&info);
231 #ifdef HAVE_LCD_BITMAP
232 #if CONFIG_CODEC != SWCODEC
233 #ifndef SIMULATOR
234 static bool dbg_audio_thread(void)
236 struct audio_debug d;
238 lcd_setfont(FONT_SYSFIXED);
240 while(1)
242 if (action_userabort(HZ/5))
243 return false;
245 audio_get_debugdata(&d);
247 lcd_clear_display();
249 lcd_putsf(0, 0, "read: %x", d.audiobuf_read);
250 lcd_putsf(0, 1, "write: %x", d.audiobuf_write);
251 lcd_putsf(0, 2, "swap: %x", d.audiobuf_swapwrite);
252 lcd_putsf(0, 3, "playing: %d", d.playing);
253 lcd_putsf(0, 4, "playable: %x", d.playable_space);
254 lcd_putsf(0, 5, "unswapped: %x", d.unswapped_space);
256 /* Playable space left */
257 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, 6*8, 112, 4, d.audiobuflen, 0,
258 d.playable_space, HORIZONTAL);
260 /* Show the watermark limit */
261 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, 6*8+4, 112, 4, d.audiobuflen, 0,
262 d.low_watermark_level, HORIZONTAL);
264 lcd_putsf(0, 7, "wm: %x - %x",
265 d.low_watermark_level, d.lowest_watermark_level);
267 lcd_update();
269 lcd_setfont(FONT_UI);
270 return false;
272 #endif /* !SIMULATOR */
273 #else /* CONFIG_CODEC == SWCODEC */
274 static unsigned int ticks, boost_ticks, freq_sum;
276 static void dbg_audio_task(void)
278 #ifndef SIMULATOR
279 if(FREQ > CPUFREQ_NORMAL)
280 boost_ticks++;
281 freq_sum += FREQ/1000000; /* in MHz */
282 #endif
283 ticks++;
286 static bool dbg_buffering_thread(void)
288 int button;
289 int line, i;
290 bool done = false;
291 size_t bufused;
292 size_t bufsize = pcmbuf_get_bufsize();
293 int pcmbufdescs = pcmbuf_descs();
294 struct buffering_debug d;
295 size_t filebuflen = audio_get_filebuflen();
296 /* This is a size_t, but call it a long so it puts a - when it's bad. */
298 ticks = boost_ticks = freq_sum = 0;
300 tick_add_task(dbg_audio_task);
302 FOR_NB_SCREENS(i)
303 screens[i].setfont(FONT_SYSFIXED);
305 while(!done)
307 button = get_action(CONTEXT_STD,HZ/5);
308 switch(button)
310 case ACTION_STD_NEXT:
311 audio_next();
312 break;
313 case ACTION_STD_PREV:
314 audio_prev();
315 break;
316 case ACTION_STD_CANCEL:
317 done = true;
318 break;
321 buffering_get_debugdata(&d);
322 bufused = bufsize - pcmbuf_free();
324 FOR_NB_SCREENS(i)
326 line = 0;
327 screens[i].clear_display();
330 screens[i].putsf(0, line++, "pcm: %6ld/%ld", (long) bufused, (long) bufsize);
332 gui_scrollbar_draw(&screens[i],0, line*8, screens[i].lcdwidth, 6,
333 bufsize, 0, bufused, HORIZONTAL);
334 line++;
336 screens[i].putsf(0, line++, "alloc: %6ld/%ld", audio_filebufused(),
337 (long) filebuflen);
339 #if LCD_HEIGHT > 80 || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_HEIGHT > 80)
340 if (screens[i].lcdheight > 80)
342 gui_scrollbar_draw(&screens[i],0, line*8, screens[i].lcdwidth, 6,
343 filebuflen, 0, audio_filebufused(), HORIZONTAL);
344 line++;
346 screens[i].putsf(0, line++, "real: %6ld/%ld", (long)d.buffered_data,
347 (long)filebuflen);
349 gui_scrollbar_draw(&screens[i],0, line*8, screens[i].lcdwidth, 6,
350 filebuflen, 0, (long)d.buffered_data, HORIZONTAL);
351 line++;
353 #endif
355 screens[i].putsf(0, line++, "usefl: %6ld/%ld", (long)(d.useful_data),
356 (long)filebuflen);
358 #if LCD_HEIGHT > 80 || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_HEIGHT > 80)
359 if (screens[i].lcdheight > 80)
361 gui_scrollbar_draw(&screens[i],0, line*8, screens[i].lcdwidth, 6,
362 filebuflen, 0, d.useful_data, HORIZONTAL);
363 line++;
365 #endif
367 screens[i].putsf(0, line++, "data_rem: %ld", (long)d.data_rem);
369 screens[i].putsf(0, line++, "track count: %2d", audio_track_count());
371 screens[i].putsf(0, line++, "handle count: %d", (int)d.num_handles);
373 #ifndef SIMULATOR
374 screens[i].putsf(0, line++, "cpu freq: %3dMHz",
375 (int)((FREQ + 500000) / 1000000));
376 #endif
378 if (ticks > 0)
380 int boostquota = boost_ticks * 1000 / ticks; /* in 0.1 % */
381 int avgclock = freq_sum * 10 / ticks; /* in 100 kHz */
382 screens[i].putsf(0, line++, "boost:%3d.%d%% (%d.%dMHz)",
383 boostquota/10, boostquota%10, avgclock/10, avgclock%10);
386 screens[i].putsf(0, line++, "pcmbufdesc: %2d/%2d",
387 pcmbuf_used_descs(), pcmbufdescs);
388 screens[i].putsf(0, line++, "watermark: %6d",
389 (int)(d.watermark));
391 screens[i].update();
395 tick_remove_task(dbg_audio_task);
397 FOR_NB_SCREENS(i)
398 screens[i].setfont(FONT_UI);
400 return false;
402 #endif /* CONFIG_CODEC */
403 #endif /* HAVE_LCD_BITMAP */
406 #if (CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE))
407 /* Tool function to read the flash manufacturer and type, if available.
408 Only chips which could be reprogrammed in system will return values.
409 (The mode switch addresses vary between flash manufacturers, hence addr1/2) */
410 /* In IRAM to avoid problems when running directly from Flash */
411 static bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
412 unsigned addr1, unsigned addr2)
413 ICODE_ATTR __attribute__((noinline));
414 static bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
415 unsigned addr1, unsigned addr2)
418 unsigned not_manu, not_id; /* read values before switching to ID mode */
419 unsigned manu, id; /* read values when in ID mode */
421 #if CONFIG_CPU == SH7034
422 volatile unsigned char* flash = (unsigned char*)0x2000000; /* flash mapping */
423 #elif defined(CPU_COLDFIRE)
424 volatile unsigned short* flash = (unsigned short*)0; /* flash mapping */
425 #endif
426 int old_level; /* saved interrupt level */
428 not_manu = flash[0]; /* read the normal content */
429 not_id = flash[1]; /* should be 'A' (0x41) and 'R' (0x52) from the "ARCH" marker */
431 /* disable interrupts, prevent any stray flash access */
432 old_level = disable_irq_save();
434 flash[addr1] = 0xAA; /* enter command mode */
435 flash[addr2] = 0x55;
436 flash[addr1] = 0x90; /* ID command */
437 /* Atmel wants 20ms pause here */
438 /* sleep(HZ/50); no sleeping possible while interrupts are disabled */
440 manu = flash[0]; /* read the IDs */
441 id = flash[1];
443 flash[0] = 0xF0; /* reset flash (back to normal read mode) */
444 /* Atmel wants 20ms pause here */
445 /* sleep(HZ/50); no sleeping possible while interrupts are disabled */
447 restore_irq(old_level); /* enable interrupts again */
449 /* I assume success if the obtained values are different from
450 the normal flash content. This is not perfectly bulletproof, they
451 could theoretically be the same by chance, causing us to fail. */
452 if (not_manu != manu || not_id != id) /* a value has changed */
454 *p_manufacturer = manu; /* return the results */
455 *p_device = id;
456 return true; /* success */
458 return false; /* fail */
460 #endif /* (CONFIG_CPU == SH7034 || CPU_COLDFIRE) */
462 #ifndef SIMULATOR
463 #ifdef CPU_PP
464 static int perfcheck(void)
466 int result;
468 asm (
469 "mrs r2, CPSR \n"
470 "orr r0, r2, #0xc0 \n" /* disable IRQ and FIQ */
471 "msr CPSR_c, r0 \n"
472 "mov %[res], #0 \n"
473 "ldr r0, [%[timr]] \n"
474 "add r0, r0, %[tmo] \n"
475 "1: \n"
476 "add %[res], %[res], #1 \n"
477 "ldr r1, [%[timr]] \n"
478 "cmp r1, r0 \n"
479 "bmi 1b \n"
480 "msr CPSR_c, r2 \n" /* reset IRQ and FIQ state */
482 [res]"=&r"(result)
484 [timr]"r"(&USEC_TIMER),
485 [tmo]"r"(
486 #if CONFIG_CPU == PP5002
487 16000
488 #else /* PP5020/5022/5024 */
489 10226
490 #endif
493 "r0", "r1", "r2"
495 return result;
497 #endif
499 #ifdef HAVE_LCD_BITMAP
500 static bool dbg_hw_info(void)
502 #if CONFIG_CPU == SH7034
503 int bitmask = HW_MASK;
504 int rom_version = ROM_VERSION;
505 unsigned manu, id; /* flash IDs */
506 bool got_id; /* flag if we managed to get the flash IDs */
507 unsigned rom_crc = 0xffffffff; /* CRC32 of the boot ROM */
508 bool has_bootrom; /* flag for boot ROM present */
509 int oldmode; /* saved memory guard mode */
511 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
513 /* get flash ROM type */
514 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
515 if (!got_id)
516 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
518 /* check if the boot ROM area is a flash mirror */
519 has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0);
520 if (has_bootrom) /* if ROM and Flash different */
522 /* calculate CRC16 checksum of boot ROM */
523 rom_crc = crc_32((unsigned char*)0x0000, 64*1024, 0xffffffff);
526 system_memory_guard(oldmode); /* re-enable memory guard */
528 lcd_setfont(FONT_SYSFIXED);
529 lcd_clear_display();
531 lcd_puts(0, 0, "[Hardware info]");
533 lcd_putsf(0, 1, "ROM: %d.%02d", rom_version/100, rom_version%100);
535 lcd_putsf(0, 2, "Mask: 0x%04x", bitmask);
537 if (got_id)
538 lcd_putsf(0, 3, "Flash: M=%02x D=%02x", manu, id);
539 else
540 lcd_puts(0, 3, "Flash: M=?? D=??"); /* unknown, sorry */
542 if (has_bootrom)
544 if (rom_crc == 0x56DBA4EE) /* known Version 1 */
545 lcd_puts(0, 4, "Boot ROM: V1");
546 else
547 lcd_putsf(0, 4, "ROMcrc: 0x%08x", rom_crc);
549 else
551 lcd_puts(0, 4, "Boot ROM: none");
554 lcd_update();
556 while (!(action_userabort(TIMEOUT_BLOCK)));
558 #elif CONFIG_CPU == MCF5249 || CONFIG_CPU == MCF5250
559 unsigned manu, id; /* flash IDs */
560 int got_id; /* flag if we managed to get the flash IDs */
561 int oldmode; /* saved memory guard mode */
562 int line = 0;
564 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
566 /* get flash ROM type */
567 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
568 if (!got_id)
569 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
571 system_memory_guard(oldmode); /* re-enable memory guard */
573 lcd_setfont(FONT_SYSFIXED);
574 lcd_clear_display();
576 lcd_puts(0, line++, "[Hardware info]");
578 if (got_id)
579 lcd_putsf(0, line++, "Flash: M=%04x D=%04x", manu, id);
580 else
581 lcd_puts(0, line++, "Flash: M=???? D=????"); /* unknown, sorry */
583 #ifdef IAUDIO_X5
585 struct ds2411_id id;
587 lcd_puts(0, ++line, "Serial Number:");
589 got_id = ds2411_read_id(&id);
591 if (got_id == DS2411_OK)
593 lcd_putsf(0, ++line, " FC=%02x", (unsigned)id.family_code);
594 lcd_putsf(0, ++line, " ID=%02X %02X %02X %02X %02X %02X",
595 (unsigned)id.uid[0], (unsigned)id.uid[1], (unsigned)id.uid[2],
596 (unsigned)id.uid[3], (unsigned)id.uid[4], (unsigned)id.uid[5]);
597 lcd_putsf(0, ++line, " CRC=%02X", (unsigned)id.crc);
599 else
601 lcd_putsf(0, ++line, "READ ERR=%d", got_id);
604 #endif
606 lcd_update();
608 while (!(action_userabort(TIMEOUT_BLOCK)));
610 #elif defined(CPU_PP502x)
611 int line = 0;
612 char pp_version[] = { (PP_VER2 >> 24) & 0xff, (PP_VER2 >> 16) & 0xff,
613 (PP_VER2 >> 8) & 0xff, (PP_VER2) & 0xff,
614 (PP_VER1 >> 24) & 0xff, (PP_VER1 >> 16) & 0xff,
615 (PP_VER1 >> 8) & 0xff, (PP_VER1) & 0xff, '\0' };
617 lcd_setfont(FONT_SYSFIXED);
618 lcd_clear_display();
620 lcd_puts(0, line++, "[Hardware info]");
622 #ifdef IPOD_ARCH
623 lcd_putsf(0, line++, "HW rev: 0x%08lx", IPOD_HW_REVISION);
624 #endif
626 #ifdef IPOD_COLOR
627 extern int lcd_type; /* Defined in lcd-colornano.c */
629 lcd_putsf(0, line++, "LCD type: %d", lcd_type);
630 #endif
632 lcd_putsf(0, line++, "PP version: %s", pp_version);
634 lcd_putsf(0, line++, "Est. clock (kHz): %d", perfcheck());
636 lcd_update();
638 while (!(action_userabort(TIMEOUT_BLOCK)));
640 #elif CONFIG_CPU == PP5002
641 int line = 0;
642 char pp_version[] = { (PP_VER4 >> 8) & 0xff, PP_VER4 & 0xff,
643 (PP_VER3 >> 8) & 0xff, PP_VER3 & 0xff,
644 (PP_VER2 >> 8) & 0xff, PP_VER2 & 0xff,
645 (PP_VER1 >> 8) & 0xff, PP_VER1 & 0xff, '\0' };
648 lcd_setfont(FONT_SYSFIXED);
649 lcd_clear_display();
651 lcd_puts(0, line++, "[Hardware info]");
653 #ifdef IPOD_ARCH
654 lcd_putsf(0, line++, "HW rev: 0x%08lx", IPOD_HW_REVISION);
655 #endif
657 lcd_putsf(0, line++, "PP version: %s", pp_version);
659 lcd_putsf(0, line++, "Est. clock (kHz): %d", perfcheck());
661 lcd_update();
663 while (!(action_userabort(TIMEOUT_BLOCK)));
665 #else
666 /* Define this function in your target tree */
667 return __dbg_hw_info();
668 #endif /* CONFIG_CPU */
669 lcd_setfont(FONT_UI);
670 return false;
672 #else /* !HAVE_LCD_BITMAP */
673 static bool dbg_hw_info(void)
675 int button;
676 int currval = 0;
677 int rom_version = ROM_VERSION;
678 unsigned manu, id; /* flash IDs */
679 bool got_id; /* flag if we managed to get the flash IDs */
680 unsigned rom_crc = 0xffffffff; /* CRC32 of the boot ROM */
681 bool has_bootrom; /* flag for boot ROM present */
682 int oldmode; /* saved memory guard mode */
684 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
686 /* get flash ROM type */
687 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
688 if (!got_id)
689 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
691 /* check if the boot ROM area is a flash mirror */
692 has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0);
693 if (has_bootrom) /* if ROM and Flash different */
695 /* calculate CRC16 checksum of boot ROM */
696 rom_crc = crc_32((unsigned char*)0x0000, 64*1024, 0xffffffff);
699 system_memory_guard(oldmode); /* re-enable memory guard */
701 lcd_clear_display();
703 lcd_puts(0, 0, "[HW Info]");
704 while(1)
706 switch(currval)
708 case 0:
709 lcd_putsf(0, 1, "ROM: %d.%02d",
710 rom_version/100, rom_version%100);
711 break;
712 case 1:
713 if (got_id)
714 lcd_putsf(0, 1, "Flash:%02x,%02x", manu, id);
715 else
716 lcd_puts(0, 1, "Flash:??,??"); /* unknown, sorry */
717 break;
718 case 2:
719 if (has_bootrom)
721 if (rom_crc == 0x56DBA4EE) /* known Version 1 */
722 lcd_puts(0, 1, "BootROM: V1");
723 else if (rom_crc == 0x358099E8)
724 lcd_puts(0, 1, "BootROM: V2");
725 /* alternative boot ROM found in one single player so far */
726 else
727 lcd_putsf(0, 1, "R: %08x", rom_crc);
729 else
730 lcd_puts(0, 1, "BootROM: no");
733 lcd_update();
735 button = get_action(CONTEXT_SETTINGS,TIMEOUT_BLOCK);
737 switch(button)
739 case ACTION_STD_CANCEL:
740 return false;
742 case ACTION_SETTINGS_DEC:
743 currval--;
744 if(currval < 0)
745 currval = 2;
746 break;
748 case ACTION_SETTINGS_INC:
749 currval++;
750 if(currval > 2)
751 currval = 0;
752 break;
755 return false;
757 #endif /* !HAVE_LCD_BITMAP */
758 #endif /* !SIMULATOR */
760 #ifndef SIMULATOR
761 static const char* dbg_partitions_getname(int selected_item, void *data,
762 char *buffer, size_t buffer_len)
764 (void)data;
765 int partition = selected_item/2;
766 struct partinfo* p = disk_partinfo(partition);
767 if (selected_item%2)
769 snprintf(buffer, buffer_len, " T:%x %ld MB", p->type, p->size / ( 2048 / ( SECTOR_SIZE / 512 )));
771 else
773 snprintf(buffer, buffer_len, "P%d: S:%lx", partition, p->start);
775 return buffer;
778 bool dbg_partitions(void)
780 struct simplelist_info info;
781 simplelist_info_init(&info, "Partition Info", 4, NULL);
782 info.selection_size = 2;
783 info.hide_selection = true;
784 info.scroll_all = true;
785 info.get_name = dbg_partitions_getname;
786 return simplelist_show_list(&info);
788 #endif
790 #if defined(CPU_COLDFIRE) && defined(HAVE_SPDIF_OUT)
791 static bool dbg_spdif(void)
793 int line;
794 unsigned int control;
795 int x;
796 char *s;
797 int category;
798 int generation;
799 unsigned int interruptstat;
800 bool valnogood, symbolerr, parityerr;
801 bool done = false;
802 bool spdif_src_on;
803 int spdif_source = spdif_get_output_source(&spdif_src_on);
804 spdif_set_output_source(AUDIO_SRC_SPDIF IF_SPDIF_POWER_(, true));
806 lcd_clear_display();
807 lcd_setfont(FONT_SYSFIXED);
809 #ifdef HAVE_SPDIF_POWER
810 spdif_power_enable(true); /* We need SPDIF power for both sending & receiving */
811 #endif
813 while (!done)
815 line = 0;
817 control = EBU1RCVCCHANNEL1;
818 interruptstat = INTERRUPTSTAT;
819 INTERRUPTCLEAR = 0x03c00000;
821 valnogood = (interruptstat & 0x01000000)?true:false;
822 symbolerr = (interruptstat & 0x00800000)?true:false;
823 parityerr = (interruptstat & 0x00400000)?true:false;
825 lcd_putsf(0, line++, "Val: %s Sym: %s Par: %s",
826 valnogood?"--":"OK",
827 symbolerr?"--":"OK",
828 parityerr?"--":"OK");
830 lcd_putsf(0, line++, "Status word: %08x", (int)control);
832 line++;
834 x = control >> 31;
835 lcd_putsf(0, line++, "PRO: %d (%s)",
836 x, x?"Professional":"Consumer");
838 x = (control >> 30) & 1;
839 lcd_putsf(0, line++, "Audio: %d (%s)",
840 x, x?"Non-PCM":"PCM");
842 x = (control >> 29) & 1;
843 lcd_putsf(0, line++, "Copy: %d (%s)",
844 x, x?"Permitted":"Inhibited");
846 x = (control >> 27) & 7;
847 switch(x)
849 case 0:
850 s = "None";
851 break;
852 case 1:
853 s = "50/15us";
854 break;
855 default:
856 s = "Reserved";
857 break;
859 lcd_putsf(0, line++, "Preemphasis: %d (%s)", x, s);
861 x = (control >> 24) & 3;
862 lcd_putsf(0, line++, "Mode: %d", x);
864 category = (control >> 17) & 127;
865 switch(category)
867 case 0x00:
868 s = "General";
869 break;
870 case 0x40:
871 s = "Audio CD";
872 break;
873 default:
874 s = "Unknown";
876 lcd_putsf(0, line++, "Category: 0x%02x (%s)", category, s);
878 x = (control >> 16) & 1;
879 generation = x;
880 if(((category & 0x70) == 0x10) ||
881 ((category & 0x70) == 0x40) ||
882 ((category & 0x78) == 0x38))
884 generation = !generation;
886 lcd_putsf(0, line++, "Generation: %d (%s)",
887 x, generation?"Original":"No ind.");
889 x = (control >> 12) & 15;
890 lcd_putsf(0, line++, "Source: %d", x);
893 x = (control >> 8) & 15;
894 switch(x)
896 case 0:
897 s = "Unspecified";
898 break;
899 case 8:
900 s = "A (Left)";
901 break;
902 case 4:
903 s = "B (Right)";
904 break;
905 default:
906 s = "";
907 break;
909 lcd_putsf(0, line++, "Channel: %d (%s)", x, s);
911 x = (control >> 4) & 15;
912 switch(x)
914 case 0:
915 s = "44.1kHz";
916 break;
917 case 0x4:
918 s = "48kHz";
919 break;
920 case 0xc:
921 s = "32kHz";
922 break;
924 lcd_putsf(0, line++, "Frequency: %d (%s)", x, s);
926 x = (control >> 2) & 3;
927 lcd_putsf(0, line++, "Clock accuracy: %d", x);
928 line++;
930 #ifndef SIMULATOR
931 lcd_putsf(0, line++, "Measured freq: %ldHz",
932 spdif_measure_frequency());
933 #endif
935 lcd_update();
937 if (action_userabort(HZ/10))
938 break;
941 spdif_set_output_source(spdif_source IF_SPDIF_POWER_(, spdif_src_on));
943 #ifdef HAVE_SPDIF_POWER
944 spdif_power_enable(global_settings.spdif_enable);
945 #endif
947 lcd_setfont(FONT_UI);
948 return false;
950 #endif /* CPU_COLDFIRE */
952 #ifndef SIMULATOR
953 #ifdef HAVE_LCD_BITMAP
954 /* button definitions */
955 #if (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
956 (CONFIG_KEYPAD == IRIVER_H300_PAD)
957 # define DEBUG_CANCEL BUTTON_OFF
959 #elif CONFIG_KEYPAD == RECORDER_PAD
960 # define DEBUG_CANCEL BUTTON_OFF
962 #elif CONFIG_KEYPAD == ONDIO_PAD
963 # define DEBUG_CANCEL BUTTON_MENU
965 #elif (CONFIG_KEYPAD == IPOD_1G2G_PAD) || \
966 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
967 (CONFIG_KEYPAD == IPOD_4G_PAD)
968 # define DEBUG_CANCEL BUTTON_MENU
970 #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
971 # define DEBUG_CANCEL BUTTON_PLAY
973 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
974 # define DEBUG_CANCEL BUTTON_REC
976 #elif (CONFIG_KEYPAD == IAUDIO_M3_PAD)
977 # define DEBUG_CANCEL BUTTON_RC_REC
979 #elif (CONFIG_KEYPAD == IRIVER_H10_PAD)
980 # define DEBUG_CANCEL BUTTON_REW
982 #elif (CONFIG_KEYPAD == MROBE100_PAD)
983 # define DEBUG_CANCEL BUTTON_MENU
985 #elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \
986 (CONFIG_KEYPAD == SANSA_C200_PAD) || \
987 (CONFIG_KEYPAD == SANSA_FUZE_PAD)
988 # define DEBUG_CANCEL BUTTON_LEFT
990 /* This is temporary until the SA9200 touchpad works */
991 #elif (CONFIG_KEYPAD == PHILIPS_SA9200_PAD) || \
992 (CONFIG_KEYPAD == PHILIPS_HDD1630_PAD) || \
993 (CONFIG_KEYPAD == PHILIPS_HDD6330_PAD)
994 # define DEBUG_CANCEL BUTTON_POWER
996 #elif (CONFIG_KEYPAD == SAMSUNG_YH_PAD)
997 # define DEBUG_CANCEL BUTTON_PLAY
999 #elif (CONFIG_KEYPAD == PBELL_VIBE500_PAD)
1000 # define DEBUG_CANCEL BUTTON_CANCEL
1002 #elif (CONFIG_KEYPAD == MPIO_HD200_PAD)
1003 # define DEBUG_CANCEL BUTTON_REC
1005 #endif /* key definitions */
1007 /* Test code!!! */
1008 bool dbg_ports(void)
1010 #if CONFIG_CPU == SH7034
1011 int adc_battery_voltage, adc_battery_level;
1013 lcd_setfont(FONT_SYSFIXED);
1014 lcd_clear_display();
1016 while(1)
1018 lcd_putsf(0, 0, "PADR: %04x", (unsigned short)PADR);
1019 lcd_putsf(0, 1, "PBDR: %04x", (unsigned short)PBDR);
1021 lcd_putsf(0, 2, "AN0: %03x AN4: %03x", adc_read(0), adc_read(4));
1022 lcd_putsf(0, 3, "AN1: %03x AN5: %03x", adc_read(1), adc_read(5));
1023 lcd_putsf(0, 4, "AN2: %03x AN6: %03x", adc_read(2), adc_read(6));
1024 lcd_putsf(0, 5, "AN3: %03x AN7: %03x", adc_read(3), adc_read(7));
1026 battery_read_info(&adc_battery_voltage, &adc_battery_level);
1027 lcd_putsf(0, 6, "Batt: %d.%03dV %d%% ", adc_battery_voltage / 1000,
1028 adc_battery_voltage % 1000, adc_battery_level);
1030 lcd_update();
1031 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1033 lcd_setfont(FONT_UI);
1034 return false;
1037 #elif defined(CPU_COLDFIRE)
1038 unsigned int gpio_out;
1039 unsigned int gpio1_out;
1040 unsigned int gpio_read;
1041 unsigned int gpio1_read;
1042 unsigned int gpio_function;
1043 unsigned int gpio1_function;
1044 unsigned int gpio_enable;
1045 unsigned int gpio1_enable;
1046 int adc_buttons, adc_remote;
1047 int adc_battery_voltage, adc_battery_level;
1048 int line;
1050 lcd_clear_display();
1051 lcd_setfont(FONT_SYSFIXED);
1053 while(1)
1055 line = 0;
1056 gpio_read = GPIO_READ;
1057 gpio1_read = GPIO1_READ;
1058 gpio_out = GPIO_OUT;
1059 gpio1_out = GPIO1_OUT;
1060 gpio_function = GPIO_FUNCTION;
1061 gpio1_function = GPIO1_FUNCTION;
1062 gpio_enable = GPIO_ENABLE;
1063 gpio1_enable = GPIO1_ENABLE;
1065 lcd_putsf(0, line++, "GPIO_READ: %08x", gpio_read);
1066 lcd_putsf(0, line++, "GPIO_OUT: %08x", gpio_out);
1067 lcd_putsf(0, line++, "GPIO_FUNC: %08x", gpio_function);
1068 lcd_putsf(0, line++, "GPIO_ENA: %08x", gpio_enable);
1070 lcd_putsf(0, line++, "GPIO1_READ: %08x", gpio1_read);
1071 lcd_putsf(0, line++, "GPIO1_OUT: %08x", gpio1_out);
1072 lcd_putsf(0, line++, "GPIO1_FUNC: %08x", gpio1_function);
1073 lcd_putsf(0, line++, "GPIO1_ENA: %08x", gpio1_enable);
1075 adc_buttons = adc_read(ADC_BUTTONS);
1076 adc_remote = adc_read(ADC_REMOTE);
1077 battery_read_info(&adc_battery_voltage, &adc_battery_level);
1078 #if defined(IAUDIO_X5) || defined(IAUDIO_M5) || defined(IRIVER_H300_SERIES)
1079 lcd_putsf(0, line++, "ADC_BUTTONS (%c): %02x",
1080 button_scan_enabled() ? '+' : '-', adc_buttons);
1081 #else
1082 lcd_putsf(0, line++, "ADC_BUTTONS: %02x", adc_buttons);
1083 #endif
1084 #if defined(IAUDIO_X5) || defined(IAUDIO_M5)
1085 lcd_putsf(0, line++, "ADC_REMOTE (%c): %02x",
1086 remote_detect() ? '+' : '-', adc_remote);
1087 #else
1088 lcd_putsf(0, line++, "ADC_REMOTE: %02x", adc_remote);
1089 #endif
1090 #if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES)
1091 lcd_putsf(0, line++, "ADC_REMOTEDETECT: %02x",
1092 adc_read(ADC_REMOTEDETECT));
1093 #endif
1095 lcd_putsf(0, line++, "Batt: %d.%03dV %d%% ", adc_battery_voltage / 1000,
1096 adc_battery_voltage % 1000, adc_battery_level);
1098 #if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES)
1099 lcd_putsf(0, line++, "remotetype: %d", remote_type());
1100 #endif
1102 lcd_update();
1103 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1105 lcd_setfont(FONT_UI);
1106 return false;
1110 #elif defined(CPU_PP502x)
1111 int line;
1113 lcd_clear_display();
1114 lcd_setfont(FONT_SYSFIXED);
1116 while(1)
1118 line = 0;
1119 #if (LCD_HEIGHT >= 176) /* Only for displays with appropriate height. */
1120 lcd_puts(0, line++, "GPIO ENABLE:");
1121 lcd_putsf(0, line++, "A: %02x E: %02x I: %02x",
1122 (unsigned int)GPIOA_ENABLE,
1123 (unsigned int)GPIOE_ENABLE,
1124 (unsigned int)GPIOI_ENABLE);
1125 lcd_putsf(0, line++, "B: %02x F: %02x J: %02x",
1126 (unsigned int)GPIOB_ENABLE,
1127 (unsigned int)GPIOF_ENABLE,
1128 (unsigned int)GPIOJ_ENABLE);
1129 lcd_putsf(0, line++, "C: %02x G: %02x K: %02x",
1130 (unsigned int)GPIOC_ENABLE,
1131 (unsigned int)GPIOG_ENABLE,
1132 (unsigned int)GPIOK_ENABLE);
1133 lcd_putsf(0, line++, "D: %02x H: %02x L: %02x",
1134 (unsigned int)GPIOD_ENABLE,
1135 (unsigned int)GPIOH_ENABLE,
1136 (unsigned int)GPIOL_ENABLE);
1137 line++;
1138 #endif
1139 lcd_puts(0, line++, "GPIO INPUT VAL:");
1140 lcd_putsf(0, line++, "A: %02x E: %02x I: %02x",
1141 (unsigned int)GPIOA_INPUT_VAL,
1142 (unsigned int)GPIOE_INPUT_VAL,
1143 (unsigned int)GPIOI_INPUT_VAL);
1144 lcd_putsf(0, line++, "B: %02x F: %02x J: %02x",
1145 (unsigned int)GPIOB_INPUT_VAL,
1146 (unsigned int)GPIOF_INPUT_VAL,
1147 (unsigned int)GPIOJ_INPUT_VAL);
1148 lcd_putsf(0, line++, "C: %02x G: %02x K: %02x",
1149 (unsigned int)GPIOC_INPUT_VAL,
1150 (unsigned int)GPIOG_INPUT_VAL,
1151 (unsigned int)GPIOK_INPUT_VAL);
1152 lcd_putsf(0, line++, "D: %02x H: %02x L: %02x",
1153 (unsigned int)GPIOD_INPUT_VAL,
1154 (unsigned int)GPIOH_INPUT_VAL,
1155 (unsigned int)GPIOL_INPUT_VAL);
1156 line++;
1157 lcd_putsf(0, line++, "GPO32_VAL: %08lx", GPO32_VAL);
1158 lcd_putsf(0, line++, "GPO32_EN: %08lx", GPO32_ENABLE);
1159 lcd_putsf(0, line++, "DEV_EN: %08lx", DEV_EN);
1160 lcd_putsf(0, line++, "DEV_EN2: %08lx", DEV_EN2);
1161 lcd_putsf(0, line++, "DEV_EN3: %08lx", inl(0x60006044)); /* to be verified */
1162 lcd_putsf(0, line++, "DEV_INIT1: %08lx", DEV_INIT1);
1163 lcd_putsf(0, line++, "DEV_INIT2: %08lx", DEV_INIT2);
1164 #ifdef ADC_ACCESSORY
1165 lcd_putsf(0, line++, "ACCESSORY: %d", adc_read(ADC_ACCESSORY));
1166 #endif
1167 #ifdef IPOD_VIDEO
1168 lcd_putsf(0, line++, "4066_ISTAT: %d", adc_read(ADC_4066_ISTAT));
1169 #endif
1171 #if defined(IPOD_ACCESSORY_PROTOCOL)
1172 extern unsigned char serbuf[];
1173 lcd_putsf(0, line++, "IAP PACKET: %02x %02x %02x %02x %02x %02x %02x %02x",
1174 serbuf[0], serbuf[1], serbuf[2], serbuf[3], serbuf[4], serbuf[5],
1175 serbuf[6], serbuf[7]);
1176 #endif
1178 #if defined(IRIVER_H10) || defined(IRIVER_H10_5GB)
1179 line++;
1180 lcd_putsf(0, line++, "BATT: %03x UNK1: %03x",
1181 adc_read(ADC_BATTERY), adc_read(ADC_UNKNOWN_1));
1182 lcd_putsf(0, line++, "REM: %03x PAD: %03x",
1183 adc_read(ADC_REMOTE), adc_read(ADC_SCROLLPAD));
1184 #elif defined(PHILIPS_HDD1630) || defined(PHILIPS_HDD6330)
1185 line++;
1186 lcd_putsf(0, line++, "BATT: %03x UNK1: %03x",
1187 adc_read(ADC_BATTERY), adc_read(ADC_UNKNOWN_1));
1188 #elif defined(SANSA_E200) || defined(PHILIPS_SA9200)
1189 lcd_putsf(0, line++, "ADC_BVDD: %4d", adc_read(ADC_BVDD));
1190 lcd_putsf(0, line++, "ADC_RTCSUP: %4d", adc_read(ADC_RTCSUP));
1191 lcd_putsf(0, line++, "ADC_UVDD: %4d", adc_read(ADC_UVDD));
1192 lcd_putsf(0, line++, "ADC_CHG_IN: %4d", adc_read(ADC_CHG_IN));
1193 lcd_putsf(0, line++, "ADC_CVDD: %4d", adc_read(ADC_CVDD));
1194 lcd_putsf(0, line++, "ADC_BATTEMP: %4d", adc_read(ADC_BATTEMP));
1195 lcd_putsf(0, line++, "ADC_MICSUP1: %4d", adc_read(ADC_MICSUP1));
1196 lcd_putsf(0, line++, "ADC_MICSUP2: %4d", adc_read(ADC_MICSUP2));
1197 lcd_putsf(0, line++, "ADC_VBE1: %4d", adc_read(ADC_VBE1));
1198 lcd_putsf(0, line++, "ADC_VBE2: %4d", adc_read(ADC_VBE2));
1199 lcd_putsf(0, line++, "ADC_I_MICSUP1:%4d", adc_read(ADC_I_MICSUP1));
1200 #if !defined(PHILIPS_SA9200)
1201 lcd_putsf(0, line++, "ADC_I_MICSUP2:%4d", adc_read(ADC_I_MICSUP2));
1202 lcd_putsf(0, line++, "ADC_VBAT: %4d", adc_read(ADC_VBAT));
1203 #endif
1204 #endif
1205 lcd_update();
1206 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1208 lcd_setfont(FONT_UI);
1209 return false;
1213 #elif CONFIG_CPU == PP5002
1214 int line;
1216 lcd_clear_display();
1217 lcd_setfont(FONT_SYSFIXED);
1219 while(1)
1221 line = 0;
1222 lcd_putsf(0, line++, "GPIO_A: %02x GPIO_B: %02x",
1223 (unsigned int)GPIOA_INPUT_VAL, (unsigned int)GPIOB_INPUT_VAL);
1224 lcd_putsf(0, line++, "GPIO_C: %02x GPIO_D: %02x",
1225 (unsigned int)GPIOC_INPUT_VAL, (unsigned int)GPIOD_INPUT_VAL);
1227 lcd_putsf(0, line++, "DEV_EN: %08lx", DEV_EN);
1228 lcd_putsf(0, line++, "CLOCK_ENABLE: %08lx", CLOCK_ENABLE);
1229 lcd_putsf(0, line++, "CLOCK_SOURCE: %08lx", CLOCK_SOURCE);
1230 lcd_putsf(0, line++, "PLL_CONTROL: %08lx", PLL_CONTROL);
1231 lcd_putsf(0, line++, "PLL_DIV: %08lx", PLL_DIV);
1232 lcd_putsf(0, line++, "PLL_MULT: %08lx", PLL_MULT);
1233 lcd_putsf(0, line++, "TIMING1_CTL: %08lx", TIMING1_CTL);
1234 lcd_putsf(0, line++, "TIMING2_CTL: %08lx", TIMING2_CTL);
1236 lcd_update();
1237 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1239 lcd_setfont(FONT_UI);
1240 return false;
1243 lcd_setfont(FONT_UI);
1244 #else
1245 return __dbg_ports();
1246 #endif /* CPU */
1247 return false;
1249 #else /* !HAVE_LCD_BITMAP */
1250 bool dbg_ports(void)
1252 char buf[32];
1253 int button;
1254 int adc_battery_voltage;
1255 int currval = 0;
1257 lcd_clear_display();
1259 while(1)
1261 switch(currval)
1263 case 0:
1264 snprintf(buf, 32, "PADR: %04x", (unsigned short)PADR);
1265 break;
1266 case 1:
1267 snprintf(buf, 32, "PBDR: %04x", (unsigned short)PBDR);
1268 break;
1269 case 2:
1270 snprintf(buf, 32, "AN0: %03x", adc_read(0));
1271 break;
1272 case 3:
1273 snprintf(buf, 32, "AN1: %03x", adc_read(1));
1274 break;
1275 case 4:
1276 snprintf(buf, 32, "AN2: %03x", adc_read(2));
1277 break;
1278 case 5:
1279 snprintf(buf, 32, "AN3: %03x", adc_read(3));
1280 break;
1281 case 6:
1282 snprintf(buf, 32, "AN4: %03x", adc_read(4));
1283 break;
1284 case 7:
1285 snprintf(buf, 32, "AN5: %03x", adc_read(5));
1286 break;
1287 case 8:
1288 snprintf(buf, 32, "AN6: %03x", adc_read(6));
1289 break;
1290 case 9:
1291 snprintf(buf, 32, "AN7: %03x", adc_read(7));
1292 break;
1294 lcd_puts(0, 0, buf);
1296 battery_read_info(&adc_battery_voltage, NULL);
1297 lcd_putsf(0, 1, "Batt: %d.%03dV", adc_battery_voltage / 1000,
1298 adc_battery_voltage % 1000);
1299 lcd_update();
1301 button = get_action(CONTEXT_SETTINGS,HZ/5);
1303 switch(button)
1305 case ACTION_STD_CANCEL:
1306 return false;
1308 case ACTION_SETTINGS_DEC:
1309 currval--;
1310 if(currval < 0)
1311 currval = 9;
1312 break;
1314 case ACTION_SETTINGS_INC:
1315 currval++;
1316 if(currval > 9)
1317 currval = 0;
1318 break;
1321 return false;
1323 #endif /* !HAVE_LCD_BITMAP */
1324 #endif /* !SIMULATOR */
1326 #if (CONFIG_RTC == RTC_PCF50605) && !defined(SIMULATOR)
1327 static bool dbg_pcf(void)
1329 int line;
1331 #ifdef HAVE_LCD_BITMAP
1332 lcd_setfont(FONT_SYSFIXED);
1333 #endif
1334 lcd_clear_display();
1336 while(1)
1338 line = 0;
1340 lcd_putsf(0, line++, "DCDC1: %02x", pcf50605_read(0x1b));
1341 lcd_putsf(0, line++, "DCDC2: %02x", pcf50605_read(0x1c));
1342 lcd_putsf(0, line++, "DCDC3: %02x", pcf50605_read(0x1d));
1343 lcd_putsf(0, line++, "DCDC4: %02x", pcf50605_read(0x1e));
1344 lcd_putsf(0, line++, "DCDEC1: %02x", pcf50605_read(0x1f));
1345 lcd_putsf(0, line++, "DCDEC2: %02x", pcf50605_read(0x20));
1346 lcd_putsf(0, line++, "DCUDC1: %02x", pcf50605_read(0x21));
1347 lcd_putsf(0, line++, "DCUDC2: %02x", pcf50605_read(0x22));
1348 lcd_putsf(0, line++, "IOREGC: %02x", pcf50605_read(0x23));
1349 lcd_putsf(0, line++, "D1REGC: %02x", pcf50605_read(0x24));
1350 lcd_putsf(0, line++, "D2REGC: %02x", pcf50605_read(0x25));
1351 lcd_putsf(0, line++, "D3REGC: %02x", pcf50605_read(0x26));
1352 lcd_putsf(0, line++, "LPREG1: %02x", pcf50605_read(0x27));
1353 lcd_update();
1354 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1356 lcd_setfont(FONT_UI);
1357 return false;
1361 lcd_setfont(FONT_UI);
1362 return false;
1364 #endif
1366 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
1367 static bool dbg_cpufreq(void)
1369 int line;
1370 int button;
1372 #ifdef HAVE_LCD_BITMAP
1373 lcd_setfont(FONT_SYSFIXED);
1374 #endif
1375 lcd_clear_display();
1377 while(1)
1379 line = 0;
1381 lcd_putsf(0, line++, "Frequency: %ld", FREQ);
1382 lcd_putsf(0, line++, "boost_counter: %d", get_cpu_boost_counter());
1384 lcd_update();
1385 button = get_action(CONTEXT_STD,HZ/10);
1387 switch(button)
1389 case ACTION_STD_PREV:
1390 cpu_boost(true);
1391 break;
1393 case ACTION_STD_NEXT:
1394 cpu_boost(false);
1395 break;
1397 case ACTION_STD_OK:
1398 while (get_cpu_boost_counter() > 0)
1399 cpu_boost(false);
1400 set_cpu_frequency(CPUFREQ_DEFAULT);
1401 break;
1403 case ACTION_STD_CANCEL:
1404 lcd_setfont(FONT_UI);
1405 return false;
1408 lcd_setfont(FONT_UI);
1409 return false;
1411 #endif /* HAVE_ADJUSTABLE_CPU_FREQ */
1413 #if defined(HAVE_TSC2100) && !defined(SIMULATOR)
1414 #include "tsc2100.h"
1415 static char *itob(int n, int len)
1417 static char binary[64];
1418 int i,j;
1419 for (i=1, j=0;i<=len;i++)
1421 binary[j++] = n&(1<<(len-i))?'1':'0';
1422 if (i%4 == 0)
1423 binary[j++] = ' ';
1425 binary[j] = '\0';
1426 return binary;
1429 static const char* tsc2100_debug_getname(int selected_item, void * data,
1430 char *buffer, size_t buffer_len)
1432 int *page = (int*)data;
1433 bool reserved = false;
1434 switch (*page)
1436 case 0:
1437 if ((selected_item > 0x0a) ||
1438 (selected_item == 0x04) ||
1439 (selected_item == 0x08))
1440 reserved = true;
1441 break;
1442 case 1:
1443 if ((selected_item > 0x05) ||
1444 (selected_item == 0x02))
1445 reserved = true;
1446 break;
1447 case 2:
1448 if (selected_item > 0x1e)
1449 reserved = true;
1450 break;
1452 if (reserved)
1453 snprintf(buffer, buffer_len, "%02x: RESERVED", selected_item);
1454 else
1455 snprintf(buffer, buffer_len, "%02x: %s", selected_item,
1456 itob(tsc2100_readreg(*page, selected_item)&0xffff,16));
1457 return buffer;
1459 static int tsc2100debug_action_callback(int action, struct gui_synclist *lists)
1461 int *page = (int*)lists->data;
1462 if (action == ACTION_STD_OK)
1464 *page = (*page+1)%3;
1465 snprintf(lists->title, 32,
1466 "tsc2100 registers - Page %d", *page);
1467 return ACTION_REDRAW;
1469 return action;
1471 static bool tsc2100_debug(void)
1473 int page = 0;
1474 char title[32] = "tsc2100 registers - Page 0";
1475 struct simplelist_info info;
1476 simplelist_info_init(&info, title, 32, &page);
1477 info.timeout = HZ/100;
1478 info.get_name = tsc2100_debug_getname;
1479 info.action_callback= tsc2100debug_action_callback;
1480 return simplelist_show_list(&info);
1482 #endif
1483 #ifndef SIMULATOR
1484 #ifdef HAVE_LCD_BITMAP
1486 * view_battery() shows a automatically scaled graph of the battery voltage
1487 * over time. Usable for estimating battery life / charging rate.
1488 * The power_history array is updated in power_thread of powermgmt.c.
1491 #define BAT_LAST_VAL MIN(LCD_WIDTH, POWER_HISTORY_LEN)
1492 #define BAT_YSPACE (LCD_HEIGHT - 20)
1494 static bool view_battery(void)
1496 int view = 0;
1497 int i, x, y;
1498 unsigned short maxv, minv;
1500 lcd_setfont(FONT_SYSFIXED);
1502 while(1)
1504 lcd_clear_display();
1505 switch (view) {
1506 case 0: /* voltage history graph */
1507 /* Find maximum and minimum voltage for scaling */
1508 minv = power_history[0];
1509 maxv = minv + 1;
1510 for (i = 1; i < BAT_LAST_VAL && power_history[i]; i++) {
1511 if (power_history[i] > maxv)
1512 maxv = power_history[i];
1513 if (power_history[i] < minv)
1514 minv = power_history[i];
1517 lcd_putsf(0, 0, "Battery %d.%03d", power_history[0] / 1000,
1518 power_history[0] % 1000);
1519 lcd_putsf(0, 1, "scale %d.%03d-%d.%03dV",
1520 minv / 1000, minv % 1000, maxv / 1000, maxv % 1000);
1522 x = 0;
1523 for (i = BAT_LAST_VAL - 1; i >= 0; i--) {
1524 y = (power_history[i] - minv) * BAT_YSPACE / (maxv - minv);
1525 lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
1526 lcd_vline(x, LCD_HEIGHT-1, 20);
1527 lcd_set_drawmode(DRMODE_SOLID);
1528 lcd_vline(x, LCD_HEIGHT-1,
1529 MIN(MAX(LCD_HEIGHT-1 - y, 20), LCD_HEIGHT-1));
1530 x++;
1533 break;
1535 case 1: /* status: */
1536 lcd_puts(0, 0, "Power status:");
1538 battery_read_info(&y, NULL);
1539 lcd_putsf(0, 1, "Battery: %d.%03d V", y / 1000, y % 1000);
1540 #ifdef ADC_EXT_POWER
1541 y = (adc_read(ADC_EXT_POWER) * EXT_SCALE_FACTOR) / 1000;
1542 lcd_putsf(0, 2, "External: %d.%03d V", y / 1000, y % 1000);
1543 #endif
1544 #if CONFIG_CHARGING
1545 #if defined ARCHOS_RECORDER
1546 lcd_putsf(0, 3, "Chgr: %s %s",
1547 charger_inserted() ? "present" : "absent",
1548 charger_enabled() ? "on" : "off");
1549 lcd_putsf(0, 5, "short delta: %d", short_delta);
1550 lcd_putsf(0, 6, "long delta: %d", long_delta);
1551 lcd_puts(0, 7, power_message);
1552 lcd_putsf(0, 8, "USB Inserted: %s",
1553 usb_inserted() ? "yes" : "no");
1554 #elif defined IRIVER_H300_SERIES
1555 lcd_putsf(0, 9, "USB Charging Enabled: %s",
1556 usb_charging_enabled() ? "yes" : "no");
1557 #elif defined IPOD_NANO || defined IPOD_VIDEO
1558 int usb_pwr = (GPIOL_INPUT_VAL & 0x10)?true:false;
1559 int ext_pwr = (GPIOL_INPUT_VAL & 0x08)?false:true;
1560 int dock = (GPIOA_INPUT_VAL & 0x10)?true:false;
1561 int charging = (GPIOB_INPUT_VAL & 0x01)?false:true;
1562 int headphone= (GPIOA_INPUT_VAL & 0x80)?true:false;
1564 lcd_putsf(0, 3, "USB pwr: %s",
1565 usb_pwr ? "present" : "absent");
1566 lcd_putsf(0, 4, "EXT pwr: %s",
1567 ext_pwr ? "present" : "absent");
1568 lcd_putsf(0, 5, "Battery: %s",
1569 charging ? "charging" : (usb_pwr||ext_pwr) ? "charged" : "discharging");
1570 lcd_putsf(0, 6, "Dock mode: %s",
1571 dock ? "enabled" : "disabled");
1572 lcd_putsf(0, 7, "Headphone: %s",
1573 headphone ? "connected" : "disconnected");
1574 #ifdef IPOD_VIDEO
1575 x = (adc_read(ADC_4066_ISTAT) * 2400) /
1576 #if MEM == 64
1577 (1024 * 2);
1578 #else
1579 (1024 * 3);
1580 #endif
1581 lcd_putsf(0, 8, "Ibat: %d mA", x);
1582 lcd_putsf(0, 9, "Vbat * Ibat: %d mW", x * y / 1000);
1583 #endif
1584 #elif defined TOSHIBA_GIGABEAT_S
1585 int line = 3;
1586 unsigned int st;
1588 static const unsigned char * const chrgstate_strings[] =
1590 "Disabled",
1591 "Error",
1592 "Discharging",
1593 "Precharge",
1594 "Constant Voltage",
1595 "Constant Current",
1596 "<unknown>",
1599 lcd_putsf(0, line++, "Charger: %s",
1600 charger_inserted() ? "present" : "absent");
1602 st = power_input_status() &
1603 (POWER_INPUT_CHARGER | POWER_INPUT_BATTERY);
1604 lcd_putsf(0, line++, "%s%s",
1605 (st & POWER_INPUT_MAIN_CHARGER) ? " Main" : "",
1606 (st & POWER_INPUT_USB_CHARGER) ? " USB" : "");
1608 lcd_putsf(0, line++, "IUSB Max: %d", usb_allowed_current());
1610 y = ARRAYLEN(chrgstate_strings) - 1;
1612 switch (charge_state)
1614 case CHARGE_STATE_DISABLED: y--;
1615 case CHARGE_STATE_ERROR: y--;
1616 case DISCHARGING: y--;
1617 case TRICKLE: y--;
1618 case TOPOFF: y--;
1619 case CHARGING: y--;
1620 default:;
1623 lcd_putsf(0, line++, "State: %s", chrgstate_strings[y]);
1625 lcd_putsf(0, line++, "Battery Switch: %s",
1626 (st & POWER_INPUT_BATTERY) ? "On" : "Off");
1628 y = chrgraw_adc_voltage();
1629 lcd_putsf(0, line++, "CHRGRAW: %d.%03d V",
1630 y / 1000, y % 1000);
1632 y = application_supply_adc_voltage();
1633 lcd_putsf(0, line++, "BP : %d.%03d V",
1634 y / 1000, y % 1000);
1636 y = battery_adc_charge_current();
1637 if (y < 0) x = '-', y = -y;
1638 else x = ' ';
1639 lcd_putsf(0, line++, "CHRGISN:%c%d mA", x, y);
1641 y = cccv_regulator_dissipation();
1642 lcd_putsf(0, line++, "P CCCV : %d mW", y);
1644 y = battery_charge_current();
1645 if (y < 0) x = '-', y = -y;
1646 else x = ' ';
1647 lcd_putsf(0, line++, "I Charge:%c%d mA", x, y);
1649 y = battery_adc_temp();
1651 if (y != INT_MIN) {
1652 lcd_putsf(0, line++, "T Battery: %dC (%dF)", y,
1653 (9*y + 160) / 5);
1654 } else {
1655 /* Conversion disabled */
1656 lcd_puts(0, line++, "T Battery: ?");
1659 #elif defined(SANSA_E200) || defined(SANSA_C200) || defined(SANSA_CLIP) || \
1660 defined(SANSA_FUZE) || defined (SANSA_C200V2)
1661 const int first = CHARGE_STATE_DISABLED;
1662 static const char * const chrgstate_strings[] =
1664 [CHARGE_STATE_DISABLED-first] = "Disabled",
1665 [CHARGE_STATE_ERROR-first] = "Error",
1666 [DISCHARGING-first] = "Discharging",
1667 [CHARGING-first] = "Charging",
1669 const char *str = NULL;
1671 lcd_putsf(0, 3, "Charger: %s",
1672 charger_inserted() ? "present" : "absent");
1674 y = charge_state - first;
1675 if ((unsigned)y < ARRAYLEN(chrgstate_strings))
1676 str = chrgstate_strings[y];
1678 lcd_putsf(0, 4, "State: %s",
1679 str ? str : "<unknown>");
1681 lcd_putsf(0, 5, "CHARGER: %02X",
1682 ascodec_read(AS3514_CHARGER));
1683 #elif defined(IPOD_NANO2G)
1684 y = pmu_read_battery_voltage();
1685 lcd_putsf(17, 1, "RAW: %d.%03d V", y / 1000, y % 1000);
1686 y = pmu_read_battery_current();
1687 lcd_putsf(0, 2, "Battery current: %d mA", y);
1688 lcd_putsf(0, 3, "PWRCON: %8x", PWRCON);
1689 lcd_putsf(0, 4, "PWRCONEXT: %8x", PWRCONEXT);
1690 x = pmu_read(0x1b) & 0xf;
1691 y = pmu_read(0x1a) * 25 + 625;
1692 lcd_putsf(0, 5, "AUTO: %x / %d mV", x, y);
1693 x = pmu_read(0x1f) & 0xf;
1694 y = pmu_read(0x1e) * 25 + 625;
1695 lcd_putsf(0, 6, "DOWN1: %x / %d mV", x, y);
1696 x = pmu_read(0x23) & 0xf;
1697 y = pmu_read(0x22) * 25 + 625;
1698 lcd_putsf(0, 7, "DOWN2: %x / %d mV", x, y);
1699 x = pmu_read(0x27) & 0xf;
1700 y = pmu_read(0x26) * 100 + 900;
1701 lcd_putsf(0, 8, "MEMLDO: %x / %d mV", x, y);
1702 for (i = 0; i < 6; i++)
1704 x = pmu_read(0x2e + (i << 1)) & 0xf;
1705 y = pmu_read(0x2d + (i << 1)) * 100 + 900;
1706 lcd_putsf(0, 9 + i, "LDO%d: %x / %d mV", i + 1, x, y);
1708 lcd_putsf(0, 15, "CLKCON: %8x", CLKCON);
1709 lcd_putsf(17, 15, "PLL0: %6x", PLL0PMS);
1710 #else
1711 lcd_putsf(0, 3, "Charger: %s",
1712 charger_inserted() ? "present" : "absent");
1713 #endif /* target type */
1714 #endif /* CONFIG_CHARGING */
1715 break;
1717 case 2: /* voltage deltas: */
1718 lcd_puts(0, 0, "Voltage deltas:");
1720 for (i = 0; i <= 6; i++) {
1721 y = power_history[i] - power_history[i+1];
1722 lcd_putsf(0, i+1, "-%d min: %s%d.%03d V", i,
1723 (y < 0) ? "-" : "", ((y < 0) ? y * -1 : y) / 1000,
1724 ((y < 0) ? y * -1 : y ) % 1000);
1726 break;
1728 case 3: /* remaining time estimation: */
1730 #ifdef ARCHOS_RECORDER
1731 lcd_putsf(0, 0, "charge_state: %d", charge_state);
1733 lcd_putsf(0, 1, "Cycle time: %d m", powermgmt_last_cycle_startstop_min);
1735 lcd_putsf(0, 2, "Lvl@cyc st: %d%%", powermgmt_last_cycle_level);
1737 lcd_putsf(0, 3, "P=%2d I=%2d", pid_p, pid_i);
1739 lcd_putsf(0, 4, "Trickle sec: %d/60", trickle_sec);
1740 #endif /* ARCHOS_RECORDER */
1742 lcd_putsf(0, 5, "Last PwrHist: %d.%03dV",
1743 power_history[0] / 1000,
1744 power_history[0] % 1000);
1746 lcd_putsf(0, 6, "battery level: %d%%", battery_level());
1748 lcd_putsf(0, 7, "Est. remain: %d m", battery_time());
1749 break;
1752 lcd_update();
1754 switch(get_action(CONTEXT_STD,HZ/2))
1756 case ACTION_STD_PREV:
1757 if (view)
1758 view--;
1759 break;
1761 case ACTION_STD_NEXT:
1762 if (view < 3)
1763 view++;
1764 break;
1766 case ACTION_STD_CANCEL:
1767 lcd_setfont(FONT_UI);
1768 return false;
1771 lcd_setfont(FONT_UI);
1772 return false;
1775 #endif /* HAVE_LCD_BITMAP */
1776 #endif
1778 #ifndef SIMULATOR
1779 #if (CONFIG_STORAGE & STORAGE_MMC) || (CONFIG_STORAGE & STORAGE_SD)
1781 #if (CONFIG_STORAGE & STORAGE_MMC)
1782 #define CARDTYPE "MMC"
1783 #elif (CONFIG_STORAGE & STORAGE_SD)
1784 #define CARDTYPE "microSD"
1785 #endif
1787 static int disk_callback(int btn, struct gui_synclist *lists)
1789 tCardInfo *card;
1790 int *cardnum = (int*)lists->data;
1791 unsigned char card_name[6];
1792 unsigned char pbuf[32];
1793 char *title = lists->title;
1794 static const unsigned char i_vmin[] = { 0, 1, 5, 10, 25, 35, 60, 100 };
1795 static const unsigned char i_vmax[] = { 1, 5, 10, 25, 35, 45, 80, 200 };
1796 static const unsigned char * const kbit_units[] = { "kBit/s", "MBit/s", "GBit/s" };
1797 static const unsigned char * const nsec_units[] = { "ns", "µs", "ms" };
1798 #if (CONFIG_STORAGE & STORAGE_MMC)
1799 static const char * const mmc_spec_vers[] = { "1.0-1.2", "1.4", "2.0-2.2",
1800 "3.1-3.31", "4.0" };
1801 #endif
1803 if ((btn == ACTION_STD_OK) || (btn == SYS_FS_CHANGED) || (btn == ACTION_REDRAW))
1805 #ifdef HAVE_HOTSWAP
1806 if (btn == ACTION_STD_OK)
1808 *cardnum ^= 0x1; /* change cards */
1810 #endif
1812 simplelist_set_line_count(0);
1814 card = card_get_info(*cardnum);
1816 if (card->initialized > 0)
1818 unsigned i;
1819 for (i=0; i<sizeof(card_name); i++)
1821 card_name[i] = card_extract_bits(card->cid, (103-8*i), 8);
1823 strlcpy(card_name, card_name, sizeof(card_name));
1824 simplelist_addline(SIMPLELIST_ADD_LINE,
1825 "%s Rev %d.%d", card_name,
1826 (int) card_extract_bits(card->cid, 63, 4),
1827 (int) card_extract_bits(card->cid, 59, 4));
1828 simplelist_addline(SIMPLELIST_ADD_LINE,
1829 "Prod: %d/%d",
1830 #if (CONFIG_STORAGE & STORAGE_SD)
1831 (int) card_extract_bits(card->cid, 11, 4),
1832 (int) card_extract_bits(card->cid, 19, 8) + 2000
1833 #elif (CONFIG_STORAGE & STORAGE_MMC)
1834 (int) card_extract_bits(card->cid, 15, 4),
1835 (int) card_extract_bits(card->cid, 11, 4) + 1997
1836 #endif
1838 simplelist_addline(SIMPLELIST_ADD_LINE,
1839 #if (CONFIG_STORAGE & STORAGE_SD)
1840 "Ser#: 0x%08lx",
1841 card_extract_bits(card->cid, 55, 32)
1842 #elif (CONFIG_STORAGE & STORAGE_MMC)
1843 "Ser#: 0x%04lx",
1844 card_extract_bits(card->cid, 47, 16)
1845 #endif
1848 simplelist_addline(SIMPLELIST_ADD_LINE, "M=%02x, "
1849 #if (CONFIG_STORAGE & STORAGE_SD)
1850 "O=%c%c",
1851 (int) card_extract_bits(card->cid, 127, 8),
1852 card_extract_bits(card->cid, 119, 8),
1853 card_extract_bits(card->cid, 111, 8)
1854 #elif (CONFIG_STORAGE & STORAGE_MMC)
1855 "O=%04x",
1856 (int) card_extract_bits(card->cid, 127, 8),
1857 (int) card_extract_bits(card->cid, 119, 16)
1858 #endif
1861 #if (CONFIG_STORAGE & STORAGE_MMC)
1862 int temp = card_extract_bits(card->csd, 125, 4);
1863 simplelist_addline(SIMPLELIST_ADD_LINE,
1864 "MMC v%s", temp < 5 ?
1865 mmc_spec_vers[temp] : "?.?");
1866 #endif
1867 simplelist_addline(SIMPLELIST_ADD_LINE,
1868 "Blocks: 0x%08lx", card->numblocks);
1869 output_dyn_value(pbuf, sizeof pbuf, card->speed / 1000,
1870 kbit_units, false);
1871 simplelist_addline(SIMPLELIST_ADD_LINE,
1872 "Speed: %s", pbuf);
1873 output_dyn_value(pbuf, sizeof pbuf, card->taac,
1874 nsec_units, false);
1875 simplelist_addline(SIMPLELIST_ADD_LINE,
1876 "Taac: %s", pbuf);
1877 simplelist_addline(SIMPLELIST_ADD_LINE,
1878 "Nsac: %d clk", card->nsac);
1879 simplelist_addline(SIMPLELIST_ADD_LINE,
1880 "R2W: *%d", card->r2w_factor);
1881 simplelist_addline(SIMPLELIST_ADD_LINE,
1882 "IRmax: %d..%d mA",
1883 i_vmin[card_extract_bits(card->csd, 61, 3)],
1884 i_vmax[card_extract_bits(card->csd, 58, 3)]);
1885 simplelist_addline(SIMPLELIST_ADD_LINE,
1886 "IWmax: %d..%d mA",
1887 i_vmin[card_extract_bits(card->csd, 55, 3)],
1888 i_vmax[card_extract_bits(card->csd, 52, 3)]);
1890 else if (card->initialized == 0)
1892 simplelist_addline(SIMPLELIST_ADD_LINE, "Not Found!");
1894 #if (CONFIG_STORAGE & STORAGE_SD)
1895 else /* card->initialized < 0 */
1897 simplelist_addline(SIMPLELIST_ADD_LINE, "Init Error! (%d)", card->initialized);
1899 #endif
1900 snprintf(title, 16, "[" CARDTYPE " %d]", *cardnum);
1901 gui_synclist_set_title(lists, title, Icon_NOICON);
1902 gui_synclist_set_nb_items(lists, simplelist_get_line_count());
1903 gui_synclist_select_item(lists, 0);
1904 btn = ACTION_REDRAW;
1906 return btn;
1908 #elif (CONFIG_STORAGE & STORAGE_ATA)
1909 static int disk_callback(int btn, struct gui_synclist *lists)
1911 (void)lists;
1912 int i;
1913 char buf[128];
1914 unsigned short* identify_info = ata_get_identify();
1915 bool timing_info_present = false;
1916 (void)btn;
1918 simplelist_set_line_count(0);
1920 for (i=0; i < 20; i++)
1921 ((unsigned short*)buf)[i]=htobe16(identify_info[i+27]);
1922 buf[40]=0;
1923 /* kill trailing space */
1924 for (i=39; i && buf[i]==' '; i--)
1925 buf[i] = 0;
1926 simplelist_addline(SIMPLELIST_ADD_LINE, "Model: %s", buf);
1927 for (i=0; i < 4; i++)
1928 ((unsigned short*)buf)[i]=htobe16(identify_info[i+23]);
1929 buf[8]=0;
1930 simplelist_addline(SIMPLELIST_ADD_LINE,
1931 "Firmware: %s", buf);
1932 snprintf(buf, sizeof buf, "%ld MB",
1933 ((unsigned long)identify_info[61] << 16 |
1934 (unsigned long)identify_info[60]) / 2048 );
1935 simplelist_addline(SIMPLELIST_ADD_LINE,
1936 "Size: %s", buf);
1937 unsigned long free;
1938 fat_size( IF_MV2(0,) NULL, &free );
1939 simplelist_addline(SIMPLELIST_ADD_LINE,
1940 "Free: %ld MB", free / 1024);
1941 simplelist_addline(SIMPLELIST_ADD_LINE,
1942 "Spinup time: %d ms", storage_spinup_time() * (1000/HZ));
1943 i = identify_info[83] & (1<<3);
1944 simplelist_addline(SIMPLELIST_ADD_LINE,
1945 "Power mgmt: %s", i ? "enabled" : "unsupported");
1946 i = identify_info[83] & (1<<9);
1947 simplelist_addline(SIMPLELIST_ADD_LINE,
1948 "Noise mgmt: %s", i ? "enabled" : "unsupported");
1949 i = identify_info[82] & (1<<6);
1950 simplelist_addline(SIMPLELIST_ADD_LINE,
1951 "Read-ahead: %s", i ? "enabled" : "unsupported");
1952 timing_info_present = identify_info[53] & (1<<1);
1953 if(timing_info_present) {
1954 char pio3[2], pio4[2];pio3[1] = 0;
1955 pio4[1] = 0;
1956 pio3[0] = (identify_info[64] & (1<<0)) ? '3' : 0;
1957 pio4[0] = (identify_info[64] & (1<<1)) ? '4' : 0;
1958 simplelist_addline(SIMPLELIST_ADD_LINE,
1959 "PIO modes: 0 1 2 %s %s", pio3, pio4);
1961 else {
1962 simplelist_addline(SIMPLELIST_ADD_LINE,
1963 "No PIO mode info");
1965 timing_info_present = identify_info[53] & (1<<1);
1966 if(timing_info_present) {
1967 simplelist_addline(SIMPLELIST_ADD_LINE,
1968 "Cycle times %dns/%dns",
1969 identify_info[67],
1970 identify_info[68] );
1971 } else {
1972 simplelist_addline(SIMPLELIST_ADD_LINE,
1973 "No timing info");
1975 int sector_size = 512;
1976 if((identify_info[106] & 0xe000) == 0x6000)
1977 sector_size *= BIT_N(identify_info[106] & 0x000f);
1978 simplelist_addline(SIMPLELIST_ADD_LINE,
1979 "Physical sector size: %d", sector_size);
1980 #ifdef HAVE_ATA_DMA
1981 if (identify_info[63] & (1<<0)) {
1982 char mdma0[2], mdma1[2], mdma2[2];
1983 mdma0[1] = mdma1[1] = mdma2[1] = 0;
1984 mdma0[0] = (identify_info[63] & (1<<0)) ? '0' : 0;
1985 mdma1[0] = (identify_info[63] & (1<<1)) ? '1' : 0;
1986 mdma2[0] = (identify_info[63] & (1<<2)) ? '2' : 0;
1987 simplelist_addline(SIMPLELIST_ADD_LINE,
1988 "MDMA modes: %s %s %s", mdma0, mdma1, mdma2);
1989 simplelist_addline(SIMPLELIST_ADD_LINE,
1990 "MDMA Cycle times %dns/%dns",
1991 identify_info[65],
1992 identify_info[66] );
1994 else {
1995 simplelist_addline(SIMPLELIST_ADD_LINE,
1996 "No MDMA mode info");
1998 if (identify_info[53] & (1<<2)) {
1999 char udma0[2], udma1[2], udma2[2], udma3[2], udma4[2], udma5[2], udma6[2];
2000 udma0[1] = udma1[1] = udma2[1] = udma3[1] = udma4[1] = udma5[1] = udma6[1] = 0;
2001 udma0[0] = (identify_info[88] & (1<<0)) ? '0' : 0;
2002 udma1[0] = (identify_info[88] & (1<<1)) ? '1' : 0;
2003 udma2[0] = (identify_info[88] & (1<<2)) ? '2' : 0;
2004 udma3[0] = (identify_info[88] & (1<<3)) ? '3' : 0;
2005 udma4[0] = (identify_info[88] & (1<<4)) ? '4' : 0;
2006 udma5[0] = (identify_info[88] & (1<<5)) ? '5' : 0;
2007 udma6[0] = (identify_info[88] & (1<<6)) ? '6' : 0;
2008 simplelist_addline(SIMPLELIST_ADD_LINE,
2009 "UDMA modes: %s %s %s %s %s %s %s", udma0, udma1, udma2,
2010 udma3, udma4, udma5, udma6);
2012 else {
2013 simplelist_addline(SIMPLELIST_ADD_LINE,
2014 "No UDMA mode info");
2016 #endif /* HAVE_ATA_DMA */
2017 timing_info_present = identify_info[53] & (1<<1);
2018 if(timing_info_present) {
2019 i = identify_info[49] & (1<<11);
2020 simplelist_addline(SIMPLELIST_ADD_LINE,
2021 "IORDY support: %s", i ? "yes" : "no");
2022 i = identify_info[49] & (1<<10);
2023 simplelist_addline(SIMPLELIST_ADD_LINE,
2024 "IORDY disable: %s", i ? "yes" : "no");
2025 } else {
2026 simplelist_addline(SIMPLELIST_ADD_LINE,
2027 "No timing info");
2029 simplelist_addline(SIMPLELIST_ADD_LINE,
2030 "Cluster size: %d bytes", fat_get_cluster_size(IF_MV(0)));
2031 #ifdef HAVE_ATA_DMA
2032 i = ata_get_dma_mode();
2033 if (i == 0) {
2034 simplelist_addline(SIMPLELIST_ADD_LINE,
2035 "DMA not enabled");
2036 } else {
2037 simplelist_addline(SIMPLELIST_ADD_LINE,
2038 "DMA mode: %s %c",
2039 (i & 0x40) ? "UDMA" : "MDMA",
2040 '0' + (i & 7));
2042 #endif /* HAVE_ATA_DMA */
2043 return btn;
2045 #else /* No SD, MMC or ATA */
2046 static int disk_callback(int btn, struct gui_synclist *lists)
2048 (void)btn;
2049 (void)lists;
2050 struct storage_info info;
2051 storage_get_info(0,&info);
2052 simplelist_addline(SIMPLELIST_ADD_LINE, "Vendor: %s", info.vendor);
2053 simplelist_addline(SIMPLELIST_ADD_LINE, "Model: %s", info.product);
2054 simplelist_addline(SIMPLELIST_ADD_LINE, "Firmware: %s", info.revision);
2055 simplelist_addline(SIMPLELIST_ADD_LINE,
2056 "Size: %ld MB", info.num_sectors*(info.sector_size/512)/2024);
2057 unsigned long free;
2058 fat_size( IF_MV2(0,) NULL, &free );
2059 simplelist_addline(SIMPLELIST_ADD_LINE,
2060 "Free: %ld MB", free / 1024);
2061 simplelist_addline(SIMPLELIST_ADD_LINE,
2062 "Cluster size: %d bytes", fat_get_cluster_size(IF_MV(0)));
2063 return btn;
2065 #endif
2067 #if (CONFIG_STORAGE & STORAGE_ATA)
2068 static bool dbg_identify_info(void)
2070 int fd = creat("/identify_info.bin", 0666);
2071 if(fd >= 0)
2073 #ifdef ROCKBOX_LITTLE_ENDIAN
2074 ecwrite(fd, ata_get_identify(), SECTOR_SIZE/2, "s", true);
2075 #else
2076 write(fd, ata_get_identify(), SECTOR_SIZE);
2077 #endif
2078 close(fd);
2080 return false;
2082 #endif
2084 static bool dbg_disk_info(void)
2086 struct simplelist_info info;
2087 simplelist_info_init(&info, "Disk Info", 1, NULL);
2088 #if (CONFIG_STORAGE & STORAGE_MMC) || (CONFIG_STORAGE & STORAGE_SD)
2089 char title[16];
2090 int card = 0;
2091 info.callback_data = (void*)&card;
2092 info.title = title;
2093 #endif
2094 info.action_callback = disk_callback;
2095 info.hide_selection = true;
2096 info.scroll_all = true;
2097 return simplelist_show_list(&info);
2099 #endif /* !SIMULATOR */
2101 #ifdef HAVE_DIRCACHE
2102 static int dircache_callback(int btn, struct gui_synclist *lists)
2104 (void)btn; (void)lists;
2105 simplelist_set_line_count(0);
2106 simplelist_addline(SIMPLELIST_ADD_LINE, "Cache initialized: %s",
2107 dircache_is_enabled() ? "Yes" : "No");
2108 simplelist_addline(SIMPLELIST_ADD_LINE, "Cache size: %d B",
2109 dircache_get_cache_size());
2110 simplelist_addline(SIMPLELIST_ADD_LINE, "Last size: %d B",
2111 global_status.dircache_size);
2112 simplelist_addline(SIMPLELIST_ADD_LINE, "Limit: %d B",
2113 DIRCACHE_LIMIT);
2114 simplelist_addline(SIMPLELIST_ADD_LINE, "Reserve: %d/%d B",
2115 dircache_get_reserve_used(), DIRCACHE_RESERVE);
2116 simplelist_addline(SIMPLELIST_ADD_LINE, "Scanning took: %d s",
2117 dircache_get_build_ticks() / HZ);
2118 simplelist_addline(SIMPLELIST_ADD_LINE, "Entry count: %d",
2119 dircache_get_entry_count());
2120 return btn;
2123 static bool dbg_dircache_info(void)
2125 struct simplelist_info info;
2126 simplelist_info_init(&info, "Dircache Info", 7, NULL);
2127 info.action_callback = dircache_callback;
2128 info.hide_selection = true;
2129 info.scroll_all = true;
2130 return simplelist_show_list(&info);
2133 #endif /* HAVE_DIRCACHE */
2135 #ifdef HAVE_TAGCACHE
2136 static int database_callback(int btn, struct gui_synclist *lists)
2138 (void)lists;
2139 struct tagcache_stat *stat = tagcache_get_stat();
2140 static bool synced = false;
2142 simplelist_set_line_count(0);
2144 simplelist_addline(SIMPLELIST_ADD_LINE, "Initialized: %s",
2145 stat->initialized ? "Yes" : "No");
2146 simplelist_addline(SIMPLELIST_ADD_LINE, "DB Ready: %s",
2147 stat->ready ? "Yes" : "No");
2148 simplelist_addline(SIMPLELIST_ADD_LINE, "RAM Cache: %s",
2149 stat->ramcache ? "Yes" : "No");
2150 simplelist_addline(SIMPLELIST_ADD_LINE, "RAM: %d/%d B",
2151 stat->ramcache_used, stat->ramcache_allocated);
2152 simplelist_addline(SIMPLELIST_ADD_LINE, "Progress: %d%% (%d entries)",
2153 stat->progress, stat->processed_entries);
2154 simplelist_addline(SIMPLELIST_ADD_LINE, "Curfile: %s",
2155 stat->curentry ? stat->curentry : "---");
2156 simplelist_addline(SIMPLELIST_ADD_LINE, "Commit step: %d",
2157 stat->commit_step);
2158 simplelist_addline(SIMPLELIST_ADD_LINE, "Commit delayed: %s",
2159 stat->commit_delayed ? "Yes" : "No");
2161 simplelist_addline(SIMPLELIST_ADD_LINE, "Queue length: %d",
2162 stat->queue_length);
2164 if (synced)
2166 synced = false;
2167 tagcache_screensync_event();
2170 if (!btn && stat->curentry)
2172 synced = true;
2173 return ACTION_REDRAW;
2176 if (btn == ACTION_STD_CANCEL)
2177 tagcache_screensync_enable(false);
2179 return btn;
2181 static bool dbg_tagcache_info(void)
2183 struct simplelist_info info;
2184 simplelist_info_init(&info, "Database Info", 8, NULL);
2185 info.action_callback = database_callback;
2186 info.hide_selection = true;
2187 info.scroll_all = true;
2189 /* Don't do nonblock here, must give enough processing time
2190 for tagcache thread. */
2191 /* info.timeout = TIMEOUT_NOBLOCK; */
2192 info.timeout = 1;
2193 tagcache_screensync_enable(true);
2194 return simplelist_show_list(&info);
2196 #endif
2198 #if CONFIG_CPU == SH7034
2199 static bool dbg_save_roms(void)
2201 int fd;
2202 int oldmode = system_memory_guard(MEMGUARD_NONE);
2204 fd = creat("/internal_rom_0000-FFFF.bin", 0666);
2205 if(fd >= 0)
2207 write(fd, (void *)0, 0x10000);
2208 close(fd);
2211 fd = creat("/internal_rom_2000000-203FFFF.bin", 0666);
2212 if(fd >= 0)
2214 write(fd, (void *)0x2000000, 0x40000);
2215 close(fd);
2218 system_memory_guard(oldmode);
2219 return false;
2221 #elif defined CPU_COLDFIRE
2222 static bool dbg_save_roms(void)
2224 int fd;
2225 int oldmode = system_memory_guard(MEMGUARD_NONE);
2227 #if defined(IRIVER_H100_SERIES)
2228 fd = creat("/internal_rom_000000-1FFFFF.bin", 0666);
2229 #elif defined(IRIVER_H300_SERIES)
2230 fd = creat("/internal_rom_000000-3FFFFF.bin", 0666);
2231 #elif defined(IAUDIO_X5) || defined(IAUDIO_M5) || defined(IAUDIO_M3)
2232 fd = creat("/internal_rom_000000-3FFFFF.bin", 0666);
2233 #elif defined(MPIO_HD200)
2234 fd = creat("/internal_rom_000000-1FFFFF.bin", 0666);
2235 #endif
2236 if(fd >= 0)
2238 write(fd, (void *)0, FLASH_SIZE);
2239 close(fd);
2241 system_memory_guard(oldmode);
2243 #ifdef HAVE_EEPROM
2244 fd = creat("/internal_eeprom.bin", 0666);
2245 if (fd >= 0)
2247 int old_irq_level;
2248 char buf[EEPROM_SIZE];
2249 int err;
2251 old_irq_level = disable_irq_save();
2253 err = eeprom_24cxx_read(0, buf, sizeof buf);
2255 restore_irq(old_irq_level);
2257 if (err)
2258 splashf(HZ*3, "Eeprom read failure (%d)", err);
2259 else
2261 write(fd, buf, sizeof buf);
2264 close(fd);
2266 #endif
2268 return false;
2270 #elif defined(CPU_PP) && !(CONFIG_STORAGE & STORAGE_SD)
2271 static bool dbg_save_roms(void)
2273 int fd;
2275 fd = creat("/internal_rom_000000-0FFFFF.bin", 0666);
2276 if(fd >= 0)
2278 write(fd, (void *)0x20000000, FLASH_SIZE);
2279 close(fd);
2282 return false;
2284 #elif CONFIG_CPU == IMX31L
2285 static bool dbg_save_roms(void)
2287 int fd;
2289 fd = creat("/flash_rom_A0000000-A01FFFFF.bin", 0666);
2290 if (fd >= 0)
2292 write(fd, (void*)0xa0000000, FLASH_SIZE);
2293 close(fd);
2296 return false;
2298 #elif defined(CPU_TCC780X)
2299 static bool dbg_save_roms(void)
2301 int fd;
2303 fd = creat("/eeprom_E0000000-E0001FFF.bin", 0666);
2304 if (fd >= 0)
2306 write(fd, (void*)0xe0000000, 0x2000);
2307 close(fd);
2310 return false;
2312 #endif /* CPU */
2314 #ifndef SIMULATOR
2315 #if CONFIG_TUNER
2316 static int radio_callback(int btn, struct gui_synclist *lists)
2318 (void)lists;
2319 if (btn == ACTION_STD_CANCEL)
2320 return btn;
2321 simplelist_set_line_count(1);
2323 #if (CONFIG_TUNER & LV24020LP)
2324 simplelist_addline(SIMPLELIST_ADD_LINE,
2325 "CTRL_STAT: %02X", lv24020lp_get(LV24020LP_CTRL_STAT) );
2326 simplelist_addline(SIMPLELIST_ADD_LINE,
2327 "RADIO_STAT: %02X", lv24020lp_get(LV24020LP_REG_STAT) );
2328 simplelist_addline(SIMPLELIST_ADD_LINE,
2329 "MSS_FM: %d kHz", lv24020lp_get(LV24020LP_MSS_FM) );
2330 simplelist_addline(SIMPLELIST_ADD_LINE,
2331 "MSS_IF: %d Hz", lv24020lp_get(LV24020LP_MSS_IF) );
2332 simplelist_addline(SIMPLELIST_ADD_LINE,
2333 "MSS_SD: %d Hz", lv24020lp_get(LV24020LP_MSS_SD) );
2334 simplelist_addline(SIMPLELIST_ADD_LINE,
2335 "if_set: %d Hz", lv24020lp_get(LV24020LP_IF_SET) );
2336 simplelist_addline(SIMPLELIST_ADD_LINE,
2337 "sd_set: %d Hz", lv24020lp_get(LV24020LP_SD_SET) );
2338 #endif /* LV24020LP */
2339 #if (CONFIG_TUNER & S1A0903X01)
2340 simplelist_addline(SIMPLELIST_ADD_LINE,
2341 "Samsung regs: %08X", s1a0903x01_get(RADIO_ALL));
2342 /* This one doesn't return dynamic data atm */
2343 #endif /* S1A0903X01 */
2344 #if (CONFIG_TUNER & TEA5767)
2345 struct tea5767_dbg_info nfo;
2346 tea5767_dbg_info(&nfo);
2347 simplelist_addline(SIMPLELIST_ADD_LINE, "Philips regs:");
2348 simplelist_addline(SIMPLELIST_ADD_LINE,
2349 " Read: %02X %02X %02X %02X %02X",
2350 (unsigned)nfo.read_regs[0], (unsigned)nfo.read_regs[1],
2351 (unsigned)nfo.read_regs[2], (unsigned)nfo.read_regs[3],
2352 (unsigned)nfo.read_regs[4]);
2353 simplelist_addline(SIMPLELIST_ADD_LINE,
2354 " Write: %02X %02X %02X %02X %02X",
2355 (unsigned)nfo.write_regs[0], (unsigned)nfo.write_regs[1],
2356 (unsigned)nfo.write_regs[2], (unsigned)nfo.write_regs[3],
2357 (unsigned)nfo.write_regs[4]);
2358 #endif /* TEA5767 */
2359 #if (CONFIG_TUNER & SI4700)
2360 struct si4700_dbg_info nfo;
2361 si4700_dbg_info(&nfo);
2362 simplelist_addline(SIMPLELIST_ADD_LINE, "SI4700 regs:");
2363 /* Registers */
2364 simplelist_addline(SIMPLELIST_ADD_LINE,
2365 "%04X %04X %04X %04X",
2366 (unsigned)nfo.regs[0], (unsigned)nfo.regs[1],
2367 (unsigned)nfo.regs[2], (unsigned)nfo.regs[3]);
2368 simplelist_addline(SIMPLELIST_ADD_LINE,
2369 "%04X %04X %04X %04X",
2370 (unsigned)nfo.regs[4], (unsigned)nfo.regs[5],
2371 (unsigned)nfo.regs[6], (unsigned)nfo.regs[7]);
2372 simplelist_addline(SIMPLELIST_ADD_LINE,
2373 "%04X %04X %04X %04X",
2374 (unsigned)nfo.regs[8], (unsigned)nfo.regs[9],
2375 (unsigned)nfo.regs[10], (unsigned)nfo.regs[11]);
2376 simplelist_addline(SIMPLELIST_ADD_LINE,
2377 "%04X %04X %04X %04X",
2378 (unsigned)nfo.regs[12], (unsigned)nfo.regs[13],
2379 (unsigned)nfo.regs[14], (unsigned)nfo.regs[15]);
2380 #endif /* SI4700 */
2381 return ACTION_REDRAW;
2383 static bool dbg_fm_radio(void)
2385 struct simplelist_info info;
2386 info.scroll_all = true;
2387 simplelist_info_init(&info, "FM Radio", 1, NULL);
2388 simplelist_set_line_count(0);
2389 simplelist_addline(SIMPLELIST_ADD_LINE, "HW detected: %s",
2390 radio_hardware_present() ? "yes" : "no");
2392 info.action_callback = radio_hardware_present()?radio_callback : NULL;
2393 info.hide_selection = true;
2394 return simplelist_show_list(&info);
2396 #endif /* CONFIG_TUNER */
2397 #endif /* !SIMULATOR */
2399 #ifdef HAVE_LCD_BITMAP
2400 extern bool do_screendump_instead_of_usb;
2402 static bool dbg_screendump(void)
2404 do_screendump_instead_of_usb = !do_screendump_instead_of_usb;
2405 splashf(HZ, "Screendump %s",
2406 do_screendump_instead_of_usb?"enabled":"disabled");
2407 return false;
2409 #endif /* HAVE_LCD_BITMAP */
2411 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
2412 static bool dbg_set_memory_guard(void)
2414 static const struct opt_items names[MAXMEMGUARD] = {
2415 { "None", -1 },
2416 { "Flash ROM writes", -1 },
2417 { "Zero area (all)", -1 }
2419 int mode = system_memory_guard(MEMGUARD_KEEP);
2421 set_option( "Catch mem accesses", &mode, INT, names, MAXMEMGUARD, NULL);
2422 system_memory_guard(mode);
2424 return false;
2426 #endif /* CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) */
2428 #if defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS)
2429 static bool dbg_write_eeprom(void)
2431 int fd;
2432 int rc;
2433 int old_irq_level;
2434 char buf[EEPROM_SIZE];
2435 int err;
2437 fd = open("/internal_eeprom.bin", O_RDONLY);
2439 if (fd >= 0)
2441 rc = read(fd, buf, EEPROM_SIZE);
2443 if(rc == EEPROM_SIZE)
2445 old_irq_level = disable_irq_save();
2447 err = eeprom_24cxx_write(0, buf, sizeof buf);
2448 if (err)
2449 splashf(HZ*3, "Eeprom write failure (%d)", err);
2450 else
2451 splash(HZ*3, "Eeprom written successfully");
2453 restore_irq(old_irq_level);
2455 else
2457 splashf(HZ*3, "File read error (%d)",rc);
2459 close(fd);
2461 else
2463 splash(HZ*3, "Failed to open 'internal_eeprom.bin'");
2466 return false;
2468 #endif /* defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS) */
2469 #ifdef CPU_BOOST_LOGGING
2470 static bool cpu_boost_log(void)
2472 int i = 0,j=0;
2473 int count = cpu_boost_log_getcount();
2474 int lines = LCD_HEIGHT/SYSFONT_HEIGHT;
2475 char *str;
2476 bool done;
2477 lcd_setfont(FONT_SYSFIXED);
2478 str = cpu_boost_log_getlog_first();
2479 while (i < count)
2481 lcd_clear_display();
2482 for(j=0; j<lines; j++,i++)
2484 if (!str)
2485 str = cpu_boost_log_getlog_next();
2486 if (str)
2488 if(strlen(str) > LCD_WIDTH/SYSFONT_WIDTH)
2489 lcd_puts_scroll(0, j, str);
2490 else
2491 lcd_puts(0, j,str);
2493 str = NULL;
2495 lcd_update();
2496 done = false;
2497 while (!done)
2499 switch(get_action(CONTEXT_STD,TIMEOUT_BLOCK))
2501 case ACTION_STD_OK:
2502 case ACTION_STD_PREV:
2503 case ACTION_STD_NEXT:
2504 done = true;
2505 break;
2506 case ACTION_STD_CANCEL:
2507 i = count;
2508 done = true;
2509 break;
2513 lcd_stop_scroll();
2514 get_action(CONTEXT_STD,TIMEOUT_BLOCK);
2515 lcd_setfont(FONT_UI);
2516 return false;
2518 #endif
2520 #if (defined(HAVE_WHEEL_ACCELERATION) && (CONFIG_KEYPAD==IPOD_4G_PAD) && !defined(SIMULATOR))
2521 extern bool wheel_is_touched;
2522 extern int old_wheel_value;
2523 extern int new_wheel_value;
2524 extern int wheel_delta;
2525 extern unsigned int accumulated_wheel_delta;
2526 extern unsigned int wheel_velocity;
2528 static bool dbg_scrollwheel(void)
2530 unsigned int speed;
2532 lcd_setfont(FONT_SYSFIXED);
2534 while (1)
2536 if (action_userabort(HZ/10))
2537 break;
2539 lcd_clear_display();
2541 /* show internal variables of scrollwheel driver */
2542 lcd_putsf(0, 0, "wheel touched: %s", (wheel_is_touched) ? "true" : "false");
2543 lcd_putsf(0, 1, "new position: %2d", new_wheel_value);
2544 lcd_putsf(0, 2, "old position: %2d", old_wheel_value);
2545 lcd_putsf(0, 3, "wheel delta: %2d", wheel_delta);
2546 lcd_putsf(0, 4, "accumulated delta: %2d", accumulated_wheel_delta);
2547 lcd_putsf(0, 5, "velo [deg/s]: %4d", (int)wheel_velocity);
2549 /* show effective accelerated scrollspeed */
2550 speed = button_apply_acceleration( (1<<31)|(1<<24)|wheel_velocity);
2551 lcd_putsf(0, 6, "accel. speed: %4d", speed);
2553 lcd_update();
2555 lcd_setfont(FONT_UI);
2556 return false;
2558 #endif
2560 #if defined (HAVE_USBSTACK)
2562 #if defined(ROCKBOX_HAS_LOGF) && defined(USB_ENABLE_SERIAL)
2563 static bool toggle_usb_core_driver(int driver, char *msg)
2565 bool enabled = !usb_core_driver_enabled(driver);
2567 usb_core_enable_driver(driver,enabled);
2568 splashf(HZ, "%s %s", msg, enabled?"enabled":"disabled");
2570 return false;
2573 static bool toggle_usb_serial(void)
2575 return toggle_usb_core_driver(USB_DRIVER_SERIAL,"USB Serial");
2577 #endif
2579 #endif
2581 #if CONFIG_USBOTG == USBOTG_ISP1583
2582 extern int dbg_usb_num_items(void);
2583 extern const char* dbg_usb_item(int selected_item, void *data,
2584 char *buffer, size_t buffer_len);
2586 static int isp1583_action_callback(int action, struct gui_synclist *lists)
2588 (void)lists;
2589 if (action == ACTION_NONE)
2590 action = ACTION_REDRAW;
2591 return action;
2594 static bool dbg_isp1583(void)
2596 struct simplelist_info isp1583;
2597 isp1583.scroll_all = true;
2598 simplelist_info_init(&isp1583, "ISP1583", dbg_usb_num_items(), NULL);
2599 isp1583.timeout = HZ/100;
2600 isp1583.hide_selection = true;
2601 isp1583.get_name = dbg_usb_item;
2602 isp1583.action_callback = isp1583_action_callback;
2603 return simplelist_show_list(&isp1583);
2605 #endif
2607 #if defined(CREATIVE_ZVx) && !defined(SIMULATOR)
2608 extern int pic_dbg_num_items(void);
2609 extern const char* pic_dbg_item(int selected_item, void *data,
2610 char *buffer, size_t buffer_len);
2612 static int pic_action_callback(int action, struct gui_synclist *lists)
2614 (void)lists;
2615 if (action == ACTION_NONE)
2616 action = ACTION_REDRAW;
2617 return action;
2620 static bool dbg_pic(void)
2622 struct simplelist_info pic;
2623 pic.scroll_all = true;
2624 simplelist_info_init(&pic, "PIC", pic_dbg_num_items(), NULL);
2625 pic.timeout = HZ/100;
2626 pic.hide_selection = true;
2627 pic.get_name = pic_dbg_item;
2628 pic.action_callback = pic_action_callback;
2629 return simplelist_show_list(&pic);
2631 #endif
2634 /****** The menu *********/
2635 struct the_menu_item {
2636 unsigned char *desc; /* string or ID */
2637 bool (*function) (void); /* return true if USB was connected */
2639 static const struct the_menu_item menuitems[] = {
2640 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || \
2641 (defined(CPU_PP) && !(CONFIG_STORAGE & STORAGE_SD)) || \
2642 CONFIG_CPU == IMX31L || defined(CPU_TCC780X)
2643 { "Dump ROM contents", dbg_save_roms },
2644 #endif
2645 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || defined(CPU_PP) \
2646 || CONFIG_CPU == S3C2440 || CONFIG_CPU == IMX31L || CONFIG_CPU == AS3525 \
2647 || CONFIG_CPU == DM320 || defined(CPU_S5L870X) || CONFIG_CPU == AS3525v2
2648 { "View I/O ports", dbg_ports },
2649 #endif
2650 #if (CONFIG_RTC == RTC_PCF50605) && !defined(SIMULATOR)
2651 { "View PCF registers", dbg_pcf },
2652 #endif
2653 #if defined(HAVE_TSC2100) && !defined(SIMULATOR)
2654 { "TSC2100 debug", tsc2100_debug },
2655 #endif
2656 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
2657 { "CPU frequency", dbg_cpufreq },
2658 #endif
2659 #if defined(IRIVER_H100_SERIES) && !defined(SIMULATOR)
2660 { "S/PDIF analyzer", dbg_spdif },
2661 #endif
2662 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
2663 { "Catch mem accesses", dbg_set_memory_guard },
2664 #endif
2665 { "View OS stacks", dbg_os },
2666 #ifdef HAVE_LCD_BITMAP
2667 #ifndef SIMULATOR
2668 { "View battery", view_battery },
2669 #endif
2670 { "Screendump", dbg_screendump },
2671 #endif
2672 #ifndef SIMULATOR
2673 { "View HW info", dbg_hw_info },
2674 #endif
2675 #ifndef SIMULATOR
2676 { "View partitions", dbg_partitions },
2677 #endif
2678 #ifndef SIMULATOR
2679 { "View disk info", dbg_disk_info },
2680 #if (CONFIG_STORAGE & STORAGE_ATA)
2681 { "Dump ATA identify info", dbg_identify_info},
2682 #endif
2683 #endif
2684 #ifdef HAVE_DIRCACHE
2685 { "View dircache info", dbg_dircache_info },
2686 #endif
2687 #ifdef HAVE_TAGCACHE
2688 { "View database info", dbg_tagcache_info },
2689 #endif
2690 #ifdef HAVE_LCD_BITMAP
2691 #if CONFIG_CODEC == SWCODEC
2692 { "View buffering thread", dbg_buffering_thread },
2693 #elif !defined(SIMULATOR)
2694 { "View audio thread", dbg_audio_thread },
2695 #endif
2696 #ifdef PM_DEBUG
2697 { "pm histogram", peak_meter_histogram},
2698 #endif /* PM_DEBUG */
2699 #endif /* HAVE_LCD_BITMAP */
2700 #ifndef SIMULATOR
2701 #if CONFIG_TUNER
2702 { "FM Radio", dbg_fm_radio },
2703 #endif
2704 #endif
2705 #if defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS)
2706 { "Write back EEPROM", dbg_write_eeprom },
2707 #endif
2708 #if CONFIG_USBOTG == USBOTG_ISP1583
2709 { "View ISP1583 info", dbg_isp1583 },
2710 #endif
2711 #if defined(CREATIVE_ZVx) && !defined(SIMULATOR)
2712 { "View PIC info", dbg_pic },
2713 #endif
2714 #ifdef ROCKBOX_HAS_LOGF
2715 {"Show Log File", logfdisplay },
2716 {"Dump Log File", logfdump },
2717 #endif
2718 #if defined(HAVE_USBSTACK)
2719 #if defined(ROCKBOX_HAS_LOGF) && defined(USB_ENABLE_SERIAL)
2720 {"USB Serial driver (logf)", toggle_usb_serial },
2721 #endif
2722 #endif /* HAVE_USBSTACK */
2723 #ifdef CPU_BOOST_LOGGING
2724 {"cpu_boost log",cpu_boost_log},
2725 #endif
2726 #if (defined(HAVE_WHEEL_ACCELERATION) && (CONFIG_KEYPAD==IPOD_4G_PAD) && !defined(SIMULATOR))
2727 {"Debug scrollwheel", dbg_scrollwheel },
2728 #endif
2730 static int menu_action_callback(int btn, struct gui_synclist *lists)
2732 int i;
2733 if (btn == ACTION_STD_OK)
2735 FOR_NB_SCREENS(i)
2736 viewportmanager_theme_enable(i, false, NULL);
2737 menuitems[gui_synclist_get_sel_pos(lists)].function();
2738 btn = ACTION_REDRAW;
2739 FOR_NB_SCREENS(i)
2740 viewportmanager_theme_undo(i, false);
2742 return btn;
2745 static const char* dbg_menu_getname(int item, void * data,
2746 char *buffer, size_t buffer_len)
2748 (void)data; (void)buffer; (void)buffer_len;
2749 return menuitems[item].desc;
2752 bool debug_menu(void)
2754 struct simplelist_info info;
2756 simplelist_info_init(&info, "Debug Menu", ARRAYLEN(menuitems), NULL);
2757 info.action_callback = menu_action_callback;
2758 info.get_name = dbg_menu_getname;
2759 return simplelist_show_list(&info);