Extend HttpGet class to allow downloading a file to a buffer instead of a file.
[Rockbox.git] / apps / debug_menu.c
blobd3cfb30c76f2febc7029e4776407e6c527586651
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2002 Heikki Hannikainen
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
20 #include "config.h"
21 #include <stdio.h>
22 #include <stdbool.h>
23 #include <string.h>
24 #include "lcd.h"
25 #include "menu.h"
26 #include "debug_menu.h"
27 #include "kernel.h"
28 #include "sprintf.h"
29 #include "action.h"
30 #include "debug.h"
31 #include "thread.h"
32 #include "powermgmt.h"
33 #include "system.h"
34 #include "font.h"
35 #include "audio.h"
36 #include "mp3_playback.h"
37 #include "settings.h"
38 #include "list.h"
39 #include "statusbar.h"
40 #include "dir.h"
41 #include "panic.h"
42 #include "screens.h"
43 #include "misc.h"
44 #include "splash.h"
45 #include "dircache.h"
46 #ifdef HAVE_TAGCACHE
47 #include "tagcache.h"
48 #endif
49 #include "lcd-remote.h"
50 #include "crc32.h"
51 #include "logf.h"
52 #ifndef SIMULATOR
53 #include "disk.h"
54 #include "adc.h"
55 #include "power.h"
56 #include "usb.h"
57 #include "rtc.h"
58 #include "ata.h"
59 #include "fat.h"
60 #include "mas.h"
61 #include "eeprom_24cxx.h"
62 #if defined(HAVE_MMC) || defined(HAVE_HOTSWAP)
63 #include "ata_mmc.h"
64 #endif
65 #if CONFIG_TUNER
66 #include "tuner.h"
67 #include "radio.h"
68 #endif
69 #endif
71 #ifdef HAVE_LCD_BITMAP
72 #include "scrollbar.h"
73 #include "peakmeter.h"
74 #endif
75 #include "logfdisp.h"
76 #if CONFIG_CODEC == SWCODEC
77 #include "pcmbuf.h"
78 #include "pcm_playback.h"
79 #if defined(HAVE_SPDIF_OUT) || defined(HAVE_SPDIF_IN)
80 #include "spdif.h"
81 #endif
82 #endif
83 #ifdef IRIVER_H300_SERIES
84 #include "pcf50606.h" /* for pcf50606_read */
85 #endif
86 #ifdef IAUDIO_X5
87 #include "ds2411.h"
88 #endif
89 #include "hwcompat.h"
91 #if defined(HAVE_DIRCACHE) || defined(HAVE_TAGCACHE) || CONFIG_TUNER
92 #define MAX_DEBUG_MESSAGES 16
93 #define DEBUG_MSG_LEN 32
94 int debug_listmessage_lines;
95 char debug_list_messages[MAX_DEBUG_MESSAGES][DEBUG_MSG_LEN];
96 static void dbg_listmessage_setlines(int lines)
98 if (lines < 0)
99 lines = 0;
100 else if (lines > MAX_DEBUG_MESSAGES)
101 lines = MAX_DEBUG_MESSAGES;
102 debug_listmessage_lines = lines;
104 #ifndef SIMULATOR
105 static int dbg_listmessage_getlines(void)
107 return debug_listmessage_lines;
109 #endif
110 static void dbg_listmessage_addline(const char *fmt, ...)
112 va_list ap;
114 if (debug_listmessage_lines >= MAX_DEBUG_MESSAGES)
115 return;
117 va_start(ap, fmt);
118 vsnprintf(debug_list_messages[debug_listmessage_lines++], DEBUG_MSG_LEN, fmt, ap);
119 va_end(ap);
121 static char* dbg_listmessage_getname(int item, void * data, char *buffer)
123 (void)buffer; (void)data;
124 return debug_list_messages[item];
126 #endif
128 struct action_callback_info;
129 struct action_callback_info
131 char *title;
132 int count;
133 int selection_size;
134 int (*action_callback)(int btn, struct action_callback_info *info);
135 char* (*dbg_getname)(int item, void * data, char *buffer);
136 intptr_t cbdata; /* extra callback data (pointer, int, whatever) */
137 struct gui_synclist *lists; /* passed back to the callback */
140 static char* dbg_menu_getname(int item, void * data, char *buffer);
141 static bool dbg_list(struct action_callback_info *info)
143 struct gui_synclist lists;
144 int action;
146 info->lists = &lists;
148 gui_synclist_init(&lists, info->dbg_getname, NULL, false,
149 info->selection_size);
150 gui_synclist_set_title(&lists, info->title, NOICON);
151 gui_synclist_set_icon_callback(&lists, NULL);
152 gui_synclist_set_nb_items(&lists, info->count*info->selection_size);
153 if (info->dbg_getname != dbg_menu_getname)
154 gui_synclist_hide_selection_marker(&lists, true);
156 if (info->action_callback)
157 info->action_callback(ACTION_REDRAW, info);
159 gui_synclist_draw(&lists);
161 while(1)
163 gui_syncstatusbar_draw(&statusbars, true);
164 action = get_action(CONTEXT_STD, HZ/5);
165 if (gui_synclist_do_button(&lists, action, LIST_WRAP_UNLESS_HELD))
166 continue;
167 if (info->action_callback)
168 action = info->action_callback(action, info);
169 if (action == ACTION_STD_CANCEL)
170 break;
171 else if (action == ACTION_REDRAW)
172 gui_synclist_draw(&lists);
173 else if(default_event_handler(action) == SYS_USB_CONNECTED)
174 return true;
176 return false;
178 /*---------------------------------------------------*/
179 /* SPECIAL DEBUG STUFF */
180 /*---------------------------------------------------*/
181 extern struct thread_entry threads[MAXTHREADS];
184 #ifndef SIMULATOR
185 static char thread_status_char(int status)
187 switch (status)
189 case STATE_RUNNING : return 'R';
190 case STATE_BLOCKED : return 'B';
191 case STATE_SLEEPING : return 'S';
192 case STATE_BLOCKED_W_TMO: return 'T';
195 return '?';
197 #if NUM_CORES > 1
198 #define IF_COP2(...) __VA_ARGS__
199 #else
200 #define IF_COP2(...)
201 #endif
202 static char* threads_getname(int selected_item, void * data, char *buffer)
204 (void)data;
205 struct thread_entry *thread = NULL;
206 int status, usage;
207 thread = &threads[selected_item];
209 if (thread->name == NULL)
211 snprintf(buffer, MAX_PATH, "%2d: ---", selected_item);
212 return buffer;
215 usage = thread_stack_usage(thread);
216 status = thread_get_status(thread);
217 #ifdef HAVE_PRIORITY_SCHEDULING
218 snprintf(buffer, MAX_PATH, "%2d: " IF_COP2("(%d) ") "%c%c %d %2d%% %s",
219 selected_item,
220 IF_COP2(thread->core,)
221 (status == STATE_RUNNING) ? '*' : ' ',
222 thread_status_char(status),
223 thread->priority,
224 usage, thread->name);
225 #else
226 snprintf(buffer, MAX_PATH, "%2d: " IF_COP2("(%d) ") "%c%c %2d%% %s",
227 selected_item,
228 IF_COP2(thread->core,)
229 (status == STATE_RUNNING) ? '*' : ' ',
230 thread_status_char(status),
231 usage, thread->name);
232 #endif
233 return buffer;
235 static int dbg_threads_action_callback(int action, struct action_callback_info *info)
237 #ifdef ROCKBOX_HAS_LOGF
238 if (action == ACTION_STD_OK)
240 struct thread_entry *thread = &threads[gui_synclist_get_sel_pos(info->lists)];
241 if (thread->name != NULL)
242 remove_thread(thread);
244 #endif
245 gui_synclist_draw(info->lists);
246 return action;
248 /* Test code!!! */
249 static bool dbg_os(void)
251 struct action_callback_info info;
252 info.title = IF_COP2("Core and ") "Stack usage:";
253 info.count = MAXTHREADS;
254 info.selection_size = 1;
255 info.action_callback = dbg_threads_action_callback;
256 info.dbg_getname = threads_getname;
257 return dbg_list(&info);
259 #endif /* !SIMULATOR */
261 #ifdef HAVE_LCD_BITMAP
262 #if CONFIG_CODEC != SWCODEC
263 #ifndef SIMULATOR
264 static bool dbg_audio_thread(void)
266 char buf[32];
267 struct audio_debug d;
269 lcd_setmargins(0, 0);
270 lcd_setfont(FONT_SYSFIXED);
272 while(1)
274 if (action_userabort(HZ/5))
275 return false;
277 audio_get_debugdata(&d);
279 lcd_clear_display();
281 snprintf(buf, sizeof(buf), "read: %x", d.audiobuf_read);
282 lcd_puts(0, 0, buf);
283 snprintf(buf, sizeof(buf), "write: %x", d.audiobuf_write);
284 lcd_puts(0, 1, buf);
285 snprintf(buf, sizeof(buf), "swap: %x", d.audiobuf_swapwrite);
286 lcd_puts(0, 2, buf);
287 snprintf(buf, sizeof(buf), "playing: %d", d.playing);
288 lcd_puts(0, 3, buf);
289 snprintf(buf, sizeof(buf), "playable: %x", d.playable_space);
290 lcd_puts(0, 4, buf);
291 snprintf(buf, sizeof(buf), "unswapped: %x", d.unswapped_space);
292 lcd_puts(0, 5, buf);
294 /* Playable space left */
295 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, 6*8, 112, 4, d.audiobuflen, 0,
296 d.playable_space, HORIZONTAL);
298 /* Show the watermark limit */
299 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, 6*8+4, 112, 4, d.audiobuflen, 0,
300 d.low_watermark_level, HORIZONTAL);
302 snprintf(buf, sizeof(buf), "wm: %x - %x",
303 d.low_watermark_level, d.lowest_watermark_level);
304 lcd_puts(0, 7, buf);
306 lcd_update();
308 return false;
310 #endif /* !SIMULATOR */
311 #else /* CONFIG_CODEC == SWCODEC */
312 extern size_t filebuflen;
313 /* This is a size_t, but call it a long so it puts a - when it's bad. */
315 static unsigned int ticks, boost_ticks;
317 static void dbg_audio_task(void)
319 #ifndef SIMULATOR
320 if(FREQ > CPUFREQ_NORMAL)
321 boost_ticks++;
322 #endif
324 ticks++;
327 static bool dbg_audio_thread(void)
329 char buf[32];
330 int button;
331 int line;
332 bool done = false;
333 size_t bufused;
334 size_t bufsize = pcmbuf_get_bufsize();
335 int pcmbufdescs = pcmbuf_descs();
337 ticks = boost_ticks = 0;
339 tick_add_task(dbg_audio_task);
341 lcd_setmargins(0, 0);
342 lcd_setfont(FONT_SYSFIXED);
343 while(!done)
345 button = get_action(CONTEXT_STD,HZ/5);
346 switch(button)
348 case ACTION_STD_NEXT:
349 audio_next();
350 break;
351 case ACTION_STD_PREV:
352 audio_prev();
353 break;
354 case ACTION_STD_CANCEL:
355 done = true;
356 break;
358 line = 0;
359 lcd_clear_display();
361 bufused = bufsize - pcmbuf_free();
363 snprintf(buf, sizeof(buf), "pcm: %7ld/%7ld", (long) bufused, (long) bufsize);
364 lcd_puts(0, line++, buf);
366 /* Playable space left */
367 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6, bufsize, 0, bufused, HORIZONTAL);
368 line++;
370 snprintf(buf, sizeof(buf), "codec: %8ld/%8ld", audio_filebufused(), (long) filebuflen);
371 lcd_puts(0, line++, buf);
373 /* Playable space left */
374 gui_scrollbar_draw(&screens[SCREEN_MAIN],0, line*8, LCD_WIDTH, 6, filebuflen, 0,
375 audio_filebufused(), HORIZONTAL);
376 line++;
378 snprintf(buf, sizeof(buf), "track count: %2d", audio_track_count());
379 lcd_puts(0, line++, buf);
381 #ifndef SIMULATOR
382 snprintf(buf, sizeof(buf), "cpu freq: %3dMHz",
383 (int)((FREQ + 500000) / 1000000));
384 lcd_puts(0, line++, buf);
385 #endif
387 if (ticks > 0)
389 snprintf(buf, sizeof(buf), "boost ratio: %3d%%",
390 boost_ticks * 100 / ticks);
391 lcd_puts(0, line++, buf);
394 snprintf(buf, sizeof(buf), "pcmbufdesc: %2d/%2d",
395 pcmbuf_used_descs(), pcmbufdescs);
396 lcd_puts(0, line++, buf);
398 lcd_update();
401 tick_remove_task(dbg_audio_task);
403 return false;
405 #endif /* CONFIG_CODEC */
406 #endif /* HAVE_LCD_BITMAP */
409 #if (CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE))
410 /* Tool function to read the flash manufacturer and type, if available.
411 Only chips which could be reprogrammed in system will return values.
412 (The mode switch addresses vary between flash manufacturers, hence addr1/2) */
413 /* In IRAM to avoid problems when running directly from Flash */
414 static bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
415 unsigned addr1, unsigned addr2)
416 ICODE_ATTR __attribute__((noinline));
417 static bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
418 unsigned addr1, unsigned addr2)
421 unsigned not_manu, not_id; /* read values before switching to ID mode */
422 unsigned manu, id; /* read values when in ID mode */
424 #if CONFIG_CPU == SH7034
425 volatile unsigned char* flash = (unsigned char*)0x2000000; /* flash mapping */
426 #elif defined(CPU_COLDFIRE)
427 volatile unsigned short* flash = (unsigned short*)0; /* flash mapping */
428 #endif
429 int old_level; /* saved interrupt level */
431 not_manu = flash[0]; /* read the normal content */
432 not_id = flash[1]; /* should be 'A' (0x41) and 'R' (0x52) from the "ARCH" marker */
434 /* disable interrupts, prevent any stray flash access */
435 old_level = set_irq_level(HIGHEST_IRQ_LEVEL);
437 flash[addr1] = 0xAA; /* enter command mode */
438 flash[addr2] = 0x55;
439 flash[addr1] = 0x90; /* ID command */
440 /* Atmel wants 20ms pause here */
441 /* sleep(HZ/50); no sleeping possible while interrupts are disabled */
443 manu = flash[0]; /* read the IDs */
444 id = flash[1];
446 flash[0] = 0xF0; /* reset flash (back to normal read mode) */
447 /* Atmel wants 20ms pause here */
448 /* sleep(HZ/50); no sleeping possible while interrupts are disabled */
450 set_irq_level(old_level); /* enable interrupts again */
452 /* I assume success if the obtained values are different from
453 the normal flash content. This is not perfectly bulletproof, they
454 could theoretically be the same by chance, causing us to fail. */
455 if (not_manu != manu || not_id != id) /* a value has changed */
457 *p_manufacturer = manu; /* return the results */
458 *p_device = id;
459 return true; /* success */
461 return false; /* fail */
463 #endif /* (CONFIG_CPU == SH7034 || CPU_COLDFIRE) */
465 #ifndef SIMULATOR
466 #ifdef CPU_PP
467 static int perfcheck(void)
469 int result;
471 asm (
472 "mrs r2, CPSR \n"
473 "orr r0, r2, #0xc0 \n" /* disable IRQ and FIQ */
474 "msr CPSR_c, r0 \n"
475 "mov %[res], #0 \n"
476 "ldr r0, [%[timr]] \n"
477 "add r0, r0, %[tmo] \n"
478 "1: \n"
479 "add %[res], %[res], #1 \n"
480 "ldr r1, [%[timr]] \n"
481 "cmp r1, r0 \n"
482 "bmi 1b \n"
483 "msr CPSR_c, r2 \n" /* reset IRQ and FIQ state */
485 [res]"=&r"(result)
487 [timr]"r"(&USEC_TIMER),
488 [tmo]"r"(
489 #if CONFIG_CPU == PP5002
490 16000
491 #else /* PP5020/5022/5024 */
492 10226
493 #endif
496 "r0", "r1", "r2"
498 return result;
500 #endif
502 #ifdef HAVE_LCD_BITMAP
503 static bool dbg_hw_info(void)
505 #if CONFIG_CPU == SH7034
506 char buf[32];
507 int bitmask = HW_MASK;
508 int rom_version = ROM_VERSION;
509 unsigned manu, id; /* flash IDs */
510 bool got_id; /* flag if we managed to get the flash IDs */
511 unsigned rom_crc = 0xffffffff; /* CRC32 of the boot ROM */
512 bool has_bootrom; /* flag for boot ROM present */
513 int oldmode; /* saved memory guard mode */
515 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
517 /* get flash ROM type */
518 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
519 if (!got_id)
520 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
522 /* check if the boot ROM area is a flash mirror */
523 has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0);
524 if (has_bootrom) /* if ROM and Flash different */
526 /* calculate CRC16 checksum of boot ROM */
527 rom_crc = crc_32((unsigned char*)0x0000, 64*1024, 0xffffffff);
530 system_memory_guard(oldmode); /* re-enable memory guard */
532 lcd_setmargins(0, 0);
533 lcd_setfont(FONT_SYSFIXED);
534 lcd_clear_display();
536 lcd_puts(0, 0, "[Hardware info]");
538 snprintf(buf, 32, "ROM: %d.%02d", rom_version/100, rom_version%100);
539 lcd_puts(0, 1, buf);
541 snprintf(buf, 32, "Mask: 0x%04x", bitmask);
542 lcd_puts(0, 2, buf);
544 if (got_id)
545 snprintf(buf, 32, "Flash: M=%02x D=%02x", manu, id);
546 else
547 snprintf(buf, 32, "Flash: M=?? D=??"); /* unknown, sorry */
548 lcd_puts(0, 3, buf);
550 if (has_bootrom)
552 if (rom_crc == 0x56DBA4EE) /* known Version 1 */
553 snprintf(buf, 32, "Boot ROM: V1");
554 else
555 snprintf(buf, 32, "ROMcrc: 0x%08x", rom_crc);
557 else
559 snprintf(buf, 32, "Boot ROM: none");
561 lcd_puts(0, 4, buf);
563 lcd_update();
565 while (!(action_userabort(TIMEOUT_BLOCK)));
567 #elif CONFIG_CPU == MCF5249 || CONFIG_CPU == MCF5250
568 char buf[32];
569 unsigned manu, id; /* flash IDs */
570 int got_id; /* flag if we managed to get the flash IDs */
571 int oldmode; /* saved memory guard mode */
572 int line = 0;
574 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
576 /* get flash ROM type */
577 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
578 if (!got_id)
579 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
581 system_memory_guard(oldmode); /* re-enable memory guard */
583 lcd_setmargins(0, 0);
584 lcd_setfont(FONT_SYSFIXED);
585 lcd_clear_display();
587 lcd_puts(0, line++, "[Hardware info]");
589 if (got_id)
590 snprintf(buf, 32, "Flash: M=%04x D=%04x", manu, id);
591 else
592 snprintf(buf, 32, "Flash: M=???? D=????"); /* unknown, sorry */
593 lcd_puts(0, line++, buf);
595 #ifdef IAUDIO_X5
597 struct ds2411_id id;
599 lcd_puts(0, ++line, "Serial Number:");
601 got_id = ds2411_read_id(&id);
603 if (got_id == DS2411_OK)
605 snprintf(buf, 32, " FC=%02x", (unsigned)id.family_code);
606 lcd_puts(0, ++line, buf);
607 snprintf(buf, 32, " ID=%02X %02X %02X %02X %02X %02X",
608 (unsigned)id.uid[0], (unsigned)id.uid[1], (unsigned)id.uid[2],
609 (unsigned)id.uid[3], (unsigned)id.uid[4], (unsigned)id.uid[5]);
610 lcd_puts(0, ++line, buf);
611 snprintf(buf, 32, " CRC=%02X", (unsigned)id.crc);
613 else
615 snprintf(buf, 32, "READ ERR=%d", got_id);
618 lcd_puts(0, ++line, buf);
620 #endif
622 lcd_update();
624 while (!(action_userabort(TIMEOUT_BLOCK)));
626 #elif defined(CPU_PP502x)
627 int line = 0;
628 char buf[32];
629 char pp_version[] = { (PP_VER2 >> 24) & 0xff, (PP_VER2 >> 16) & 0xff,
630 (PP_VER2 >> 8) & 0xff, (PP_VER2) & 0xff,
631 (PP_VER1 >> 24) & 0xff, (PP_VER1 >> 16) & 0xff,
632 (PP_VER1 >> 8) & 0xff, (PP_VER1) & 0xff, '\0' };
634 lcd_setmargins(0, 0);
635 lcd_setfont(FONT_SYSFIXED);
636 lcd_clear_display();
638 lcd_puts(0, line++, "[Hardware info]");
640 #ifdef IPOD_ARCH
641 snprintf(buf, sizeof(buf), "HW rev: 0x%08lx", IPOD_HW_REVISION);
642 lcd_puts(0, line++, buf);
643 #endif
645 #ifdef IPOD_COLOR
646 extern int lcd_type; /* Defined in lcd-colornano.c */
648 snprintf(buf, sizeof(buf), "LCD type: %d", lcd_type);
649 lcd_puts(0, line++, buf);
650 #endif
652 snprintf(buf, sizeof(buf), "PP version: %s", pp_version);
653 lcd_puts(0, line++, buf);
655 snprintf(buf, sizeof(buf), "Est. clock (kHz): %d", perfcheck());
656 lcd_puts(0, line++, buf);
658 lcd_update();
660 while (!(action_userabort(TIMEOUT_BLOCK)));
662 #elif CONFIG_CPU == PP5002
663 int line = 0;
664 char buf[32];
666 lcd_setmargins(0, 0);
667 lcd_setfont(FONT_SYSFIXED);
668 lcd_clear_display();
670 lcd_puts(0, line++, "[Hardware info]");
672 #ifdef IPOD_ARCH
673 snprintf(buf, sizeof(buf), "HW rev: 0x%08lx", IPOD_HW_REVISION);
674 lcd_puts(0, line++, buf);
675 #endif
677 snprintf(buf, sizeof(buf), "Est. clock (kHz): %d", perfcheck());
678 lcd_puts(0, line++, buf);
680 lcd_update();
682 while (!(action_userabort(TIMEOUT_BLOCK)));
684 #endif /* CONFIG_CPU */
685 return false;
687 #else /* !HAVE_LCD_BITMAP */
688 static bool dbg_hw_info(void)
690 char buf[32];
691 int button;
692 int currval = 0;
693 int rom_version = ROM_VERSION;
694 unsigned manu, id; /* flash IDs */
695 bool got_id; /* flag if we managed to get the flash IDs */
696 unsigned rom_crc = 0xffffffff; /* CRC32 of the boot ROM */
697 bool has_bootrom; /* flag for boot ROM present */
698 int oldmode; /* saved memory guard mode */
700 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
702 /* get flash ROM type */
703 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
704 if (!got_id)
705 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
707 /* check if the boot ROM area is a flash mirror */
708 has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0);
709 if (has_bootrom) /* if ROM and Flash different */
711 /* calculate CRC16 checksum of boot ROM */
712 rom_crc = crc_32((unsigned char*)0x0000, 64*1024, 0xffffffff);
715 system_memory_guard(oldmode); /* re-enable memory guard */
717 lcd_clear_display();
719 lcd_puts(0, 0, "[HW Info]");
720 while(1)
722 switch(currval)
724 case 0:
725 snprintf(buf, 32, "ROM: %d.%02d",
726 rom_version/100, rom_version%100);
727 break;
728 case 1:
729 if (got_id)
730 snprintf(buf, 32, "Flash:%02x,%02x", manu, id);
731 else
732 snprintf(buf, 32, "Flash:??,??"); /* unknown, sorry */
733 break;
734 case 2:
735 if (has_bootrom)
737 if (rom_crc == 0x56DBA4EE) /* known Version 1 */
738 snprintf(buf, 32, "BootROM: V1");
739 else if (rom_crc == 0x358099E8)
740 snprintf(buf, 32, "BootROM: V2");
741 /* alternative boot ROM found in one single player so far */
742 else
743 snprintf(buf, 32, "R: %08x", rom_crc);
745 else
746 snprintf(buf, 32, "BootROM: no");
749 lcd_puts(0, 1, buf);
750 lcd_update();
752 button = get_action(CONTEXT_SETTINGS,TIMEOUT_BLOCK);
754 switch(button)
756 case ACTION_STD_CANCEL:
757 return false;
759 case ACTION_SETTINGS_DEC:
760 currval--;
761 if(currval < 0)
762 currval = 2;
763 break;
765 case ACTION_SETTINGS_INC:
766 currval++;
767 if(currval > 2)
768 currval = 0;
769 break;
772 return false;
774 #endif /* !HAVE_LCD_BITMAP */
775 #endif /* !SIMULATOR */
777 #ifndef SIMULATOR
778 static char* dbg_partitions_getname(int selected_item, void * data, char *buffer)
780 (void)data;
781 int partition = selected_item/2;
782 struct partinfo* p = disk_partinfo(partition);
783 if (selected_item%2)
785 snprintf(buffer, MAX_PATH, " T:%x %ld MB", p->type, p->size / 2048);
787 else
789 snprintf(buffer, MAX_PATH, "P%d: S:%lx", partition, p->start);
791 return buffer;
794 bool dbg_partitions(void)
796 struct action_callback_info info;
797 info.title = "Partition Info";
798 info.count = 4;
799 info.selection_size = 2;
800 info.action_callback = NULL;
801 info.dbg_getname = dbg_partitions_getname;
802 dbg_list(&info);
803 return false;
805 #endif
807 #if defined(CPU_COLDFIRE) && defined(HAVE_SPDIF_OUT)
808 static bool dbg_spdif(void)
810 char buf[128];
811 int line;
812 unsigned int control;
813 int x;
814 char *s;
815 int category;
816 int generation;
817 unsigned int interruptstat;
818 bool valnogood, symbolerr, parityerr;
819 bool done = false;
820 bool spdif_src_on;
821 int spdif_source = spdif_get_output_source(&spdif_src_on);
822 spdif_set_output_source(AUDIO_SRC_SPDIF IF_SPDIF_POWER_(, true));
824 lcd_setmargins(0, 0);
825 lcd_clear_display();
826 lcd_setfont(FONT_SYSFIXED);
828 #ifdef HAVE_SPDIF_POWER
829 spdif_power_enable(true); /* We need SPDIF power for both sending & receiving */
830 #endif
832 while (!done)
834 line = 0;
836 control = EBU1RCVCCHANNEL1;
837 interruptstat = INTERRUPTSTAT;
838 INTERRUPTCLEAR = 0x03c00000;
840 valnogood = (interruptstat & 0x01000000)?true:false;
841 symbolerr = (interruptstat & 0x00800000)?true:false;
842 parityerr = (interruptstat & 0x00400000)?true:false;
844 snprintf(buf, sizeof(buf), "Val: %s Sym: %s Par: %s",
845 valnogood?"--":"OK",
846 symbolerr?"--":"OK",
847 parityerr?"--":"OK");
848 lcd_puts(0, line++, buf);
850 snprintf(buf, sizeof(buf), "Status word: %08x", (int)control);
851 lcd_puts(0, line++, buf);
853 line++;
855 x = control >> 31;
856 snprintf(buf, sizeof(buf), "PRO: %d (%s)",
857 x, x?"Professional":"Consumer");
858 lcd_puts(0, line++, buf);
860 x = (control >> 30) & 1;
861 snprintf(buf, sizeof(buf), "Audio: %d (%s)",
862 x, x?"Non-PCM":"PCM");
863 lcd_puts(0, line++, buf);
865 x = (control >> 29) & 1;
866 snprintf(buf, sizeof(buf), "Copy: %d (%s)",
867 x, x?"Permitted":"Inhibited");
868 lcd_puts(0, line++, buf);
870 x = (control >> 27) & 7;
871 switch(x)
873 case 0:
874 s = "None";
875 break;
876 case 1:
877 s = "50/15us";
878 break;
879 default:
880 s = "Reserved";
881 break;
883 snprintf(buf, sizeof(buf), "Preemphasis: %d (%s)", x, s);
884 lcd_puts(0, line++, buf);
886 x = (control >> 24) & 3;
887 snprintf(buf, sizeof(buf), "Mode: %d", x);
888 lcd_puts(0, line++, buf);
890 category = (control >> 17) & 127;
891 switch(category)
893 case 0x00:
894 s = "General";
895 break;
896 case 0x40:
897 s = "Audio CD";
898 break;
899 default:
900 s = "Unknown";
902 snprintf(buf, sizeof(buf), "Category: 0x%02x (%s)", category, s);
903 lcd_puts(0, line++, buf);
905 x = (control >> 16) & 1;
906 generation = x;
907 if(((category & 0x70) == 0x10) ||
908 ((category & 0x70) == 0x40) ||
909 ((category & 0x78) == 0x38))
911 generation = !generation;
913 snprintf(buf, sizeof(buf), "Generation: %d (%s)",
914 x, generation?"Original":"No ind.");
915 lcd_puts(0, line++, buf);
917 x = (control >> 12) & 15;
918 snprintf(buf, sizeof(buf), "Source: %d", x);
919 lcd_puts(0, line++, buf);
921 x = (control >> 8) & 15;
922 switch(x)
924 case 0:
925 s = "Unspecified";
926 break;
927 case 8:
928 s = "A (Left)";
929 break;
930 case 4:
931 s = "B (Right)";
932 break;
933 default:
934 s = "";
935 break;
937 snprintf(buf, sizeof(buf), "Channel: %d (%s)", x, s);
938 lcd_puts(0, line++, buf);
940 x = (control >> 4) & 15;
941 switch(x)
943 case 0:
944 s = "44.1kHz";
945 break;
946 case 0x4:
947 s = "48kHz";
948 break;
949 case 0xc:
950 s = "32kHz";
951 break;
953 snprintf(buf, sizeof(buf), "Frequency: %d (%s)", x, s);
954 lcd_puts(0, line++, buf);
956 x = (control >> 2) & 3;
957 snprintf(buf, sizeof(buf), "Clock accuracy: %d", x);
958 lcd_puts(0, line++, buf);
959 line++;
961 #ifndef SIMULATOR
962 snprintf(buf, sizeof(buf), "Measured freq: %ldHz",
963 spdif_measure_frequency());
964 lcd_puts(0, line++, buf);
965 #endif
967 lcd_update();
969 if (action_userabort(HZ/10))
970 break;
973 spdif_set_output_source(spdif_source IF_SPDIF_POWER_(, spdif_src_on));
975 #ifdef HAVE_SPDIF_POWER
976 spdif_power_enable(global_settings.spdif_enable);
977 #endif
979 return false;
981 #endif /* CPU_COLDFIRE */
983 #ifndef SIMULATOR
984 #ifdef HAVE_LCD_BITMAP
985 /* button definitions */
986 #if (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
987 (CONFIG_KEYPAD == IRIVER_H300_PAD)
988 # define DEBUG_CANCEL BUTTON_OFF
990 #elif CONFIG_KEYPAD == RECORDER_PAD
991 # define DEBUG_CANCEL BUTTON_OFF
993 #elif CONFIG_KEYPAD == ONDIO_PAD
994 # define DEBUG_CANCEL BUTTON_MENU
996 #elif (CONFIG_KEYPAD == IPOD_1G2G_PAD) || \
997 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
998 (CONFIG_KEYPAD == IPOD_4G_PAD)
999 # define DEBUG_CANCEL BUTTON_MENU
1001 #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
1002 # define DEBUG_CANCEL BUTTON_PLAY
1004 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
1005 # define DEBUG_CANCEL BUTTON_REC
1007 #elif CONFIG_KEYPAD == GIGABEAT_PAD
1008 # define DEBUG_CANCEL BUTTON_A
1010 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
1011 # define DEBUG_CANCEL BUTTON_REW
1013 #elif CONFIG_KEYPAD == SANSA_E200_PAD
1014 # define DEBUG_CANCEL BUTTON_LEFT
1015 #endif /* key definitios */
1017 /* Test code!!! */
1018 bool dbg_ports(void)
1020 #if CONFIG_CPU == SH7034
1021 unsigned short porta;
1022 unsigned short portb;
1023 unsigned char portc;
1024 char buf[32];
1025 int adc_battery_voltage, adc_battery_level;
1027 lcd_setfont(FONT_SYSFIXED);
1028 lcd_setmargins(0, 0);
1029 lcd_clear_display();
1031 while(1)
1033 porta = PADR;
1034 portb = PBDR;
1035 portc = PCDR;
1037 snprintf(buf, 32, "PADR: %04x", porta);
1038 lcd_puts(0, 0, buf);
1039 snprintf(buf, 32, "PBDR: %04x", portb);
1040 lcd_puts(0, 1, buf);
1042 snprintf(buf, 32, "AN0: %03x AN4: %03x", adc_read(0), adc_read(4));
1043 lcd_puts(0, 2, buf);
1044 snprintf(buf, 32, "AN1: %03x AN5: %03x", adc_read(1), adc_read(5));
1045 lcd_puts(0, 3, buf);
1046 snprintf(buf, 32, "AN2: %03x AN6: %03x", adc_read(2), adc_read(6));
1047 lcd_puts(0, 4, buf);
1048 snprintf(buf, 32, "AN3: %03x AN7: %03x", adc_read(3), adc_read(7));
1049 lcd_puts(0, 5, buf);
1051 battery_read_info(NULL, &adc_battery_voltage,
1052 &adc_battery_level);
1053 snprintf(buf, 32, "Batt: %d.%02dV %d%% ", adc_battery_voltage / 100,
1054 adc_battery_voltage % 100, adc_battery_level);
1055 lcd_puts(0, 6, buf);
1057 lcd_update();
1058 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1059 return false;
1061 #elif defined(CPU_COLDFIRE)
1062 unsigned int gpio_out;
1063 unsigned int gpio1_out;
1064 unsigned int gpio_read;
1065 unsigned int gpio1_read;
1066 unsigned int gpio_function;
1067 unsigned int gpio1_function;
1068 unsigned int gpio_enable;
1069 unsigned int gpio1_enable;
1070 int adc_buttons, adc_remote;
1071 int adc_battery, adc_battery_voltage, adc_battery_level;
1072 char buf[128];
1073 int line;
1075 lcd_setmargins(0, 0);
1076 lcd_clear_display();
1077 lcd_setfont(FONT_SYSFIXED);
1079 while(1)
1081 line = 0;
1082 gpio_read = GPIO_READ;
1083 gpio1_read = GPIO1_READ;
1084 gpio_out = GPIO_OUT;
1085 gpio1_out = GPIO1_OUT;
1086 gpio_function = GPIO_FUNCTION;
1087 gpio1_function = GPIO1_FUNCTION;
1088 gpio_enable = GPIO_ENABLE;
1089 gpio1_enable = GPIO1_ENABLE;
1091 snprintf(buf, sizeof(buf), "GPIO_READ: %08x", gpio_read);
1092 lcd_puts(0, line++, buf);
1093 snprintf(buf, sizeof(buf), "GPIO_OUT: %08x", gpio_out);
1094 lcd_puts(0, line++, buf);
1095 snprintf(buf, sizeof(buf), "GPIO_FUNCTION: %08x", gpio_function);
1096 lcd_puts(0, line++, buf);
1097 snprintf(buf, sizeof(buf), "GPIO_ENABLE: %08x", gpio_enable);
1098 lcd_puts(0, line++, buf);
1100 snprintf(buf, sizeof(buf), "GPIO1_READ: %08x", gpio1_read);
1101 lcd_puts(0, line++, buf);
1102 snprintf(buf, sizeof(buf), "GPIO1_OUT: %08x", gpio1_out);
1103 lcd_puts(0, line++, buf);
1104 snprintf(buf, sizeof(buf), "GPIO1_FUNCTION: %08x", gpio1_function);
1105 lcd_puts(0, line++, buf);
1106 snprintf(buf, sizeof(buf), "GPIO1_ENABLE: %08x", gpio1_enable);
1107 lcd_puts(0, line++, buf);
1109 adc_buttons = adc_read(ADC_BUTTONS);
1110 adc_remote = adc_read(ADC_REMOTE);
1111 battery_read_info(&adc_battery, &adc_battery_voltage,
1112 &adc_battery_level);
1113 #if defined(IAUDIO_X5) || defined(IAUDIO_M5) || defined(IRIVER_H300_SERIES)
1114 snprintf(buf, sizeof(buf), "ADC_BUTTONS (%c): %02x",
1115 button_scan_enabled() ? '+' : '-', adc_buttons);
1116 #else
1117 snprintf(buf, sizeof(buf), "ADC_BUTTONS: %02x", adc_buttons);
1118 #endif
1119 lcd_puts(0, line++, buf);
1120 #if defined(IAUDIO_X5) || defined(IAUDIO_M5)
1121 snprintf(buf, sizeof(buf), "ADC_REMOTE (%c): %02x",
1122 remote_detect() ? '+' : '-', adc_remote);
1123 #else
1124 snprintf(buf, sizeof(buf), "ADC_REMOTE: %02x", adc_remote);
1125 #endif
1127 lcd_puts(0, line++, buf);
1128 snprintf(buf, sizeof(buf), "ADC_BATTERY: %02x", adc_battery);
1129 lcd_puts(0, line++, buf);
1130 #if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES)
1131 snprintf(buf, sizeof(buf), "ADC_REMOTEDETECT: %02x",
1132 adc_read(ADC_REMOTEDETECT));
1133 lcd_puts(0, line++, buf);
1134 #endif
1136 snprintf(buf, 32, "Batt: %d.%02dV %d%% ", adc_battery_voltage / 100,
1137 adc_battery_voltage % 100, adc_battery_level);
1138 lcd_puts(0, line++, buf);
1140 #if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES)
1141 snprintf(buf, sizeof(buf), "remotetype: %d", remote_type());
1142 lcd_puts(0, line++, buf);
1143 #endif
1145 lcd_update();
1146 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1147 return false;
1150 #elif defined(CPU_PP502x)
1152 unsigned int gpio_a, gpio_b, gpio_c, gpio_d;
1153 unsigned int gpio_e, gpio_f, gpio_g, gpio_h;
1154 unsigned int gpio_i, gpio_j, gpio_k, gpio_l;
1156 char buf[128];
1157 int line;
1159 lcd_setmargins(0, 0);
1160 lcd_clear_display();
1161 lcd_setfont(FONT_SYSFIXED);
1163 while(1)
1165 gpio_a = GPIOA_INPUT_VAL;
1166 gpio_b = GPIOB_INPUT_VAL;
1167 gpio_c = GPIOC_INPUT_VAL;
1169 gpio_g = GPIOG_INPUT_VAL;
1170 gpio_h = GPIOH_INPUT_VAL;
1171 gpio_i = GPIOI_INPUT_VAL;
1173 line = 0;
1174 snprintf(buf, sizeof(buf), "GPIO_A: %02x GPIO_G: %02x", gpio_a, gpio_g);
1175 lcd_puts(0, line++, buf);
1176 snprintf(buf, sizeof(buf), "GPIO_B: %02x GPIO_H: %02x", gpio_b, gpio_h);
1177 lcd_puts(0, line++, buf);
1178 snprintf(buf, sizeof(buf), "GPIO_C: %02x GPIO_I: %02x", gpio_c, gpio_i);
1179 lcd_puts(0, line++, buf);
1181 gpio_d = GPIOD_INPUT_VAL;
1182 gpio_e = GPIOE_INPUT_VAL;
1183 gpio_f = GPIOF_INPUT_VAL;
1185 gpio_j = GPIOJ_INPUT_VAL;
1186 gpio_k = GPIOK_INPUT_VAL;
1187 gpio_l = GPIOL_INPUT_VAL;
1189 snprintf(buf, sizeof(buf), "GPIO_D: %02x GPIO_J: %02x", gpio_d, gpio_j);
1190 lcd_puts(0, line++, buf);
1191 snprintf(buf, sizeof(buf), "GPIO_E: %02x GPIO_K: %02x", gpio_e, gpio_k);
1192 lcd_puts(0, line++, buf);
1193 snprintf(buf, sizeof(buf), "GPIO_F: %02x GPIO_L: %02x", gpio_f, gpio_l);
1194 lcd_puts(0, line++, buf);
1195 line++;
1197 snprintf(buf, sizeof(buf), "DEV_EN: %08lx", DEV_EN);
1198 lcd_puts(0, line++, buf);
1199 snprintf(buf, sizeof(buf), "CLOCK_SRC: %08lx", CLOCK_SOURCE);
1200 lcd_puts(0, line++, buf);
1201 snprintf(buf, sizeof(buf), "CLCD_CLK_SRC: %08lx", CLCD_CLOCK_SRC);
1202 lcd_puts(0, line++, buf);
1203 snprintf(buf, sizeof(buf), "PLL_CONTROL: %08lx", PLL_CONTROL);
1204 lcd_puts(0, line++, buf);
1205 snprintf(buf, sizeof(buf), "PLL_STATUS: %08lx", PLL_STATUS);
1206 lcd_puts(0, line++, buf);
1207 snprintf(buf, sizeof(buf), "DEV_TIMING1: %08lx", DEV_TIMING1);
1208 lcd_puts(0, line++, buf);
1210 #if defined(IRIVER_H10) || defined(IRIVER_H10_5GB)
1211 line++;
1212 snprintf(buf, sizeof(buf), "ADC_BATTERY: %02x", adc_read(ADC_BATTERY));
1213 lcd_puts(0, line++, buf);
1214 snprintf(buf, sizeof(buf), "ADC_UNKNOWN_1: %02x", adc_read(ADC_UNKNOWN_1));
1215 lcd_puts(0, line++, buf);
1216 snprintf(buf, sizeof(buf), "ADC_REMOTE: %02x", adc_read(ADC_REMOTE));
1217 lcd_puts(0, line++, buf);
1218 snprintf(buf, sizeof(buf), "ADC_SCROLLPAD: %02x", adc_read(ADC_SCROLLPAD));
1219 lcd_puts(0, line++, buf);
1220 #elif defined(SANSA_E200)
1221 line++;
1222 snprintf(buf, sizeof(buf), "ADC_BVDD: %02x", adc_read(ADC_BVDD));
1223 lcd_puts(0, line++, buf);
1224 snprintf(buf, sizeof(buf), "ADC_RTCSUP: %02x", adc_read(ADC_RTCSUP));
1225 lcd_puts(0, line++, buf);
1226 snprintf(buf, sizeof(buf), "ADC_UVDD: %02x", adc_read(ADC_UVDD));
1227 lcd_puts(0, line++, buf);
1228 snprintf(buf, sizeof(buf), "ADC_CHG_IN: %02x", adc_read(ADC_CHG_IN));
1229 lcd_puts(0, line++, buf);
1230 snprintf(buf, sizeof(buf), "ADC_CVDD: %02x", adc_read(ADC_CVDD));
1231 lcd_puts(0, line++, buf);
1232 snprintf(buf, sizeof(buf), "ADC_BATTEMP: %02x", adc_read(ADC_BATTEMP));
1233 lcd_puts(0, line++, buf);
1234 snprintf(buf, sizeof(buf), "ADC_MICSUP1: %02x", adc_read(ADC_MICSUP1));
1235 lcd_puts(0, line++, buf);
1236 snprintf(buf, sizeof(buf), "ADC_MICSUP2: %02x", adc_read(ADC_MICSUP2));
1237 lcd_puts(0, line++, buf);
1238 snprintf(buf, sizeof(buf), "ADC_VBE1: %02x", adc_read(ADC_VBE1));
1239 lcd_puts(0, line++, buf);
1240 snprintf(buf, sizeof(buf), "ADC_VBE2: %02x", adc_read(ADC_VBE2));
1241 lcd_puts(0, line++, buf);
1242 snprintf(buf, sizeof(buf), "ADC_I_MICSUP1: %02x", adc_read(ADC_I_MICSUP1));
1243 lcd_puts(0, line++, buf);
1244 snprintf(buf, sizeof(buf), "ADC_I_MICSUP2: %02x", adc_read(ADC_I_MICSUP2));
1245 lcd_puts(0, line++, buf);
1246 snprintf(buf, sizeof(buf), "ADC_VBAT: %02x", adc_read(ADC_VBAT));
1247 lcd_puts(0, line++, buf);
1248 #endif
1249 lcd_update();
1250 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1251 return false;
1254 #elif CONFIG_CPU == PP5002
1255 unsigned int gpio_a, gpio_b, gpio_c, gpio_d;
1257 char buf[128];
1258 int line;
1260 lcd_setmargins(0, 0);
1261 lcd_clear_display();
1262 lcd_setfont(FONT_SYSFIXED);
1264 while(1)
1266 gpio_a = GPIOA_INPUT_VAL;
1267 gpio_b = GPIOB_INPUT_VAL;
1268 gpio_c = GPIOC_INPUT_VAL;
1269 gpio_d = GPIOD_INPUT_VAL;
1271 line = 0;
1272 snprintf(buf, sizeof(buf), "GPIO_A: %02x GPIO_B: %02x", gpio_a, gpio_b);
1273 lcd_puts(0, line++, buf);
1274 snprintf(buf, sizeof(buf), "GPIO_C: %02x GPIO_D: %02x", gpio_c, gpio_d);
1275 lcd_puts(0, line++, buf);
1277 snprintf(buf, sizeof(buf), "DEV_EN: %08lx", DEV_EN);
1278 lcd_puts(0, line++, buf);
1279 snprintf(buf, sizeof(buf), "CLOCK_ENABLE: %08lx", CLOCK_ENABLE);
1280 lcd_puts(0, line++, buf);
1281 snprintf(buf, sizeof(buf), "CLOCK_SOURCE: %08lx", CLOCK_SOURCE);
1282 lcd_puts(0, line++, buf);
1283 snprintf(buf, sizeof(buf), "PLL_CONTROL: %08lx", PLL_CONTROL);
1284 lcd_puts(0, line++, buf);
1285 snprintf(buf, sizeof(buf), "PLL_DIV: %08lx", PLL_DIV);
1286 lcd_puts(0, line++, buf);
1287 snprintf(buf, sizeof(buf), "PLL_MULT: %08lx", PLL_MULT);
1288 lcd_puts(0, line++, buf);
1289 snprintf(buf, sizeof(buf), "TIMING1_CTL: %08lx", TIMING1_CTL);
1290 lcd_puts(0, line++, buf);
1291 snprintf(buf, sizeof(buf), "TIMING2_CTL: %08lx", TIMING2_CTL);
1292 lcd_puts(0, line++, buf);
1294 lcd_update();
1295 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1296 return false;
1298 #elif CONFIG_CPU == S3C2440
1299 char buf[50];
1300 int line;
1302 lcd_setmargins(0, 0);
1303 lcd_clear_display();
1304 lcd_setfont(FONT_SYSFIXED);
1306 while(1)
1308 line = 0;
1309 snprintf(buf, sizeof(buf), "[Ports and Registers]"); lcd_puts(0, line++, buf);
1311 snprintf(buf, sizeof(buf), "GPACON: %08x GPBCON: %08x", GPACON, GPBCON); lcd_puts(0, line++, buf);
1312 snprintf(buf, sizeof(buf), "GPADAT: %08x GPBDAT: %08x", GPADAT, GPBDAT); lcd_puts(0, line++, buf);
1313 snprintf(buf, sizeof(buf), "GPAUP: %08x GPBUP: %08x", 0, GPBUP); lcd_puts(0, line++, buf);
1314 snprintf(buf, sizeof(buf), "GPCCON: %08x GPDCON: %08x", GPCCON, GPDCON); lcd_puts(0, line++, buf);
1315 snprintf(buf, sizeof(buf), "GPCDAT: %08x GPDDAT: %08x", GPCDAT, GPDDAT); lcd_puts(0, line++, buf);
1316 snprintf(buf, sizeof(buf), "GPCUP: %08x GPDUP: %08x", GPCUP, GPDUP); lcd_puts(0, line++, buf);
1318 snprintf(buf, sizeof(buf), "GPCCON: %08x GPDCON: %08x", GPCCON, GPDCON); lcd_puts(0, line++, buf);
1319 snprintf(buf, sizeof(buf), "GPCDAT: %08x GPDDAT: %08x", GPCDAT, GPDDAT); lcd_puts(0, line++, buf);
1320 snprintf(buf, sizeof(buf), "GPCUP: %08x GPDUP: %08x", GPCUP, GPDUP); lcd_puts(0, line++, buf);
1322 snprintf(buf, sizeof(buf), "GPECON: %08x GPFCON: %08x", GPECON, GPFCON); lcd_puts(0, line++, buf);
1323 snprintf(buf, sizeof(buf), "GPEDAT: %08x GPFDAT: %08x", GPEDAT, GPFDAT); lcd_puts(0, line++, buf);
1324 snprintf(buf, sizeof(buf), "GPEUP: %08x GPFUP: %08x", GPEUP, GPFUP); lcd_puts(0, line++, buf);
1326 snprintf(buf, sizeof(buf), "GPGCON: %08x GPHCON: %08x", GPGCON, GPHCON); lcd_puts(0, line++, buf);
1327 snprintf(buf, sizeof(buf), "GPGDAT: %08x GPHDAT: %08x", GPGDAT, GPHDAT); lcd_puts(0, line++, buf);
1328 snprintf(buf, sizeof(buf), "GPGUP: %08x GPHUP: %08x", GPGUP, GPHUP); lcd_puts(0, line++, buf);
1330 snprintf(buf, sizeof(buf), "GPJCON: %08x", GPJCON); lcd_puts(0, line++, buf);
1331 snprintf(buf, sizeof(buf), "GPJDAT: %08x", GPJDAT); lcd_puts(0, line++, buf);
1332 snprintf(buf, sizeof(buf), "GPJUP: %08x", GPJUP); lcd_puts(0, line++, buf);
1334 line++;
1336 snprintf(buf, sizeof(buf), "SRCPND: %08x INTMOD: %08x", SRCPND, INTMOD); lcd_puts(0, line++, buf);
1337 snprintf(buf, sizeof(buf), "INTMSK: %08x INTPND: %08x", INTMSK, INTPND); lcd_puts(0, line++, buf);
1338 snprintf(buf, sizeof(buf), "CLKCON: %08x CLKSLOW: %08x", CLKCON, CLKSLOW); lcd_puts(0, line++, buf);
1339 snprintf(buf, sizeof(buf), "MPLLCON: %08x UPLLCON: %08x", MPLLCON, UPLLCON); lcd_puts(0, line++, buf);
1340 snprintf(buf, sizeof(buf), "CLKDIVN: %08x", CLKDIVN); lcd_puts(0, line++, buf);
1342 lcd_update();
1343 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
1344 return false;
1346 #endif /* CPU */
1347 return false;
1349 #else /* !HAVE_LCD_BITMAP */
1350 bool dbg_ports(void)
1352 unsigned short porta;
1353 unsigned short portb;
1354 unsigned char portc;
1355 char buf[32];
1356 int button;
1357 int adc_battery_voltage;
1358 int currval = 0;
1360 lcd_clear_display();
1362 while(1)
1364 porta = PADR;
1365 portb = PBDR;
1366 portc = PCDR;
1368 switch(currval)
1370 case 0:
1371 snprintf(buf, 32, "PADR: %04x", porta);
1372 break;
1373 case 1:
1374 snprintf(buf, 32, "PBDR: %04x", portb);
1375 break;
1376 case 2:
1377 snprintf(buf, 32, "AN0: %03x", adc_read(0));
1378 break;
1379 case 3:
1380 snprintf(buf, 32, "AN1: %03x", adc_read(1));
1381 break;
1382 case 4:
1383 snprintf(buf, 32, "AN2: %03x", adc_read(2));
1384 break;
1385 case 5:
1386 snprintf(buf, 32, "AN3: %03x", adc_read(3));
1387 break;
1388 case 6:
1389 snprintf(buf, 32, "AN4: %03x", adc_read(4));
1390 break;
1391 case 7:
1392 snprintf(buf, 32, "AN5: %03x", adc_read(5));
1393 break;
1394 case 8:
1395 snprintf(buf, 32, "AN6: %03x", adc_read(6));
1396 break;
1397 case 9:
1398 snprintf(buf, 32, "AN7: %03x", adc_read(7));
1399 break;
1400 break;
1402 lcd_puts(0, 0, buf);
1404 battery_read_info(NULL, &adc_battery_voltage, NULL);
1405 snprintf(buf, 32, "Batt: %d.%02dV", adc_battery_voltage / 100,
1406 adc_battery_voltage % 100);
1407 lcd_puts(0, 1, buf);
1408 lcd_update();
1410 button = get_action(CONTEXT_SETTINGS,HZ/5);
1412 switch(button)
1414 case ACTION_STD_CANCEL:
1415 return false;
1417 case ACTION_SETTINGS_DEC:
1418 currval--;
1419 if(currval < 0)
1420 currval = 9;
1421 break;
1423 case ACTION_SETTINGS_INC:
1424 currval++;
1425 if(currval > 9)
1426 currval = 0;
1427 break;
1430 return false;
1432 #endif /* !HAVE_LCD_BITMAP */
1433 #endif /* !SIMULATOR */
1435 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
1436 static bool dbg_cpufreq(void)
1438 char buf[128];
1439 int line;
1440 int button;
1442 #ifdef HAVE_LCD_BITMAP
1443 lcd_setmargins(0, 0);
1444 lcd_setfont(FONT_SYSFIXED);
1445 #endif
1446 lcd_clear_display();
1448 while(1)
1450 line = 0;
1452 snprintf(buf, sizeof(buf), "Frequency: %ld", FREQ);
1453 lcd_puts(0, line++, buf);
1455 snprintf(buf, sizeof(buf), "boost_counter: %d", get_cpu_boost_counter());
1456 lcd_puts(0, line++, buf);
1458 lcd_update();
1459 button = get_action(CONTEXT_STD,HZ/10);
1461 switch(button)
1463 case ACTION_STD_PREV:
1464 cpu_boost(true);
1465 break;
1467 case ACTION_STD_NEXT:
1468 cpu_boost(false);
1469 break;
1471 case ACTION_STD_OK:
1472 while (get_cpu_boost_counter() > 0)
1473 cpu_boost(false);
1474 set_cpu_frequency(CPUFREQ_DEFAULT);
1475 break;
1477 case ACTION_STD_CANCEL:
1478 return false;
1482 return false;
1484 #endif /* HAVE_ADJUSTABLE_CPU_FREQ */
1486 #ifndef SIMULATOR
1487 #ifdef HAVE_LCD_BITMAP
1489 * view_battery() shows a automatically scaled graph of the battery voltage
1490 * over time. Usable for estimating battery life / charging rate.
1491 * The power_history array is updated in power_thread of powermgmt.c.
1494 #define BAT_LAST_VAL MIN(LCD_WIDTH, POWER_HISTORY_LEN)
1495 #define BAT_YSPACE (LCD_HEIGHT - 20)
1497 static bool view_battery(void)
1499 int view = 0;
1500 int i, x, y;
1501 unsigned short maxv, minv;
1502 char buf[32];
1504 lcd_setmargins(0, 0);
1505 lcd_setfont(FONT_SYSFIXED);
1507 while(1)
1509 lcd_clear_display();
1510 switch (view) {
1511 case 0: /* voltage history graph */
1512 /* Find maximum and minimum voltage for scaling */
1513 maxv = 0;
1514 minv = 65535;
1515 for (i = 0; i < BAT_LAST_VAL; i++) {
1516 if (power_history[i] > maxv)
1517 maxv = power_history[i];
1518 if (power_history[i] && (power_history[i] < minv))
1520 minv = power_history[i];
1524 if ((minv < 1) || (minv >= 65535))
1525 minv = 1;
1526 if (maxv < 2)
1527 maxv = 2;
1528 if (minv == maxv)
1529 maxv < 65535 ? maxv++ : minv--;
1531 snprintf(buf, 30, "Battery %d.%02d", power_history[0] / 100,
1532 power_history[0] % 100);
1533 lcd_puts(0, 0, buf);
1534 snprintf(buf, 30, "scale %d.%02d-%d.%02d V",
1535 minv / 100, minv % 100, maxv / 100, maxv % 100);
1536 lcd_puts(0, 1, buf);
1538 x = 0;
1539 for (i = BAT_LAST_VAL - 1; i >= 0; i--) {
1540 y = (power_history[i] - minv) * BAT_YSPACE / (maxv - minv);
1541 lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
1542 lcd_vline(x, LCD_HEIGHT-1, 20);
1543 lcd_set_drawmode(DRMODE_SOLID);
1544 lcd_vline(x, LCD_HEIGHT-1,
1545 MIN(MAX(LCD_HEIGHT-1 - y, 20), LCD_HEIGHT-1));
1546 x++;
1549 break;
1551 case 1: /* status: */
1552 lcd_puts(0, 0, "Power status:");
1554 battery_read_info(NULL, &y, NULL);
1555 snprintf(buf, 30, "Battery: %d.%02d V", y / 100, y % 100);
1556 lcd_puts(0, 1, buf);
1557 #ifdef ADC_EXT_POWER
1558 y = (adc_read(ADC_EXT_POWER) * EXT_SCALE_FACTOR) / 10000;
1559 snprintf(buf, 30, "External: %d.%02d V", y / 100, y % 100);
1560 lcd_puts(0, 2, buf);
1561 #endif
1562 #if CONFIG_CHARGING
1563 #if CONFIG_CHARGING == CHARGING_CONTROL
1564 snprintf(buf, 30, "Chgr: %s %s",
1565 charger_inserted() ? "present" : "absent",
1566 charger_enabled ? "on" : "off");
1567 lcd_puts(0, 3, buf);
1568 snprintf(buf, 30, "short delta: %d", short_delta);
1569 lcd_puts(0, 5, buf);
1570 snprintf(buf, 30, "long delta: %d", long_delta);
1571 lcd_puts(0, 6, buf);
1572 lcd_puts(0, 7, power_message);
1573 snprintf(buf, 30, "USB Inserted: %s",
1574 usb_inserted() ? "yes" : "no");
1575 lcd_puts(0, 8, buf);
1576 #if defined IRIVER_H300_SERIES
1577 snprintf(buf, 30, "USB Charging Enabled: %s",
1578 usb_charging_enabled() ? "yes" : "no");
1579 lcd_puts(0, 9, buf);
1580 #endif
1581 #else /* CONFIG_CHARGING != CHARGING_CONTROL */
1582 #if defined IPOD_NANO || defined IPOD_VIDEO
1583 int usb_pwr = (GPIOL_INPUT_VAL & 0x10)?true:false;
1584 int ext_pwr = (GPIOL_INPUT_VAL & 0x08)?false:true;
1585 int dock = (GPIOA_INPUT_VAL & 0x10)?true:false;
1586 int charging = (GPIOB_INPUT_VAL & 0x01)?false:true;
1587 int headphone= (GPIOA_INPUT_VAL & 0x80)?true:false;
1589 snprintf(buf, 30, "USB pwr: %s",
1590 usb_pwr ? "present" : "absent");
1591 lcd_puts(0, 3, buf);
1592 snprintf(buf, 30, "EXT pwr: %s",
1593 ext_pwr ? "present" : "absent");
1594 lcd_puts(0, 4, buf);
1595 snprintf(buf, 30, "Battery: %s",
1596 charging ? "charging" : (usb_pwr||ext_pwr) ? "charged" : "discharging");
1597 lcd_puts(0, 5, buf);
1598 snprintf(buf, 30, "Dock mode: %s",
1599 dock ? "enabled" : "disabled");
1600 lcd_puts(0, 6, buf);
1601 snprintf(buf, 30, "Headphone: %s",
1602 headphone ? "connected" : "disconnected");
1603 lcd_puts(0, 7, buf);
1604 #else
1605 snprintf(buf, 30, "Charger: %s",
1606 charger_inserted() ? "present" : "absent");
1607 lcd_puts(0, 3, buf);
1608 #endif
1609 #endif /* CONFIG_CHARGING != CHARGING_CONTROL */
1610 #endif /* CONFIG_CHARGING */
1611 break;
1613 case 2: /* voltage deltas: */
1614 lcd_puts(0, 0, "Voltage deltas:");
1616 for (i = 0; i <= 6; i++) {
1617 y = power_history[i] - power_history[i+i];
1618 snprintf(buf, 30, "-%d min: %s%d.%02d V", i,
1619 (y < 0) ? "-" : "", ((y < 0) ? y * -1 : y) / 100,
1620 ((y < 0) ? y * -1 : y ) % 100);
1621 lcd_puts(0, i+1, buf);
1623 break;
1625 case 3: /* remaining time estimation: */
1627 #if CONFIG_CHARGING == CHARGING_CONTROL
1628 snprintf(buf, 30, "charge_state: %d", charge_state);
1629 lcd_puts(0, 0, buf);
1631 snprintf(buf, 30, "Cycle time: %d m", powermgmt_last_cycle_startstop_min);
1632 lcd_puts(0, 1, buf);
1634 snprintf(buf, 30, "Lvl@cyc st: %d%%", powermgmt_last_cycle_level);
1635 lcd_puts(0, 2, buf);
1637 snprintf(buf, 30, "P=%2d I=%2d", pid_p, pid_i);
1638 lcd_puts(0, 3, buf);
1640 snprintf(buf, 30, "Trickle sec: %d/60", trickle_sec);
1641 lcd_puts(0, 4, buf);
1642 #endif /* CONFIG_CHARGING == CHARGING_CONTROL */
1644 snprintf(buf, 30, "Last PwrHist: %d.%02d V",
1645 power_history[0] / 100,
1646 power_history[0] % 100);
1647 lcd_puts(0, 5, buf);
1649 snprintf(buf, 30, "battery level: %d%%", battery_level());
1650 lcd_puts(0, 6, buf);
1652 snprintf(buf, 30, "Est. remain: %d m", battery_time());
1653 lcd_puts(0, 7, buf);
1654 break;
1657 lcd_update();
1659 switch(get_action(CONTEXT_SETTINGS,HZ/2))
1661 case ACTION_SETTINGS_DEC:
1662 if (view)
1663 view--;
1664 break;
1666 case ACTION_SETTINGS_INC:
1667 if (view < 3)
1668 view++;
1669 break;
1671 case ACTION_STD_CANCEL:
1672 return false;
1675 return false;
1678 #endif /* HAVE_LCD_BITMAP */
1679 #endif
1681 #ifndef SIMULATOR
1682 #if defined(HAVE_MMC) || defined(HAVE_HOTSWAP)
1683 #if defined(HAVE_MMC)
1684 #define CARDTYPE "MMC"
1685 #else
1686 #define CARDTYPE "microSD"
1687 #endif
1688 static int cardinfo_callback(int btn, struct action_callback_info *info)
1690 tCardInfo *card;
1691 unsigned char card_name[7];
1692 unsigned char pbuf[32];
1693 static const unsigned char i_vmin[] = { 0, 1, 5, 10, 25, 35, 60, 100 };
1694 static const unsigned char i_vmax[] = { 1, 5, 10, 25, 35, 45, 80, 200 };
1695 static const unsigned char *kbit_units[] = { "kBit/s", "MBit/s", "GBit/s" };
1696 static const unsigned char *nsec_units[] = { "ns", "µs", "ms" };
1697 static const char *spec_vers[] = { "1.0-1.2", "1.4", "2.0-2.2",
1698 "3.1-3.31", "4.0" };
1699 if ((btn == ACTION_STD_OK) || (btn == SYS_FS_CHANGED) || (btn == ACTION_REDRAW))
1701 if (btn == ACTION_STD_OK)
1702 info->cbdata ^= 0x1; /* change cards */
1704 dbg_listmessage_setlines(0);
1706 card = card_get_info(info->cbdata);
1708 if (card->initialized > 0)
1710 card_name[6] = '\0';
1711 strncpy(card_name, ((unsigned char*)card->cid) + 3, 6);
1712 dbg_listmessage_addline(
1713 "%s Rev %d.%d", card_name,
1714 (int) card_extract_bits(card->cid, 72, 4),
1715 (int) card_extract_bits(card->cid, 76, 4));
1716 dbg_listmessage_addline(
1717 "Prod: %d/%d",
1718 (int) card_extract_bits(card->cid, 112, 4),
1719 (int) card_extract_bits(card->cid, 116, 4) + 1997);
1720 dbg_listmessage_addline(
1721 "Ser#: 0x%08lx",
1722 card_extract_bits(card->cid, 80, 32));
1723 dbg_listmessage_addline(
1724 "M=%02x, O=%04x",
1725 (int) card_extract_bits(card->cid, 0, 8),
1726 (int) card_extract_bits(card->cid, 8, 16));
1727 int temp = card_extract_bits(card->csd, 2, 4);
1728 dbg_listmessage_addline(
1729 CARDTYPE " v%s", temp < 5 ?
1730 spec_vers[temp] : "?.?");
1731 dbg_listmessage_addline(
1732 "Blocks: 0x%06lx", card->numblocks);
1733 dbg_listmessage_addline(
1734 "Blksz.: %d P:%c%c", card->blocksize,
1735 card_extract_bits(card->csd, 48, 1) ? 'R' : '-',
1736 card_extract_bits(card->csd, 106, 1) ? 'W' : '-');
1737 output_dyn_value(pbuf, sizeof pbuf, card->speed / 1000,
1738 kbit_units, false);
1739 dbg_listmessage_addline(
1740 "Speed: %s", pbuf);
1741 output_dyn_value(pbuf, sizeof pbuf, card->tsac,
1742 nsec_units, false);
1743 dbg_listmessage_addline(
1744 "Tsac: %s", pbuf);
1745 dbg_listmessage_addline(
1746 "Nsac: %d clk", card->nsac);
1747 dbg_listmessage_addline(
1748 "R2W: *%d", card->r2w_factor);
1749 dbg_listmessage_addline(
1750 "IRmax: %d..%d mA",
1751 i_vmin[card_extract_bits(card->csd, 66, 3)],
1752 i_vmax[card_extract_bits(card->csd, 69, 3)]);
1753 dbg_listmessage_addline(
1754 "IWmax: %d..%d mA",
1755 i_vmin[card_extract_bits(card->csd, 72, 3)],
1756 i_vmax[card_extract_bits(card->csd, 75, 3)]);
1758 else if (card->initialized == 0)
1760 dbg_listmessage_addline("Not Found!");
1762 #ifndef HAVE_MMC
1763 else /* card->initialized < 0 */
1765 dbg_listmessage_addline("Init Error! (%d)", card->initialized);
1767 #endif
1768 snprintf(info->title, 16, "[" CARDTYPE " %d]", (int)info->cbdata);
1769 gui_synclist_set_nb_items(info->lists, dbg_listmessage_getlines());
1770 gui_synclist_select_item(info->lists, 0);
1771 btn = ACTION_REDRAW;
1773 return btn;
1775 static bool dbg_disk_info(void)
1777 char listtitle[16];
1778 struct action_callback_info info;
1779 info.title = listtitle;
1780 info.count = 1;
1781 info.selection_size = 1;
1782 info.action_callback = cardinfo_callback;
1783 info.dbg_getname = dbg_listmessage_getname;
1784 info.cbdata = 0;
1785 dbg_list(&info);
1786 return false;
1788 #else /* !defined(HAVE_MMC) && !defined(HAVE_HOTSWAP) */
1789 static int disk_callback(int btn, struct action_callback_info *info)
1791 int i;
1792 char buf[128];
1793 unsigned short* identify_info = ata_get_identify();
1794 bool timing_info_present = false;
1795 (void)btn;
1797 dbg_listmessage_setlines(0);
1799 for (i=0; i < 20; i++)
1800 ((unsigned short*)buf)[i]=htobe16(identify_info[i+27]);
1801 buf[40]=0;
1802 /* kill trailing space */
1803 for (i=39; i && buf[i]==' '; i--)
1804 buf[i] = 0;
1805 dbg_listmessage_addline(
1806 "Model: %s", buf);
1807 for (i=0; i < 4; i++)
1808 ((unsigned short*)buf)[i]=htobe16(identify_info[i+23]);
1809 buf[8]=0;
1810 dbg_listmessage_addline(
1811 "Firmware: %s", buf);
1812 snprintf(buf, sizeof buf, "%ld MB",
1813 ((unsigned long)identify_info[61] << 16 |
1814 (unsigned long)identify_info[60]) / 2048 );
1815 dbg_listmessage_addline(
1816 "Size: %s", buf);
1817 unsigned long free;
1818 fat_size( IF_MV2(0,) NULL, &free );
1819 dbg_listmessage_addline(
1820 "Free: %ld MB", free / 1024);
1821 dbg_listmessage_addline(
1822 "Spinup time: %d ms", ata_spinup_time * (1000/HZ));
1823 i = identify_info[83] & (1<<3);
1824 dbg_listmessage_addline(
1825 "Power mgmt: %s", i ? "enabled" : "unsupported");
1826 i = identify_info[83] & (1<<9);
1827 dbg_listmessage_addline(
1828 "Noise mgmt: %s", i ? "enabled" : "unsupported");
1829 i = identify_info[82] & (1<<6);
1830 dbg_listmessage_addline(
1831 "Read-ahead: %s", i ? "enabled" : "unsupported");
1832 timing_info_present = identify_info[53] & (1<<1);
1833 if(timing_info_present) {
1834 char pio3[2], pio4[2];pio3[1] = 0;
1835 pio4[1] = 0;
1836 pio3[0] = (identify_info[64] & (1<<0)) ? '3' : 0;
1837 pio4[0] = (identify_info[64] & (1<<1)) ? '4' : 0;
1838 dbg_listmessage_addline(
1839 "PIO modes: 0 1 2 %s %s", pio3, pio4);
1841 else {
1842 dbg_listmessage_addline(
1843 "No PIO mode info");
1845 timing_info_present = identify_info[53] & (1<<1);
1846 if(timing_info_present) {
1847 dbg_listmessage_addline(
1848 "Cycle times %dns/%dns",
1849 identify_info[67],
1850 identify_info[68] );
1851 } else {
1852 dbg_listmessage_addline(
1853 "No timing info");
1855 timing_info_present = identify_info[53] & (1<<1);
1856 if(timing_info_present) {
1857 i = identify_info[49] & (1<<11);
1858 dbg_listmessage_addline(
1859 "IORDY support: %s", i ? "yes" : "no");
1860 i = identify_info[49] & (1<<10);
1861 dbg_listmessage_addline(
1862 "IORDY disable: %s", i ? "yes" : "no");
1863 } else {
1864 dbg_listmessage_addline(
1865 "No timing info");
1867 dbg_listmessage_addline(
1868 "Cluster size: %d bytes", fat_get_cluster_size(IF_MV(0)));
1869 gui_synclist_set_nb_items(info->lists, dbg_listmessage_getlines());
1870 return btn;
1872 static bool dbg_disk_info(void)
1874 struct action_callback_info info;
1875 info.title = "Disk Info";
1876 info.count = 1;
1877 info.selection_size = 1;
1878 info.action_callback = disk_callback;
1879 info.dbg_getname = dbg_listmessage_getname;
1880 dbg_list(&info);
1881 return false;
1883 #endif /* !defined(HAVE_MMC) && !defined(HAVE_HOTSWAP) */
1884 #endif /* !SIMULATOR */
1886 #ifdef HAVE_DIRCACHE
1887 static int dircache_callback(int btn, struct action_callback_info *info)
1889 (void)btn; (void)info;
1890 dbg_listmessage_setlines(0);
1891 dbg_listmessage_addline("Cache initialized: %s",
1892 dircache_is_enabled() ? "Yes" : "No");
1893 dbg_listmessage_addline("Cache size: %d B",
1894 dircache_get_cache_size());
1895 dbg_listmessage_addline("Last size: %d B",
1896 global_status.dircache_size);
1897 dbg_listmessage_addline("Limit: %d B",
1898 DIRCACHE_LIMIT);
1899 dbg_listmessage_addline("Reserve: %d/%d B",
1900 dircache_get_reserve_used(), DIRCACHE_RESERVE);
1901 dbg_listmessage_addline("Scanning took: %d s",
1902 dircache_get_build_ticks() / HZ);
1903 dbg_listmessage_addline("Entry count: %d",
1904 dircache_get_entry_count());
1905 return btn;
1908 static bool dbg_dircache_info(void)
1910 struct action_callback_info info;
1911 info.title = "Dircache Info";
1912 info.count = 7;
1913 info.selection_size = 1;
1914 info.action_callback = dircache_callback;
1915 info.dbg_getname = dbg_listmessage_getname;
1916 dbg_list(&info);
1917 return false;
1920 #endif /* HAVE_DIRCACHE */
1922 #ifdef HAVE_TAGCACHE
1923 static int database_callback(int btn, struct action_callback_info *info)
1925 (void)btn; (void)info;
1926 struct tagcache_stat *stat = tagcache_get_stat();
1927 dbg_listmessage_setlines(0);
1928 dbg_listmessage_addline("Initialized: %s",
1929 stat->initialized ? "Yes" : "No");
1930 dbg_listmessage_addline("DB Ready: %s",
1931 stat->ready ? "Yes" : "No");
1932 dbg_listmessage_addline("RAM Cache: %s",
1933 stat->ramcache ? "Yes" : "No");
1934 dbg_listmessage_addline("RAM: %d/%d B",
1935 stat->ramcache_used, stat->ramcache_allocated);
1936 dbg_listmessage_addline("Progress: %d%% (%d entries)",
1937 stat->progress, stat->processed_entries);
1938 dbg_listmessage_addline("Commit step: %d",
1939 stat->commit_step);
1940 dbg_listmessage_addline("Commit delayed: %s",
1941 stat->commit_delayed ? "Yes" : "No");
1942 return btn;
1944 static bool dbg_tagcache_info(void)
1946 struct action_callback_info info;
1947 info.title = "Database Info";
1948 info.count = 7;
1949 info.selection_size = 1;
1950 info.action_callback = database_callback;
1951 info.dbg_getname = dbg_listmessage_getname;
1952 dbg_list(&info);
1953 return false;
1955 #endif
1957 #if CONFIG_CPU == SH7034
1958 static bool dbg_save_roms(void)
1960 int fd;
1961 int oldmode = system_memory_guard(MEMGUARD_NONE);
1963 fd = creat("/internal_rom_0000-FFFF.bin");
1964 if(fd >= 0)
1966 write(fd, (void *)0, 0x10000);
1967 close(fd);
1970 fd = creat("/internal_rom_2000000-203FFFF.bin");
1971 if(fd >= 0)
1973 write(fd, (void *)0x2000000, 0x40000);
1974 close(fd);
1977 system_memory_guard(oldmode);
1978 return false;
1980 #elif defined CPU_COLDFIRE
1981 static bool dbg_save_roms(void)
1983 int fd;
1984 int oldmode = system_memory_guard(MEMGUARD_NONE);
1986 #if defined(IRIVER_H100_SERIES)
1987 fd = creat("/internal_rom_000000-1FFFFF.bin");
1988 #elif defined(IRIVER_H300_SERIES)
1989 fd = creat("/internal_rom_000000-3FFFFF.bin");
1990 #elif defined(IAUDIO_X5) || defined(IAUDIO_M5)
1991 fd = creat("/internal_rom_000000-3FFFFF.bin");
1992 #endif
1993 if(fd >= 0)
1995 write(fd, (void *)0, FLASH_SIZE);
1996 close(fd);
1998 system_memory_guard(oldmode);
2000 #ifdef HAVE_EEPROM
2001 fd = creat("/internal_eeprom.bin");
2002 if (fd >= 0)
2004 int old_irq_level;
2005 char buf[EEPROM_SIZE];
2006 int err;
2008 old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL);
2010 err = eeprom_24cxx_read(0, buf, sizeof buf);
2011 if (err)
2012 gui_syncsplash(HZ*3, "Eeprom read failure (%d)",err);
2013 else
2015 write(fd, buf, sizeof buf);
2018 set_irq_level(old_irq_level);
2020 close(fd);
2022 #endif
2024 return false;
2026 #elif defined(CPU_PP) && !defined(SANSA_E200)
2027 static bool dbg_save_roms(void)
2029 int fd;
2031 fd = creat("/internal_rom_000000-0FFFFF.bin");
2032 if(fd >= 0)
2034 write(fd, (void *)0x20000000, FLASH_SIZE);
2035 close(fd);
2038 return false;
2040 #endif /* CPU */
2042 #ifndef SIMULATOR
2043 #if CONFIG_TUNER
2044 static int radio_callback(int btn, struct action_callback_info *info)
2046 dbg_listmessage_setlines(1);
2048 #if (CONFIG_TUNER & LV24020LP)
2049 dbg_listmessage_addline("CTRL_STAT: %02X", lv24020lp_get(LV24020LP_CTRL_STAT) );
2050 dbg_listmessage_addline("RADIO_STAT: %02X", lv24020lp_get(LV24020LP_REG_STAT) );
2051 dbg_listmessage_addline("MSS_FM: %d kHz", lv24020lp_get(LV24020LP_MSS_FM) );
2052 dbg_listmessage_addline("MSS_IF: %d Hz", lv24020lp_get(LV24020LP_MSS_IF) );
2053 dbg_listmessage_addline("MSS_SD: %d Hz", lv24020lp_get(LV24020LP_MSS_SD) );
2054 dbg_listmessage_addline("if_set: %d Hz", lv24020lp_get(LV24020LP_IF_SET) );
2055 dbg_listmessage_addline("sd_set: %d Hz", lv24020lp_get(LV24020LP_SD_SET) );
2056 #endif
2057 #if (CONFIG_TUNER & S1A0903X01)
2058 dbg_listmessage_addline("Samsung regs: %08X", s1a0903x01_get(RADIO_ALL));
2059 /* This one doesn't return dynamic data atm */
2060 #endif
2061 #if (CONFIG_TUNER & TEA5767)
2062 struct tea5767_dbg_info nfo;
2063 tea5767_dbg_info(&nfo);
2064 dbg_listmessage_addline("Philips regs:");
2065 dbg_listmessage_addline(
2066 " Read: %02X %02X %02X %02X %02X",
2067 (unsigned)nfo.read_regs[0], (unsigned)nfo.read_regs[1],
2068 (unsigned)nfo.read_regs[2], (unsigned)nfo.read_regs[3],
2069 (unsigned)nfo.read_regs[4]);
2070 dbg_listmessage_addline(
2071 " Write: %02X %02X %02X %02X %02X",
2072 (unsigned)nfo.write_regs[0], (unsigned)nfo.write_regs[1],
2073 (unsigned)nfo.write_regs[2], (unsigned)nfo.write_regs[3],
2074 (unsigned)nfo.write_regs[4]);
2075 #endif
2077 if (btn != ACTION_STD_CANCEL)
2078 btn = ACTION_REDRAW;
2080 gui_synclist_set_nb_items(info->lists, dbg_listmessage_getlines());
2081 return btn;
2083 static bool dbg_fm_radio(void)
2085 struct action_callback_info info;
2087 info.title = "FM Radio";
2088 info.count = 1;
2089 info.selection_size = 1;
2090 info.cbdata = radio_hardware_present();
2091 info.action_callback = info.cbdata ? radio_callback : NULL;
2092 info.dbg_getname = dbg_listmessage_getname;
2094 dbg_listmessage_setlines(0);
2095 dbg_listmessage_addline("HW detected: %s", info.cbdata ? "yes" : "no");
2097 dbg_list(&info);
2098 return false;
2100 #endif /* CONFIG_TUNER */
2101 #endif /* !SIMULATOR */
2103 #ifdef HAVE_LCD_BITMAP
2104 extern bool do_screendump_instead_of_usb;
2106 static bool dbg_screendump(void)
2108 do_screendump_instead_of_usb = !do_screendump_instead_of_usb;
2109 gui_syncsplash(HZ, "Screendump %s",
2110 do_screendump_instead_of_usb?"enabled":"disabled");
2111 return false;
2113 #endif /* HAVE_LCD_BITMAP */
2115 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
2116 static bool dbg_set_memory_guard(void)
2118 static const struct opt_items names[MAXMEMGUARD] = {
2119 { "None", -1 },
2120 { "Flash ROM writes", -1 },
2121 { "Zero area (all)", -1 }
2123 int mode = system_memory_guard(MEMGUARD_KEEP);
2125 set_option( "Catch mem accesses", &mode, INT, names, MAXMEMGUARD, NULL);
2126 system_memory_guard(mode);
2128 return false;
2130 #endif /* CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) */
2132 #if defined(TOSHIBA_GIGABEAT_F) && !defined(SIMULATOR)
2134 extern volatile bool lcd_poweroff;
2136 static bool dbg_lcd_power_off(void)
2138 lcd_setmargins(0, 0);
2140 while(1)
2142 int button;
2144 lcd_clear_display();
2145 lcd_puts(0, 0, "LCD Power Off");
2146 if(lcd_poweroff)
2147 lcd_puts(1, 1, "Yes");
2148 else
2149 lcd_puts(1, 1, "No");
2151 lcd_update();
2153 button = get_action(CONTEXT_STD,HZ/5);
2154 switch(button)
2156 case ACTION_STD_PREV:
2157 case ACTION_STD_NEXT:
2158 lcd_poweroff = !lcd_poweroff;
2159 break;
2160 case ACTION_STD_OK:
2161 case ACTION_STD_CANCEL:
2162 return false;
2163 default:
2164 sleep(HZ/10);
2165 break;
2168 return false;
2170 #endif
2172 #if defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS)
2173 static bool dbg_write_eeprom(void)
2175 int fd;
2176 int rc;
2177 int old_irq_level;
2178 char buf[EEPROM_SIZE];
2179 int err;
2181 fd = open("/internal_eeprom.bin", O_RDONLY);
2183 if (fd >= 0)
2185 rc = read(fd, buf, EEPROM_SIZE);
2187 if(rc == EEPROM_SIZE)
2189 old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL);
2191 err = eeprom_24cxx_write(0, buf, sizeof buf);
2192 if (err)
2193 gui_syncsplash(HZ*3, "Eeprom write failure (%d)",err);
2194 else
2195 gui_syncsplash(HZ*3, "Eeprom written successfully");
2197 set_irq_level(old_irq_level);
2199 else
2201 gui_syncsplash(HZ*3, "File read error (%d)",rc);
2203 close(fd);
2205 else
2207 gui_syncsplash(HZ*3, "Failed to open 'internal_eeprom.bin'");
2210 return false;
2212 #endif /* defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS) */
2213 #ifdef CPU_BOOST_LOGGING
2214 static bool cpu_boost_log(void)
2216 int i = 0,j=0;
2217 int count = cpu_boost_log_getcount();
2218 int lines = LCD_HEIGHT/SYSFONT_HEIGHT;
2219 char *str;
2220 bool done;
2221 lcd_setmargins(0, 0);
2222 lcd_setfont(FONT_SYSFIXED);
2223 str = cpu_boost_log_getlog_first();
2224 while (i < count)
2226 lcd_clear_display();
2227 for(j=0; j<lines; j++,i++)
2229 if (!str)
2230 str = cpu_boost_log_getlog_next();
2231 if (str)
2233 lcd_puts(0, j,str);
2235 str = NULL;
2237 lcd_update();
2238 done = false;
2239 while (!done)
2241 switch(get_action(CONTEXT_STD,TIMEOUT_BLOCK))
2243 case ACTION_STD_OK:
2244 case ACTION_STD_PREV:
2245 case ACTION_STD_NEXT:
2246 done = true;
2247 break;
2248 case ACTION_STD_CANCEL:
2249 i = count;
2250 done = true;
2251 break;
2255 get_action(CONTEXT_STD,TIMEOUT_BLOCK);
2256 lcd_setfont(FONT_UI);
2257 return false;
2259 #endif
2263 /****** The menu *********/
2264 struct the_menu_item {
2265 unsigned char *desc; /* string or ID */
2266 bool (*function) (void); /* return true if USB was connected */
2268 static const struct the_menu_item menuitems[] = {
2269 #if defined(TOSHIBA_GIGABEAT_F) && !defined(SIMULATOR)
2270 { "LCD Power Off", dbg_lcd_power_off },
2271 #endif
2272 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || \
2273 (defined(CPU_PP) && !defined(SANSA_E200))
2274 { "Dump ROM contents", dbg_save_roms },
2275 #endif
2276 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || defined(CPU_PP) || CONFIG_CPU == S3C2440
2277 { "View I/O ports", dbg_ports },
2278 #endif
2279 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
2280 { "CPU frequency", dbg_cpufreq },
2281 #endif
2282 #if defined(IRIVER_H100_SERIES) && !defined(SIMULATOR)
2283 { "S/PDIF analyzer", dbg_spdif },
2284 #endif
2285 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
2286 { "Catch mem accesses", dbg_set_memory_guard },
2287 #endif
2288 #ifndef SIMULATOR
2289 { "View OS stacks", dbg_os },
2290 #endif
2291 #ifdef HAVE_LCD_BITMAP
2292 #ifndef SIMULATOR
2293 { "View battery", view_battery },
2294 #endif
2295 { "Screendump", dbg_screendump },
2296 #endif
2297 #ifndef SIMULATOR
2298 { "View HW info", dbg_hw_info },
2299 #endif
2300 #ifndef SIMULATOR
2301 { "View partitions", dbg_partitions },
2302 #endif
2303 #ifndef SIMULATOR
2304 { "View disk info", dbg_disk_info },
2305 #endif
2306 #ifdef HAVE_DIRCACHE
2307 { "View dircache info", dbg_dircache_info },
2308 #endif
2309 #ifdef HAVE_TAGCACHE
2310 { "View database info", dbg_tagcache_info },
2311 #endif
2312 #ifdef HAVE_LCD_BITMAP
2313 #if CONFIG_CODEC == SWCODEC || !defined(SIMULATOR)
2314 { "View audio thread", dbg_audio_thread },
2315 #endif
2316 #ifdef PM_DEBUG
2317 { "pm histogram", peak_meter_histogram},
2318 #endif /* PM_DEBUG */
2319 #endif /* HAVE_LCD_BITMAP */
2320 #ifndef SIMULATOR
2321 #if CONFIG_TUNER
2322 { "FM Radio", dbg_fm_radio },
2323 #endif
2324 #endif
2325 #if defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS)
2326 { "Write back EEPROM", dbg_write_eeprom },
2327 #endif
2328 #ifdef ROCKBOX_HAS_LOGF
2329 {"logf", logfdisplay },
2330 {"logfdump", logfdump },
2331 #endif
2332 #ifdef CPU_BOOST_LOGGING
2333 {"cpu_boost log",cpu_boost_log},
2334 #endif
2336 static int menu_action_callback(int btn, struct action_callback_info *info)
2338 if (btn == ACTION_STD_OK)
2340 menuitems[gui_synclist_get_sel_pos(info->lists)].function();
2341 gui_synclist_draw(info->lists);
2343 return btn;
2345 static char* dbg_menu_getname(int item, void * data, char *buffer)
2347 (void)data; (void)buffer;
2348 return menuitems[item].desc;
2350 bool debug_menu(void)
2352 struct action_callback_info info;
2353 info.title = "Debug Menu";
2354 info.count = ARRAYLEN(menuitems);
2355 info.selection_size = 1;
2356 info.action_callback = menu_action_callback;
2357 info.dbg_getname = dbg_menu_getname;
2358 dbg_list(&info);
2359 return false;