Add AAC audio type
[Rockbox.git] / apps / debug_menu.c
blob6b6b1f5a05f84900c882c8347b8ea0231b0854f0
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 #ifndef SIMULATOR
22 #include <stdio.h>
23 #include <stdbool.h>
24 #include <string.h>
25 #include "lcd.h"
26 #include "menu.h"
27 #include "debug_menu.h"
28 #include "kernel.h"
29 #include "sprintf.h"
30 #include "button.h"
31 #include "adc.h"
32 #include "mas.h"
33 #include "power.h"
34 #include "rtc.h"
35 #include "debug.h"
36 #include "thread.h"
37 #include "powermgmt.h"
38 #include "system.h"
39 #include "font.h"
40 #include "disk.h"
41 #include "audio.h"
42 #include "mp3_playback.h"
43 #include "settings.h"
44 #include "ata.h"
45 #include "fat.h"
46 #include "dir.h"
47 #include "panic.h"
48 #include "screens.h"
49 #include "misc.h"
50 #ifdef HAVE_LCD_BITMAP
51 #include "widgets.h"
52 #include "peakmeter.h"
53 #endif
54 #ifdef CONFIG_TUNER
55 #include "radio.h"
56 #endif
57 #ifdef HAVE_MMC
58 #include "ata_mmc.h"
59 #endif
60 #include "logfdisp.h"
61 #if defined(IRIVER_H100_SERIES) && !defined(SIMULATOR)
62 extern bool pcm_rec_screen(void);
63 #endif
64 #if CONFIG_CODEC == SWCODEC
65 #include "pcmbuf.h"
66 #include "pcm_playback.h"
67 #endif
69 /*---------------------------------------------------*/
70 /* SPECIAL DEBUG STUFF */
71 /*---------------------------------------------------*/
72 extern char ata_device;
73 extern int ata_io_address;
74 extern int num_threads;
75 extern const char *thread_name[];
77 #ifdef HAVE_LCD_BITMAP
78 /* Test code!!! */
79 bool dbg_os(void)
81 char buf[32];
82 int button;
83 int i;
84 int usage;
86 lcd_setmargins(0, 0);
87 lcd_setfont(FONT_SYSFIXED);
88 lcd_clear_display();
90 while(1)
92 lcd_puts(0, 0, "Stack usage:");
93 for(i = 0; i < num_threads;i++)
95 usage = thread_stack_usage(i);
96 snprintf(buf, 32, "%s: %d%%", thread_name[i], usage);
97 lcd_puts(0, 1+i, buf);
100 lcd_update();
102 button = button_get_w_tmo(HZ/10);
104 switch(button)
106 case SETTINGS_CANCEL:
107 return false;
110 return false;
112 #else /* !HAVE_LCD_BITMAP */
113 bool dbg_os(void)
115 char buf[32];
116 int button;
117 int usage;
118 int currval = 0;
120 lcd_clear_display();
122 while(1)
124 lcd_puts(0, 0, "Stack usage");
126 usage = thread_stack_usage(currval);
127 snprintf(buf, 32, "%d: %d%% ", currval, usage);
128 lcd_puts(0, 1, buf);
130 button = button_get_w_tmo(HZ/10);
132 switch(button)
134 case SETTINGS_CANCEL:
135 return false;
137 case SETTINGS_DEC:
138 currval--;
139 if(currval < 0)
140 currval = num_threads-1;
141 break;
143 case SETTINGS_INC:
144 currval++;
145 if(currval > num_threads-1)
146 currval = 0;
147 break;
150 return false;
152 #endif /* !HAVE_LCD_BITMAP */
154 #ifdef HAVE_LCD_BITMAP
155 #if CONFIG_CODEC != SWCODEC
156 bool dbg_audio_thread(void)
158 char buf[32];
159 int button;
160 struct audio_debug d;
162 lcd_setmargins(0, 0);
163 lcd_setfont(FONT_SYSFIXED);
165 while(1)
167 button = button_get_w_tmo(HZ/5);
168 switch(button)
170 case SETTINGS_CANCEL:
171 return false;
174 audio_get_debugdata(&d);
176 lcd_clear_display();
178 snprintf(buf, sizeof(buf), "read: %x", d.audiobuf_read);
179 lcd_puts(0, 0, buf);
180 snprintf(buf, sizeof(buf), "write: %x", d.audiobuf_write);
181 lcd_puts(0, 1, buf);
182 snprintf(buf, sizeof(buf), "swap: %x", d.audiobuf_swapwrite);
183 lcd_puts(0, 2, buf);
184 snprintf(buf, sizeof(buf), "playing: %d", d.playing);
185 lcd_puts(0, 3, buf);
186 snprintf(buf, sizeof(buf), "playable: %x", d.playable_space);
187 lcd_puts(0, 4, buf);
188 snprintf(buf, sizeof(buf), "unswapped: %x", d.unswapped_space);
189 lcd_puts(0, 5, buf);
191 /* Playable space left */
192 scrollbar(0, 6*8, 112, 4, d.audiobuflen, 0,
193 d.playable_space, HORIZONTAL);
195 /* Show the watermark limit */
196 scrollbar(0, 6*8+4, 112, 4, d.audiobuflen, 0,
197 d.low_watermark_level, HORIZONTAL);
199 snprintf(buf, sizeof(buf), "wm: %x - %x",
200 d.low_watermark_level, d.lowest_watermark_level);
201 lcd_puts(0, 7, buf);
203 lcd_update();
205 return false;
207 #else /* CONFIG_CODEC == SWCODEC */
208 extern size_t audiobuffer_free;
209 extern int filebuflen;
210 extern int filebufused;
211 extern int track_count;
213 static int ticks, boost_ticks;
215 void dbg_audio_task(void)
217 if(FREQ > CPUFREQ_NORMAL)
218 boost_ticks++;
220 ticks++;
223 bool dbg_audio_thread(void)
225 char buf[32];
226 int button;
227 int line;
228 bool done = false;
229 int bufsize = pcmbuf_get_bufsize();
231 ticks = boost_ticks = 0;
233 tick_add_task(dbg_audio_task);
235 lcd_setmargins(0, 0);
236 lcd_setfont(FONT_SYSFIXED);
238 while(!done)
240 button = button_get_w_tmo(HZ/5);
241 switch(button)
243 case SETTINGS_CANCEL:
244 done = true;
245 break;
248 line = 0;
250 lcd_clear_display();
252 snprintf(buf, sizeof(buf), "pcm: %d/%d",
253 bufsize-(int)audiobuffer_free, bufsize);
254 lcd_puts(0, line++, buf);
256 /* Playable space left */
257 scrollbar(0, line*8, LCD_WIDTH, 6, bufsize, 0,
258 bufsize-audiobuffer_free, HORIZONTAL);
259 line++;
261 snprintf(buf, sizeof(buf), "codec: %d/%d", filebufused, filebuflen);
262 lcd_puts(0, line++, buf);
264 /* Playable space left */
265 scrollbar(0, line*8, LCD_WIDTH, 6, filebuflen, 0,
266 filebufused, HORIZONTAL);
267 line++;
269 snprintf(buf, sizeof(buf), "track count: %d", track_count);
270 lcd_puts(0, line++, buf);
272 snprintf(buf, sizeof(buf), "cpu freq: %dMHz",
273 (int)((FREQ + 500000) / 1000000));
274 lcd_puts(0, line++, buf);
276 snprintf(buf, sizeof(buf), "boost ratio: %d%%",
277 boost_ticks * 100 / ticks);
278 lcd_puts(0, line++, buf);
280 lcd_update();
283 tick_remove_task(dbg_audio_task);
285 return false;
287 #endif /* CONFIG_CODEC */
288 #endif /* HAVE_LCD_BITMAP */
290 /* Tool function to calculate a CRC16 across some buffer */
291 unsigned short crc_16(const unsigned char* buf, unsigned len)
293 /* CCITT standard polynomial 0x1021 */
294 static const unsigned short crc16_lookup[16] =
295 { /* lookup table for 4 bits at a time is affordable */
296 0x0000, 0x1021, 0x2042, 0x3063,
297 0x4084, 0x50A5, 0x60C6, 0x70E7,
298 0x8108, 0x9129, 0xA14A, 0xB16B,
299 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF
301 unsigned short crc16 = 0xFFFF; /* initialise to 0xFFFF (CCITT specification) */
302 unsigned t;
303 unsigned char byte;
305 while (len--)
307 byte = *buf++; /* get one byte of data */
309 /* upper nibble of our data */
310 t = crc16 >> 12; /* extract the 4 most significant bits */
311 t ^= byte >> 4; /* XOR in 4 bits of the data into the extracted bits */
312 crc16 <<= 4; /* shift the CRC Register left 4 bits */
313 crc16 ^= crc16_lookup[t]; /* do the table lookup and XOR the result */
315 /* lower nibble of our data */
316 t = crc16 >> 12; /* extract the 4 most significant bits */
317 t ^= byte & 0x0F; /* XOR in 4 bits of the data into the extracted bits */
318 crc16 <<= 4; /* shift the CRC Register left 4 bits */
319 crc16 ^= crc16_lookup[t]; /* do the table lookup and XOR the result */
322 return crc16;
326 #if CONFIG_CPU == TCC730
327 static unsigned flash_word_temp __attribute__ ((section (".idata")));
329 static void flash_write_word(unsigned addr, unsigned value) __attribute__ ((section(".icode")));
330 static void flash_write_word(unsigned addr, unsigned value) {
331 flash_word_temp = value;
333 long extAddr = (long)addr << 1;
334 ddma_transfer(1, 1, &flash_word_temp, extAddr, 2);
337 static unsigned flash_read_word(unsigned addr) __attribute__ ((section(".icode")));
338 static unsigned flash_read_word(unsigned addr) {
339 long extAddr = (long)addr << 1;
340 ddma_transfer(1, 1, &flash_word_temp, extAddr, 2);
341 return flash_word_temp;
344 #endif
346 /* Tool function to read the flash manufacturer and type, if available.
347 Only chips which could be reprogrammed in system will return values.
348 (The mode switch addresses vary between flash manufacturers, hence addr1/2) */
349 /* In IRAM to avoid problems when running directly from Flash */
350 bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
351 unsigned addr1, unsigned addr2)
352 __attribute__ ((section (".icode")));
353 bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
354 unsigned addr1, unsigned addr2)
357 unsigned not_manu, not_id; /* read values before switching to ID mode */
358 unsigned manu, id; /* read values when in ID mode */
359 #if CONFIG_CPU == TCC730
360 #define FLASH(addr) (flash_read_word(addr))
361 #define SET_FLASH(addr, val) (flash_write_word((addr), (val)))
363 #else /* memory mapped */
364 #if CONFIG_CPU == SH7034
365 volatile unsigned char* flash = (unsigned char*)0x2000000; /* flash mapping */
366 #elif CONFIG_CPU == MCF5249
367 volatile unsigned short* flash = (unsigned short*)0; /* flash mapping */
368 #endif
369 #define FLASH(addr) (flash[addr])
370 #define SET_FLASH(addr, val) (flash[addr] = val)
371 #endif
372 int old_level; /* saved interrupt level */
374 not_manu = FLASH(0); /* read the normal content */
375 not_id = FLASH(1); /* should be 'A' (0x41) and 'R' (0x52) from the "ARCH" marker */
377 /* disable interrupts, prevent any stray flash access */
378 old_level = set_irq_level(HIGHEST_IRQ_LEVEL);
380 SET_FLASH(addr1, 0xAA); /* enter command mode */
381 SET_FLASH(addr2, 0x55);
382 SET_FLASH(addr1, 0x90); /* ID command */
383 /* Atmel wants 20ms pause here */
384 /* sleep(HZ/50); no sleeping possible while interrupts are disabled */
386 manu = FLASH(0); /* read the IDs */
387 id = FLASH(1);
389 SET_FLASH(0, 0xF0); /* reset flash (back to normal read mode) */
390 /* Atmel wants 20ms pause here */
391 /* sleep(HZ/50); no sleeping possible while interrupts are disabled */
393 set_irq_level(old_level); /* enable interrupts again */
395 /* I assume success if the obtained values are different from
396 the normal flash content. This is not perfectly bulletproof, they
397 could theoretically be the same by chance, causing us to fail. */
398 if (not_manu != manu || not_id != id) /* a value has changed */
400 *p_manufacturer = manu; /* return the results */
401 *p_device = id;
402 return true; /* success */
404 return false; /* fail */
408 #ifdef HAVE_LCD_BITMAP
409 bool dbg_hw_info(void)
411 #if CONFIG_CPU == SH7034
412 char buf[32];
413 int button;
414 int usb_polarity;
415 int pr_polarity;
416 int bitmask = *(unsigned short*)0x20000fc;
417 int rom_version = *(unsigned short*)0x20000fe;
418 unsigned manu, id; /* flash IDs */
419 bool got_id; /* flag if we managed to get the flash IDs */
420 unsigned rom_crc = 0xFFFF; /* CRC16 of the boot ROM */
421 bool has_bootrom; /* flag for boot ROM present */
422 int oldmode; /* saved memory guard mode */
424 #ifdef USB_ENABLE_ONDIOSTYLE
425 if(PADRL & 0x20)
426 #else
427 if(PADRH & 0x04)
428 #endif
429 usb_polarity = 0; /* Negative */
430 else
431 usb_polarity = 1; /* Positive */
433 if(PADRH & 0x08)
434 pr_polarity = 0; /* Negative */
435 else
436 pr_polarity = 1; /* Positive */
438 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
440 /* get flash ROM type */
441 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
442 if (!got_id)
443 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
445 /* check if the boot ROM area is a flash mirror */
446 has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0);
447 if (has_bootrom) /* if ROM and Flash different */
449 /* calculate CRC16 checksum of boot ROM */
450 rom_crc = crc_16((unsigned char*)0x0000, 64*1024);
453 system_memory_guard(oldmode); /* re-enable memory guard */
455 lcd_setmargins(0, 0);
456 lcd_setfont(FONT_SYSFIXED);
457 lcd_clear_display();
459 lcd_puts(0, 0, "[Hardware info]");
461 snprintf(buf, 32, "ROM: %d.%02d", rom_version/100, rom_version%100);
462 lcd_puts(0, 1, buf);
464 snprintf(buf, 32, "Mask: 0x%04x", bitmask);
465 lcd_puts(0, 2, buf);
467 snprintf(buf, 32, "USB: %s", usb_polarity?"positive":"negative");
468 lcd_puts(0, 3, buf);
470 snprintf(buf, 32, "PR: %s", pr_polarity?"positive":"negative");
471 lcd_puts(0, 4, buf);
473 if (got_id)
474 snprintf(buf, 32, "Flash: M=%02x D=%02x", manu, id);
475 else
476 snprintf(buf, 32, "Flash: M=?? D=??"); /* unknown, sorry */
477 lcd_puts(0, 5, buf);
479 if (has_bootrom)
481 snprintf(buf, 32-3, "ROM CRC: 0x%04x", rom_crc);
482 if (rom_crc == 0x222F) /* known Version 1 */
483 strcat(buf, " V1");
485 else
487 snprintf(buf, 32, "Boot ROM: none");
489 lcd_puts(0, 6, buf);
491 #ifndef HAVE_MMC /* have ATA */
492 snprintf(buf, 32, "ATA: 0x%x,%s", ata_io_address,
493 ata_device ? "slave":"master");
494 lcd_puts(0, 7, buf);
495 #endif
496 lcd_update();
498 while(1)
500 button = button_get(true);
501 if(button == SETTINGS_CANCEL)
502 return false;
504 #elif CONFIG_CPU == MCF5249
505 char buf[32];
506 int button;
507 unsigned manu, id; /* flash IDs */
508 bool got_id; /* flag if we managed to get the flash IDs */
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 system_memory_guard(oldmode); /* re-enable memory guard */
520 lcd_setmargins(0, 0);
521 lcd_setfont(FONT_SYSFIXED);
522 lcd_clear_display();
524 lcd_puts(0, 0, "[Hardware info]");
526 if (got_id)
527 snprintf(buf, 32, "Flash: M=%04x D=%04x", manu, id);
528 else
529 snprintf(buf, 32, "Flash: M=???? D=????"); /* unknown, sorry */
530 lcd_puts(0, 1, buf);
532 lcd_update();
534 while(1)
536 button = button_get(true);
537 if(button == SETTINGS_CANCEL)
538 return false;
540 #endif /* CONFIG_CPU */
541 return false;
543 #else /* !HAVE_LCD_BITMAP */
544 bool dbg_hw_info(void)
546 char buf[32];
547 int button;
548 int currval = 0;
549 int usb_polarity;
550 int bitmask = *(unsigned short*)0x20000fc;
551 int rom_version = *(unsigned short*)0x20000fe;
552 unsigned manu, id; /* flash IDs */
553 bool got_id; /* flag if we managed to get the flash IDs */
554 unsigned rom_crc = 0xFFFF; /* CRC16 of the boot ROM */
555 bool has_bootrom; /* flag for boot ROM present */
556 int oldmode; /* saved memory guard mode */
558 if(PADRH & 0x04)
559 usb_polarity = 0; /* Negative */
560 else
561 usb_polarity = 1; /* Positive */
563 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
565 /* get flash ROM type */
566 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
567 if (!got_id)
568 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
570 /* check if the boot ROM area is a flash mirror */
571 has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0);
572 if (has_bootrom) /* if ROM and Flash different */
574 /* calculate CRC16 checksum of boot ROM */
575 rom_crc = crc_16((unsigned char*)0x0000, 64*1024);
578 system_memory_guard(oldmode); /* re-enable memory guard */
580 lcd_clear_display();
582 lcd_puts(0, 0, "[HW Info]");
583 while(1)
585 switch(currval)
587 case 0:
588 snprintf(buf, 32, "ROM: %d.%02d",
589 rom_version/100, rom_version%100);
590 break;
591 case 1:
592 snprintf(buf, 32, "USB: %s",
593 usb_polarity?"pos":"neg");
594 break;
595 case 2:
596 snprintf(buf, 32, "ATA: 0x%x%s",
597 ata_io_address, ata_device ? "s":"m");
598 break;
599 case 3:
600 snprintf(buf, 32, "Mask: %04x", bitmask);
601 break;
602 case 4:
603 if (got_id)
604 snprintf(buf, 32, "Flash:%02x,%02x", manu, id);
605 else
606 snprintf(buf, 32, "Flash:??,??"); /* unknown, sorry */
607 break;
608 case 5:
609 if (has_bootrom)
610 snprintf(buf, 32, "RomCRC:%04x", rom_crc);
611 else
612 snprintf(buf, 32, "BootROM: no");
615 lcd_puts(0, 1, buf);
616 lcd_update();
618 button = button_get(true);
620 switch(button)
622 case SETTINGS_CANCEL:
623 return false;
625 case SETTINGS_DEC:
626 currval--;
627 if(currval < 0)
628 currval = 5;
629 break;
631 case SETTINGS_INC:
632 currval++;
633 if(currval > 5)
634 currval = 0;
635 break;
638 return false;
640 #endif /* !HAVE_LCD_BITMAP */
642 bool dbg_partitions(void)
644 int partition=0;
646 lcd_clear_display();
647 lcd_puts(0, 0, "Partition");
648 lcd_puts(0, 1, "list");
649 lcd_update();
650 sleep(HZ/2);
652 while(1)
654 char buf[32];
655 int button;
656 struct partinfo* p = disk_partinfo(partition);
658 lcd_clear_display();
659 snprintf(buf, sizeof buf, "P%d: S:%lx", partition, p->start);
660 lcd_puts(0, 0, buf);
661 snprintf(buf, sizeof buf, "T:%x %ld MB", p->type, p->size / 2048);
662 lcd_puts(0, 1, buf);
663 lcd_update();
665 button = button_get(true);
667 switch(button)
669 case SETTINGS_OK:
670 case SETTINGS_CANCEL:
671 return false;
673 case SETTINGS_DEC:
674 partition--;
675 if (partition < 0)
676 partition = 3;
677 break;
679 case SETTINGS_INC:
680 partition++;
681 if (partition > 3)
682 partition = 0;
683 break;
685 default:
686 if(default_event_handler(button) == SYS_USB_CONNECTED)
687 return true;
688 break;
691 return false;
694 #ifdef CPU_COLDFIRE
695 bool dbg_spdif(void)
697 char buf[128];
698 int button;
699 int line;
700 unsigned int control;
701 int x;
702 char *s;
703 int category;
704 int generation;
705 unsigned int interruptstat;
706 bool valnogood, symbolerr, parityerr;
708 lcd_setmargins(0, 0);
709 lcd_clear_display();
710 lcd_setfont(FONT_SYSFIXED);
712 while(1)
714 line = 0;
716 control = EBU1RCVCCHANNEL1;
717 interruptstat = INTERRUPTSTAT;
718 INTERRUPTCLEAR = 0x03c00000;
720 valnogood = (interruptstat & 0x01000000)?true:false;
721 symbolerr = (interruptstat & 0x00800000)?true:false;
722 parityerr = (interruptstat & 0x00400000)?true:false;
724 snprintf(buf, sizeof(buf), "Val: %s Sym: %s Par: %s",
725 valnogood?"--":"OK",
726 symbolerr?"--":"OK",
727 parityerr?"--":"OK");
728 lcd_puts(0, line++, buf);
730 snprintf(buf, sizeof(buf), "Status word: %08x", (int)control);
731 lcd_puts(0, line++, buf);
733 line++;
735 x = control >> 31;
736 snprintf(buf, sizeof(buf), "PRO: %d (%s)",
737 x, x?"Professional":"Consumer");
738 lcd_puts(0, line++, buf);
740 x = (control >> 30) & 1;
741 snprintf(buf, sizeof(buf), "Audio: %d (%s)",
742 x, x?"Non-PCM":"PCM");
743 lcd_puts(0, line++, buf);
745 x = (control >> 29) & 1;
746 snprintf(buf, sizeof(buf), "Copy: %d (%s)",
747 x, x?"Permitted":"Inhibited");
748 lcd_puts(0, line++, buf);
750 x = (control >> 27) & 7;
751 switch(x)
753 case 0:
754 s = "None";
755 break;
756 case 1:
757 s = "50/15us";
758 break;
759 default:
760 s = "Reserved";
761 break;
763 snprintf(buf, sizeof(buf), "Preemphasis: %d (%s)", x, s);
764 lcd_puts(0, line++, buf);
766 x = (control >> 24) & 3;
767 snprintf(buf, sizeof(buf), "Mode: %d", x);
768 lcd_puts(0, line++, buf);
770 category = (control >> 17) & 127;
771 switch(category)
773 case 0x00:
774 s = "General";
775 break;
776 case 0x40:
777 s = "Audio CD";
778 break;
779 default:
780 s = "Unknown";
782 snprintf(buf, sizeof(buf), "Category: 0x%02x (%s)", category, s);
783 lcd_puts(0, line++, buf);
785 x = (control >> 16) & 1;
786 generation = x;
787 if(((category & 0x70) == 0x10) ||
788 ((category & 0x70) == 0x40) ||
789 ((category & 0x78) == 0x38))
791 generation = !generation;
793 snprintf(buf, sizeof(buf), "Generation: %d (%s)",
794 x, generation?"Original":"No ind.");
795 lcd_puts(0, line++, buf);
797 x = (control >> 12) & 15;
798 snprintf(buf, sizeof(buf), "Source: %d", x);
799 lcd_puts(0, line++, buf);
801 x = (control >> 8) & 15;
802 switch(x)
804 case 0:
805 s = "Unspecified";
806 break;
807 case 8:
808 s = "A (Left)";
809 break;
810 case 4:
811 s = "B (Right)";
812 break;
813 default:
814 s = "";
815 break;
817 snprintf(buf, sizeof(buf), "Channel: %d (%s)", x, s);
818 lcd_puts(0, line++, buf);
820 x = (control >> 4) & 15;
821 switch(x)
823 case 0:
824 s = "44.1kHz";
825 break;
826 case 0x4:
827 s = "48kHz";
828 break;
829 case 0xc:
830 s = "32kHz";
831 break;
833 snprintf(buf, sizeof(buf), "Frequency: %d (%s)", x, s);
834 lcd_puts(0, line++, buf);
836 x = (control >> 2) & 3;
837 snprintf(buf, sizeof(buf), "Clock accuracy: %d", x);
838 lcd_puts(0, line++, buf);
840 lcd_update();
841 button = button_get_w_tmo(HZ/10);
843 switch(button)
845 case SETTINGS_CANCEL:
846 case SETTINGS_OK2:
847 return false;
851 return false;
853 #endif /* CPU_COLDFIRE */
855 #ifdef HAVE_LCD_BITMAP
856 /* Test code!!! */
857 bool dbg_ports(void)
859 #if CONFIG_CPU == SH7034
860 unsigned short porta;
861 unsigned short portb;
862 unsigned char portc;
863 char buf[32];
864 int button;
865 int battery_voltage;
866 int batt_int, batt_frac;
868 lcd_setfont(FONT_SYSFIXED);
869 lcd_setmargins(0, 0);
870 lcd_clear_display();
872 while(1)
874 porta = PADR;
875 portb = PBDR;
876 portc = PCDR;
878 snprintf(buf, 32, "PADR: %04x", porta);
879 lcd_puts(0, 0, buf);
880 snprintf(buf, 32, "PBDR: %04x", portb);
881 lcd_puts(0, 1, buf);
883 snprintf(buf, 32, "AN0: %03x AN4: %03x", adc_read(0), adc_read(4));
884 lcd_puts(0, 2, buf);
885 snprintf(buf, 32, "AN1: %03x AN5: %03x", adc_read(1), adc_read(5));
886 lcd_puts(0, 3, buf);
887 snprintf(buf, 32, "AN2: %03x AN6: %03x", adc_read(2), adc_read(6));
888 lcd_puts(0, 4, buf);
889 snprintf(buf, 32, "AN3: %03x AN7: %03x", adc_read(3), adc_read(7));
890 lcd_puts(0, 5, buf);
892 battery_voltage = (adc_read(ADC_UNREG_POWER) * BATTERY_SCALE_FACTOR) / 10000;
893 batt_int = battery_voltage / 100;
894 batt_frac = battery_voltage % 100;
896 snprintf(buf, 32, "Batt: %d.%02dV %d%% ", batt_int, batt_frac,
897 battery_level());
898 lcd_puts(0, 6, buf);
899 #ifndef HAVE_MMC /* have ATA */
900 snprintf(buf, 32, "ATA: %s, 0x%x",
901 ata_device?"slave":"master", ata_io_address);
902 lcd_puts(0, 7, buf);
903 #endif
904 lcd_update();
905 button = button_get_w_tmo(HZ/10);
907 switch(button)
909 case SETTINGS_CANCEL:
910 return false;
913 #elif defined(CPU_COLDFIRE)
914 unsigned int gpio_out;
915 unsigned int gpio1_out;
916 unsigned int gpio_read;
917 unsigned int gpio1_read;
918 unsigned int gpio_function;
919 unsigned int gpio1_function;
920 unsigned int gpio_enable;
921 unsigned int gpio1_enable;
922 int adc_buttons, adc_remote, adc_battery;
923 char buf[128];
924 int button;
925 int line;
926 int battery_voltage;
927 int batt_int, batt_frac;
929 lcd_setmargins(0, 0);
930 lcd_clear_display();
931 lcd_setfont(FONT_SYSFIXED);
933 while(1)
935 line = 0;
936 gpio_read = GPIO_READ;
937 gpio1_read = GPIO1_READ;
938 gpio_out = GPIO_OUT;
939 gpio1_out = GPIO1_OUT;
940 gpio_function = GPIO_FUNCTION;
941 gpio1_function = GPIO1_FUNCTION;
942 gpio_enable = GPIO_ENABLE;
943 gpio1_enable = GPIO1_ENABLE;
945 snprintf(buf, sizeof(buf), "GPIO_READ: %08x", gpio_read);
946 lcd_puts(0, line++, buf);
947 snprintf(buf, sizeof(buf), "GPIO_OUT: %08x", gpio_out);
948 lcd_puts(0, line++, buf);
949 snprintf(buf, sizeof(buf), "GPIO_FUNCTION: %08x", gpio_function);
950 lcd_puts(0, line++, buf);
951 snprintf(buf, sizeof(buf), "GPIO_ENABLE: %08x", gpio_enable);
952 lcd_puts(0, line++, buf);
954 snprintf(buf, sizeof(buf), "GPIO1_READ: %08x", gpio1_read);
955 lcd_puts(0, line++, buf);
956 snprintf(buf, sizeof(buf), "GPIO1_OUT: %08x", gpio1_out);
957 lcd_puts(0, line++, buf);
958 snprintf(buf, sizeof(buf), "GPIO1_FUNCTION: %08x", gpio1_function);
959 lcd_puts(0, line++, buf);
960 snprintf(buf, sizeof(buf), "GPIO1_ENABLE: %08x", gpio1_enable);
961 lcd_puts(0, line++, buf);
963 adc_buttons = adc_read(ADC_BUTTONS);
964 adc_remote = adc_read(ADC_REMOTE);
965 adc_battery = adc_read(ADC_BATTERY);
967 snprintf(buf, sizeof(buf), "ADC_BUTTONS: %02x", adc_buttons);
968 lcd_puts(0, line++, buf);
969 snprintf(buf, sizeof(buf), "ADC_REMOTE: %02x", adc_remote);
970 lcd_puts(0, line++, buf);
971 snprintf(buf, sizeof(buf), "ADC_BATTERY: %02x", adc_battery);
972 lcd_puts(0, line++, buf);
974 battery_voltage = (adc_battery * BATTERY_SCALE_FACTOR) / 10000;
975 batt_int = battery_voltage / 100;
976 batt_frac = battery_voltage % 100;
978 snprintf(buf, 32, "Batt: %d.%02dV %d%% ", batt_int, batt_frac,
979 battery_level());
980 lcd_puts(0, line++, buf);
982 lcd_update();
983 button = button_get_w_tmo(HZ/10);
985 switch(button)
987 case SETTINGS_CANCEL:
988 return false;
992 #endif /* CPU */
993 return false;
995 #else /* !HAVE_LCD_BITMAP */
996 bool dbg_ports(void)
998 unsigned short porta;
999 unsigned short portb;
1000 unsigned char portc;
1001 char buf[32];
1002 int button;
1003 int battery_voltage;
1004 int batt_int, batt_frac;
1005 int currval = 0;
1007 lcd_clear_display();
1009 while(1)
1011 porta = PADR;
1012 portb = PBDR;
1013 portc = PCDR;
1015 switch(currval)
1017 case 0:
1018 snprintf(buf, 32, "PADR: %04x ", porta);
1019 break;
1020 case 1:
1021 snprintf(buf, 32, "PBDR: %04x ", portb);
1022 break;
1023 case 2:
1024 snprintf(buf, 32, "AN0: %03x ", adc_read(0));
1025 break;
1026 case 3:
1027 snprintf(buf, 32, "AN1: %03x ", adc_read(1));
1028 break;
1029 case 4:
1030 snprintf(buf, 32, "AN2: %03x ", adc_read(2));
1031 break;
1032 case 5:
1033 snprintf(buf, 32, "AN3: %03x ", adc_read(3));
1034 break;
1035 case 6:
1036 snprintf(buf, 32, "AN4: %03x ", adc_read(4));
1037 break;
1038 case 7:
1039 snprintf(buf, 32, "AN5: %03x ", adc_read(5));
1040 break;
1041 case 8:
1042 snprintf(buf, 32, "AN6: %03x ", adc_read(6));
1043 break;
1044 case 9:
1045 snprintf(buf, 32, "AN7: %03x ", adc_read(7));
1046 break;
1047 case 10:
1048 snprintf(buf, 32, "%s, 0x%x ",
1049 ata_device?"slv":"mst", ata_io_address);
1050 break;
1052 lcd_puts(0, 0, buf);
1054 battery_voltage = (adc_read(ADC_UNREG_POWER) *
1055 BATTERY_SCALE_FACTOR) / 10000;
1056 batt_int = battery_voltage / 100;
1057 batt_frac = battery_voltage % 100;
1059 snprintf(buf, 32, "Batt: %d.%02dV", batt_int, batt_frac);
1060 lcd_puts(0, 1, buf);
1062 button = button_get_w_tmo(HZ/5);
1064 switch(button)
1066 case SETTINGS_CANCEL:
1067 return false;
1069 case SETTINGS_DEC:
1070 currval--;
1071 if(currval < 0)
1072 currval = 10;
1073 break;
1075 case SETTINGS_INC:
1076 currval++;
1077 if(currval > 10)
1078 currval = 0;
1079 break;
1082 return false;
1084 #endif /* !HAVE_LCD_BITMAP */
1086 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
1087 extern int boost_counter;
1088 bool dbg_cpufreq(void)
1090 char buf[128];
1091 int line;
1092 int button;
1094 #ifdef HAVE_LCD_BITMAP
1095 lcd_setmargins(0, 0);
1096 lcd_setfont(FONT_SYSFIXED);
1097 #endif
1098 lcd_clear_display();
1100 while(1)
1102 line = 0;
1104 snprintf(buf, sizeof(buf), "Frequency: %ld", FREQ);
1105 lcd_puts(0, line++, buf);
1107 snprintf(buf, sizeof(buf), "boost_counter: %d", boost_counter);
1108 lcd_puts(0, line++, buf);
1110 lcd_update();
1111 button = button_get_w_tmo(HZ/10);
1113 switch(button)
1115 case BUTTON_UP:
1116 cpu_boost(true);
1117 break;
1119 case BUTTON_DOWN:
1120 cpu_boost(false);
1121 break;
1123 #if (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
1124 (CONFIG_KEYPAD == IRIVER_H300_PAD)
1125 case BUTTON_SELECT:
1126 #else
1127 case BUTTON_PLAY:
1128 #endif
1129 set_cpu_frequency(CPUFREQ_DEFAULT);
1130 boost_counter = 0;
1131 break;
1133 case SETTINGS_CANCEL:
1134 case SETTINGS_OK2:
1135 return false;
1139 return false;
1141 #endif /* HAVE_ADJUSTABLE_CPU_FREQ */
1143 #ifdef HAVE_LCD_BITMAP
1145 * view_battery() shows a automatically scaled graph of the battery voltage
1146 * over time. Usable for estimating battery life / charging rate.
1147 * The power_history array is updated in power_thread of powermgmt.c.
1150 #define BAT_LAST_VAL MIN(LCD_WIDTH, POWER_HISTORY_LEN)
1151 #define BAT_YSPACE (LCD_HEIGHT - 20)
1153 bool view_battery(void)
1155 int view = 0;
1156 int i, x, y;
1157 unsigned short maxv, minv;
1158 char buf[32];
1160 lcd_setmargins(0, 0);
1161 lcd_setfont(FONT_SYSFIXED);
1163 while(1)
1165 switch (view) {
1166 case 0: /* voltage history graph */
1167 /* Find maximum and minimum voltage for scaling */
1168 maxv = 0;
1169 minv = 65535;
1170 for (i = 0; i < BAT_LAST_VAL; i++) {
1171 if (power_history[i] > maxv)
1172 maxv = power_history[i];
1173 if (power_history[i] && (power_history[i] < minv))
1175 minv = power_history[i];
1179 if ((minv < 1) || (minv >= 65535))
1180 minv = 1;
1181 if (maxv < 2)
1182 maxv = 2;
1184 lcd_clear_display();
1185 snprintf(buf, 30, "Battery %d.%02d", power_history[0] / 100,
1186 power_history[0] % 100);
1187 lcd_puts(0, 0, buf);
1188 snprintf(buf, 30, "scale %d.%02d-%d.%02d V",
1189 minv / 100, minv % 100, maxv / 100, maxv % 100);
1190 lcd_puts(0, 1, buf);
1192 x = 0;
1193 for (i = BAT_LAST_VAL - 1; i >= 0; i--) {
1194 y = (power_history[i] - minv) * BAT_YSPACE / (maxv - minv);
1195 lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
1196 lcd_vline(x, LCD_HEIGHT-1, 20);
1197 lcd_set_drawmode(DRMODE_SOLID);
1198 lcd_vline(x, LCD_HEIGHT-1,
1199 MIN(MAX(LCD_HEIGHT-1 - y, 20), LCD_HEIGHT-1));
1200 x++;
1203 break;
1205 case 1: /* status: */
1206 lcd_clear_display();
1207 lcd_puts(0, 0, "Power status:");
1209 y = (adc_read(ADC_UNREG_POWER) * BATTERY_SCALE_FACTOR) / 10000;
1210 snprintf(buf, 30, "Battery: %d.%02d V", y / 100, y % 100);
1211 lcd_puts(0, 1, buf);
1212 #ifdef ADC_EXT_POWER
1213 y = (adc_read(ADC_EXT_POWER) * EXT_SCALE_FACTOR) / 10000;
1214 snprintf(buf, 30, "External: %d.%02d V", y / 100, y % 100);
1215 lcd_puts(0, 2, buf);
1216 #endif
1217 #ifdef HAVE_CHARGING
1218 snprintf(buf, 30, "Charger: %s",
1219 charger_inserted() ? "present" : "absent");
1220 lcd_puts(0, 3, buf);
1221 #endif
1222 #ifdef HAVE_CHARGE_CTRL
1223 snprintf(buf, 30, "Chgr: %s %s",
1224 charger_inserted() ? "present" : "absent",
1225 charger_enabled ? "on" : "off");
1226 lcd_puts(0, 3, buf);
1227 snprintf(buf, 30, "short delta: %d", short_delta);
1228 lcd_puts(0, 5, buf);
1229 snprintf(buf, 30, "long delta: %d", long_delta);
1230 lcd_puts(0, 6, buf);
1231 lcd_puts(0, 7, power_message);
1232 #endif /* HAVE_CHARGE_CTRL */
1233 break;
1235 case 2: /* voltage deltas: */
1236 lcd_clear_display();
1237 lcd_puts(0, 0, "Voltage deltas:");
1239 for (i = 0; i <= 6; i++) {
1240 y = power_history[i] - power_history[i+i];
1241 snprintf(buf, 30, "-%d min: %s%d.%02d V", i,
1242 (y < 0) ? "-" : "", ((y < 0) ? y * -1 : y) / 100,
1243 ((y < 0) ? y * -1 : y ) % 100);
1244 lcd_puts(0, i+1, buf);
1246 break;
1248 case 3: /* remaining time estimation: */
1249 lcd_clear_display();
1251 #ifdef HAVE_CHARGE_CTRL
1252 snprintf(buf, 30, "charge_state: %d", charge_state);
1253 lcd_puts(0, 0, buf);
1255 snprintf(buf, 30, "Cycle time: %d m", powermgmt_last_cycle_startstop_min);
1256 lcd_puts(0, 1, buf);
1258 snprintf(buf, 30, "Lvl@cyc st: %d%%", powermgmt_last_cycle_level);
1259 lcd_puts(0, 2, buf);
1261 snprintf(buf, 30, "P=%2d I=%2d", pid_p, pid_i);
1262 lcd_puts(0, 3, buf);
1264 snprintf(buf, 30, "Trickle sec: %d/60", trickle_sec);
1265 lcd_puts(0, 4, buf);
1266 #endif /* HAVE_CHARGE_CTRL */
1268 snprintf(buf, 30, "Last PwrHist: %d.%02d V",
1269 power_history[0] / 100,
1270 power_history[0] % 100);
1271 lcd_puts(0, 5, buf);
1273 snprintf(buf, 30, "battery level: %d%%", battery_level());
1274 lcd_puts(0, 6, buf);
1276 snprintf(buf, 30, "Est. remain: %d m", battery_time());
1277 lcd_puts(0, 7, buf);
1278 break;
1281 lcd_update();
1283 switch(button_get_w_tmo(HZ/2))
1285 case SETTINGS_DEC:
1286 if (view)
1287 view--;
1288 break;
1290 case SETTINGS_INC:
1291 if (view < 3)
1292 view++;
1293 break;
1295 case SETTINGS_OK:
1296 case SETTINGS_CANCEL:
1297 return false;
1300 return false;
1303 #endif /* HAVE_LCD_BITMAP */
1305 static bool view_runtime(void)
1307 char s[32];
1308 bool done = false;
1309 int state = 1;
1311 while(!done)
1313 int y=0;
1314 int t;
1315 int key;
1316 lcd_clear_display();
1317 #ifdef HAVE_LCD_BITMAP
1318 lcd_puts(0, y++, "Running time:");
1319 y++;
1320 #endif
1322 if (state & 1) {
1323 if (charger_inserted())
1325 global_settings.runtime = 0;
1327 else
1329 global_settings.runtime += ((current_tick - lasttime) / HZ);
1331 lasttime = current_tick;
1333 t = global_settings.runtime;
1334 lcd_puts(0, y++, "Current time");
1336 else {
1337 t = global_settings.topruntime;
1338 lcd_puts(0, y++, "Top time");
1341 snprintf(s, sizeof(s), "%dh %dm %ds",
1342 t / 3600, (t % 3600) / 60, t % 60);
1343 lcd_puts(0, y++, s);
1344 lcd_update();
1346 /* Wait for a key to be pushed */
1347 key = button_get_w_tmo(HZ);
1348 switch(key) {
1349 case SETTINGS_CANCEL:
1350 done = true;
1351 break;
1353 case SETTINGS_INC:
1354 case SETTINGS_DEC:
1355 if (state == 1)
1356 state = 2;
1357 else
1358 state = 1;
1359 break;
1361 case SETTINGS_OK:
1362 lcd_clear_display();
1363 lcd_puts(0,0,"Clear time?");
1364 lcd_puts(0,1,"PLAY = Yes");
1365 lcd_update();
1366 while (1) {
1367 key = button_get(true);
1368 if ( key == SETTINGS_OK ) {
1369 if ( state == 1 )
1370 global_settings.runtime = 0;
1371 else
1372 global_settings.topruntime = 0;
1373 break;
1375 if (!(key & BUTTON_REL)) /* ignore button releases */
1376 break;
1378 break;
1382 return false;
1385 #ifdef HAVE_MMC
1386 bool dbg_mmc_info(void)
1388 bool done = false;
1389 int currval = 0;
1390 tCardInfo *card;
1391 unsigned char pbuf[32], pbuf2[32];
1392 unsigned char card_name[7];
1394 static const unsigned char i_vmin[] = { 0, 1, 5, 10, 25, 35, 60, 100 };
1395 static const unsigned char i_vmax[] = { 1, 5, 10, 25, 35, 45, 80, 200 };
1396 static const unsigned char *kbit_units[] = { "kBit/s", "MBit/s", "GBit/s" };
1397 static const unsigned char *nsec_units[] = { "ns", "µs", "ms" };
1399 card_name[6] = '\0';
1401 lcd_setmargins(0, 0);
1402 lcd_setfont(FONT_SYSFIXED);
1404 while (!done)
1406 card = mmc_card_info(currval / 2);
1408 lcd_clear_display();
1409 snprintf(pbuf, sizeof(pbuf), "[MMC%d p%d]", currval / 2,
1410 (currval % 2) + 1);
1411 lcd_puts(0, 0, pbuf);
1413 if (card->initialized)
1415 if (!(currval % 2)) /* General info */
1417 strncpy(card_name, ((unsigned char*)card->cid) + 3, 6);
1418 snprintf(pbuf, sizeof(pbuf), "%s Rev %d.%d", card_name,
1419 (int) mmc_extract_bits(card->cid, 72, 4),
1420 (int) mmc_extract_bits(card->cid, 76, 4));
1421 lcd_puts(0, 1, pbuf);
1422 snprintf(pbuf, sizeof(pbuf), "Prod: %d/%d",
1423 (int) mmc_extract_bits(card->cid, 112, 4),
1424 (int) mmc_extract_bits(card->cid, 116, 4) + 1997);
1425 lcd_puts(0, 2, pbuf);
1426 snprintf(pbuf, sizeof(pbuf), "Ser#: 0x%08lx",
1427 mmc_extract_bits(card->cid, 80, 32));
1428 lcd_puts(0, 3, pbuf);
1429 snprintf(pbuf, sizeof(pbuf), "M=%02x, O=%04x",
1430 (int) mmc_extract_bits(card->cid, 0, 8),
1431 (int) mmc_extract_bits(card->cid, 8, 16));
1432 lcd_puts(0, 4, pbuf);
1433 snprintf(pbuf, sizeof(pbuf), "Blocks: 0x%06lx", card->numblocks);
1434 lcd_puts(0, 5, pbuf);
1435 snprintf(pbuf, sizeof(pbuf), "Blksz.: %d", card->blocksize);
1436 lcd_puts(0, 6, pbuf);
1438 else /* Technical details */
1440 output_dyn_value(pbuf2, sizeof pbuf2, card->speed / 1000,
1441 kbit_units, false);
1442 snprintf(pbuf, sizeof pbuf, "Speed: %s", pbuf2);
1443 lcd_puts(0, 1, pbuf);
1445 output_dyn_value(pbuf2, sizeof pbuf2, card->tsac,
1446 nsec_units, false);
1447 snprintf(pbuf, sizeof pbuf, "Tsac: %s", pbuf2);
1448 lcd_puts(0, 2, pbuf);
1450 snprintf(pbuf, sizeof(pbuf), "Nsac: %d clk", card->nsac);
1451 lcd_puts(0, 3, pbuf);
1452 snprintf(pbuf, sizeof(pbuf), "R2W: *%d", card->r2w_factor);
1453 lcd_puts(0, 4, pbuf);
1454 snprintf(pbuf, sizeof(pbuf), "IRmax: %d..%d mA",
1455 i_vmin[mmc_extract_bits(card->csd, 66, 3)],
1456 i_vmax[mmc_extract_bits(card->csd, 69, 3)]);
1457 lcd_puts(0, 5, pbuf);
1458 snprintf(pbuf, sizeof(pbuf), "IWmax: %d..%d mA",
1459 i_vmin[mmc_extract_bits(card->csd, 72, 3)],
1460 i_vmax[mmc_extract_bits(card->csd, 75, 3)]);
1461 lcd_puts(0, 6, pbuf);
1464 else
1465 lcd_puts(0, 1, "Not found!");
1467 lcd_update();
1469 switch (button_get_w_tmo(HZ/2))
1471 case SETTINGS_OK:
1472 case SETTINGS_CANCEL:
1473 done = true;
1474 break;
1476 case SETTINGS_DEC:
1477 currval--;
1478 if (currval < 0)
1479 currval = 3;
1480 break;
1482 case SETTINGS_INC:
1483 currval++;
1484 if (currval > 3)
1485 currval = 0;
1486 break;
1490 return false;
1492 #else /* !HAVE_MMC */
1493 static bool dbg_disk_info(void)
1495 char buf[128];
1496 bool done = false;
1497 int i;
1498 int page = 0;
1499 const int max_page = 11;
1500 unsigned short* identify_info = ata_get_identify();
1501 bool timing_info_present = false;
1502 char pio3[2], pio4[2];
1504 #ifdef HAVE_LCD_BITMAP
1505 lcd_setmargins(0, 0);
1506 #endif
1508 while(!done)
1510 int y=0;
1511 int key;
1512 lcd_clear_display();
1513 #ifdef HAVE_LCD_BITMAP
1514 lcd_puts(0, y++, "Disk info:");
1515 y++;
1516 #endif
1518 switch (page) {
1519 case 0:
1520 for (i=0; i < 20; i++)
1521 ((unsigned short*)buf)[i]=identify_info[i+27];
1522 buf[40]=0;
1523 /* kill trailing space */
1524 for (i=39; i && buf[i]==' '; i--)
1525 buf[i] = 0;
1526 lcd_puts(0, y++, "Model");
1527 lcd_puts_scroll(0, y++, buf);
1528 break;
1530 case 1:
1531 for (i=0; i < 4; i++)
1532 ((unsigned short*)buf)[i]=identify_info[i+23];
1533 buf[8]=0;
1534 lcd_puts(0, y++, "Firmware");
1535 lcd_puts(0, y++, buf);
1536 break;
1538 case 2:
1539 snprintf(buf, sizeof buf, "%ld MB",
1540 ((unsigned long)identify_info[61] << 16 |
1541 (unsigned long)identify_info[60]) / 2048 );
1542 lcd_puts(0, y++, "Size");
1543 lcd_puts(0, y++, buf);
1544 break;
1546 case 3: {
1547 unsigned long free;
1548 fat_size( IF_MV2(0,) NULL, &free );
1549 snprintf(buf, sizeof buf, "%ld MB", free / 1024 );
1550 lcd_puts(0, y++, "Free");
1551 lcd_puts(0, y++, buf);
1552 break;
1555 case 4:
1556 snprintf(buf, sizeof buf, "%d ms", ata_spinup_time * (1000/HZ));
1557 lcd_puts(0, y++, "Spinup time");
1558 lcd_puts(0, y++, buf);
1559 break;
1561 case 5:
1562 i = identify_info[83] & (1<<3);
1563 lcd_puts(0, y++, "Power mgmt:");
1564 lcd_puts(0, y++, i ? "enabled" : "unsupported");
1565 break;
1567 case 6:
1568 i = identify_info[83] & (1<<9);
1569 lcd_puts(0, y++, "Noise mgmt:");
1570 lcd_puts(0, y++, i ? "enabled" : "unsupported");
1571 break;
1573 case 7:
1574 i = identify_info[82] & (1<<6);
1575 lcd_puts(0, y++, "Read-ahead:");
1576 lcd_puts(0, y++, i ? "enabled" : "unsupported");
1577 break;
1579 case 8:
1580 timing_info_present = identify_info[53] & (1<<1);
1581 if(timing_info_present) {
1582 pio3[1] = 0;
1583 pio4[1] = 0;
1584 lcd_puts(0, y++, "PIO modes:");
1585 pio3[0] = (identify_info[64] & (1<<0)) ? '3' : 0;
1586 pio4[0] = (identify_info[64] & (1<<1)) ? '4' : 0;
1587 snprintf(buf, 128, "0 1 2 %s %s", pio3, pio4);
1588 lcd_puts(0, y++, buf);
1589 } else {
1590 lcd_puts(0, y++, "No PIO mode info");
1592 break;
1594 case 9:
1595 timing_info_present = identify_info[53] & (1<<1);
1596 if(timing_info_present) {
1597 lcd_puts(0, y++, "Cycle times");
1598 snprintf(buf, 128, "%dns/%dns",
1599 identify_info[67],
1600 identify_info[68]);
1601 lcd_puts(0, y++, buf);
1602 } else {
1603 lcd_puts(0, y++, "No timing info");
1605 break;
1607 case 10:
1608 timing_info_present = identify_info[53] & (1<<1);
1609 if(timing_info_present) {
1610 i = identify_info[49] & (1<<11);
1611 snprintf(buf, 128, "IORDY support: %s", i ? "yes" : "no");
1612 lcd_puts(0, y++, buf);
1613 i = identify_info[49] & (1<<10);
1614 snprintf(buf, 128, "IORDY disable: %s", i ? "yes" : "no");
1615 lcd_puts(0, y++, buf);
1616 } else {
1617 lcd_puts(0, y++, "No timing info");
1619 break;
1621 case 11:
1622 lcd_puts(0, y++, "Cluster size");
1623 snprintf(buf, 128, "%d bytes", fat_get_cluster_size(IF_MV(0)));
1624 lcd_puts(0, y++, buf);
1625 break;
1627 lcd_update();
1629 /* Wait for a key to be pushed */
1630 key = button_get_w_tmo(HZ*5);
1631 switch(key) {
1632 case SETTINGS_CANCEL:
1633 done = true;
1634 break;
1636 case SETTINGS_DEC:
1637 if (--page < 0)
1638 page = max_page;
1639 break;
1641 case SETTINGS_INC:
1642 if (++page > max_page)
1643 page = 0;
1644 break;
1646 case SETTINGS_OK:
1647 if (page == 3) {
1648 audio_stop(); /* stop playback, to avoid disk access */
1649 lcd_clear_display();
1650 lcd_puts(0,0,"Scanning");
1651 lcd_puts(0,1,"disk...");
1652 lcd_update();
1653 fat_recalc_free(IF_MV(0));
1655 break;
1657 lcd_stop_scroll();
1660 return false;
1662 #endif /* !HAVE_MMC */
1664 #if CONFIG_CPU == SH7034
1665 bool dbg_save_roms(void)
1667 int fd;
1668 int oldmode = system_memory_guard(MEMGUARD_NONE);
1670 fd = creat("/internal_rom_0000-FFFF.bin", O_WRONLY);
1671 if(fd >= 0)
1673 write(fd, (void *)0, 0x10000);
1674 close(fd);
1677 fd = creat("/internal_rom_2000000-203FFFF.bin", O_WRONLY);
1678 if(fd >= 0)
1680 write(fd, (void *)0x2000000, 0x40000);
1681 close(fd);
1684 system_memory_guard(oldmode);
1685 return false;
1687 #elif defined CPU_COLDFIRE
1688 bool dbg_save_roms(void)
1690 int fd;
1691 int oldmode = system_memory_guard(MEMGUARD_NONE);
1693 #if defined(IRIVER_H100_SERIES)
1694 fd = creat("/internal_rom_000000-1FFFFF.bin", O_WRONLY);
1695 if(fd >= 0)
1697 write(fd, (void *)0, 0x200000);
1698 close(fd);
1700 #endif
1702 system_memory_guard(oldmode);
1703 return false;
1705 #endif /* CPU */
1707 #ifdef CONFIG_TUNER
1708 bool dbg_fm_radio(void)
1710 char buf[32];
1711 int button;
1712 bool fm_detected;
1714 #ifdef HAVE_LCD_BITMAP
1715 lcd_setmargins(0, 0);
1716 #endif
1718 while(1)
1720 lcd_clear_display();
1721 fm_detected = radio_hardware_present();
1723 snprintf(buf, sizeof buf, "HW detected: %s", fm_detected?"yes":"no");
1724 lcd_puts(0, 0, buf);
1725 lcd_update();
1727 button = button_get(true);
1729 switch(button)
1731 case SETTINGS_CANCEL:
1732 return false;
1735 return false;
1737 #endif /* CONFIG_TUNER */
1739 #ifdef HAVE_LCD_BITMAP
1740 extern bool do_screendump_instead_of_usb;
1742 bool dbg_screendump(void)
1744 do_screendump_instead_of_usb = !do_screendump_instead_of_usb;
1745 splash(HZ, true, "Screendump %s",
1746 do_screendump_instead_of_usb?"enabled":"disabled");
1747 return false;
1749 #endif /* HAVE_LCD_BITMAP */
1751 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
1752 bool dbg_set_memory_guard(void)
1754 static const struct opt_items names[MAXMEMGUARD] = {
1755 { "None", -1 },
1756 { "Flash ROM writes", -1 },
1757 { "Zero area (all)", -1 }
1759 int mode = system_memory_guard(MEMGUARD_KEEP);
1761 set_option( "Catch mem accesses", &mode, INT, names, MAXMEMGUARD, NULL);
1762 system_memory_guard(mode);
1764 return false;
1766 #endif /* CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) */
1768 bool debug_menu(void)
1770 int m;
1771 bool result;
1773 static const struct menu_item items[] = {
1774 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
1775 { "Dump ROM contents", dbg_save_roms },
1776 { "View I/O ports", dbg_ports },
1777 #endif
1778 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
1779 { "CPU frequency", dbg_cpufreq },
1780 #endif
1781 #if defined(IRIVER_H100_SERIES) && !defined(SIMULATOR)
1782 { "PCM recording", pcm_rec_screen },
1783 { "S/PDIF analyzer", dbg_spdif },
1784 #endif
1785 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
1786 { "Catch mem accesses", dbg_set_memory_guard },
1787 #endif
1788 { "View OS stacks", dbg_os },
1789 #ifdef HAVE_LCD_BITMAP
1790 { "View battery", view_battery },
1791 { "Screendump", dbg_screendump },
1792 #endif
1793 { "View HW info", dbg_hw_info },
1794 { "View partitions", dbg_partitions },
1795 #ifdef HAVE_MMC
1796 { "View MMC info", dbg_mmc_info },
1797 #else
1798 { "View disk info", dbg_disk_info },
1799 #endif
1800 #ifdef HAVE_LCD_BITMAP
1801 { "View audio thread", dbg_audio_thread },
1802 #ifdef PM_DEBUG
1803 { "pm histogram", peak_meter_histogram},
1804 #endif /* PM_DEBUG */
1805 #endif /* HAVE_LCD_BITMAP */
1806 { "View runtime", view_runtime },
1807 #ifdef CONFIG_TUNER
1808 { "FM Radio", dbg_fm_radio },
1809 #endif
1810 #ifdef ROCKBOX_HAS_LOGF
1811 {"logf", logfdisplay },
1812 {"logfdump", logfdump },
1813 #endif
1816 m=menu_init( items, sizeof items / sizeof(struct menu_item), NULL,
1817 NULL, NULL, NULL);
1818 result = menu_run(m);
1819 menu_exit(m);
1821 return result;
1824 #endif /* SIMULATOR */