Added ID3 searching
[kugel-rb.git] / apps / debug_menu.c
blob1c633200c22a081ead10226df3b5dd8d0b96c120
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 "mpeg.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
61 /*---------------------------------------------------*/
62 /* SPECIAL DEBUG STUFF */
63 /*---------------------------------------------------*/
64 extern int ata_device;
65 extern int ata_io_address;
66 extern int num_threads;
67 extern const char *thread_name[];
69 #ifdef HAVE_LCD_BITMAP
70 /* Test code!!! */
71 bool dbg_os(void)
73 char buf[32];
74 int button;
75 int i;
76 int usage;
78 #ifdef HAVE_LCD_BITMAP
79 lcd_setmargins(0, 0);
80 #endif
81 lcd_clear_display();
83 while(1)
85 lcd_puts(0, 0, "Stack usage:");
86 for(i = 0; i < num_threads;i++)
88 usage = thread_stack_usage(i);
89 snprintf(buf, 32, "%s: %d%%", thread_name[i], usage);
90 lcd_puts(0, 1+i, buf);
93 lcd_update();
95 button = button_get_w_tmo(HZ/10);
97 switch(button)
99 case SETTINGS_CANCEL:
100 return false;
103 return false;
105 #else
106 bool dbg_os(void)
108 char buf[32];
109 int button;
110 int usage;
111 int currval = 0;
113 #ifdef HAVE_LCD_BITMAP
114 lcd_setmargins(0, 0);
115 #endif
116 lcd_clear_display();
118 while(1)
120 lcd_puts(0, 0, "Stack usage");
122 usage = thread_stack_usage(currval);
123 snprintf(buf, 32, "%d: %d%% ", currval, usage);
124 lcd_puts(0, 1, buf);
126 button = button_get_w_tmo(HZ/10);
128 switch(button)
130 case SETTINGS_CANCEL:
131 return false;
133 case SETTINGS_DEC:
134 currval--;
135 if(currval < 0)
136 currval = num_threads-1;
137 break;
139 case SETTINGS_INC:
140 currval++;
141 if(currval > num_threads-1)
142 currval = 0;
143 break;
146 return false;
148 #endif
150 #ifdef HAVE_LCD_BITMAP
151 bool dbg_mpeg_thread(void)
153 char buf[32];
154 int button;
155 struct mpeg_debug d;
157 lcd_setmargins(0, 0);
159 while(1)
161 button = button_get_w_tmo(HZ/5);
162 switch(button)
164 case SETTINGS_CANCEL:
165 return false;
168 mpeg_get_debugdata(&d);
170 lcd_clear_display();
172 snprintf(buf, sizeof(buf), "read: %x", d.mp3buf_read);
173 lcd_puts(0, 0, buf);
174 snprintf(buf, sizeof(buf), "write: %x", d.mp3buf_write);
175 lcd_puts(0, 1, buf);
176 snprintf(buf, sizeof(buf), "swap: %x", d.mp3buf_swapwrite);
177 lcd_puts(0, 2, buf);
178 snprintf(buf, sizeof(buf), "playing: %d", d.playing);
179 lcd_puts(0, 3, buf);
180 snprintf(buf, sizeof(buf), "playable: %x", d.playable_space);
181 lcd_puts(0, 4, buf);
182 snprintf(buf, sizeof(buf), "unswapped: %x", d.unswapped_space);
183 lcd_puts(0, 5, buf);
185 /* Playable space left */
186 scrollbar(0, 6*8, 112, 4, d.mp3buflen, 0,
187 d.playable_space, HORIZONTAL);
189 /* Show the watermark limit */
190 scrollbar(0, 6*8+4, 112, 4, d.mp3buflen, 0,
191 d.low_watermark_level, HORIZONTAL);
193 snprintf(buf, sizeof(buf), "wm: %x - %x",
194 d.low_watermark_level, d.lowest_watermark_level);
195 lcd_puts(0, 7, buf);
197 lcd_update();
199 return false;
201 #endif
204 /* Tool function to calculate a CRC16 across some buffer */
205 unsigned short crc_16(const unsigned char* buf, unsigned len)
207 /* CCITT standard polynomial 0x1021 */
208 static const unsigned short crc16_lookup[16] =
209 { /* lookup table for 4 bits at a time is affordable */
210 0x0000, 0x1021, 0x2042, 0x3063,
211 0x4084, 0x50A5, 0x60C6, 0x70E7,
212 0x8108, 0x9129, 0xA14A, 0xB16B,
213 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF
215 unsigned short crc16 = 0xFFFF; /* initialise to 0xFFFF (CCITT specification) */
216 unsigned t;
217 unsigned char byte;
219 while (len--)
221 byte = *buf++; /* get one byte of data */
223 /* upper nibble of our data */
224 t = crc16 >> 12; /* extract the 4 most significant bits */
225 t ^= byte >> 4; /* XOR in 4 bits of the data into the extracted bits */
226 crc16 <<= 4; /* shift the CRC Register left 4 bits */
227 crc16 ^= crc16_lookup[t]; /* do the table lookup and XOR the result */
229 /* lower nibble of our data */
230 t = crc16 >> 12; /* extract the 4 most significant bits */
231 t ^= byte & 0x0F; /* XOR in 4 bits of the data into the extracted bits */
232 crc16 <<= 4; /* shift the CRC Register left 4 bits */
233 crc16 ^= crc16_lookup[t]; /* do the table lookup and XOR the result */
236 return crc16;
241 /* Tool function to read the flash manufacturer and type, if available.
242 Only chips which could be reprogrammed in system will return values.
243 (The mode switch addresses vary between flash manufacturers, hence addr1/2) */
244 /* In IRAM to avoid problems when running directly from Flash */
245 bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
246 unsigned addr1, unsigned addr2)
247 __attribute__ ((section (".icode")));
248 bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
249 unsigned addr1, unsigned addr2)
252 unsigned not_manu, not_id; /* read values before switching to ID mode */
253 unsigned manu, id; /* read values when in ID mode */
254 volatile unsigned char* flash = (unsigned char*)0x2000000; /* flash mapping */
255 int old_level; /* saved interrupt level */
257 not_manu = flash[0]; /* read the normal content */
258 not_id = flash[1]; /* should be 'A' (0x41) and 'R' (0x52) from the "ARCH" marker */
260 /* disable interrupts, prevent any stray flash access */
261 old_level = set_irq_level(HIGHEST_IRQ_LEVEL);
263 flash[addr1] = 0xAA; /* enter command mode */
264 flash[addr2] = 0x55;
265 flash[addr1] = 0x90; /* ID command */
266 /* Atmel wants 20ms pause here */
267 /* sleep(HZ/50); no sleeping possible while interrupts are disabled */
269 manu = flash[0]; /* read the IDs */
270 id = flash[1];
272 flash[0] = 0xF0; /* reset flash (back to normal read mode) */
273 /* Atmel wants 20ms pause here */
274 /* sleep(HZ/50); no sleeping possible while interrupts are disabled */
276 set_irq_level(old_level); /* enable interrupts again */
278 /* I assume success if the obtained values are different from
279 the normal flash content. This is not perfectly bulletproof, they
280 could theoretically be the same by chance, causing us to fail. */
281 if (not_manu != manu || not_id != id) /* a value has changed */
283 *p_manufacturer = manu; /* return the results */
284 *p_device = id;
285 return true; /* success */
287 return false; /* fail */
291 #ifdef HAVE_LCD_BITMAP
292 bool dbg_hw_info(void)
294 char buf[32];
295 int button;
296 int usb_polarity;
297 int pr_polarity;
298 int bitmask = *(unsigned short*)0x20000fc;
299 int rom_version = *(unsigned short*)0x20000fe;
300 unsigned manu, id; /* flash IDs */
301 bool got_id; /* flag if we managed to get the flash IDs */
302 unsigned rom_crc = 0xFFFF; /* CRC16 of the boot ROM */
303 bool has_bootrom; /* flag for boot ROM present */
304 int oldmode; /* saved memory guard mode */
306 #ifdef USB_ENABLE_ONDIOSTYLE
307 if(PADR & 0x20)
308 #else
309 if(PADR & 0x400)
310 #endif
311 usb_polarity = 0; /* Negative */
312 else
313 usb_polarity = 1; /* Positive */
315 if(PADR & 0x800)
316 pr_polarity = 0; /* Negative */
317 else
318 pr_polarity = 1; /* Positive */
320 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
322 /* get flash ROM type */
323 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
324 if (!got_id)
325 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
327 /* check if the boot ROM area is a flash mirror */
328 has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0);
329 if (has_bootrom) /* if ROM and Flash different */
331 /* calculate CRC16 checksum of boot ROM */
332 rom_crc = crc_16((unsigned char*)0x0000, 64*1024);
335 system_memory_guard(oldmode); /* re-enable memory guard */
337 lcd_setmargins(0, 0);
338 lcd_setfont(FONT_SYSFIXED);
339 lcd_clear_display();
341 lcd_puts(0, 0, "[Hardware info]");
343 snprintf(buf, 32, "ROM: %d.%02d", rom_version/100, rom_version%100);
344 lcd_puts(0, 1, buf);
346 snprintf(buf, 32, "Mask: 0x%04x", bitmask);
347 lcd_puts(0, 2, buf);
349 snprintf(buf, 32, "USB: %s", usb_polarity?"positive":"negative");
350 lcd_puts(0, 3, buf);
352 snprintf(buf, 32, "PR: %s", pr_polarity?"positive":"negative");
353 lcd_puts(0, 4, buf);
355 if (got_id)
356 snprintf(buf, 32, "Flash: M=%02x D=%02x", manu, id);
357 else
358 snprintf(buf, 32, "Flash: M=?? D=??"); /* unknown, sorry */
359 lcd_puts(0, 5, buf);
361 if (has_bootrom)
363 snprintf(buf, 32-3, "ROM CRC: 0x%04x", rom_crc);
364 if (rom_crc == 0x222F) /* known Version 1 */
365 strcat(buf, " V1");
367 else
369 snprintf(buf, 32, "Boot ROM: none");
371 lcd_puts(0, 6, buf);
373 #ifndef HAVE_MMC /* have ATA */
374 snprintf(buf, 32, "ATA: 0x%x,%s", ata_io_address,
375 ata_device ? "slave":"master");
376 lcd_puts(0, 7, buf);
377 #endif
378 lcd_update();
380 while(1)
382 button = button_get(true);
383 if(button == SETTINGS_CANCEL)
384 return false;
387 return false;
389 #else
390 bool dbg_hw_info(void)
392 char buf[32];
393 int button;
394 int currval = 0;
395 int usb_polarity;
396 int bitmask = *(unsigned short*)0x20000fc;
397 int rom_version = *(unsigned short*)0x20000fe;
398 unsigned manu, id; /* flash IDs */
399 bool got_id; /* flag if we managed to get the flash IDs */
400 unsigned rom_crc = 0xFFFF; /* CRC16 of the boot ROM */
401 bool has_bootrom; /* flag for boot ROM present */
402 int oldmode; /* saved memory guard mode */
404 if(PADR & 0x400)
405 usb_polarity = 0; /* Negative */
406 else
407 usb_polarity = 1; /* Positive */
409 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
411 /* get flash ROM type */
412 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
413 if (!got_id)
414 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
416 /* check if the boot ROM area is a flash mirror */
417 has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0);
418 if (has_bootrom) /* if ROM and Flash different */
420 /* calculate CRC16 checksum of boot ROM */
421 rom_crc = crc_16((unsigned char*)0x0000, 64*1024);
424 system_memory_guard(oldmode); /* re-enable memory guard */
426 lcd_clear_display();
428 lcd_puts(0, 0, "[HW Info]");
429 while(1)
431 switch(currval)
433 case 0:
434 snprintf(buf, 32, "ROM: %d.%02d",
435 rom_version/100, rom_version%100);
436 break;
437 case 1:
438 snprintf(buf, 32, "USB: %s",
439 usb_polarity?"pos":"neg");
440 break;
441 case 2:
442 snprintf(buf, 32, "ATA: 0x%x%s",
443 ata_io_address, ata_device ? "s":"m");
444 break;
445 case 3:
446 snprintf(buf, 32, "Mask: %04x", bitmask);
447 break;
448 case 4:
449 if (got_id)
450 snprintf(buf, 32, "Flash:%02x,%02x", manu, id);
451 else
452 snprintf(buf, 32, "Flash:??,??"); /* unknown, sorry */
453 break;
454 case 5:
455 if (has_bootrom)
456 snprintf(buf, 32, "RomCRC:%04x", rom_crc);
457 else
458 snprintf(buf, 32, "BootROM: no");
461 lcd_puts(0, 1, buf);
462 lcd_update();
464 button = button_get(true);
466 switch(button)
468 case SETTINGS_CANCEL:
469 return false;
471 case SETTINGS_DEC:
472 currval--;
473 if(currval < 0)
474 currval = 5;
475 break;
477 case SETTINGS_INC:
478 currval++;
479 if(currval > 5)
480 currval = 0;
481 break;
484 return false;
486 #endif
488 bool dbg_partitions(void)
490 int partition=0;
492 lcd_clear_display();
493 lcd_puts(0, 0, "Partition");
494 lcd_puts(0, 1, "list");
495 lcd_update();
496 sleep(HZ/2);
498 while(1)
500 char buf[32];
501 int button;
502 struct partinfo* p = disk_partinfo(partition);
504 lcd_clear_display();
505 snprintf(buf, sizeof buf, "P%d: S:%lx", partition, p->start);
506 lcd_puts(0, 0, buf);
507 snprintf(buf, sizeof buf, "T:%x %ld MB", p->type, p->size / 2048);
508 lcd_puts(0, 1, buf);
509 lcd_update();
511 button = button_get(true);
513 switch(button)
515 case SETTINGS_OK:
516 case SETTINGS_CANCEL:
517 return false;
519 case SETTINGS_DEC:
520 partition--;
521 if (partition < 0)
522 partition = 3;
523 break;
525 case SETTINGS_INC:
526 partition++;
527 if (partition > 3)
528 partition = 0;
529 break;
531 default:
532 if(default_event_handler(button) == SYS_USB_CONNECTED)
533 return true;
534 break;
537 return false;
540 #ifdef HAVE_LCD_BITMAP
541 /* Test code!!! */
542 bool dbg_ports(void)
544 unsigned short porta;
545 unsigned short portb;
546 unsigned char portc;
547 char buf[32];
548 int button;
549 int battery_voltage;
550 int batt_int, batt_frac;
552 #ifdef HAVE_LCD_BITMAP
553 lcd_setmargins(0, 0);
554 #endif
555 lcd_clear_display();
557 while(1)
559 porta = PADR;
560 portb = PBDR;
561 portc = PCDR;
563 snprintf(buf, 32, "PADR: %04x", porta);
564 lcd_puts(0, 0, buf);
565 snprintf(buf, 32, "PBDR: %04x", portb);
566 lcd_puts(0, 1, buf);
568 snprintf(buf, 32, "AN0: %03x AN4: %03x", adc_read(0), adc_read(4));
569 lcd_puts(0, 2, buf);
570 snprintf(buf, 32, "AN1: %03x AN5: %03x", adc_read(1), adc_read(5));
571 lcd_puts(0, 3, buf);
572 snprintf(buf, 32, "AN2: %03x AN6: %03x", adc_read(2), adc_read(6));
573 lcd_puts(0, 4, buf);
574 snprintf(buf, 32, "AN3: %03x AN7: %03x", adc_read(3), adc_read(7));
575 lcd_puts(0, 5, buf);
577 battery_voltage = (adc_read(ADC_UNREG_POWER) * BATTERY_SCALE_FACTOR) / 10000;
578 batt_int = battery_voltage / 100;
579 batt_frac = battery_voltage % 100;
581 snprintf(buf, 32, "Batt: %d.%02dV %d%% ", batt_int, batt_frac,
582 battery_level());
583 lcd_puts(0, 6, buf);
584 #ifndef HAVE_MMC /* have ATA */
585 snprintf(buf, 32, "ATA: %s, 0x%x",
586 ata_device?"slave":"master", ata_io_address);
587 lcd_puts(0, 7, buf);
588 #endif
589 lcd_update();
590 button = button_get_w_tmo(HZ/10);
592 switch(button)
594 case SETTINGS_CANCEL:
595 return false;
598 return false;
600 #else
601 bool dbg_ports(void)
603 unsigned short porta;
604 unsigned short portb;
605 unsigned char portc;
606 char buf[32];
607 int button;
608 int battery_voltage;
609 int batt_int, batt_frac;
610 int currval = 0;
612 #ifdef HAVE_LCD_BITMAP
613 lcd_setmargins(0, 0);
614 #endif
615 lcd_clear_display();
617 while(1)
619 porta = PADR;
620 portb = PBDR;
621 portc = PCDR;
623 switch(currval)
625 case 0:
626 snprintf(buf, 32, "PADR: %04x ", porta);
627 break;
628 case 1:
629 snprintf(buf, 32, "PBDR: %04x ", portb);
630 break;
631 case 2:
632 snprintf(buf, 32, "AN0: %03x ", adc_read(0));
633 break;
634 case 3:
635 snprintf(buf, 32, "AN1: %03x ", adc_read(1));
636 break;
637 case 4:
638 snprintf(buf, 32, "AN2: %03x ", adc_read(2));
639 break;
640 case 5:
641 snprintf(buf, 32, "AN3: %03x ", adc_read(3));
642 break;
643 case 6:
644 snprintf(buf, 32, "AN4: %03x ", adc_read(4));
645 break;
646 case 7:
647 snprintf(buf, 32, "AN5: %03x ", adc_read(5));
648 break;
649 case 8:
650 snprintf(buf, 32, "AN6: %03x ", adc_read(6));
651 break;
652 case 9:
653 snprintf(buf, 32, "AN7: %03x ", adc_read(7));
654 break;
655 case 10:
656 snprintf(buf, 32, "%s, 0x%x ",
657 ata_device?"slv":"mst", ata_io_address);
658 break;
660 lcd_puts(0, 0, buf);
662 battery_voltage = (adc_read(ADC_UNREG_POWER) *
663 BATTERY_SCALE_FACTOR) / 10000;
664 batt_int = battery_voltage / 100;
665 batt_frac = battery_voltage % 100;
667 snprintf(buf, 32, "Batt: %d.%02dV", batt_int, batt_frac);
668 lcd_puts(0, 1, buf);
670 button = button_get_w_tmo(HZ/5);
672 switch(button)
674 case SETTINGS_CANCEL:
675 return false;
677 case SETTINGS_DEC:
678 currval--;
679 if(currval < 0)
680 currval = 10;
681 break;
683 case SETTINGS_INC:
684 currval++;
685 if(currval > 10)
686 currval = 0;
687 break;
690 return false;
692 #endif
694 #ifdef HAVE_RTC
695 /* Read RTC RAM contents and display them */
696 bool dbg_rtc(void)
698 char buf[32];
699 unsigned char addr = 0, r, c;
700 int i;
701 int button;
703 #ifdef HAVE_LCD_BITMAP
704 lcd_setmargins(0, 0);
705 #endif
706 lcd_clear_display();
707 lcd_puts(0, 0, "RTC read:");
709 while(1)
711 for (r = 0; r < 4; r++) {
712 snprintf(buf, 10, "0x%02x: ", addr + r*4);
713 for (c = 0; c <= 3; c++) {
714 i = rtc_read(addr + r*4 + c);
715 snprintf(buf + 6 + c*2, 3, "%02x", i);
717 lcd_puts(1, r+1, buf);
720 lcd_update();
722 button = button_get_w_tmo(HZ/2);
724 switch(button)
726 case SETTINGS_INC:
727 if (addr < 63-16) { addr += 16; }
728 break;
730 case SETTINGS_DEC:
731 if (addr) { addr -= 16; }
732 break;
734 #ifdef BUTTON_F2
735 case BUTTON_F2:
736 /* clear the user RAM space */
737 for (c = 0; c <= 43; c++)
738 rtc_write(0x14 + c, 0);
739 break;
740 #endif
742 case SETTINGS_OK:
743 case SETTINGS_CANCEL:
744 return false;
747 return false;
749 #else
750 bool dbg_rtc(void)
752 return false;
754 #endif
756 #ifdef HAVE_LCD_CHARCELLS
757 #define NUMROWS 1
758 #else
759 #define NUMROWS 4
760 #endif
761 /* Read MAS registers and display them */
762 bool dbg_mas(void)
764 char buf[32];
765 unsigned int addr = 0, r, i;
767 #ifdef HAVE_LCD_BITMAP
768 lcd_setmargins(0, 0);
769 #endif
770 lcd_clear_display();
771 lcd_puts(0, 0, "MAS register read:");
773 while(1)
775 for (r = 0; r < NUMROWS; r++) {
776 i = mas_readreg(addr + r);
777 snprintf(buf, 30, "%02x %08x", addr + r, i);
778 lcd_puts(0, r+1, buf);
781 lcd_update();
783 switch(button_get_w_tmo(HZ/16))
785 case SETTINGS_INC:
786 addr = (addr + NUMROWS) & 0xFF; /* register addrs are 8 bit */
787 break;
789 case SETTINGS_DEC:
790 addr = (addr - NUMROWS) & 0xFF; /* register addrs are 8 bit */
791 break;
793 case SETTINGS_OK:
794 case SETTINGS_CANCEL:
795 return false;
798 return false;
801 #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
802 bool dbg_mas_codec(void)
804 char buf[32];
805 unsigned int addr = 0, r, i;
807 #ifdef HAVE_LCD_BITMAP
808 lcd_setmargins(0, 0);
809 #endif
810 lcd_clear_display();
811 lcd_puts(0, 0, "MAS codec reg read:");
813 while(1)
815 for (r = 0; r < 4; r++) {
816 i = mas_codec_readreg(addr + r);
817 snprintf(buf, 30, "0x%02x: %08x", addr + r, i);
818 lcd_puts(1, r+1, buf);
821 lcd_update();
823 switch(button_get_w_tmo(HZ/16))
825 case SETTINGS_INC:
826 addr += 4;
827 break;
828 case SETTINGS_DEC:
829 if (addr) { addr -= 4; }
830 break;
832 case SETTINGS_OK:
833 case SETTINGS_CANCEL:
834 return false;
837 return false;
839 #endif
841 #ifdef HAVE_LCD_BITMAP
843 * view_battery() shows a automatically scaled graph of the battery voltage
844 * over time. Usable for estimating battery life / charging rate.
845 * The power_history array is updated in power_thread of powermgmt.c.
848 #define BAT_FIRST_VAL MAX(POWER_HISTORY_LEN - LCD_WIDTH - 1, 0)
849 #define BAT_YSPACE (LCD_HEIGHT - 20)
851 bool view_battery(void)
853 int view = 0;
854 int i, x, y;
855 int maxv, minv;
856 char buf[32];
858 #ifdef HAVE_LCD_BITMAP
859 lcd_setmargins(0, 0);
860 #endif
861 while(1)
863 switch (view) {
864 case 0: /* voltage history graph */
865 /* Find maximum and minimum voltage for scaling */
866 maxv = minv = 0;
867 for (i = BAT_FIRST_VAL; i < POWER_HISTORY_LEN; i++) {
868 if (power_history[i] > maxv)
869 maxv = power_history[i];
870 if ((minv == 0) || ((power_history[i]) &&
871 (power_history[i] < minv)) )
873 minv = power_history[i];
877 if (minv < 1)
878 minv = 1;
879 if (maxv < 2)
880 maxv = 2;
882 lcd_clear_display();
883 lcd_puts(0, 0, "Battery voltage:");
884 snprintf(buf, 30, "scale %d.%02d-%d.%02d V",
885 minv / 100, minv % 100, maxv / 100, maxv % 100);
886 lcd_puts(0, 1, buf);
888 x = 0;
889 for (i = BAT_FIRST_VAL+1; i < POWER_HISTORY_LEN; i++) {
890 y = (power_history[i] - minv) * BAT_YSPACE / (maxv - minv);
891 lcd_clearline(x, LCD_HEIGHT-1, x, 20);
892 lcd_drawline(x, LCD_HEIGHT-1, x,
893 MIN(MAX(LCD_HEIGHT-1 - y, 20), LCD_HEIGHT-1));
894 x++;
897 break;
899 case 1: /* status: */
900 lcd_clear_display();
901 lcd_puts(0, 0, "Power status:");
903 y = (adc_read(ADC_UNREG_POWER) * BATTERY_SCALE_FACTOR) / 10000;
904 snprintf(buf, 30, "Battery: %d.%02d V", y / 100, y % 100);
905 lcd_puts(0, 1, buf);
906 #ifdef ADC_EXT_POWER
907 y = (adc_read(ADC_EXT_POWER) * EXT_SCALE_FACTOR) / 10000;
908 snprintf(buf, 30, "External: %d.%02d V", y / 100, y % 100);
909 lcd_puts(0, 2, buf);
910 #endif
911 #ifdef HAVE_CHARGING
912 snprintf(buf, 30, "Charger: %s",
913 charger_inserted() ? "present" : "absent");
914 lcd_puts(0, 3, buf);
915 #ifdef HAVE_CHARGE_CTRL
916 snprintf(buf, 30, "Charging: %s",
917 charger_enabled ? "yes" : "no");
918 lcd_puts(0, 4, buf);
919 #endif
920 #endif
921 y = ( power_history[POWER_HISTORY_LEN-1] * 100
922 + power_history[POWER_HISTORY_LEN-2] * 100
923 - power_history[POWER_HISTORY_LEN-1-CHARGE_END_NEGD+1] * 100
924 - power_history[POWER_HISTORY_LEN-1-CHARGE_END_NEGD] * 100 )
925 / CHARGE_END_NEGD / 2;
927 snprintf(buf, 30, "short delta: %d", y);
928 lcd_puts(0, 5, buf);
930 y = ( power_history[POWER_HISTORY_LEN-1] * 100
931 + power_history[POWER_HISTORY_LEN-2] * 100
932 - power_history[POWER_HISTORY_LEN-1-CHARGE_END_ZEROD+1] * 100
933 - power_history[POWER_HISTORY_LEN-1-CHARGE_END_ZEROD] * 100 )
934 / CHARGE_END_ZEROD / 2;
936 snprintf(buf, 30, "long delta: %d", y);
937 lcd_puts(0, 6, buf);
939 #ifdef HAVE_CHARGE_CTRL
940 lcd_puts(0, 7, power_message);
941 #endif
942 break;
944 case 2: /* voltage deltas: */
945 lcd_clear_display();
946 lcd_puts(0, 0, "Voltage deltas:");
948 for (i = 0; i <= 6; i++) {
949 y = power_history[POWER_HISTORY_LEN-1-i] -
950 power_history[POWER_HISTORY_LEN-1-i-1];
951 snprintf(buf, 30, "-%d min: %s%d.%02d V", i,
952 (y < 0) ? "-" : "", ((y < 0) ? y * -1 : y) / 100,
953 ((y < 0) ? y * -1 : y ) % 100);
954 lcd_puts(0, i+1, buf);
956 break;
958 case 3: /* remeining time estimation: */
959 lcd_clear_display();
961 #ifdef HAVE_CHARGE_CTRL
962 snprintf(buf, 30, "charge_state: %d", charge_state);
963 lcd_puts(0, 0, buf);
965 snprintf(buf, 30, "Cycle time: %d m", powermgmt_last_cycle_startstop_min);
966 lcd_puts(0, 1, buf);
968 snprintf(buf, 30, "Lev.at cycle start: %d%%", powermgmt_last_cycle_level);
969 lcd_puts(0, 2, buf);
970 #endif
972 snprintf(buf, 30, "Last PwrHist val: %d.%02d V",
973 power_history[POWER_HISTORY_LEN-1] / 100,
974 power_history[POWER_HISTORY_LEN-1] % 100);
975 lcd_puts(0, 3, buf);
977 snprintf(buf, 30, "battery level: %d%%", battery_level());
978 lcd_puts(0, 5, buf);
980 snprintf(buf, 30, "Est. remaining: %d m", battery_time());
981 lcd_puts(0, 6, buf);
983 #ifdef HAVE_CHARGE_CTRL
984 snprintf(buf, 30, "Trickle sec: %d/60", trickle_sec);
985 lcd_puts(0, 7, buf);
986 #endif
987 break;
990 lcd_update();
992 switch(button_get_w_tmo(HZ/2))
994 case SETTINGS_DEC:
995 if (view)
996 view--;
997 break;
999 case SETTINGS_INC:
1000 if (view < 3)
1001 view++;
1002 break;
1004 case SETTINGS_OK:
1005 case SETTINGS_CANCEL:
1006 return false;
1009 return false;
1012 #endif
1014 #if CONFIG_HWCODEC == MAS3507D
1015 bool dbg_mas_info(void)
1017 int button;
1018 char buf[32];
1019 int currval = 0;
1020 unsigned long val;
1021 unsigned long pll48, pll44, config;
1022 int pll_toggle = 0;
1024 #ifdef HAVE_LCD_BITMAP
1025 lcd_setmargins(0, 0);
1026 #endif
1027 while(1)
1029 switch(currval)
1031 case 0:
1032 mas_readmem(MAS_BANK_D1, 0xff7, &val, 1);
1033 lcd_puts(0, 0, "Design Code");
1034 snprintf(buf, 32, "%05lx ", val);
1035 break;
1036 case 1:
1037 lcd_puts(0, 0, "DC/DC mode ");
1038 snprintf(buf, 32, "8e: %05x ", mas_readreg(0x8e) & 0xfffff);
1039 break;
1040 case 2:
1041 lcd_puts(0, 0, "Mute/Bypass");
1042 snprintf(buf, 32, "aa: %05x ", mas_readreg(0xaa) & 0xfffff);
1043 break;
1044 case 3:
1045 lcd_puts(0, 0, "PIOData ");
1046 snprintf(buf, 32, "ed: %05x ", mas_readreg(0xed) & 0xfffff);
1047 break;
1048 case 4:
1049 lcd_puts(0, 0, "Startup Cfg");
1050 snprintf(buf, 32, "e6: %05x ", mas_readreg(0xe6) & 0xfffff);
1051 break;
1052 case 5:
1053 lcd_puts(0, 0, "KPrescale ");
1054 snprintf(buf, 32, "e7: %05x ", mas_readreg(0xe7) & 0xfffff);
1055 break;
1056 case 6:
1057 lcd_puts(0, 0, "KBass ");
1058 snprintf(buf, 32, "6b: %05x ", mas_readreg(0x6b) & 0xfffff);
1059 break;
1060 case 7:
1061 lcd_puts(0, 0, "KTreble ");
1062 snprintf(buf, 32, "6f: %05x ", mas_readreg(0x6f) & 0xfffff);
1063 break;
1064 case 8:
1065 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_FRAME_COUNT, &val, 1);
1066 lcd_puts(0, 0, "Frame Count");
1067 snprintf(buf, 32, "0/300: %04x", (unsigned int)(val & 0xffff));
1068 break;
1069 case 9:
1070 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_STATUS_1, &val, 1);
1071 lcd_puts(0, 0, "Status1 ");
1072 snprintf(buf, 32, "0/301: %04x", (unsigned int)(val & 0xffff));
1073 break;
1074 case 10:
1075 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_STATUS_2, &val, 1);
1076 lcd_puts(0, 0, "Status2 ");
1077 snprintf(buf, 32, "0/302: %04x", (unsigned int)(val & 0xffff));
1078 break;
1079 case 11:
1080 mas_readmem(MAS_BANK_D0, MAS_D0_CRC_ERROR_COUNT, &val, 1);
1081 lcd_puts(0, 0, "CRC Count ");
1082 snprintf(buf, 32, "0/303: %04x", (unsigned int)(val & 0xffff));
1083 break;
1084 case 12:
1085 mas_readmem(MAS_BANK_D0, 0x36d, &val, 1);
1086 lcd_puts(0, 0, "PLLOffset48");
1087 snprintf(buf, 32, "0/36d %05lx", val & 0xfffff);
1088 break;
1089 case 13:
1090 mas_readmem(MAS_BANK_D0, 0x32d, &val, 1);
1091 lcd_puts(0, 0, "PLLOffset48");
1092 snprintf(buf, 32, "0/32d %05lx", val & 0xfffff);
1093 break;
1094 case 14:
1095 mas_readmem(MAS_BANK_D0, 0x36e, &val, 1);
1096 lcd_puts(0, 0, "PLLOffset44");
1097 snprintf(buf, 32, "0/36e %05lx", val & 0xfffff);
1098 break;
1099 case 15:
1100 mas_readmem(MAS_BANK_D0, 0x32e, &val, 1);
1101 lcd_puts(0, 0, "PLLOffset44");
1102 snprintf(buf, 32, "0/32e %05lx", val & 0xfffff);
1103 break;
1104 case 16:
1105 mas_readmem(MAS_BANK_D0, 0x36f, &val, 1);
1106 lcd_puts(0, 0, "OutputConf ");
1107 snprintf(buf, 32, "0/36f %05lx", val & 0xfffff);
1108 break;
1109 case 17:
1110 mas_readmem(MAS_BANK_D0, 0x32f, &val, 1);
1111 lcd_puts(0, 0, "OutputConf ");
1112 snprintf(buf, 32, "0/32f %05lx", val & 0xfffff);
1113 break;
1114 case 18:
1115 mas_readmem(MAS_BANK_D1, 0x7f8, &val, 1);
1116 lcd_puts(0, 0, "LL Gain ");
1117 snprintf(buf, 32, "1/7f8 %05lx", val & 0xfffff);
1118 break;
1119 case 19:
1120 mas_readmem(MAS_BANK_D1, 0x7f9, &val, 1);
1121 lcd_puts(0, 0, "LR Gain ");
1122 snprintf(buf, 32, "1/7f9 %05lx", val & 0xfffff);
1123 break;
1124 case 20:
1125 mas_readmem(MAS_BANK_D1, 0x7fa, &val, 1);
1126 lcd_puts(0, 0, "RL Gain ");
1127 snprintf(buf, 32, "1/7fa %05lx", val & 0xfffff);
1128 break;
1129 case 21:
1130 mas_readmem(MAS_BANK_D1, 0x7fb, &val, 1);
1131 lcd_puts(0, 0, "RR Gain ");
1132 snprintf(buf, 32, "1/7fb %05lx", val & 0xfffff);
1133 break;
1134 case 22:
1135 lcd_puts(0, 0, "L Trailbits");
1136 snprintf(buf, 32, "c5: %05x ", mas_readreg(0xc5) & 0xfffff);
1137 break;
1138 case 23:
1139 lcd_puts(0, 0, "R Trailbits");
1140 snprintf(buf, 32, "c6: %05x ", mas_readreg(0xc6) & 0xfffff);
1141 break;
1143 lcd_puts(0, 1, buf);
1145 button = button_get_w_tmo(HZ/5);
1146 switch(button)
1148 case SETTINGS_CANCEL:
1149 return false;
1151 case SETTINGS_DEC:
1152 currval--;
1153 if(currval < 0)
1154 currval = 23;
1155 break;
1157 case SETTINGS_INC:
1158 currval++;
1159 if(currval > 23)
1160 currval = 0;
1161 break;
1163 case SETTINGS_OK:
1164 pll_toggle = !pll_toggle;
1165 if(pll_toggle)
1167 /* 14.31818 MHz crystal */
1168 pll48 = 0x5d9d0;
1169 pll44 = 0xfffceceb;
1170 config = 0;
1172 else
1174 /* 14.725 MHz crystal */
1175 pll48 = 0x2d0de;
1176 pll44 = 0xfffa2319;
1177 config = 0;
1179 mas_writemem(MAS_BANK_D0, 0x32d, &pll48, 1);
1180 mas_writemem(MAS_BANK_D0, 0x32e, &pll44, 1);
1181 mas_writemem(MAS_BANK_D0, 0x32f, &config, 1);
1182 mas_run(0x475);
1183 break;
1186 return false;
1188 #endif
1190 static bool view_runtime(void)
1192 char s[32];
1193 bool done = false;
1194 int state = 1;
1196 while(!done)
1198 int y=0;
1199 int t;
1200 int key;
1201 lcd_clear_display();
1202 #ifdef HAVE_LCD_BITMAP
1203 lcd_puts(0, y++, "Running time:");
1204 y++;
1205 #endif
1207 if (state & 1) {
1208 if (charger_inserted())
1210 global_settings.runtime = 0;
1212 else
1214 global_settings.runtime += ((current_tick - lasttime) / HZ);
1216 lasttime = current_tick;
1218 t = global_settings.runtime;
1219 lcd_puts(0, y++, "Current time");
1221 else {
1222 t = global_settings.topruntime;
1223 lcd_puts(0, y++, "Top time");
1226 snprintf(s, sizeof(s), "%dh %dm %ds",
1227 t / 3600, (t % 3600) / 60, t % 60);
1228 lcd_puts(0, y++, s);
1229 lcd_update();
1231 /* Wait for a key to be pushed */
1232 key = button_get_w_tmo(HZ);
1233 switch(key) {
1234 case SETTINGS_CANCEL:
1235 done = true;
1236 break;
1238 case SETTINGS_INC:
1239 case SETTINGS_DEC:
1240 if (state == 1)
1241 state = 2;
1242 else
1243 state = 1;
1244 break;
1246 case SETTINGS_OK:
1247 lcd_clear_display();
1248 lcd_puts(0,0,"Clear time?");
1249 lcd_puts(0,1,"PLAY = Yes");
1250 lcd_update();
1251 while (1) {
1252 key = button_get(true);
1253 if ( key == SETTINGS_OK ) {
1254 if ( state == 1 )
1255 global_settings.runtime = 0;
1256 else
1257 global_settings.topruntime = 0;
1258 break;
1260 if (!(key & BUTTON_REL)) /* ignore button releases */
1261 break;
1263 break;
1267 return false;
1270 #ifdef HAVE_MMC
1271 /* value is 10 * real value */
1272 static unsigned char prep_value_unit(unsigned long *value,
1273 const unsigned char *units)
1275 int unit_no = 0;
1277 while (*value >= 10000)
1279 *value /= 1000;
1280 unit_no++;
1282 return units[unit_no];
1285 bool dbg_mmc_info(void)
1287 bool done = false;
1288 int currval = 0;
1289 unsigned long value;
1290 tCardInfo *card;
1291 unsigned char pbuf[32];
1292 unsigned char card_name[7];
1293 unsigned char unit;
1295 static const unsigned char i_vmin[] = { 0, 1, 5, 10, 25, 35, 60, 100 };
1296 static const unsigned char i_vmax[] = { 1, 5, 10, 25, 35, 45, 80, 200 };
1298 card_name[6] = '\0';
1300 lcd_setmargins(0, 0);
1301 lcd_setfont(FONT_SYSFIXED);
1303 while (!done)
1305 card = mmc_card_info(currval / 2);
1307 lcd_clear_display();
1308 snprintf(pbuf, sizeof(pbuf), "[MMC%d p%d]", currval / 2,
1309 (currval % 2) + 1);
1310 lcd_puts(0, 0, pbuf);
1312 if (card->initialized)
1314 if (!(currval % 2)) /* General info */
1316 strncpy(card_name, ((unsigned char*)card->cid) + 3, 6);
1317 snprintf(pbuf, sizeof(pbuf), "%s Rev %d.%d", card_name,
1318 (int) mmc_extract_bits(card->cid, 72, 4),
1319 (int) mmc_extract_bits(card->cid, 76, 4));
1320 lcd_puts(0, 1, pbuf);
1321 snprintf(pbuf, sizeof(pbuf), "Prod: %d/%d",
1322 (int) mmc_extract_bits(card->cid, 112, 4),
1323 (int) mmc_extract_bits(card->cid, 116, 4) + 1997);
1324 lcd_puts(0, 2, pbuf);
1325 snprintf(pbuf, sizeof(pbuf), "Ser#: 0x%08lx",
1326 mmc_extract_bits(card->cid, 80, 32));
1327 lcd_puts(0, 3, pbuf);
1328 snprintf(pbuf, sizeof(pbuf), "M=%02x, O=%04x",
1329 (int) mmc_extract_bits(card->cid, 0, 8),
1330 (int) mmc_extract_bits(card->cid, 8, 16));
1331 lcd_puts(0, 4, pbuf);
1332 value = mmc_extract_bits(card->csd, 54, 12)
1333 * (SECTOR_SIZE << (mmc_extract_bits(card->csd, 78, 3)+2));
1334 snprintf(pbuf, sizeof(pbuf), "Size: %ld MB",
1335 value / (1024*1024));
1336 lcd_puts(0, 5, pbuf);
1338 else /* Technical details */
1340 value = card->speed / 100;
1341 unit = prep_value_unit(&value, "kMG");
1342 if (value < 100)
1343 snprintf(pbuf, sizeof(pbuf), "Speed: %d.%01d %cBit/s",
1344 (int)(value / 10), (int)(value % 10), unit);
1345 else
1346 snprintf(pbuf, sizeof(pbuf), "Speed: %d %cBit/s",
1347 (int)(value / 10), unit);
1348 lcd_puts(0, 1, pbuf);
1350 value = card->tsac;
1351 unit = prep_value_unit(&value, "nµm");
1352 if (value < 100)
1353 snprintf(pbuf, sizeof(pbuf), "Tsac: %d.%01d %cs",
1354 (int)(value / 10), (int)(value % 10), unit);
1355 else
1356 snprintf(pbuf, sizeof(pbuf), "Tsac: %d %cs",
1357 (int)(value / 10), unit);
1358 lcd_puts(0, 2, pbuf);
1360 snprintf(pbuf, sizeof(pbuf), "Nsac: %d clk", card->nsac);
1361 lcd_puts(0, 3, pbuf);
1362 snprintf(pbuf, sizeof(pbuf), "R2W: *%d", card->r2w_factor);
1363 lcd_puts(0, 4, pbuf);
1364 snprintf(pbuf, sizeof(pbuf), "IRmax: %d..%d mA",
1365 i_vmin[mmc_extract_bits(card->csd, 66, 3)],
1366 i_vmax[mmc_extract_bits(card->csd, 69, 3)]);
1367 lcd_puts(0, 5, pbuf);
1368 snprintf(pbuf, sizeof(pbuf), "IWmax: %d..%d mA",
1369 i_vmin[mmc_extract_bits(card->csd, 72, 3)],
1370 i_vmax[mmc_extract_bits(card->csd, 75, 3)]);
1371 lcd_puts(0, 6, pbuf);
1374 else
1375 lcd_puts(0, 1, "Not found!");
1377 lcd_update();
1379 switch (button_get_w_tmo(HZ/2))
1381 case SETTINGS_OK:
1382 case SETTINGS_CANCEL:
1383 done = true;
1384 break;
1386 case SETTINGS_DEC:
1387 currval--;
1388 if (currval < 0)
1389 currval = 3;
1390 break;
1392 case SETTINGS_INC:
1393 currval++;
1394 if (currval > 3)
1395 currval = 0;
1396 break;
1400 return false;
1402 #else /* Disk-based jukebox */
1403 static bool dbg_disk_info(void)
1405 char buf[128];
1406 bool done = false;
1407 int i;
1408 int page = 0;
1409 const int max_page = 11;
1410 unsigned short* identify_info = ata_get_identify();
1411 bool timing_info_present = false;
1412 char pio3[2], pio4[2];
1414 #ifdef HAVE_LCD_BITMAP
1415 lcd_setmargins(0, 0);
1416 #endif
1418 while(!done)
1420 int y=0;
1421 int key;
1422 lcd_clear_display();
1423 #ifdef HAVE_LCD_BITMAP
1424 lcd_puts(0, y++, "Disk info:");
1425 y++;
1426 #endif
1428 switch (page) {
1429 case 0:
1430 for (i=0; i < 20; i++)
1431 ((unsigned short*)buf)[i]=identify_info[i+27];
1432 buf[40]=0;
1433 /* kill trailing space */
1434 for (i=39; i && buf[i]==' '; i--)
1435 buf[i] = 0;
1436 lcd_puts(0, y++, "Model");
1437 lcd_puts_scroll(0, y++, buf);
1438 break;
1440 case 1:
1441 for (i=0; i < 4; i++)
1442 ((unsigned short*)buf)[i]=identify_info[i+23];
1443 buf[8]=0;
1444 lcd_puts(0, y++, "Firmware");
1445 lcd_puts(0, y++, buf);
1446 break;
1448 case 2:
1449 snprintf(buf, sizeof buf, "%d MB",
1450 ((unsigned)identify_info[61] << 16 |
1451 (unsigned)identify_info[60]) / 2048 );
1452 lcd_puts(0, y++, "Size");
1453 lcd_puts(0, y++, buf);
1454 break;
1456 case 3: {
1457 unsigned long free;
1458 fat_size( IF_MV2(0,) NULL, &free );
1459 snprintf(buf, sizeof buf, "%ld MB", free / 1024 );
1460 lcd_puts(0, y++, "Free");
1461 lcd_puts(0, y++, buf);
1462 break;
1465 case 4:
1466 snprintf(buf, sizeof buf, "%d ms", ata_spinup_time * (1000/HZ));
1467 lcd_puts(0, y++, "Spinup time");
1468 lcd_puts(0, y++, buf);
1469 break;
1471 case 5:
1472 i = identify_info[83] & (1<<3);
1473 lcd_puts(0, y++, "Power mgmt:");
1474 lcd_puts(0, y++, i ? "enabled" : "unsupported");
1475 break;
1477 case 6:
1478 i = identify_info[83] & (1<<9);
1479 lcd_puts(0, y++, "Noise mgmt:");
1480 lcd_puts(0, y++, i ? "enabled" : "unsupported");
1481 break;
1483 case 7:
1484 i = identify_info[82] & (1<<6);
1485 lcd_puts(0, y++, "Read-ahead:");
1486 lcd_puts(0, y++, i ? "enabled" : "unsupported");
1487 break;
1489 case 8:
1490 timing_info_present = identify_info[53] & (1<<1);
1491 if(timing_info_present) {
1492 pio3[1] = 0;
1493 pio4[1] = 0;
1494 lcd_puts(0, y++, "PIO modes:");
1495 pio3[0] = (identify_info[64] & (1<<0)) ? '3' : 0;
1496 pio4[0] = (identify_info[64] & (1<<1)) ? '4' : 0;
1497 snprintf(buf, 128, "0 1 2 %s %s", pio3, pio4);
1498 lcd_puts(0, y++, buf);
1499 } else {
1500 lcd_puts(0, y++, "No PIO mode info");
1502 break;
1504 case 9:
1505 timing_info_present = identify_info[53] & (1<<1);
1506 if(timing_info_present) {
1507 lcd_puts(0, y++, "Cycle times");
1508 snprintf(buf, 128, "%dns/%dns",
1509 identify_info[67],
1510 identify_info[68]);
1511 lcd_puts(0, y++, buf);
1512 } else {
1513 lcd_puts(0, y++, "No timing info");
1515 break;
1517 case 10:
1518 timing_info_present = identify_info[53] & (1<<1);
1519 if(timing_info_present) {
1520 i = identify_info[49] & (1<<11);
1521 snprintf(buf, 128, "IORDY support: %s", i ? "yes" : "no");
1522 lcd_puts(0, y++, buf);
1523 i = identify_info[49] & (1<<10);
1524 snprintf(buf, 128, "IORDY disable: %s", i ? "yes" : "no");
1525 lcd_puts(0, y++, buf);
1526 } else {
1527 lcd_puts(0, y++, "No timing info");
1529 break;
1531 case 11:
1532 lcd_puts(0, y++, "Cluster size");
1533 snprintf(buf, 128, "%d bytes", fat_get_cluster_size(IF_MV(0)));
1534 lcd_puts(0, y++, buf);
1535 break;
1537 lcd_update();
1539 /* Wait for a key to be pushed */
1540 key = button_get_w_tmo(HZ*5);
1541 switch(key) {
1542 case SETTINGS_CANCEL:
1543 done = true;
1544 break;
1546 case SETTINGS_DEC:
1547 if (--page < 0)
1548 page = max_page;
1549 break;
1551 case SETTINGS_INC:
1552 if (++page > max_page)
1553 page = 0;
1554 break;
1556 case SETTINGS_OK:
1557 if (page == 3) {
1558 mpeg_stop(); /* stop playback, to avoid disk access */
1559 lcd_clear_display();
1560 lcd_puts(0,0,"Scanning");
1561 lcd_puts(0,1,"disk...");
1562 lcd_update();
1563 fat_recalc_free(IF_MV(0));
1565 break;
1567 lcd_stop_scroll();
1570 return false;
1572 #endif
1574 bool dbg_save_roms(void)
1576 int fd;
1577 int oldmode = system_memory_guard(MEMGUARD_NONE);
1579 fd = creat("/internal_rom_0000-FFFF.bin", O_WRONLY);
1580 if(fd >= 0)
1582 write(fd, (void *)0, 0x10000);
1583 close(fd);
1586 fd = creat("/internal_rom_2000000-203FFFF.bin", O_WRONLY);
1587 if(fd >= 0)
1589 write(fd, (void *)0x2000000, 0x40000);
1590 close(fd);
1593 system_memory_guard(oldmode);
1594 return false;
1597 #ifdef CONFIG_TUNER
1598 extern int debug_fm_detection;
1600 bool dbg_fm_radio(void)
1602 char buf[32];
1603 int button;
1604 bool fm_detected;
1606 #ifdef HAVE_LCD_BITMAP
1607 lcd_setmargins(0, 0);
1608 #endif
1610 while(1)
1612 lcd_clear_display();
1613 fm_detected = radio_hardware_present();
1615 snprintf(buf, sizeof buf, "HW detected: %s", fm_detected?"yes":"no");
1616 lcd_puts(0, 0, buf);
1617 snprintf(buf, sizeof buf, "Result: %08x", debug_fm_detection);
1618 lcd_puts(0, 1, buf);
1619 lcd_update();
1621 button = button_get(true);
1623 switch(button)
1625 case SETTINGS_CANCEL:
1626 return false;
1629 return false;
1631 #endif
1633 #ifdef HAVE_LCD_BITMAP
1634 extern bool do_screendump_instead_of_usb;
1636 bool dbg_screendump(void)
1638 do_screendump_instead_of_usb = !do_screendump_instead_of_usb;
1639 splash(HZ, true, "Screendump %s",
1640 do_screendump_instead_of_usb?"enabled":"disabled");
1641 return false;
1643 #endif
1645 bool dbg_set_memory_guard(void)
1647 static const struct opt_items names[MAXMEMGUARD] = {
1648 { "None", -1 },
1649 { "Flash ROM writes", -1 },
1650 { "Zero area (all)", -1 }
1652 int mode = system_memory_guard(MEMGUARD_KEEP);
1654 set_option( "Catch mem accesses", &mode, INT, names, MAXMEMGUARD, NULL);
1655 system_memory_guard(mode);
1657 return false;
1660 bool debug_menu(void)
1662 int m;
1663 bool result;
1665 static const struct menu_item items[] = {
1666 { "Dump ROM contents", dbg_save_roms },
1667 { "View I/O ports", dbg_ports },
1668 #ifdef HAVE_LCD_BITMAP
1669 #ifdef HAVE_RTC
1670 { "View/clr RTC RAM", dbg_rtc },
1671 #endif /* HAVE_RTC */
1672 #endif /* HAVE_LCD_BITMAP */
1673 { "View OS stacks", dbg_os },
1674 { "Catch mem accesses", dbg_set_memory_guard },
1675 #if CONFIG_HWCODEC == MAS3507D
1676 { "View MAS info", dbg_mas_info },
1677 #endif
1678 { "View MAS regs", dbg_mas },
1679 #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
1680 { "View MAS codec", dbg_mas_codec },
1681 #endif
1682 #ifdef HAVE_LCD_BITMAP
1683 { "View battery", view_battery },
1684 { "Screendump", dbg_screendump },
1685 #endif
1686 { "View HW info", dbg_hw_info },
1687 { "View partitions", dbg_partitions },
1688 #ifdef HAVE_MMC
1689 { "View MMC info", dbg_mmc_info },
1690 #else
1691 { "View disk info", dbg_disk_info },
1692 #endif
1693 #ifdef HAVE_LCD_BITMAP
1694 { "View mpeg thread", dbg_mpeg_thread },
1695 #ifdef PM_DEBUG
1696 { "pm histogram", peak_meter_histogram},
1697 #endif /* PM_DEBUG */
1698 #endif /* HAVE_LCD_BITMAP */
1699 { "View runtime", view_runtime },
1700 #ifdef CONFIG_TUNER
1701 { "FM Radio", dbg_fm_radio },
1702 #endif
1705 m=menu_init( items, sizeof items / sizeof(struct menu_item), NULL,
1706 NULL, NULL, NULL);
1707 result = menu_run(m);
1708 menu_exit(m);
1710 return result;
1713 #endif /* SIMULATOR */