HAVE_ADJUSTABLE_CPU_FREQ isn't defined for simulators, so we don't have to check...
[Rockbox.git] / apps / debug_menu.c
blobfff124f77979ea8f8d26df8f76ca5c0968629b1c
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 "usb.h"
35 #include "rtc.h"
36 #include "debug.h"
37 #include "thread.h"
38 #include "powermgmt.h"
39 #include "system.h"
40 #include "font.h"
41 #include "disk.h"
42 #include "audio.h"
43 #include "mp3_playback.h"
44 #include "settings.h"
45 #include "ata.h"
46 #include "fat.h"
47 #include "dir.h"
48 #include "panic.h"
49 #include "screens.h"
50 #include "misc.h"
51 #include "splash.h"
52 #include "dircache.h"
53 #include "tagcache.h"
54 #include "lcd-remote.h"
56 #ifdef HAVE_LCD_BITMAP
57 #include "widgets.h"
58 #include "peakmeter.h"
59 #endif
60 #ifdef CONFIG_TUNER
61 #include "radio.h"
62 #endif
63 #ifdef HAVE_MMC
64 #include "ata_mmc.h"
65 #endif
66 #include "logfdisp.h"
67 #if CONFIG_CODEC == SWCODEC
68 #include "pcmbuf.h"
69 #include "pcm_playback.h"
70 #endif
72 /*---------------------------------------------------*/
73 /* SPECIAL DEBUG STUFF */
74 /*---------------------------------------------------*/
75 extern char ata_device;
76 extern int ata_io_address;
77 extern int num_threads;
78 extern const char *thread_name[];
80 #ifdef HAVE_LCD_BITMAP
81 /* Test code!!! */
82 bool dbg_os(void)
84 char buf[32];
85 int button;
86 int i;
87 int usage;
89 lcd_setmargins(0, 0);
90 lcd_setfont(FONT_SYSFIXED);
91 lcd_clear_display();
93 while(1)
95 lcd_puts(0, 0, "Stack usage:");
96 for(i = 0; i < num_threads;i++)
98 usage = thread_stack_usage(i);
99 snprintf(buf, 32, "%s: %d%%", thread_name[i], usage);
100 lcd_puts(0, 1+i, buf);
103 lcd_update();
105 button = button_get_w_tmo(HZ/10);
107 switch(button)
109 case SETTINGS_CANCEL:
110 return false;
113 return false;
115 #else /* !HAVE_LCD_BITMAP */
116 bool dbg_os(void)
118 char buf[32];
119 int button;
120 int usage;
121 int currval = 0;
123 lcd_clear_display();
125 while(1)
127 lcd_puts(0, 0, "Stack usage");
129 usage = thread_stack_usage(currval);
130 snprintf(buf, 32, "%d: %d%% ", currval, usage);
131 lcd_puts(0, 1, buf);
133 button = button_get_w_tmo(HZ/10);
135 switch(button)
137 case SETTINGS_CANCEL:
138 return false;
140 case SETTINGS_DEC:
141 currval--;
142 if(currval < 0)
143 currval = num_threads-1;
144 break;
146 case SETTINGS_INC:
147 currval++;
148 if(currval > num_threads-1)
149 currval = 0;
150 break;
153 return false;
155 #endif /* !HAVE_LCD_BITMAP */
157 #ifdef HAVE_LCD_BITMAP
158 #if CONFIG_CODEC != SWCODEC
159 bool dbg_audio_thread(void)
161 char buf[32];
162 int button;
163 struct audio_debug d;
165 lcd_setmargins(0, 0);
166 lcd_setfont(FONT_SYSFIXED);
168 while(1)
170 button = button_get_w_tmo(HZ/5);
171 switch(button)
173 case SETTINGS_CANCEL:
174 return false;
177 audio_get_debugdata(&d);
179 lcd_clear_display();
181 snprintf(buf, sizeof(buf), "read: %x", d.audiobuf_read);
182 lcd_puts(0, 0, buf);
183 snprintf(buf, sizeof(buf), "write: %x", d.audiobuf_write);
184 lcd_puts(0, 1, buf);
185 snprintf(buf, sizeof(buf), "swap: %x", d.audiobuf_swapwrite);
186 lcd_puts(0, 2, buf);
187 snprintf(buf, sizeof(buf), "playing: %d", d.playing);
188 lcd_puts(0, 3, buf);
189 snprintf(buf, sizeof(buf), "playable: %x", d.playable_space);
190 lcd_puts(0, 4, buf);
191 snprintf(buf, sizeof(buf), "unswapped: %x", d.unswapped_space);
192 lcd_puts(0, 5, buf);
194 /* Playable space left */
195 scrollbar(0, 6*8, 112, 4, d.audiobuflen, 0,
196 d.playable_space, HORIZONTAL);
198 /* Show the watermark limit */
199 scrollbar(0, 6*8+4, 112, 4, d.audiobuflen, 0,
200 d.low_watermark_level, HORIZONTAL);
202 snprintf(buf, sizeof(buf), "wm: %x - %x",
203 d.low_watermark_level, d.lowest_watermark_level);
204 lcd_puts(0, 7, buf);
206 lcd_update();
208 return false;
210 #else /* CONFIG_CODEC == SWCODEC */
211 extern size_t audiobuffer_free;
212 extern int filebuflen;
213 extern int filebufused;
215 static unsigned int ticks, boost_ticks;
217 void dbg_audio_task(void)
219 if(FREQ > CPUFREQ_NORMAL)
220 boost_ticks++;
222 ticks++;
225 bool dbg_audio_thread(void)
227 char buf[32];
228 int button;
229 int line;
230 bool done = false;
231 size_t bufsize = pcmbuf_get_bufsize();
232 int pcmbufdescs = pcmbuf_descs();
234 ticks = boost_ticks = 0;
236 tick_add_task(dbg_audio_task);
238 lcd_setmargins(0, 0);
239 lcd_setfont(FONT_SYSFIXED);
241 while(!done)
243 button = button_get_w_tmo(HZ/5);
244 switch(button)
246 case SETTINGS_NEXT:
247 audio_next();
248 break;
249 case SETTINGS_PREV:
250 audio_prev();
251 break;
252 case SETTINGS_CANCEL:
253 done = true;
254 break;
257 line = 0;
259 lcd_clear_display();
261 snprintf(buf, sizeof(buf), "pcm: %7ld/%7ld",
262 bufsize-audiobuffer_free, bufsize);
263 lcd_puts(0, line++, buf);
265 /* Playable space left */
266 scrollbar(0, line*8, LCD_WIDTH, 6, bufsize, 0,
267 bufsize-audiobuffer_free, HORIZONTAL);
268 line++;
270 snprintf(buf, sizeof(buf), "codec: %8d/%8d", filebufused, filebuflen);
271 lcd_puts(0, line++, buf);
273 /* Playable space left */
274 scrollbar(0, line*8, LCD_WIDTH, 6, filebuflen, 0,
275 filebufused, HORIZONTAL);
276 line++;
278 snprintf(buf, sizeof(buf), "track count: %2d", audio_track_count());
279 lcd_puts(0, line++, buf);
281 snprintf(buf, sizeof(buf), "cpu freq: %3dMHz",
282 (int)((FREQ + 500000) / 1000000));
283 lcd_puts(0, line++, buf);
285 snprintf(buf, sizeof(buf), "boost ratio: %3d%%",
286 boost_ticks * 100 / ticks);
287 lcd_puts(0, line++, buf);
289 snprintf(buf, sizeof(buf), "pcmbufdesc: %2d/%2d",
290 pcmbuf_used_descs(), pcmbufdescs);
291 lcd_puts(0, line++, buf);
293 lcd_update();
296 tick_remove_task(dbg_audio_task);
298 return false;
300 #endif /* CONFIG_CODEC */
301 #endif /* HAVE_LCD_BITMAP */
303 /* Tool function to calculate a CRC16 across some buffer */
304 unsigned short crc_16(const unsigned char* buf, unsigned len)
306 /* CCITT standard polynomial 0x1021 */
307 static const unsigned short crc16_lookup[16] =
308 { /* lookup table for 4 bits at a time is affordable */
309 0x0000, 0x1021, 0x2042, 0x3063,
310 0x4084, 0x50A5, 0x60C6, 0x70E7,
311 0x8108, 0x9129, 0xA14A, 0xB16B,
312 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF
314 unsigned short crc16 = 0xFFFF; /* initialise to 0xFFFF (CCITT specification) */
315 unsigned t;
316 unsigned char byte;
318 while (len--)
320 byte = *buf++; /* get one byte of data */
322 /* upper nibble of our data */
323 t = crc16 >> 12; /* extract the 4 most significant bits */
324 t ^= byte >> 4; /* XOR in 4 bits of the data into the extracted bits */
325 crc16 <<= 4; /* shift the CRC Register left 4 bits */
326 crc16 ^= crc16_lookup[t]; /* do the table lookup and XOR the result */
328 /* lower nibble of our data */
329 t = crc16 >> 12; /* extract the 4 most significant bits */
330 t ^= byte & 0x0F; /* XOR in 4 bits of the data into the extracted bits */
331 crc16 <<= 4; /* shift the CRC Register left 4 bits */
332 crc16 ^= crc16_lookup[t]; /* do the table lookup and XOR the result */
335 return crc16;
339 #if CONFIG_CPU == TCC730
340 static unsigned flash_word_temp __attribute__ ((section (".idata")));
342 static void flash_write_word(unsigned addr, unsigned value) __attribute__ ((section(".icode")));
343 static void flash_write_word(unsigned addr, unsigned value) {
344 flash_word_temp = value;
346 long extAddr = (long)addr << 1;
347 ddma_transfer(1, 1, &flash_word_temp, extAddr, 2);
350 static unsigned flash_read_word(unsigned addr) __attribute__ ((section(".icode")));
351 static unsigned flash_read_word(unsigned addr) {
352 long extAddr = (long)addr << 1;
353 ddma_transfer(1, 1, &flash_word_temp, extAddr, 2);
354 return flash_word_temp;
357 #endif
359 /* Tool function to read the flash manufacturer and type, if available.
360 Only chips which could be reprogrammed in system will return values.
361 (The mode switch addresses vary between flash manufacturers, hence addr1/2) */
362 /* In IRAM to avoid problems when running directly from Flash */
363 bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
364 unsigned addr1, unsigned addr2)
365 __attribute__ ((section (".icode")));
366 bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
367 unsigned addr1, unsigned addr2)
370 #if (CONFIG_CPU == PP5002) || (CONFIG_CPU == PP5020)
371 /* TODO: Implement for iPod */
372 (void)p_manufacturer;
373 (void)p_device;
374 (void)addr1;
375 (void)addr2;
376 #elif CONFIG_CPU == PNX0101
377 /* TODO: Implement for iFP7xx */
378 (void)p_manufacturer;
379 (void)p_device;
380 (void)addr1;
381 (void)addr2;
382 #else
383 unsigned not_manu, not_id; /* read values before switching to ID mode */
384 unsigned manu, id; /* read values when in ID mode */
385 #if CONFIG_CPU == TCC730
386 #define FLASH(addr) (flash_read_word(addr))
387 #define SET_FLASH(addr, val) (flash_write_word((addr), (val)))
389 #else /* memory mapped */
390 #if CONFIG_CPU == SH7034
391 volatile unsigned char* flash = (unsigned char*)0x2000000; /* flash mapping */
392 #elif defined(CPU_COLDFIRE)
393 volatile unsigned short* flash = (unsigned short*)0; /* flash mapping */
394 #endif
395 #define FLASH(addr) (flash[addr])
396 #define SET_FLASH(addr, val) (flash[addr] = val)
397 #endif
398 int old_level; /* saved interrupt level */
400 not_manu = FLASH(0); /* read the normal content */
401 not_id = FLASH(1); /* should be 'A' (0x41) and 'R' (0x52) from the "ARCH" marker */
403 /* disable interrupts, prevent any stray flash access */
404 old_level = set_irq_level(HIGHEST_IRQ_LEVEL);
406 SET_FLASH(addr1, 0xAA); /* enter command mode */
407 SET_FLASH(addr2, 0x55);
408 SET_FLASH(addr1, 0x90); /* ID command */
409 /* Atmel wants 20ms pause here */
410 /* sleep(HZ/50); no sleeping possible while interrupts are disabled */
412 manu = FLASH(0); /* read the IDs */
413 id = FLASH(1);
415 SET_FLASH(0, 0xF0); /* reset flash (back to normal read mode) */
416 /* Atmel wants 20ms pause here */
417 /* sleep(HZ/50); no sleeping possible while interrupts are disabled */
419 set_irq_level(old_level); /* enable interrupts again */
421 /* I assume success if the obtained values are different from
422 the normal flash content. This is not perfectly bulletproof, they
423 could theoretically be the same by chance, causing us to fail. */
424 if (not_manu != manu || not_id != id) /* a value has changed */
426 *p_manufacturer = manu; /* return the results */
427 *p_device = id;
428 return true; /* success */
430 #endif
431 return false; /* fail */
434 #ifdef HAVE_LCD_BITMAP
435 bool dbg_hw_info(void)
437 #if CONFIG_CPU == SH7034
438 char buf[32];
439 int button;
440 int usb_polarity;
441 int pr_polarity;
442 int bitmask = *(unsigned short*)0x20000fc;
443 int rom_version = *(unsigned short*)0x20000fe;
444 unsigned manu, id; /* flash IDs */
445 bool got_id; /* flag if we managed to get the flash IDs */
446 unsigned rom_crc = 0xFFFF; /* CRC16 of the boot ROM */
447 bool has_bootrom; /* flag for boot ROM present */
448 int oldmode; /* saved memory guard mode */
450 #ifdef USB_ENABLE_ONDIOSTYLE
451 if(PADRL & 0x20)
452 #else
453 if(PADRH & 0x04)
454 #endif
455 usb_polarity = 0; /* Negative */
456 else
457 usb_polarity = 1; /* Positive */
459 if(PADRH & 0x08)
460 pr_polarity = 0; /* Negative */
461 else
462 pr_polarity = 1; /* Positive */
464 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
466 /* get flash ROM type */
467 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
468 if (!got_id)
469 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
471 /* check if the boot ROM area is a flash mirror */
472 has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0);
473 if (has_bootrom) /* if ROM and Flash different */
475 /* calculate CRC16 checksum of boot ROM */
476 rom_crc = crc_16((unsigned char*)0x0000, 64*1024);
479 system_memory_guard(oldmode); /* re-enable memory guard */
481 lcd_setmargins(0, 0);
482 lcd_setfont(FONT_SYSFIXED);
483 lcd_clear_display();
485 lcd_puts(0, 0, "[Hardware info]");
487 snprintf(buf, 32, "ROM: %d.%02d", rom_version/100, rom_version%100);
488 lcd_puts(0, 1, buf);
490 snprintf(buf, 32, "Mask: 0x%04x", bitmask);
491 lcd_puts(0, 2, buf);
493 snprintf(buf, 32, "USB: %s", usb_polarity?"positive":"negative");
494 lcd_puts(0, 3, buf);
496 snprintf(buf, 32, "PR: %s", pr_polarity?"positive":"negative");
497 lcd_puts(0, 4, buf);
499 if (got_id)
500 snprintf(buf, 32, "Flash: M=%02x D=%02x", manu, id);
501 else
502 snprintf(buf, 32, "Flash: M=?? D=??"); /* unknown, sorry */
503 lcd_puts(0, 5, buf);
505 if (has_bootrom)
507 snprintf(buf, 32-3, "ROM CRC: 0x%04x", rom_crc);
508 if (rom_crc == 0x222F) /* known Version 1 */
509 strcat(buf, " V1");
511 else
513 snprintf(buf, 32, "Boot ROM: none");
515 lcd_puts(0, 6, buf);
517 #ifndef HAVE_MMC /* have ATA */
518 snprintf(buf, 32, "ATA: 0x%x,%s", ata_io_address,
519 ata_device ? "slave":"master");
520 lcd_puts(0, 7, buf);
521 #endif
522 lcd_update();
524 while(1)
526 button = button_get(true);
527 if(button == SETTINGS_CANCEL)
528 return false;
530 #elif CONFIG_CPU == MCF5249
531 char buf[32];
532 int button;
533 unsigned manu, id; /* flash IDs */
534 bool got_id; /* flag if we managed to get the flash IDs */
535 int oldmode; /* saved memory guard mode */
537 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
539 /* get flash ROM type */
540 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
541 if (!got_id)
542 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
544 system_memory_guard(oldmode); /* re-enable memory guard */
546 lcd_setmargins(0, 0);
547 lcd_setfont(FONT_SYSFIXED);
548 lcd_clear_display();
550 lcd_puts(0, 0, "[Hardware info]");
552 if (got_id)
553 snprintf(buf, 32, "Flash: M=%04x D=%04x", manu, id);
554 else
555 snprintf(buf, 32, "Flash: M=???? D=????"); /* unknown, sorry */
556 lcd_puts(0, 1, buf);
558 lcd_update();
560 while(1)
562 button = button_get(true);
563 if(button == SETTINGS_CANCEL)
564 return false;
566 #endif /* CONFIG_CPU */
567 return false;
569 #else /* !HAVE_LCD_BITMAP */
570 bool dbg_hw_info(void)
572 char buf[32];
573 int button;
574 int currval = 0;
575 int usb_polarity;
576 int bitmask = *(unsigned short*)0x20000fc;
577 int rom_version = *(unsigned short*)0x20000fe;
578 unsigned manu, id; /* flash IDs */
579 bool got_id; /* flag if we managed to get the flash IDs */
580 unsigned rom_crc = 0xFFFF; /* CRC16 of the boot ROM */
581 bool has_bootrom; /* flag for boot ROM present */
582 int oldmode; /* saved memory guard mode */
584 if(PADRH & 0x04)
585 usb_polarity = 0; /* Negative */
586 else
587 usb_polarity = 1; /* Positive */
589 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
591 /* get flash ROM type */
592 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
593 if (!got_id)
594 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
596 /* check if the boot ROM area is a flash mirror */
597 has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0);
598 if (has_bootrom) /* if ROM and Flash different */
600 /* calculate CRC16 checksum of boot ROM */
601 rom_crc = crc_16((unsigned char*)0x0000, 64*1024);
604 system_memory_guard(oldmode); /* re-enable memory guard */
606 lcd_clear_display();
608 lcd_puts(0, 0, "[HW Info]");
609 while(1)
611 switch(currval)
613 case 0:
614 snprintf(buf, 32, "ROM: %d.%02d",
615 rom_version/100, rom_version%100);
616 break;
617 case 1:
618 snprintf(buf, 32, "USB: %s",
619 usb_polarity?"pos":"neg");
620 break;
621 case 2:
622 snprintf(buf, 32, "ATA: 0x%x%s",
623 ata_io_address, ata_device ? "s":"m");
624 break;
625 case 3:
626 snprintf(buf, 32, "Mask: %04x", bitmask);
627 break;
628 case 4:
629 if (got_id)
630 snprintf(buf, 32, "Flash:%02x,%02x", manu, id);
631 else
632 snprintf(buf, 32, "Flash:??,??"); /* unknown, sorry */
633 break;
634 case 5:
635 if (has_bootrom)
636 snprintf(buf, 32, "RomCRC:%04x", rom_crc);
637 else
638 snprintf(buf, 32, "BootROM: no");
641 lcd_puts(0, 1, buf);
642 lcd_update();
644 button = button_get(true);
646 switch(button)
648 case SETTINGS_CANCEL:
649 return false;
651 case SETTINGS_DEC:
652 currval--;
653 if(currval < 0)
654 currval = 5;
655 break;
657 case SETTINGS_INC:
658 currval++;
659 if(currval > 5)
660 currval = 0;
661 break;
664 return false;
666 #endif /* !HAVE_LCD_BITMAP */
668 bool dbg_partitions(void)
670 int partition=0;
672 lcd_clear_display();
673 lcd_puts(0, 0, "Partition");
674 lcd_puts(0, 1, "list");
675 lcd_update();
676 sleep(HZ/2);
678 while(1)
680 char buf[32];
681 int button;
682 struct partinfo* p = disk_partinfo(partition);
684 lcd_clear_display();
685 snprintf(buf, sizeof buf, "P%d: S:%lx", partition, p->start);
686 lcd_puts(0, 0, buf);
687 snprintf(buf, sizeof buf, "T:%x %ld MB", p->type, p->size / 2048);
688 lcd_puts(0, 1, buf);
689 lcd_update();
691 button = button_get(true);
693 switch(button)
695 case SETTINGS_OK:
696 case SETTINGS_CANCEL:
697 return false;
699 case SETTINGS_DEC:
700 partition--;
701 if (partition < 0)
702 partition = 3;
703 break;
705 case SETTINGS_INC:
706 partition++;
707 if (partition > 3)
708 partition = 0;
709 break;
711 default:
712 if(default_event_handler(button) == SYS_USB_CONNECTED)
713 return true;
714 break;
717 return false;
720 #if defined(CPU_COLDFIRE) && defined(HAVE_SPDIF_OUT)
721 bool dbg_spdif(void)
723 char buf[128];
724 int button;
725 int line;
726 unsigned int control;
727 int x;
728 char *s;
729 int category;
730 int generation;
731 unsigned int interruptstat;
732 bool valnogood, symbolerr, parityerr;
734 lcd_setmargins(0, 0);
735 lcd_clear_display();
736 lcd_setfont(FONT_SYSFIXED);
738 while(1)
740 line = 0;
742 control = EBU1RCVCCHANNEL1;
743 interruptstat = INTERRUPTSTAT;
744 INTERRUPTCLEAR = 0x03c00000;
746 valnogood = (interruptstat & 0x01000000)?true:false;
747 symbolerr = (interruptstat & 0x00800000)?true:false;
748 parityerr = (interruptstat & 0x00400000)?true:false;
750 snprintf(buf, sizeof(buf), "Val: %s Sym: %s Par: %s",
751 valnogood?"--":"OK",
752 symbolerr?"--":"OK",
753 parityerr?"--":"OK");
754 lcd_puts(0, line++, buf);
756 snprintf(buf, sizeof(buf), "Status word: %08x", (int)control);
757 lcd_puts(0, line++, buf);
759 line++;
761 x = control >> 31;
762 snprintf(buf, sizeof(buf), "PRO: %d (%s)",
763 x, x?"Professional":"Consumer");
764 lcd_puts(0, line++, buf);
766 x = (control >> 30) & 1;
767 snprintf(buf, sizeof(buf), "Audio: %d (%s)",
768 x, x?"Non-PCM":"PCM");
769 lcd_puts(0, line++, buf);
771 x = (control >> 29) & 1;
772 snprintf(buf, sizeof(buf), "Copy: %d (%s)",
773 x, x?"Permitted":"Inhibited");
774 lcd_puts(0, line++, buf);
776 x = (control >> 27) & 7;
777 switch(x)
779 case 0:
780 s = "None";
781 break;
782 case 1:
783 s = "50/15us";
784 break;
785 default:
786 s = "Reserved";
787 break;
789 snprintf(buf, sizeof(buf), "Preemphasis: %d (%s)", x, s);
790 lcd_puts(0, line++, buf);
792 x = (control >> 24) & 3;
793 snprintf(buf, sizeof(buf), "Mode: %d", x);
794 lcd_puts(0, line++, buf);
796 category = (control >> 17) & 127;
797 switch(category)
799 case 0x00:
800 s = "General";
801 break;
802 case 0x40:
803 s = "Audio CD";
804 break;
805 default:
806 s = "Unknown";
808 snprintf(buf, sizeof(buf), "Category: 0x%02x (%s)", category, s);
809 lcd_puts(0, line++, buf);
811 x = (control >> 16) & 1;
812 generation = x;
813 if(((category & 0x70) == 0x10) ||
814 ((category & 0x70) == 0x40) ||
815 ((category & 0x78) == 0x38))
817 generation = !generation;
819 snprintf(buf, sizeof(buf), "Generation: %d (%s)",
820 x, generation?"Original":"No ind.");
821 lcd_puts(0, line++, buf);
823 x = (control >> 12) & 15;
824 snprintf(buf, sizeof(buf), "Source: %d", x);
825 lcd_puts(0, line++, buf);
827 x = (control >> 8) & 15;
828 switch(x)
830 case 0:
831 s = "Unspecified";
832 break;
833 case 8:
834 s = "A (Left)";
835 break;
836 case 4:
837 s = "B (Right)";
838 break;
839 default:
840 s = "";
841 break;
843 snprintf(buf, sizeof(buf), "Channel: %d (%s)", x, s);
844 lcd_puts(0, line++, buf);
846 x = (control >> 4) & 15;
847 switch(x)
849 case 0:
850 s = "44.1kHz";
851 break;
852 case 0x4:
853 s = "48kHz";
854 break;
855 case 0xc:
856 s = "32kHz";
857 break;
859 snprintf(buf, sizeof(buf), "Frequency: %d (%s)", x, s);
860 lcd_puts(0, line++, buf);
862 x = (control >> 2) & 3;
863 snprintf(buf, sizeof(buf), "Clock accuracy: %d", x);
864 lcd_puts(0, line++, buf);
866 lcd_update();
867 button = button_get_w_tmo(HZ/10);
869 switch(button)
871 case SETTINGS_CANCEL:
872 case SETTINGS_OK2:
873 return false;
877 return false;
879 #endif /* CPU_COLDFIRE */
881 #ifdef HAVE_LCD_BITMAP
882 /* Test code!!! */
883 bool dbg_ports(void)
885 #if CONFIG_CPU == SH7034
886 unsigned short porta;
887 unsigned short portb;
888 unsigned char portc;
889 char buf[32];
890 int button;
891 int battery_voltage;
892 int batt_int, batt_frac;
894 lcd_setfont(FONT_SYSFIXED);
895 lcd_setmargins(0, 0);
896 lcd_clear_display();
898 while(1)
900 porta = PADR;
901 portb = PBDR;
902 portc = PCDR;
904 snprintf(buf, 32, "PADR: %04x", porta);
905 lcd_puts(0, 0, buf);
906 snprintf(buf, 32, "PBDR: %04x", portb);
907 lcd_puts(0, 1, buf);
909 snprintf(buf, 32, "AN0: %03x AN4: %03x", adc_read(0), adc_read(4));
910 lcd_puts(0, 2, buf);
911 snprintf(buf, 32, "AN1: %03x AN5: %03x", adc_read(1), adc_read(5));
912 lcd_puts(0, 3, buf);
913 snprintf(buf, 32, "AN2: %03x AN6: %03x", adc_read(2), adc_read(6));
914 lcd_puts(0, 4, buf);
915 snprintf(buf, 32, "AN3: %03x AN7: %03x", adc_read(3), adc_read(7));
916 lcd_puts(0, 5, buf);
918 battery_voltage = (adc_read(ADC_UNREG_POWER) * BATTERY_SCALE_FACTOR) / 10000;
919 batt_int = battery_voltage / 100;
920 batt_frac = battery_voltage % 100;
922 snprintf(buf, 32, "Batt: %d.%02dV %d%% ", batt_int, batt_frac,
923 battery_level());
924 lcd_puts(0, 6, buf);
925 #ifndef HAVE_MMC /* have ATA */
926 snprintf(buf, 32, "ATA: %s, 0x%x",
927 ata_device?"slave":"master", ata_io_address);
928 lcd_puts(0, 7, buf);
929 #endif
930 lcd_update();
931 button = button_get_w_tmo(HZ/10);
933 switch(button)
935 case SETTINGS_CANCEL:
936 return false;
939 #elif defined(CPU_COLDFIRE)
940 unsigned int gpio_out;
941 unsigned int gpio1_out;
942 unsigned int gpio_read;
943 unsigned int gpio1_read;
944 unsigned int gpio_function;
945 unsigned int gpio1_function;
946 unsigned int gpio_enable;
947 unsigned int gpio1_enable;
948 int adc_buttons, adc_remote, adc_battery;
949 #ifdef IRIVER
950 int adc_remotedetect;
951 #endif
952 char buf[128];
953 int button;
954 int line;
955 int battery_voltage;
956 int batt_int, batt_frac;
958 lcd_setmargins(0, 0);
959 lcd_clear_display();
960 lcd_setfont(FONT_SYSFIXED);
962 while(1)
964 line = 0;
965 gpio_read = GPIO_READ;
966 gpio1_read = GPIO1_READ;
967 gpio_out = GPIO_OUT;
968 gpio1_out = GPIO1_OUT;
969 gpio_function = GPIO_FUNCTION;
970 gpio1_function = GPIO1_FUNCTION;
971 gpio_enable = GPIO_ENABLE;
972 gpio1_enable = GPIO1_ENABLE;
974 snprintf(buf, sizeof(buf), "GPIO_READ: %08x", gpio_read);
975 lcd_puts(0, line++, buf);
976 snprintf(buf, sizeof(buf), "GPIO_OUT: %08x", gpio_out);
977 lcd_puts(0, line++, buf);
978 snprintf(buf, sizeof(buf), "GPIO_FUNCTION: %08x", gpio_function);
979 lcd_puts(0, line++, buf);
980 snprintf(buf, sizeof(buf), "GPIO_ENABLE: %08x", gpio_enable);
981 lcd_puts(0, line++, buf);
983 snprintf(buf, sizeof(buf), "GPIO1_READ: %08x", gpio1_read);
984 lcd_puts(0, line++, buf);
985 snprintf(buf, sizeof(buf), "GPIO1_OUT: %08x", gpio1_out);
986 lcd_puts(0, line++, buf);
987 snprintf(buf, sizeof(buf), "GPIO1_FUNCTION: %08x", gpio1_function);
988 lcd_puts(0, line++, buf);
989 snprintf(buf, sizeof(buf), "GPIO1_ENABLE: %08x", gpio1_enable);
990 lcd_puts(0, line++, buf);
992 adc_buttons = adc_read(ADC_BUTTONS);
993 adc_remote = adc_read(ADC_REMOTE);
994 adc_battery = adc_read(ADC_BATTERY);
995 #ifdef IRIVER
996 adc_remotedetect = adc_read(ADC_REMOTEDETECT);
997 #endif
999 snprintf(buf, sizeof(buf), "ADC_BUTTONS: %02x", adc_buttons);
1000 lcd_puts(0, line++, buf);
1001 snprintf(buf, sizeof(buf), "ADC_REMOTE: %02x", adc_remote);
1002 lcd_puts(0, line++, buf);
1003 snprintf(buf, sizeof(buf), "ADC_BATTERY: %02x", adc_battery);
1004 lcd_puts(0, line++, buf);
1005 #ifdef IRIVER
1006 snprintf(buf, sizeof(buf), "ADC_REMOTEDETECT: %02x", adc_remotedetect);
1007 lcd_puts(0, line++, buf);
1008 #endif
1010 battery_voltage = (adc_battery * BATTERY_SCALE_FACTOR) / 10000;
1011 batt_int = battery_voltage / 100;
1012 batt_frac = battery_voltage % 100;
1014 snprintf(buf, 32, "Batt: %d.%02dV %d%% ", batt_int, batt_frac,
1015 battery_level());
1016 lcd_puts(0, line++, buf);
1018 #ifdef IRIVER
1019 snprintf(buf, sizeof(buf), "remotetype:: %d", remote_type());
1020 lcd_puts(0, line++, buf);
1021 #endif
1023 lcd_update();
1024 button = button_get_w_tmo(HZ/10);
1026 switch(button)
1027 { /* quit on release to allow for reading the cancel button input */
1028 case (SETTINGS_CANCEL|BUTTON_REL):
1029 return false;
1033 #elif CONFIG_CPU == PP5020
1035 unsigned int gpio_a, gpio_b, gpio_c, gpio_d;
1036 unsigned int gpio_e, gpio_f, gpio_g, gpio_h;
1037 unsigned int gpio_i, gpio_j, gpio_k, gpio_l;
1039 char buf[128];
1040 int button;
1041 int line;
1043 lcd_setmargins(0, 0);
1044 lcd_clear_display();
1045 lcd_setfont(FONT_SYSFIXED);
1047 while(1)
1049 gpio_a = GPIOA_INPUT_VAL;
1050 gpio_b = GPIOB_INPUT_VAL;
1051 gpio_c = GPIOC_INPUT_VAL;
1052 gpio_d = GPIOD_INPUT_VAL;
1054 line = 0;
1055 snprintf(buf, sizeof(buf), "IPOD version: 0x%08x", ipod_hw_rev);
1056 lcd_puts(0, line++, buf);
1057 snprintf(buf, sizeof(buf), "GPIO_A: %02x", gpio_a);
1058 lcd_puts(0, line++, buf);
1059 snprintf(buf, sizeof(buf), "GPIO_B: %02x", gpio_b);
1060 lcd_puts(0, line++, buf);
1061 snprintf(buf, sizeof(buf), "GPIO_C: %02x", gpio_c);
1062 lcd_puts(0, line++, buf);
1063 snprintf(buf, sizeof(buf), "GPIO_D: %02x", gpio_d);
1064 lcd_puts(0, line++, buf);
1065 line++;
1067 gpio_e = GPIOE_INPUT_VAL;
1068 gpio_f = GPIOF_INPUT_VAL;
1069 gpio_g = GPIOG_INPUT_VAL;
1070 gpio_h = GPIOH_INPUT_VAL;
1072 snprintf(buf, sizeof(buf), "GPIO_E: %02x", gpio_e);
1073 lcd_puts(0, line++, buf);
1074 snprintf(buf, sizeof(buf), "GPIO_F: %02x", gpio_f);
1075 lcd_puts(0, line++, buf);
1076 snprintf(buf, sizeof(buf), "GPIO_G: %02x", gpio_g);
1077 lcd_puts(0, line++, buf);
1078 snprintf(buf, sizeof(buf), "GPIO_H: %02x", gpio_h);
1079 lcd_puts(0, line++, buf);
1080 line++;
1082 gpio_i = GPIOI_INPUT_VAL;
1083 gpio_j = GPIOJ_INPUT_VAL;
1084 gpio_k = GPIOK_INPUT_VAL;
1085 gpio_l = GPIOL_INPUT_VAL;
1087 snprintf(buf, sizeof(buf), "GPIO_I: %02x", gpio_i);
1088 lcd_puts(0, line++, buf);
1089 snprintf(buf, sizeof(buf), "GPIO_J: %02x", gpio_j);
1090 lcd_puts(0, line++, buf);
1091 snprintf(buf, sizeof(buf), "GPIO_K: %02x", gpio_k);
1092 lcd_puts(0, line++, buf);
1093 snprintf(buf, sizeof(buf), "GPIO_L: %02x", gpio_l);
1094 lcd_puts(0, line++, buf);
1096 lcd_update();
1097 button = button_get_w_tmo(HZ/10);
1099 switch(button)
1101 case SETTINGS_CANCEL:
1102 return false;
1106 #endif /* CPU */
1107 return false;
1109 #else /* !HAVE_LCD_BITMAP */
1110 bool dbg_ports(void)
1112 unsigned short porta;
1113 unsigned short portb;
1114 unsigned char portc;
1115 char buf[32];
1116 int button;
1117 int battery_voltage;
1118 int batt_int, batt_frac;
1119 int currval = 0;
1121 lcd_clear_display();
1123 while(1)
1125 porta = PADR;
1126 portb = PBDR;
1127 portc = PCDR;
1129 switch(currval)
1131 case 0:
1132 snprintf(buf, 32, "PADR: %04x ", porta);
1133 break;
1134 case 1:
1135 snprintf(buf, 32, "PBDR: %04x ", portb);
1136 break;
1137 case 2:
1138 snprintf(buf, 32, "AN0: %03x ", adc_read(0));
1139 break;
1140 case 3:
1141 snprintf(buf, 32, "AN1: %03x ", adc_read(1));
1142 break;
1143 case 4:
1144 snprintf(buf, 32, "AN2: %03x ", adc_read(2));
1145 break;
1146 case 5:
1147 snprintf(buf, 32, "AN3: %03x ", adc_read(3));
1148 break;
1149 case 6:
1150 snprintf(buf, 32, "AN4: %03x ", adc_read(4));
1151 break;
1152 case 7:
1153 snprintf(buf, 32, "AN5: %03x ", adc_read(5));
1154 break;
1155 case 8:
1156 snprintf(buf, 32, "AN6: %03x ", adc_read(6));
1157 break;
1158 case 9:
1159 snprintf(buf, 32, "AN7: %03x ", adc_read(7));
1160 break;
1161 case 10:
1162 snprintf(buf, 32, "%s, 0x%x ",
1163 ata_device?"slv":"mst", ata_io_address);
1164 break;
1166 lcd_puts(0, 0, buf);
1168 battery_voltage = (adc_read(ADC_UNREG_POWER) *
1169 BATTERY_SCALE_FACTOR) / 10000;
1170 batt_int = battery_voltage / 100;
1171 batt_frac = battery_voltage % 100;
1173 snprintf(buf, 32, "Batt: %d.%02dV", batt_int, batt_frac);
1174 lcd_puts(0, 1, buf);
1176 button = button_get_w_tmo(HZ/5);
1178 switch(button)
1180 case SETTINGS_CANCEL:
1181 return false;
1183 case SETTINGS_DEC:
1184 currval--;
1185 if(currval < 0)
1186 currval = 10;
1187 break;
1189 case SETTINGS_INC:
1190 currval++;
1191 if(currval > 10)
1192 currval = 0;
1193 break;
1196 return false;
1198 #endif /* !HAVE_LCD_BITMAP */
1200 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
1201 extern int boost_counter;
1202 bool dbg_cpufreq(void)
1204 char buf[128];
1205 int line;
1206 int button;
1208 #ifdef HAVE_LCD_BITMAP
1209 lcd_setmargins(0, 0);
1210 lcd_setfont(FONT_SYSFIXED);
1211 #endif
1212 lcd_clear_display();
1214 while(1)
1216 line = 0;
1218 snprintf(buf, sizeof(buf), "Frequency: %ld", FREQ);
1219 lcd_puts(0, line++, buf);
1221 snprintf(buf, sizeof(buf), "boost_counter: %d", boost_counter);
1222 lcd_puts(0, line++, buf);
1224 lcd_update();
1225 button = button_get_w_tmo(HZ/10);
1227 switch(button)
1229 #if (CONFIG_KEYPAD == IPOD_4G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD)
1230 case BUTTON_MENU:
1231 #else
1232 case BUTTON_UP:
1233 #endif
1234 cpu_boost(true);
1235 break;
1236 #if (CONFIG_KEYPAD == IPOD_4G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD)
1237 case BUTTON_PLAY:
1238 #else
1239 case BUTTON_DOWN:
1240 #endif
1241 cpu_boost(false);
1242 break;
1244 #if (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
1245 (CONFIG_KEYPAD == IRIVER_H300_PAD) || \
1246 (CONFIG_KEYPAD == IPOD_4G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD)
1247 case BUTTON_SELECT:
1248 #else
1249 case BUTTON_PLAY:
1250 #endif
1251 set_cpu_frequency(CPUFREQ_DEFAULT);
1252 boost_counter = 0;
1253 break;
1255 #if (CONFIG_KEYPAD == IPOD_4G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD)
1256 case BUTTON_LEFT:
1257 #else
1258 case SETTINGS_CANCEL:
1259 case SETTINGS_OK2:
1260 #endif
1261 return false;
1265 return false;
1267 #endif /* HAVE_ADJUSTABLE_CPU_FREQ */
1269 #ifdef HAVE_LCD_BITMAP
1271 * view_battery() shows a automatically scaled graph of the battery voltage
1272 * over time. Usable for estimating battery life / charging rate.
1273 * The power_history array is updated in power_thread of powermgmt.c.
1276 #define BAT_LAST_VAL MIN(LCD_WIDTH, POWER_HISTORY_LEN)
1277 #define BAT_YSPACE (LCD_HEIGHT - 20)
1279 bool view_battery(void)
1281 int view = 0;
1282 int i, x, y;
1283 unsigned short maxv, minv;
1284 char buf[32];
1286 lcd_setmargins(0, 0);
1287 lcd_setfont(FONT_SYSFIXED);
1289 while(1)
1291 switch (view) {
1292 case 0: /* voltage history graph */
1293 /* Find maximum and minimum voltage for scaling */
1294 maxv = 0;
1295 minv = 65535;
1296 for (i = 0; i < BAT_LAST_VAL; i++) {
1297 if (power_history[i] > maxv)
1298 maxv = power_history[i];
1299 if (power_history[i] && (power_history[i] < minv))
1301 minv = power_history[i];
1305 if ((minv < 1) || (minv >= 65535))
1306 minv = 1;
1307 if (maxv < 2)
1308 maxv = 2;
1310 lcd_clear_display();
1311 snprintf(buf, 30, "Battery %d.%02d", power_history[0] / 100,
1312 power_history[0] % 100);
1313 lcd_puts(0, 0, buf);
1314 snprintf(buf, 30, "scale %d.%02d-%d.%02d V",
1315 minv / 100, minv % 100, maxv / 100, maxv % 100);
1316 lcd_puts(0, 1, buf);
1318 x = 0;
1319 for (i = BAT_LAST_VAL - 1; i >= 0; i--) {
1320 y = (power_history[i] - minv) * BAT_YSPACE / (maxv - minv);
1321 lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
1322 lcd_vline(x, LCD_HEIGHT-1, 20);
1323 lcd_set_drawmode(DRMODE_SOLID);
1324 lcd_vline(x, LCD_HEIGHT-1,
1325 MIN(MAX(LCD_HEIGHT-1 - y, 20), LCD_HEIGHT-1));
1326 x++;
1329 break;
1331 case 1: /* status: */
1332 lcd_clear_display();
1333 lcd_puts(0, 0, "Power status:");
1335 y = (adc_read(ADC_UNREG_POWER) * BATTERY_SCALE_FACTOR) / 10000;
1336 snprintf(buf, 30, "Battery: %d.%02d V", y / 100, y % 100);
1337 lcd_puts(0, 1, buf);
1338 #ifdef ADC_EXT_POWER
1339 y = (adc_read(ADC_EXT_POWER) * EXT_SCALE_FACTOR) / 10000;
1340 snprintf(buf, 30, "External: %d.%02d V", y / 100, y % 100);
1341 lcd_puts(0, 2, buf);
1342 #endif
1343 #ifdef HAVE_CHARGING
1344 #ifdef HAVE_CHARGE_CTRL
1345 snprintf(buf, 30, "Chgr: %s %s",
1346 charger_inserted() ? "present" : "absent",
1347 charger_enabled ? "on" : "off");
1348 lcd_puts(0, 3, buf);
1349 snprintf(buf, 30, "short delta: %d", short_delta);
1350 lcd_puts(0, 5, buf);
1351 snprintf(buf, 30, "long delta: %d", long_delta);
1352 lcd_puts(0, 6, buf);
1353 lcd_puts(0, 7, power_message);
1354 #else /* !HAVE_CHARGE_CTRL */
1355 #if defined IPOD_NANO || defined IPOD_VIDEO
1356 int usb_pwr = (GPIOL_INPUT_VAL & 0x10)?true:false;
1357 int ext_pwr = (GPIOL_INPUT_VAL & 0x08)?false:true;
1358 int dock = (GPIOA_INPUT_VAL & 0x10)?true:false;
1359 int charging = (GPIOB_INPUT_VAL & 0x01)?false:true;
1360 int headphone= (GPIOA_INPUT_VAL & 0x80)?true:false;
1362 snprintf(buf, 30, "USB pwr: %s",
1363 usb_pwr ? "present" : "absent");
1364 lcd_puts(0, 3, buf);
1365 snprintf(buf, 30, "EXT pwr: %s",
1366 ext_pwr ? "present" : "absent");
1367 lcd_puts(0, 4, buf);
1368 snprintf(buf, 30, "Battery: %s",
1369 charging ? "charging" : (usb_pwr||ext_pwr) ? "charged" : "discharging");
1370 lcd_puts(0, 5, buf);
1371 snprintf(buf, 30, "Dock mode: %s",
1372 dock ? "enabled" : "disabled");
1373 lcd_puts(0, 6, buf);
1374 snprintf(buf, 30, "Headphone: %s",
1375 headphone ? "connected" : "disconnected");
1376 lcd_puts(0, 7, buf);
1377 #else
1378 snprintf(buf, 30, "Charger: %s",
1379 charger_inserted() ? "present" : "absent");
1380 lcd_puts(0, 3, buf);
1381 #endif
1382 #endif /* !HAVE_CHARGE_CTRL */
1383 #endif /* HAVE_CHARGING */
1384 break;
1386 case 2: /* voltage deltas: */
1387 lcd_clear_display();
1388 lcd_puts(0, 0, "Voltage deltas:");
1390 for (i = 0; i <= 6; i++) {
1391 y = power_history[i] - power_history[i+i];
1392 snprintf(buf, 30, "-%d min: %s%d.%02d V", i,
1393 (y < 0) ? "-" : "", ((y < 0) ? y * -1 : y) / 100,
1394 ((y < 0) ? y * -1 : y ) % 100);
1395 lcd_puts(0, i+1, buf);
1397 break;
1399 case 3: /* remaining time estimation: */
1400 lcd_clear_display();
1402 #ifdef HAVE_CHARGE_CTRL
1403 snprintf(buf, 30, "charge_state: %d", charge_state);
1404 lcd_puts(0, 0, buf);
1406 snprintf(buf, 30, "Cycle time: %d m", powermgmt_last_cycle_startstop_min);
1407 lcd_puts(0, 1, buf);
1409 snprintf(buf, 30, "Lvl@cyc st: %d%%", powermgmt_last_cycle_level);
1410 lcd_puts(0, 2, buf);
1412 snprintf(buf, 30, "P=%2d I=%2d", pid_p, pid_i);
1413 lcd_puts(0, 3, buf);
1415 snprintf(buf, 30, "Trickle sec: %d/60", trickle_sec);
1416 lcd_puts(0, 4, buf);
1417 #endif /* HAVE_CHARGE_CTRL */
1419 snprintf(buf, 30, "Last PwrHist: %d.%02d V",
1420 power_history[0] / 100,
1421 power_history[0] % 100);
1422 lcd_puts(0, 5, buf);
1424 snprintf(buf, 30, "battery level: %d%%", battery_level());
1425 lcd_puts(0, 6, buf);
1427 snprintf(buf, 30, "Est. remain: %d m", battery_time());
1428 lcd_puts(0, 7, buf);
1429 break;
1432 lcd_update();
1434 switch(button_get_w_tmo(HZ/2))
1436 case SETTINGS_DEC:
1437 if (view)
1438 view--;
1439 break;
1441 case SETTINGS_INC:
1442 if (view < 3)
1443 view++;
1444 break;
1446 case SETTINGS_OK:
1447 case SETTINGS_CANCEL:
1448 return false;
1451 return false;
1454 #endif /* HAVE_LCD_BITMAP */
1456 static bool view_runtime(void)
1458 char s[32];
1459 bool done = false;
1460 int state = 1;
1462 while(!done)
1464 int y=0;
1465 int t;
1466 int key;
1467 lcd_clear_display();
1468 #ifdef HAVE_LCD_BITMAP
1469 lcd_puts(0, y++, "Running time:");
1470 y++;
1471 #endif
1473 if (state & 1) {
1474 #ifdef HAVE_CHARGING
1475 if (charger_inserted()
1476 #ifdef HAVE_USB_POWER
1477 || usb_powered()
1478 #endif
1481 global_settings.runtime = 0;
1483 else
1484 #endif
1486 global_settings.runtime += ((current_tick - lasttime) / HZ);
1488 lasttime = current_tick;
1490 t = global_settings.runtime;
1491 lcd_puts(0, y++, "Current time");
1493 else {
1494 t = global_settings.topruntime;
1495 lcd_puts(0, y++, "Top time");
1498 snprintf(s, sizeof(s), "%dh %dm %ds",
1499 t / 3600, (t % 3600) / 60, t % 60);
1500 lcd_puts(0, y++, s);
1501 lcd_update();
1503 /* Wait for a key to be pushed */
1504 key = button_get_w_tmo(HZ);
1505 switch(key) {
1506 case SETTINGS_CANCEL:
1507 done = true;
1508 break;
1510 case SETTINGS_INC:
1511 case SETTINGS_DEC:
1512 if (state == 1)
1513 state = 2;
1514 else
1515 state = 1;
1516 break;
1518 case SETTINGS_OK:
1519 lcd_clear_display();
1520 lcd_puts(0,0,"Clear time?");
1521 lcd_puts(0,1,"PLAY = Yes");
1522 lcd_update();
1523 while (1) {
1524 key = button_get(true);
1525 if ( key == SETTINGS_OK ) {
1526 if ( state == 1 )
1527 global_settings.runtime = 0;
1528 else
1529 global_settings.topruntime = 0;
1530 break;
1532 if (!(key & BUTTON_REL)) /* ignore button releases */
1533 break;
1535 break;
1539 return false;
1542 #ifdef HAVE_MMC
1543 bool dbg_mmc_info(void)
1545 bool done = false;
1546 int currval = 0;
1547 tCardInfo *card;
1548 unsigned char pbuf[32], pbuf2[32];
1549 unsigned char card_name[7];
1551 static const unsigned char i_vmin[] = { 0, 1, 5, 10, 25, 35, 60, 100 };
1552 static const unsigned char i_vmax[] = { 1, 5, 10, 25, 35, 45, 80, 200 };
1553 static const unsigned char *kbit_units[] = { "kBit/s", "MBit/s", "GBit/s" };
1554 static const unsigned char *nsec_units[] = { "ns", "µs", "ms" };
1556 card_name[6] = '\0';
1558 lcd_setmargins(0, 0);
1559 lcd_setfont(FONT_SYSFIXED);
1561 while (!done)
1563 card = mmc_card_info(currval / 2);
1565 lcd_clear_display();
1566 snprintf(pbuf, sizeof(pbuf), "[MMC%d p%d]", currval / 2,
1567 (currval % 2) + 1);
1568 lcd_puts(0, 0, pbuf);
1570 if (card->initialized)
1572 if (!(currval % 2)) /* General info */
1574 strncpy(card_name, ((unsigned char*)card->cid) + 3, 6);
1575 snprintf(pbuf, sizeof(pbuf), "%s Rev %d.%d", card_name,
1576 (int) mmc_extract_bits(card->cid, 72, 4),
1577 (int) mmc_extract_bits(card->cid, 76, 4));
1578 lcd_puts(0, 1, pbuf);
1579 snprintf(pbuf, sizeof(pbuf), "Prod: %d/%d",
1580 (int) mmc_extract_bits(card->cid, 112, 4),
1581 (int) mmc_extract_bits(card->cid, 116, 4) + 1997);
1582 lcd_puts(0, 2, pbuf);
1583 snprintf(pbuf, sizeof(pbuf), "Ser#: 0x%08lx",
1584 mmc_extract_bits(card->cid, 80, 32));
1585 lcd_puts(0, 3, pbuf);
1586 snprintf(pbuf, sizeof(pbuf), "M=%02x, O=%04x",
1587 (int) mmc_extract_bits(card->cid, 0, 8),
1588 (int) mmc_extract_bits(card->cid, 8, 16));
1589 lcd_puts(0, 4, pbuf);
1590 snprintf(pbuf, sizeof(pbuf), "Blocks: 0x%06lx", card->numblocks);
1591 lcd_puts(0, 5, pbuf);
1592 snprintf(pbuf, sizeof(pbuf), "Blksz.: %d", card->blocksize);
1593 lcd_puts(0, 6, pbuf);
1595 else /* Technical details */
1597 output_dyn_value(pbuf2, sizeof pbuf2, card->speed / 1000,
1598 kbit_units, false);
1599 snprintf(pbuf, sizeof pbuf, "Speed: %s", pbuf2);
1600 lcd_puts(0, 1, pbuf);
1602 output_dyn_value(pbuf2, sizeof pbuf2, card->tsac,
1603 nsec_units, false);
1604 snprintf(pbuf, sizeof pbuf, "Tsac: %s", pbuf2);
1605 lcd_puts(0, 2, pbuf);
1607 snprintf(pbuf, sizeof(pbuf), "Nsac: %d clk", card->nsac);
1608 lcd_puts(0, 3, pbuf);
1609 snprintf(pbuf, sizeof(pbuf), "R2W: *%d", card->r2w_factor);
1610 lcd_puts(0, 4, pbuf);
1611 snprintf(pbuf, sizeof(pbuf), "IRmax: %d..%d mA",
1612 i_vmin[mmc_extract_bits(card->csd, 66, 3)],
1613 i_vmax[mmc_extract_bits(card->csd, 69, 3)]);
1614 lcd_puts(0, 5, pbuf);
1615 snprintf(pbuf, sizeof(pbuf), "IWmax: %d..%d mA",
1616 i_vmin[mmc_extract_bits(card->csd, 72, 3)],
1617 i_vmax[mmc_extract_bits(card->csd, 75, 3)]);
1618 lcd_puts(0, 6, pbuf);
1621 else
1622 lcd_puts(0, 1, "Not found!");
1624 lcd_update();
1626 switch (button_get_w_tmo(HZ/2))
1628 case SETTINGS_OK:
1629 case SETTINGS_CANCEL:
1630 done = true;
1631 break;
1633 case SETTINGS_DEC:
1634 currval--;
1635 if (currval < 0)
1636 currval = 3;
1637 break;
1639 case SETTINGS_INC:
1640 currval++;
1641 if (currval > 3)
1642 currval = 0;
1643 break;
1647 return false;
1649 #else /* !HAVE_MMC */
1650 static bool dbg_disk_info(void)
1652 char buf[128];
1653 bool done = false;
1654 int i;
1655 int page = 0;
1656 const int max_page = 11;
1657 unsigned short* identify_info = ata_get_identify();
1658 bool timing_info_present = false;
1659 char pio3[2], pio4[2];
1661 #ifdef HAVE_LCD_BITMAP
1662 lcd_setmargins(0, 0);
1663 #endif
1665 while(!done)
1667 int y=0;
1668 int key;
1669 lcd_clear_display();
1670 #ifdef HAVE_LCD_BITMAP
1671 lcd_puts(0, y++, "Disk info:");
1672 y++;
1673 #endif
1675 switch (page) {
1676 case 0:
1677 for (i=0; i < 20; i++)
1678 ((unsigned short*)buf)[i]=htobe16(identify_info[i+27]);
1679 buf[40]=0;
1680 /* kill trailing space */
1681 for (i=39; i && buf[i]==' '; i--)
1682 buf[i] = 0;
1683 lcd_puts(0, y++, "Model");
1684 lcd_puts_scroll(0, y++, buf);
1685 break;
1687 case 1:
1688 for (i=0; i < 4; i++)
1689 ((unsigned short*)buf)[i]=htobe16(identify_info[i+23]);
1690 buf[8]=0;
1691 lcd_puts(0, y++, "Firmware");
1692 lcd_puts(0, y++, buf);
1693 break;
1695 case 2:
1696 snprintf(buf, sizeof buf, "%ld MB",
1697 ((unsigned long)identify_info[61] << 16 |
1698 (unsigned long)identify_info[60]) / 2048 );
1699 lcd_puts(0, y++, "Size");
1700 lcd_puts(0, y++, buf);
1701 break;
1703 case 3: {
1704 unsigned long free;
1705 fat_size( IF_MV2(0,) NULL, &free );
1706 snprintf(buf, sizeof buf, "%ld MB", free / 1024 );
1707 lcd_puts(0, y++, "Free");
1708 lcd_puts(0, y++, buf);
1709 break;
1712 case 4:
1713 snprintf(buf, sizeof buf, "%d ms", ata_spinup_time * (1000/HZ));
1714 lcd_puts(0, y++, "Spinup time");
1715 lcd_puts(0, y++, buf);
1716 break;
1718 case 5:
1719 i = identify_info[83] & (1<<3);
1720 lcd_puts(0, y++, "Power mgmt:");
1721 lcd_puts(0, y++, i ? "enabled" : "unsupported");
1722 break;
1724 case 6:
1725 i = identify_info[83] & (1<<9);
1726 lcd_puts(0, y++, "Noise mgmt:");
1727 lcd_puts(0, y++, i ? "enabled" : "unsupported");
1728 break;
1730 case 7:
1731 i = identify_info[82] & (1<<6);
1732 lcd_puts(0, y++, "Read-ahead:");
1733 lcd_puts(0, y++, i ? "enabled" : "unsupported");
1734 break;
1736 case 8:
1737 timing_info_present = identify_info[53] & (1<<1);
1738 if(timing_info_present) {
1739 pio3[1] = 0;
1740 pio4[1] = 0;
1741 lcd_puts(0, y++, "PIO modes:");
1742 pio3[0] = (identify_info[64] & (1<<0)) ? '3' : 0;
1743 pio4[0] = (identify_info[64] & (1<<1)) ? '4' : 0;
1744 snprintf(buf, 128, "0 1 2 %s %s", pio3, pio4);
1745 lcd_puts(0, y++, buf);
1746 } else {
1747 lcd_puts(0, y++, "No PIO mode info");
1749 break;
1751 case 9:
1752 timing_info_present = identify_info[53] & (1<<1);
1753 if(timing_info_present) {
1754 lcd_puts(0, y++, "Cycle times");
1755 snprintf(buf, 128, "%dns/%dns",
1756 identify_info[67],
1757 identify_info[68]);
1758 lcd_puts(0, y++, buf);
1759 } else {
1760 lcd_puts(0, y++, "No timing info");
1762 break;
1764 case 10:
1765 timing_info_present = identify_info[53] & (1<<1);
1766 if(timing_info_present) {
1767 i = identify_info[49] & (1<<11);
1768 snprintf(buf, 128, "IORDY support: %s", i ? "yes" : "no");
1769 lcd_puts(0, y++, buf);
1770 i = identify_info[49] & (1<<10);
1771 snprintf(buf, 128, "IORDY disable: %s", i ? "yes" : "no");
1772 lcd_puts(0, y++, buf);
1773 } else {
1774 lcd_puts(0, y++, "No timing info");
1776 break;
1778 case 11:
1779 lcd_puts(0, y++, "Cluster size");
1780 snprintf(buf, 128, "%d bytes", fat_get_cluster_size(IF_MV(0)));
1781 lcd_puts(0, y++, buf);
1782 break;
1784 lcd_update();
1786 /* Wait for a key to be pushed */
1787 key = button_get_w_tmo(HZ*5);
1788 switch(key) {
1789 case SETTINGS_CANCEL:
1790 done = true;
1791 break;
1793 case SETTINGS_DEC:
1794 if (--page < 0)
1795 page = max_page;
1796 break;
1798 case SETTINGS_INC:
1799 if (++page > max_page)
1800 page = 0;
1801 break;
1803 case SETTINGS_OK:
1804 if (page == 3) {
1805 audio_stop(); /* stop playback, to avoid disk access */
1806 lcd_clear_display();
1807 lcd_puts(0,0,"Scanning");
1808 lcd_puts(0,1,"disk...");
1809 lcd_update();
1810 fat_recalc_free(IF_MV(0));
1812 break;
1814 lcd_stop_scroll();
1817 return false;
1819 #endif /* !HAVE_MMC */
1821 #ifdef HAVE_DIRCACHE
1822 static bool dbg_dircache_info(void)
1824 bool done = false;
1825 int line;
1826 char buf[32];
1828 lcd_setmargins(0, 0);
1829 lcd_setfont(FONT_SYSFIXED);
1831 while (!done)
1833 line = 0;
1835 lcd_clear_display();
1836 snprintf(buf, sizeof(buf), "Cache initialized: %s",
1837 dircache_is_enabled() ? "Yes" : "No");
1838 lcd_puts(0, line++, buf);
1840 snprintf(buf, sizeof(buf), "Cache size: %d B",
1841 dircache_get_cache_size());
1842 lcd_puts(0, line++, buf);
1844 snprintf(buf, sizeof(buf), "Last size: %d B",
1845 global_settings.dircache_size);
1846 lcd_puts(0, line++, buf);
1848 snprintf(buf, sizeof(buf), "Limit: %d B", DIRCACHE_LIMIT);
1849 lcd_puts(0, line++, buf);
1851 snprintf(buf, sizeof(buf), "Reserve: %d/%d B",
1852 dircache_get_reserve_used(), DIRCACHE_RESERVE);
1853 lcd_puts(0, line++, buf);
1855 snprintf(buf, sizeof(buf), "Scanning took: %d s",
1856 dircache_get_build_ticks() / HZ);
1857 lcd_puts(0, line++, buf);
1859 snprintf(buf, sizeof(buf), "Entry count: %d",
1860 dircache_get_entry_count());
1861 lcd_puts(0, line++, buf);
1863 lcd_update();
1865 switch (button_get_w_tmo(HZ/2))
1867 case SETTINGS_OK:
1868 case SETTINGS_CANCEL:
1869 done = true;
1870 break;
1874 return false;
1877 #endif /* HAVE_DIRCACHE */
1879 #ifdef HAVE_LCD_BITMAP
1880 static bool dbg_tagcache_info(void)
1882 bool done = false;
1883 int line;
1884 char buf[32];
1886 lcd_setmargins(0, 0);
1887 lcd_setfont(FONT_SYSFIXED);
1889 while (!done)
1891 line = 0;
1893 lcd_clear_display();
1894 snprintf(buf, sizeof(buf), "Current progress: %d%%",
1895 tagcache_get_progress());
1896 lcd_puts(0, line++, buf);
1898 lcd_update();
1900 switch (button_get_w_tmo(HZ/2))
1902 case SETTINGS_OK:
1903 case SETTINGS_CANCEL:
1904 done = true;
1905 break;
1909 return false;
1911 #endif
1913 #if CONFIG_CPU == SH7034
1914 bool dbg_save_roms(void)
1916 int fd;
1917 int oldmode = system_memory_guard(MEMGUARD_NONE);
1919 fd = creat("/internal_rom_0000-FFFF.bin", O_WRONLY);
1920 if(fd >= 0)
1922 write(fd, (void *)0, 0x10000);
1923 close(fd);
1926 fd = creat("/internal_rom_2000000-203FFFF.bin", O_WRONLY);
1927 if(fd >= 0)
1929 write(fd, (void *)0x2000000, 0x40000);
1930 close(fd);
1933 system_memory_guard(oldmode);
1934 return false;
1936 #elif defined CPU_COLDFIRE
1937 bool dbg_save_roms(void)
1939 int fd;
1940 int oldmode = system_memory_guard(MEMGUARD_NONE);
1942 #if defined(IRIVER_H100_SERIES)
1943 fd = creat("/internal_rom_000000-1FFFFF.bin", O_WRONLY);
1944 #elif defined(IRIVER_H300_SERIES)
1945 fd = creat("/internal_rom_000000-3FFFFF.bin", O_WRONLY);
1946 #elif defined(IAUDIO_X5)
1947 fd = creat("/internal_rom_000000-3FFFFF.bin", O_WRONLY);
1948 #endif
1949 if(fd >= 0)
1951 write(fd, (void *)0, FLASH_SIZE);
1952 close(fd);
1954 system_memory_guard(oldmode);
1955 return false;
1957 #endif /* CPU */
1959 #ifdef CONFIG_TUNER
1960 bool dbg_fm_radio(void)
1962 char buf[32];
1963 int button;
1964 bool fm_detected;
1966 #ifdef HAVE_LCD_BITMAP
1967 lcd_setmargins(0, 0);
1968 #endif
1970 while(1)
1972 lcd_clear_display();
1973 fm_detected = radio_hardware_present();
1975 snprintf(buf, sizeof buf, "HW detected: %s", fm_detected?"yes":"no");
1976 lcd_puts(0, 0, buf);
1977 lcd_update();
1979 button = button_get(true);
1981 switch(button)
1983 case SETTINGS_CANCEL:
1984 return false;
1987 return false;
1989 #endif /* CONFIG_TUNER */
1991 #ifdef HAVE_LCD_BITMAP
1992 extern bool do_screendump_instead_of_usb;
1994 bool dbg_screendump(void)
1996 do_screendump_instead_of_usb = !do_screendump_instead_of_usb;
1997 gui_syncsplash(HZ, true, "Screendump %s",
1998 do_screendump_instead_of_usb?"enabled":"disabled");
1999 return false;
2001 #endif /* HAVE_LCD_BITMAP */
2003 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
2004 bool dbg_set_memory_guard(void)
2006 static const struct opt_items names[MAXMEMGUARD] = {
2007 { "None", -1 },
2008 { "Flash ROM writes", -1 },
2009 { "Zero area (all)", -1 }
2011 int mode = system_memory_guard(MEMGUARD_KEEP);
2013 set_option( "Catch mem accesses", &mode, INT, names, MAXMEMGUARD, NULL);
2014 system_memory_guard(mode);
2016 return false;
2018 #endif /* CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) */
2020 bool debug_menu(void)
2022 int m;
2023 bool result;
2025 static const struct menu_item items[] = {
2026 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
2027 { "Dump ROM contents", dbg_save_roms },
2028 #endif
2029 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || (CONFIG_CPU == PP5020)
2030 { "View I/O ports", dbg_ports },
2031 #endif
2032 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
2033 { "CPU frequency", dbg_cpufreq },
2034 #endif
2035 #if defined(IRIVER_H100_SERIES) && !defined(SIMULATOR)
2036 { "S/PDIF analyzer", dbg_spdif },
2037 #endif
2038 #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE)
2039 { "Catch mem accesses", dbg_set_memory_guard },
2040 #endif
2041 { "View OS stacks", dbg_os },
2042 #ifdef HAVE_LCD_BITMAP
2043 { "View battery", view_battery },
2044 { "Screendump", dbg_screendump },
2045 #endif
2046 { "View HW info", dbg_hw_info },
2047 { "View partitions", dbg_partitions },
2048 #ifdef HAVE_MMC
2049 { "View MMC info", dbg_mmc_info },
2050 #else
2051 { "View disk info", dbg_disk_info },
2052 #endif
2053 #ifdef HAVE_DIRCACHE
2054 { "View dircache info", dbg_dircache_info },
2055 #endif
2056 #ifdef HAVE_LCD_BITMAP
2057 { "View tagcache info", dbg_tagcache_info },
2058 { "View audio thread", dbg_audio_thread },
2059 #ifdef PM_DEBUG
2060 { "pm histogram", peak_meter_histogram},
2061 #endif /* PM_DEBUG */
2062 #endif /* HAVE_LCD_BITMAP */
2063 { "View runtime", view_runtime },
2064 #ifdef CONFIG_TUNER
2065 { "FM Radio", dbg_fm_radio },
2066 #endif
2067 #ifdef ROCKBOX_HAS_LOGF
2068 {"logf", logfdisplay },
2069 {"logfdump", logfdump },
2070 #endif
2073 m=menu_init( items, sizeof items / sizeof(struct menu_item), NULL,
2074 NULL, NULL, NULL);
2075 result = menu_run(m);
2076 menu_exit(m);
2078 return result;
2081 #endif /* SIMULATOR */